cc-safety-net 2.0.1 → 2.0.3

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{$ as Tt,$a as Xr,A as dn,Aa as mr,B as zl,Ba as Gt,C as P,Ca as gr,D as U,Da as $r,E as Yt,Ea as O,F as qt,Fa as Bt,G as Jn,Ga as Rt,H as jt,Ha as At,I as W2,Ia as T,J as y2,Ja as Nl,K as Ht,Ka as Ut,L as s2,La as nd,M as aa,Ma as lr,N as Ot,Na as td,O as Sn,Oa as ed,P as la,Pa as rd,Q as da,Qa as ad,R as Qn,Ra as ld,S as Xn,Sa as dd,T as un,Ta as Gr,U as pn,Ua as Ur,V as Ar,Va as Or,W as sn,Wa as Tr,X as w2,Xa as Zl,Y as Mt,Ya as Zr,Z as V2,Za as Qr,_ as sa,_a as Jt,aa as La,ab as Yr,b as Lr,ba as oa,bb as u2,c as or,ca as Hr,cb as h2,d as A,da as fr,db as l2,e as ur,ea as Mr,eb as Rr,f as gt,fa as Wr,fb as H,g as S,ga as Vr,gb as on,h as $,ha as Wt,hb as cn,i as rn,ia as hr,ib as ia,j as m,ja as D,jb as vn,k as f2,ka as Vt,kb as c2,l as jr,la as ca,lb as wa,m as X2,ma as d2,mb as Zn,n as an,na as Ln,o as Al,oa as Kt,p as kt,pa as Ct,q as Fr,qa as Kr,r as ln,ra as Cr,s as zr,sa as yr,t as Xt,ta as H2,u as Br,ua as Ft,v as Jr,va as zt,w as E,wa as Sr,x as _,xa as Z2,y as R2,ya as Il,z as A2,za as xr}from"../chunks/index-mf3j7fqk.js";var ud=["-h","--help"];function j(n,t){let e=Object.entries(n.booleans??{}),r=Object.entries(n.values??{}),a=Object.fromEntries(e.map(([L])=>[L,!1])),l={},d=[],s=[],c=!1,i=-1;for(let[L,u]of t.entries()){if(L<=i)continue;if(u==="--"){d.push(...t.slice(L+1));break}if(ud.includes(u)){c=!0;continue}let p=e.find(([,b])=>b.includes(u));if(p){a[p[0]]=!0;continue}let o=r.find(([,b])=>b.includes(u));if(o){let b=t[L+1];if(b===void 0||b.startsWith("-")){s.push(`${u} requires a value`);continue}l[o[0]]=b,i=L+1;continue}if(u.startsWith("-")){s.push(`Unknown option for ${n.label}: ${u}`);continue}if(n.positionals==="tail"){d.push(...t.slice(L));break}d.push(u)}if(n.positionals!=="list"&&n.positionals!=="tail")s.push(...d.map((L)=>`Unexpected argument for ${n.label}: ${L}`));return{flags:a,values:l,positionals:d,help:c,errors:s}}function r2(n){for(let t of n)console.error(t);return n.length>0}import{readdirSync as Pd,statSync as _r,unlinkSync as Id}from"node:fs";import{basename as Pr,dirname as Nd,join as ns,resolve as ts}from"node:path";function F(n){return Array.from(n,(t)=>{let e=t.charCodeAt(0);if(e<=31||e>=127&&e<=159)return`\\x${e.toString(16).padStart(2,"0")}`;return t}).join("")}var yt=(n)=>{let t=Date.now()-new Date(n).getTime();if(!Number.isFinite(t))return"";let e=Math.floor(t/60000),r=Math.floor(e/60),a=Math.floor(r/24);if(a>0)return`${a}d ago`;if(r>0)return`${r}h ago`;if(e>0)return`${e}m ago`;return"just now"},B2=(n)=>{let t=(n??"").trim().split(/\s+/).filter((a)=>a&&!/^[A-Za-z_][A-Za-z0-9_]*=/.test(a)),e=t[0]?.split("/").pop();if(!e)return null;let r=t[1];return r&&/^[a-z][a-z0-9-]*$/.test(r)?`${e} ${r}`:e};import{existsSync as pd,readdirSync as vd,readFileSync as bd}from"node:fs";import{join as fd}from"node:path";function o2(n,t){try{return vd(n,{withFileTypes:!0,encoding:"utf8"}).flatMap((e)=>{let r=fd(n,e.name);if(e.isDirectory())return o2(r,t);if(e.name.endsWith(".jsonl"))return[r];return[]})}catch{if(t&&pd(n))t.count++;return[]}}function wt(n){let t=(a)=>`${a.sessionId}
3
- ${B2(a.segment||a.command)}`,e=n.filter((a)=>a.decision!=="allow"),r=e.filter((a)=>a.sessionId).reduce((a,l)=>a.set(t(l),(a.get(t(l))??0)+1),new Map);return new Set(e.filter((a)=>a.failureStage||(r.get(t(a))??0)>=2))}function en(n,t){try{return bd(n,"utf-8").split(`
4
- `).filter(Boolean).flatMap((e)=>{try{return[JSON.parse(e)]}catch{if(t)t.count++;return[]}})}catch{if(t)t.count++;return[]}}import{resolve as Kd}from"node:path";var hd=["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 pr(n){let t=0,e={allocateSegment(){return t++},getNextSegmentIndex(){return t},recordGlobal(r){n.record({kind:"step",scope:"global",step:r})},recordSegment(r,a=e.currentSegmentIndex){if(a===void 0)return;n.record({kind:"step",scope:"segment",segmentIndex:a,step:r})}};return e}function vr(n={}){let t=[],e=n.maxEvents??512,r={maxTextLength:n.maxTextLength??2048,maxListLength:n.maxListLength??128,maxObjectProperties:n.maxObjectProperties??n.maxListLength??128,maxDepth:n.maxDepth??16},a=0,l,d=new Set;return{record(s){if(l)return;try{if(!s||t.length>=e){a++;return}t.push(mt(yd(s,r,d)))}catch{a++}},finish(s){if(l)return l;try{l=mt({events:Object.freeze(t),droppedEvents:a,terminal:wd(s,r,d)})}catch{a++,l=Object.freeze({events:Object.freeze(t),droppedEvents:a,terminal:Object.freeze({result:"blocked",reason:"trace unavailable".slice(0,r.maxTextLength),segment:"trace unavailable".slice(0,r.maxTextLength)})})}return l}}}function yd(n,t,e){if(n.kind!=="step")throw TypeError("invalid trace event");let{scope:r,step:a}=n;Fn(a,e,t);let l=J2(a,t,e);if(r==="global")return{kind:"step",scope:"global",step:l};if(r!=="segment")throw TypeError("invalid trace event scope");return{kind:"step",scope:"segment",segmentIndex:n.segmentIndex,step:l}}function wd(n,t,e){let r=n.result;if(r==="allowed")return Object.freeze({result:"allowed"});if(r!=="blocked")throw TypeError("invalid trace terminal");let a=n.ruleId;return Object.freeze({result:"blocked",reason:J2(n.reason,t,e),segment:J2(n.segment,t,e),...a?{ruleId:J2(a,t,e)}:{}})}function Fn(n,t,e,r=0,a=new WeakSet){if(typeof n==="string"){let s=n.slice(0,e.maxTextLength);if(!gt(s))return;for(let c of ur(s))for(let i of c.match(/[^\s"'()$]+/g)??[])t.add(br(i));return}if(!n||typeof n!=="object"||r>=e.maxDepth||a.has(n))return;if(a.add(n),Array.isArray(n)){let s=Math.min(n.length,e.maxListLength);for(let c=0;c<s;c++)Fn(n[c],t,e,r+1,a);return}let l=0,d=new Set;for(let s in n){if(!Object.hasOwn(n,s))continue;if(l>=e.maxObjectProperties)break;l++,Fn(s,t,e);let c=xt(s,e,t);if(d.has(c))continue;d.add(c),Fn(n[s],t,e,r+1,a)}}function J2(n,t,e,r=0,a=new WeakSet){if(typeof n==="string")return xt(n,t,e);if(!n||typeof n!=="object")return n;if(r>=t.maxDepth)return;if(a.has(n))return;if(a.add(n),Array.isArray(n)){let s=[],c=Math.min(n.length,t.maxListLength);for(let i=0;i<c;i++)s.push(J2(n[i],t,e,r+1,a));return s}let l={},d=0;for(let s in n){if(!Object.hasOwn(n,s))continue;if(d>=t.maxObjectProperties)break;d++;let c=xt(s,t,e);if(Object.hasOwn(l,c))continue;Object.defineProperty(l,c,{value:J2(n[s],t,e,r+1,a),enumerable:!0,configurable:!0,writable:!0})}return l}function xt(n,t,e){let r=n.slice(0,t.maxTextLength),a=gt(r)?or(r):r,l=e.size>0?md(a,e):a;return(xd(l)?Lr(l):l).slice(0,t.maxTextLength)}function xd(n){return n.includes("PRIVATE KEY")||n.includes("://")||n.includes("eyJ")||n.includes(":")&&/(?:authorization|cookie|x-api-key|api-key|(?:^|\s)(?:-u|--user)(?:\s|=))/i.test(n)||n.length>=14&&hd.some((t)=>n.includes(t))||n.length>=49&&/\b[a-f0-9]{32}\.[A-Za-z0-9]{16}\b/.test(n)}function md(n,t){return n.replace(/[^\s"'()$]+/g,(e)=>t.has(br(e))?"<redacted>":e)}function br(n){let t=2166136261,e=2166136261;for(let r=0;r<n.length;r++)t=Math.imul(t^n.charCodeAt(r),16777619),e=Math.imul(e^n.charCodeAt(n.length-r-1),16777619);return`${t>>>0}:${e>>>0}:${n.length}`}function mt(n){if(n&&typeof n==="object"&&!Object.isFrozen(n)){for(let t of Object.values(n))mt(t);Object.freeze(n)}return n}function wr(n,t,e,r){let a=r??fr(),l=e??a.getCommandProgram(n,t.shell??"auto"),d=vr(),s=pr(d),c=l.dialect==="powershell"?a.getCommandProgram(n,"posix"):l,i=hr(c);s.recordGlobal({type:"parse",input:n,segments:i.map((p)=>[...p])});let L=yr(n,{...t,analyzePartialProgram:!0,trace:s},l,a),u=s.getNextSegmentIndex();if(L&&u>0&&u<i.length)s.recordSegment({type:"segment-skipped",index:u,reason:"prior-segment-blocked"},u);return Object.freeze({decision:L,trace:d.finish(L?{result:"blocked",reason:L.reason,segment:L.evidence.find((p)=>p.kind==="command")?.segment??n,...L.ruleId?{ruleId:L.ruleId}:{}}:{result:"allowed"}),program:l})}import{resolve as gd}from"node:path";function $t(n){let t=xr().safeParse(n);return{errors:t.success?[]:gr(t.error.issues),ruleNames:new Set(mr(n).map((e)=>e.toLowerCase()))}}function Dt(n){let t=Dr(n);if(!t.ok)return t.result;return $t(t.parsed)}function Dr(n){let t=[],e=new Set;try{let r=typeof n==="string"?rn(n):n,a=m(r);if(a===null)return t.push(`File not found: ${r.path}`),{ok:!1,result:{errors:t,ruleNames:e}};if(!a.trim())return t.push("Config file is empty"),{ok:!1,result:{errors:t,ruleNames:e}};return{ok:!0,parsed:JSON.parse(a)}}catch(r){return t.push(r instanceof S?r.message:"Invalid JSON"),{ok:!1,result:{errors:t,ruleNames:e}}}}function kr(n){return gd(n??process.cwd(),".safety-net.json")}function a2(n){let t=Dr(n);if(!t.ok)return t.result;let e=$r(t.parsed);return{errors:e.errors,ruleNames:e.sources}}import{isAbsolute as $d,join as zn,relative as Dd,resolve as qr,sep as kd}from"node:path";async function Y2(n={}){let t=Zt(n);return qd(t,await Bn(t,Z2()))}function qd(n,t){if(!t.ok)return t;let e=U(n),r=[...new Set(l2(e.configPath,e.lockPath,n,e.filesystemScope))];if(r.length===0)return t;return{ok:!1,errors:r,warnings:t.warnings,entries:t.entries}}async function Bn(n,t,e,r={}){let a=null,l=!1;try{let d=U(n),s=Bt(d.configTarget);if(!s.ok)return s.result;let c=s.config;if(n.check)return Sd(c,d,n);a={target:d.lockTarget,content:m(d.lockTarget)};let i=Jt(d.lockTarget);if(i.errors.some((f)=>f.startsWith("Unable to access ")))return{ok:!1,errors:i.errors,warnings:[],entries:[]};if(n.only&&i.errors.length>0)return{ok:!1,errors:i.errors,warnings:[],entries:[]};let L=i.errors.length>0?null:i.lock,u=n.only?Zr(c,L,n.only):{ok:!0,specs:c.rules};if(!u.ok)return u.result;if(n.only&&!L&&u.specs.length<c.rules.length)return{ok:!1,errors:[`No lockfile available for partial update; run ${Jr}`],warnings:[],entries:[]};let p=(await Fd(u.specs,(f)=>Xr(f,d.configDir,n,L,d.filesystemScope,t),t)).map((f)=>Zd(f,L,e));for(let f of p)Yd(f.content,f.entry,d.configDir,n,d.filesystemScope);let o=n.only?Qd(c,L,p):p.map((f)=>f.entry);l=!0,T(d.lockTarget,{version:1,rulebooks:o},void 0,r._testAfterPolicyRename);let b=new Map(p.map((f)=>[f.entry.spec,f.rulebook.rules.length])),v=Rd(o,d.configDir,n,d.filesystemScope,r);return{ok:!0,errors:[],warnings:v,entries:o.map((f)=>Xd(f,b))}}catch(d){if(l&&a)try{S2(a.target,a.content)}catch(s){return Q2(s)}return Q2(d)}}async function St(n,t={}){return jd(n,Zt(t),Z2())}async function jd(n,t,e,r={}){let a=null,l=!1;try{let d=U(t),s=m(d.configTarget);a={target:d.configTarget,content:s};let c=Bt(d.configTarget);if(!c.ok)return c.result;let i=c.config,L=Br(n)?await Yr(n,e):[{spec:n}],u=L.map((b)=>b.spec),p=[...new Set([...i.rules,...u])];if(p.length>Ft)return zd();if(p.length!==i.rules.length)l=!0,T(d.configTarget,{version:1,rules:p,overrides:i.overrides??{},transparent_wrappers:i.transparent_wrappers??[]},void 0,r._testAfterPolicyRename);let o=await Bn(t,e,new Map(L.filter((b)=>!!b.display_ref).map((b)=>[b.spec,b.display_ref])),r);if(!o.ok)S2(d.configTarget,s);return o}catch(d){if(l&&a)try{S2(a.target,a.content)}catch(s){return Q2(s)}return Q2(d)}}async function Fd(n,t,e=Z2()){if(n.length>Ft)throw Error(zt);let r=Array(n.length),a=0,l,d=Array.from({length:Math.min(n.length,Sr.concurrency)},async()=>{while(!l){let s=a;if(s>=n.length)return;a++;try{r[s]=await t(n[s],s,e.controller.signal)}catch(c){if(!l)l={value:c},a=n.length,e.controller.abort(c);return}}});if(await Promise.all(d),l)throw l.value;return r}function zd(){return{ok:!1,errors:[zt],warnings:[],entries:[]}}function Zt(n){return{cwd:n.cwd,cacheConfigDir:n.cacheConfigDir,userConfigDir:n.userConfigDir,userConfigPath:n.userConfigPath,projectConfigPath:n.projectConfigPath,global:n.global,check:n.check,only:n.only,refresh:n.refresh}}function Bd(n){return{...Zt(n),deleteSource:n.deleteSource}}async function Qt(n,t={}){try{return await Jd(n,Bd(t),{})}catch(e){return Q2(e)}}async function Jd(n,t,e){let r=U(t),a=O(r.configTarget);if(a.errors.length>0)return{ok:!1,errors:a.errors,warnings:[],entries:[]};if(!a.config)return{ok:!1,errors:[`No config found at ${r.configPath}`],warnings:[],entries:[]};let l=Jt(r.lockTarget);if(l.errors.length>0)return{ok:!1,errors:l.errors,warnings:[],entries:[]};let d=Qr(a.config.rules,l.lock,n);if(!d.ok)return d.result;let s=t.deleteSource?Ad(r.configDir,d.specs,l.lock,r.filesystemScope):{ok:!0,dirs:[]};if(!s.ok)return s.result;let c=m(r.configTarget);if(c===null)return Q2(Error("Rules config is unavailable."));try{T(r.configTarget,{version:1,rules:a.config.rules.filter((u)=>!d.specs.includes(u)),overrides:a.config.overrides??{},transparent_wrappers:a.config.transparent_wrappers??[]},void 0,e._testAfterPolicyRename)}catch(u){throw S2(r.configTarget,c),u}let i=await Bn(t,Z2(),void 0,e);if(!i.ok)return S2(r.configTarget,c),i;let L=Md(s.dirs,e,r.filesystemScope);if(!L.ok){S2(r.configTarget,c);let u=await Bn(t,Z2(),void 0,e);if(!u.ok)return{ok:!1,errors:[...L.result.errors,...u.errors],warnings:u.warnings,entries:u.entries};return L.result}return i}async function Sd(n,t,e){let r=Rr(n,t.lockPath,t.configDir,e,e.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 Zd(n,t,e){let r=t?.rulebooks.find((l)=>l.spec===n.entry.spec&&l.kind==="github"),a=e?.get(n.entry.spec)??(r?.kind==="github"?r.display_ref:void 0);if(!a||n.entry.kind!=="github")return n;return{...n,entry:{...n.entry,display_ref:a}}}function Qd(n,t,e){let r=new Set(n.rules),a=new Set(t?.rulebooks.map((d)=>d.spec)??[]),l=new Map(e.map((d)=>[d.entry.spec,d.entry]));return[...(t?.rulebooks.filter((d)=>r.has(d.spec))??[]).map((d)=>l.get(d.spec)??d),...e.filter((d)=>!a.has(d.entry.spec)).map((d)=>d.entry)]}function Xd(n,t){return{...n,ruleCount:t.get(n.spec)}}function Yd(n,t,e,r,a){let l=qt(t,jt(e,r));f2($(a,l),n)}function Rd(n,t,e,r,a){let l=jt(t,e),d=Jn(l),s=$(r,d),c=X2(s);if(!c)return[];let i=n.map((u)=>$(r,qt(u,l))),L=c.filter((u)=>u.kind==="directory").map((u)=>({directory:$(r,zn(d,u.name)),identity:$(r,zn(d,u.name,zr))})).filter((u)=>!i.some((p)=>jr(u.identity,p))).map((u)=>u.directory);for(let u of L)Fr(u);return L.flatMap((u)=>{try{return Wd(u,a),[]}catch{return["Unable to prune rules policy cache safely."]}})}function Ad(n,t,e,r){let a=new Map(e?.rulebooks.map((i)=>[i.spec,i])??[]),l=t.flatMap((i)=>{let L=a.get(i);if(!L)return ln.test(i)?[]:["--delete-source can only delete local rulebook sources"];return L.kind==="local-directory"?[]:["--delete-source can only delete local rulebook sources"]}),d=t.map((i)=>{let L=a.get(i);return zn(n,L?.kind==="local-directory"?L.path:i)}),s=l.length>0?[]:d.flatMap((i)=>Hd(n,i,r)),c=[...l,...s];return c.length>0?{ok:!1,result:{ok:!1,errors:c,warnings:[],entries:[]}}:{ok:!0,dirs:d}}function Hd(n,t,e){let r=qr(n),a=qr(t),l=Dd(r,a);if(l===""||l===".."||l.startsWith(`..${kd}`)||$d(l))return[`Refusing to delete local rulebook source outside ${n}: ${t}`];let d=$(e,a),s=X2(d);if(!s)return[`Local rulebook source directory not found: ${t}`];let c=s.find((i)=>i.name==="rulebook.json");if(!c)return[`Local rulebook source directory is missing rulebook.json: ${t}`];if(c.kind!=="file")throw new S(e.label);if(m($(e,zn(a,"rulebook.json"))),s.length>1)return[`Local rulebook source directory contains extra files: ${t}. delete manually if you really want to remove the directory.`];return[]}function Md(n,t,e){let r=n.flatMap((a)=>{try{return Vd($(e,a),t),[]}catch(l){return[`Failed to delete local rulebook source ${a}: ${l instanceof Error?l.message:String(l)}`]}});return r.length>0?{ok:!1,result:{ok:!1,errors:r,warnings:[],entries:[]}}:{ok:!0}}function Wd(n,t){if(t._testPruneRulebookCacheDir){t._testPruneRulebookCacheDir(n.path);return}kt(n)}function Vd(n,t){if(t._testDeleteLocalSourceDir){t._testDeleteLocalSourceDir(n.path);return}kt(n)}function S2(n,t){if(t===null){an(n);return}f2(n,t)}function Q2(n){return{ok:!1,errors:[n instanceof Error?n.message:String(n)],warnings:[],entries:[]}}function M2(n,t){let e=Gd(t),r=Kr(e),a={effectiveLevel:r.effectiveLevel,selectedPreset:e.policySnapshot.policy.safety.level??"standard",effectiveCapabilities:r.effectiveCapabilities,destructiveCommandRuleOverrides:e.policySnapshot.policy.destructiveCommandRuleOverrides},{configSource:l,configValid:d}=Cd({cwd:t?.cwd,userConfigDir:t?.userConfigDir});if(!n||!n.trim())return{trace:{steps:[{type:"error",message:"No command provided"}],segments:[]},result:"allowed",configSource:l,configValid:d,...a};let s=Ud(n,e);if(s)return{trace:{steps:[],segments:[{index:0,steps:[{type:"rule-check",ruleModule:s.ruleModule,ruleFunction:s.ruleFunction,matched:!0,reason:s.reason}]}]},result:"blocked",reason:A(s.reason),segment:A(s.target),...s.ruleId?{ruleId:A(s.ruleId)}:{},configSource:l,configValid:d,...a};let c=wr(n,e),i=c.decision,L=i?.ruleId??Od(n,e),u=sn.find((o)=>o.id===L&&o.activationCapability),p=u?r.policy.effectiveDestructiveCommandRules[u.id]:void 0;return{trace:Ed(c.trace),result:i?"blocked":"allowed",reason:i?A(i.reason):void 0,segment:i?A(i.evidence.find((o)=>o.kind==="command")?.segment??n):void 0,ruleId:i?.ruleId?A(i.ruleId):void 0,customRule:Td(_d(i?.ruleId,e.policySnapshot)),configSource:l,configValid:d,...a,...u&&p?{ruleActivation:{id:u.id,...p}}:{}}}function Cd(n){let t=E(n?.cwd),e=n?.userConfigPath??_(n),r=P({cwd:n?.cwd,userConfigDir:n?.userConfigDir,userConfigPath:n?.userConfigPath});try{if(m(r.projectConfigTarget)!==null){if(a2(r.projectConfigTarget).errors.length===0)return{configSource:t,configValid:!0};return{configSource:t,configValid:!1}}}catch(a){if(a instanceof S)return{configSource:t,configValid:!1};throw a}try{if(m(r.userConfigTarget)!==null){let a=a2(r.userConfigTarget);return{configSource:e,configValid:a.errors.length===0}}return{configSource:null,configValid:!0}}catch(a){if(a instanceof S)return{configSource:e,configValid:!1};throw a}}function Gd(n){let t=Kd(n?.cwd??process.cwd()),e=n?.policySnapshot??H({cwd:t,userConfigDir:n?.userConfigDir}),r=d2(e.policy);return{cwd:t,effectiveCwd:t,policySnapshot:e,environment:Ar(),protectedGitMetadata:Vr(t),effectiveCapabilities:r.capabilities,strict:n?.strict??r.strict,paranoidRm:r.paranoidRm,paranoidInterpreters:r.paranoidInterpreters,worktreeMode:r.worktreeMode}}function Ud(n,t){let e=t.cwd??process.cwd(),r=Hr(H2("",{command:n},{kind:"command",shell:"posix"},{executionCwd:e,configCwd:e},n)),a=Ur(r);if(a)return{reason:Gr,target:a.target,ruleId:"policy-protection",ruleModule:"policy-protection",ruleFunction:"findPolicyConfigMutationTarget"};let l=Wr(r,t.protectedGitMetadata);if(l)return{reason:Mr,target:l.target,ruleId:"git-metadata-protection",ruleModule:"git-metadata-protection",ruleFunction:"findGitMetadataMutationTarget"};let d=t.policySnapshot.policy,s=d.secretProtection.enabled===!1?null:Tr(r,d.secretProtection,{strict:t.strict});if(s)return{reason:Or,target:s.target,ruleId:s.ruleId,ruleModule:"secret-protection",ruleFunction:"findSensitiveTarget"};return null}function Od(n,t){let e=t.policySnapshot.policy,r=cn({...e,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:{...e.destructiveCommandRuleOverrides,...Object.fromEntries(sn.flatMap((a)=>a.activationCapability?[[a.id,"on"]]:[]))}},t.policySnapshot.state==="degraded"?{diagnostics:t.policySnapshot.diagnostics,reason:t.policySnapshot.reason}:void 0);return Cr(n,{...t,policySnapshot:r,strict:!0,paranoidRm:!0,paranoidInterpreters:!0})?.ruleId}function Td(n){if(!n)return;return{id:A(n.id),...n.rulebook?{rulebook:{name:A(n.rulebook.name),version:A(n.rulebook.version)}}:{},...n.source?{source:A(n.source)}:{},...n.override?{override:{type:"reason",reason:A(n.override.reason)}}:{}}}function Ed(n){let t=n.events.flatMap((r)=>r.kind==="step"&&r.scope==="global"?[r.step]:[]),e=new Map;for(let r of n.events){if(r.kind!=="step"||r.scope!=="segment")continue;let a=e.get(r.segmentIndex)??{index:r.segmentIndex,steps:[]};a.steps.push(r.step),e.set(r.segmentIndex,a)}return{steps:t,segments:[...e.values()]}}function _d(n,t){let e=n?.replace(/^custom\./,"");if(!e||!t.policy.rules.some((r)=>r.name===e))return;return t.ruleMetadata[e]??Object.freeze({id:e})}function es(n){let t=W2(),e=j({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"]}},n);if(r2(e.errors))return null;if(e.values.id!==void 0&&!/^[a-f0-9]{16}$/.test(e.values.id))return console.error("--id must be 16 hexadecimal characters"),null;let r=e.values.limit===void 0?20:Er(e.values.limit);if(r===null)return console.error("--limit must be a positive number"),null;let a=e.values.since===void 0?Math.min(30,t):Er(e.values.since);if(a===null||a>t)return console.error(`--since must be a positive number of days no greater than ${t}`),null;let l={limit:r,limitExplicit:e.values.limit!==void 0,since:a,sinceExplicit:e.values.since!==void 0,all:e.flags.all,json:e.flags.json,suspect:e.flags.suspect,pruneLegacy:e.flags.pruneLegacy,dryRun:e.flags.dryRun,id:e.values.id,agent:e.values.agent,rule:e.values.rule,session:e.values.session,project:e.values.project===void 0?void 0:ts(e.values.project)};if(l.id&&(l.agent!==void 0||l.rule!==void 0||l.session!==void 0||l.project!==void 0||l.suspect||l.sinceExplicit||l.limitExplicit))return console.error("--id cannot be combined with --agent, --rule, --session, --project, --suspect, --since, or --limit"),null;if(l.pruneLegacy&&(l.id!==void 0||l.agent!==void 0||l.rule!==void 0||l.session!==void 0||l.project!==void 0||l.suspect||l.all||l.sinceExplicit||l.limitExplicit))return console.error("--prune-legacy cannot be combined with --id, --agent, --rule, --session, --project, --suspect, --all, --since, or --limit"),null;if(l.dryRun&&!l.pruneLegacy)return console.error("--dry-run requires --prune-legacy"),null;return l}async function Ir(n,t={}){let e=es(n);if(!e)return 1;let r=t.logsDir??s2();if(e.pruneLegacy)return rs(r,e.json,e.dryRun);if(!r)return console.log(e.json?"[]":e.id?`No retained audit log entry found for id ${F(e.id)}.`:"No audit log entries found."),0;y2(r);let a={count:0},l=o2(r,a).flatMap((L)=>en(L,a).map((u)=>({entry:u,file:L})));if(a.count>0)console.error(`warning: ${a.count} audit log ${a.count===1?"source":"sources"} could not be read; these results are incomplete`);if(e.id)return ss(l,e,t.timeZone);let d=Date.now()-e.since*24*60*60*1000,s=l.filter((L)=>cs(L,e,r,d)),c=e.suspect?wt(s.map((L)=>L.entry)):null,i=(c?s.filter((L)=>c.has(L.entry)):s).sort((L,u)=>Date.parse(u.entry.ts)-Date.parse(L.entry.ts)).slice(0,e.limit);if(e.json)return console.log(JSON.stringify(i.map((L)=>L.entry),null,2)),0;if(i.length===0)return console.log("No audit log entries found."),0;for(let L of i)console.log(os(L.entry,t.timeZone));return 0}function rs(n,t,e){let r=n?ls(n).map((s)=>ns(n,s)):[];if(e)return as(r,t);let a=[],l=0,d=0;for(let s of r){let c=_r(s,{throwIfNoEntry:!1})?.size??0,i=ds(s);if(i){a.push(`${Pr(s)}: ${i}`);continue}l++,d+=c}if(t)return console.log(JSON.stringify({removedFiles:l,removedBytes:d,failedFiles:a.length})),a.length===0?0:1;console.log(l===0&&a.length===0?"No legacy audit log files found.":`Removed ${l} legacy audit log ${l===1?"file":"files"} (${Nr(d)}).`);for(let s of a)console.error(`Could not remove ${F(s)}`);if(console.log("Nested v2 audit logs were not changed."),l>0)console.log("This deletion cannot be undone.");return a.length===0?0:1}function as(n,t){let e=n.reduce((r,a)=>r+(_r(a,{throwIfNoEntry:!1})?.size??0),0);if(t)return console.log(JSON.stringify({dryRun:!0,files:n.length,bytes:e})),0;if(console.log(n.length===0?"No legacy audit log files found.":`Would remove ${n.length} legacy audit log ${n.length===1?"file":"files"} (${Nr(e)}).`),console.log("Nested v2 audit logs are not included."),n.length>0)console.log("Run the same command without --dry-run to delete them.");return 0}function ls(n){try{return Pd(n,{withFileTypes:!0}).filter((t)=>t.isFile()&&t.name.endsWith(".jsonl")).map((t)=>t.name)}catch{return[]}}function ds(n){try{return Id(n),null}catch(t){return t instanceof Error?t.message:String(t)}}function Nr(n){let t=["B","KiB","MiB","GiB"],e=Math.min(Math.floor(Math.log2(Math.max(n,1))/10),t.length-1);return`${Math.round(n/1024**e*10)/10} ${t[e]}`}function ss(n,t,e){let r=n.filter((l)=>l.entry.id===t.id);if(r.length>1)return console.error(`Multiple audit log entries found for id ${F(t.id??"")}.`),1;if(t.json)return console.log(JSON.stringify(r.map((l)=>l.entry),null,2)),0;let a=r[0];if(!a)return console.log(`No retained audit log entry found for id ${F(t.id??"")}.`),0;return console.log(us(a.entry,e)),0}function cs(n,t,e,r){if(!t.all&&n.entry.decision==="allow")return!1;if(Date.parse(n.entry.ts)<r)return!1;if(t.agent!==void 0&&n.entry.agent!==t.agent)return!1;if(t.rule!==void 0&&n.entry.ruleId!==t.rule)return!1;if(t.session!==void 0&&!is(n,e,t.session))return!1;if(t.project!==void 0&&!Ls(n.entry.cwd,t.project))return!1;return!0}function is(n,t,e){if(n.entry.sessionId===e)return!0;return Nd(n.file)===t&&Pr(n.file,".jsonl")===e}function Ls(n,t){if(!n)return!1;return n===t||n.startsWith(`${t}/`)}function os(n,t){let e=F(n.id??"-"),r=F(n.decision??"deny"),a=n.cwd?` [${F(n.cwd)}]`:"",l=n.segment||n.command,d=l===n.command?"":"↳ ",s=l.length>50?`${l.slice(0,50)}…`:l;return`${e.padEnd(16)} ${F(na(n.ts,t))} ${r.padEnd(5)} ${F(n.agent??"-").padEnd(15)} ${F(n.ruleId??"-").padEnd(20)} ${d}${F(s)}${a}`}function us(n,t){let e=(a)=>F(a===void 0||a===null||a===""?"-":a),r=n.shape?`${n.agent??"-"} (shape: ${n.shape})`:n.agent??"-";return[`id: ${e(n.id)}`,`ts: ${e(na(n.ts,t))}`,`decision: ${e(n.decision)}`,`agent: ${e(r)}`,`level: ${e(n.level)}`,`tool: ${e(n.toolName)}`,`rule: ${e(n.ruleId)}`,`intent: ${e(n.intent)}`,`stage: ${e(n.failureStage)}`,`error: ${e(n.errorCode)}`,`session: ${e(n.sessionId)}`,`cwd: ${e(n.cwd)}`,`version: ${e(n.v)}`,`truncated: ${e(n.truncated===!0?"yes":void 0)}`,`reason: ${e(n.reason)}`,`command: ${e(n.command)}`,`segment: ${e(n.segment)}`].join(`
5
- `)}function na(n,t){let e=new Date(n);if(Number.isNaN(e.getTime()))return n;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(e)}function Er(n){let t=Number(n);return Number.isFinite(t)&&t>0?t:null}var ta={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 ea={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 ra={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 ua,relative as $s}from"node:path";var ps=8388608;function vs(n,t){console.log(JSON.stringify(n(la(t))))}async function bs(n){let t;try{t=(await Et(process.stdin)).trim()}catch{n({reason:"Failed to parse hook input JSON."});return}if(!t){n({reason:"Missing hook input JSON."});return}return _t(t,n,"Failed to parse hook input JSON.")}async function Et(n){let t=[],e=0;for await(let r of n){let a=typeof r==="string"?Buffer.from(r,"utf-8"):Buffer.from(r.buffer,r.byteOffset,r.byteLength);if(e+=a.byteLength,e>ps)throw fs(n),Error("hook input byte limit exceeded");t.push(a)}return Buffer.concat(t,e).toString("utf-8")}function fs(n){let t=n.destroy??n.cancel;if(!t)return;try{Promise.resolve(t.call(n)).catch(()=>{})}catch{}}function _t(n,t,e){try{return JSON.parse(n)}catch{t({reason:e});return}}function Q(n,t){let e=t.get(n);return e?{kind:"command",shell:e}:{kind:sa(n)}}function I(n,t,e,r){let a=n===void 0?process.cwd():n,l=typeof a==="string"&&a.trim()!==""?c2([a]):void 0;if(l)return{configCwd:l,executionCwd:l};return R(r,t,e,xs(a)),null}function R(n,t,e,r){let a;try{a=Tt(t)}catch(l){if(!(l instanceof V2))throw l}n(Sn({command:a,segment:r,toolName:e}))}async function hs(n){let t=await bs(n.outputDeny);if(t===void 0)return;if(!t||typeof t!=="object"||Array.isArray(t)){R(n.outputDeny);return}if(!n.isSupported(t))return;let e=n.getAgent?.(t)??n.agent,r=n.agent===e?void 0:n.agent,a=gs(t),l=(o,b)=>{aa(o,()=>n.getSessionId(t),{agent:e,shape:r,toolName:b,cwd:a}),n.outputDeny(o)},d=n.getToolName(t);if(typeof d!=="string"||d.trim()===""){R((o)=>l(o),ms(t));return}let s=d,c=(o)=>l(o,s),i;try{i=n.getToolInput(t,s,c)}catch(o){if(!(o instanceof V2))throw o;R(c,void 0,s);return}if(!i.ok)return;let L=n.getContext(t,i.input,s,c);if(!L)return;let u;try{u=Tt(i.input)}catch(o){if(!(o instanceof V2))throw o;R(c,void 0,s);return}let p=H2(s,i.input,i.route,L,u??null);try{let o=Zn(p,{guard:{auditAllowed:ca(),dependencies:n.guardDependencies},audit:{agent:e,shape:r,getSessionId:()=>n.getSessionId(t)}}),b=Ot(o,{includeEvidence:!0,toolName:o.stage==="command-analysis"?void 0:s});if(b){n.outputDeny(b);return}n.outputAllow?.()}catch(o){if(!(o instanceof ia))throw o;ys(o);let b=Ot(o.evaluation,{includeEvidence:!0,toolName:o.evaluation.stage==="command-analysis"?void 0:s});if(b)n.outputDeny(b);return}}function ys(n){if(!Ln(D.debug))return;console.error(`CC Safety Net debug: ${ws(n.stage)}: ${da(n.cause)}`)}function ws(n){if(n==="policy-protection")return"hook policy protection failed";if(n==="config-load")return"hook config loading failed";if(n==="secret-protection")return"hook secret protection failed";return"hook analysis failed"}function xs(n){return typeof n==="string"?n:void 0}function ms(n){if(!n||typeof n!=="object"||Array.isArray(n))return;if(Object.hasOwn(n,"tool_input"))return n.tool_input;let t=n.toolCall;if(t&&typeof t==="object"&&!Array.isArray(t))return t.args;return}function gs(n){if(!n||typeof n!=="object"||Array.isArray(n))return null;let t=n.cwd;if(typeof t==="string")return t;let e=n.toolCall;if(!e||typeof e!=="object"||Array.isArray(e))return null;let r=e.args;if(!r||typeof r!=="object"||Array.isArray(r))return null;let a=r.Cwd;return typeof a==="string"?a:null}async function X(n){let t=(a)=>vs(n.createDenyOutput,a),e=n.createAllowOutput;await hs({...n,outputDeny:t,outputAllow:e?()=>console.log(JSON.stringify(e())):void 0})}var Ds=new Map([["run_command","auto"]]),ks=new Set(["absolutepath","directorypath","file_path","filepath","path","searchdirectory","searchpath","target_file","targetfile"]);function pa(n){return Q(n,Ds)}async function va(){await X({agent:"antigravity-cli",createDenyOutput:(n)=>({decision:"deny",reason:n}),isSupported:()=>!0,getToolName:(n)=>n.toolCall?.name,getToolInput:(n,t)=>({ok:!0,input:Bs(n.toolCall?.args,t),route:pa(t)}),getContext:qs,getSessionId:(n)=>n.conversationId})}function qs(n,t,e,r){let l=zs(n).flatMap((i)=>{let L=c2([i]);return L?[L]:[]});if(!l[0])return x2(r,t,e),null;if(e!=="run_command"){let i;try{i=js(t,e,l)}catch(L){if(L instanceof V2)return x2(r,void 0,e),null;if(!(L instanceof Qn))throw L;return x2(r,t,e),null}if(!i)return x2(r,t,e),null;return{configCwd:i,executionCwd:i,policyConfigCwds:l}}let d=n.toolCall?.args;if(!d||!Object.hasOwn(d,"Cwd"))return{configCwd:l[0],executionCwd:l[0],policyConfigCwds:l};let s=d.Cwd;if(typeof s!=="string"||s.trim()==="")return x2(r,t,e),null;let c=vn(s,l);if(c){let i=ba(c,l);if(!i)return x2(r,t,e,s),null;return{configCwd:i,executionCwd:c,policyConfigCwds:l}}return x2(r,t,e,s),null}function js(n,t,e){let r=pa(t),a=[...La(n,ks),...r.kind==="patch"?oa(n):[]].filter(ua),l=Xn(),d=new Set(a.flatMap((s)=>{let c=ba(un(s,pn,l),e);return c?[c]:[]}));if(d.size>1)return null;return[...d][0]??e[0]??null}function ba(n,t){return t.filter((e)=>Fs(n,e)).reduce((e,r)=>r.length>e.length?r:e,"")||null}function Fs(n,t){let e=$s(t,n);return e===""||!e.startsWith("..")&&!ua(e)}function x2(n,t,e,r){let a=t&&typeof t==="object"?t.command:void 0;n(Sn({command:typeof a==="string"?a:void 0,segment:r,toolName:e}))}function zs(n){if(n.workspacePaths===void 0)return[process.cwd()];let t=Array.isArray(n.workspacePaths)?n.workspacePaths.filter((e)=>typeof e==="string"&&e.trim()!==""):[];return c2(t)?t:[]}function Bs(n,t){if(!n)return;if(t!=="run_command")return n;return{...n,command:typeof n.CommandLine==="string"&&n.CommandLine!==""?n.CommandLine:void 0}}var K2=[{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",installLabel:"Antigravity CLI",helpTarget:"Antigravity CLI 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",installLabel:"Claude Code",helpTarget:"Claude Code plugin",probeCommand:["claude","--version"]}},{id:"codex",displayName:"Codex",doctorOrder:4,install:{order:4,flag:"--codex",installLabel:"Codex",helpTarget:"Codex 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",installLabel:"GitHub Copilot CLI",helpTarget:"GitHub Copilot CLI 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",installLabel:"Gemini CLI",helpTarget:"Gemini CLI 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",installLabel:"Hermes Agent",helpTarget:"Hermes Agent 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",installLabel:"Kimi Code",helpTarget:"Kimi Code hook config",probeCommand:["kimi","--version"]}},{id:"openclaw",displayName:"OpenClaw",doctorOrder:10,install:{order:10,flag:"--openclaw",installLabel:"OpenClaw",helpTarget:"OpenClaw plugin",probeCommand:["openclaw","--version"]}},{id:"opencode",displayName:"OpenCode",doctorOrder:11,install:{order:11,flag:"--opencode",installLabel:"OpenCode",helpTarget:"OpenCode plugin",probeCommand:["opencode","--version"]}},{id:"pi",displayName:"Pi",doctorOrder:12,install:{order:12,flag:"--pi",installLabel:"Pi",helpTarget:"Pi 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",installLabel:"Cursor",helpTarget:"Cursor hook config",probeCommand:["cursor","--version"]}},{id:"amp",displayName:"Amp Code",doctorOrder:2,install:{order:1,flag:"--amp",installLabel:"Amp Code",helpTarget:"Amp Code plugin",probeCommand:["amp","--version"]}}],fa=K2.slice().sort((n,t)=>n.doctorOrder-t.doctorOrder).map((n)=>n.id),ha=K2.filter((n)=>("runtime"in n)).slice().sort((n,t)=>n.runtime.order-t.runtime.order).map((n)=>({id:n.id,displayName:"displayName"in n.runtime?n.runtime.displayName:n.displayName,flags:n.runtime.flags,legacyFlags:"legacyFlags"in n.runtime?n.runtime.legacyFlags:[],description:n.runtime.description,legacyTopLevelFlags:n.runtime.legacyTopLevelFlags})),i2=K2.slice().sort((n,t)=>n.install.order-t.install.order).map((n)=>({id:n.id,...n.install})).map(({order:n,...t})=>t),ip=Object.fromEntries(K2.map((n)=>[n.id,n.displayName]));function p2(n){return K2.find((t)=>t.id===n)?.displayName??n}function m2(n){return K2.find((t)=>t.id===n)?.install.installLabel??n}import{homedir as Js}from"node:os";import{isAbsolute as ya,join as Pt}from"node:path";function xa(n){if(n!==void 0&&n!==null&&!ya(n))return"unknown";try{let t=Xn(),e=n?un(n,pn,t):void 0,r=process.env.HOME||Js(),a=[["codex",process.env.CODEX_HOME||Pt(r,".codex")],["copilot-cli",process.env.COPILOT_HOME||Pt(r,".copilot")],["claude-code",process.env.CLAUDE_CONFIG_DIR||Pt(r,".claude")]],l=e?a.flatMap(([d,s])=>{if(!ya(s))return[];return wa(e,un(s,pn,t))?[d]:[]}):[];if(l.length===1)return l[0]??"unknown";if(l.length>1)return"unknown"}catch(t){if(t instanceof Qn)return"unknown";return"unknown"}if(process.env.CLAUDECODE==="1"||Boolean(process.env.CLAUDE_CODE_ENTRYPOINT))return"claude-code";return"unknown"}var It="PreToolUse",ma="BeforeTool",ga="pre_tool_call",Nt="PreToolUse";var Ss=new Map([["Bash","posix"],["PowerShell","powershell"]]);function Zs(n){return Q(n,Ss)}async function $a(){await X({agent:"claude-code",getAgent:(n)=>xa(n.transcript_path),createDenyOutput:(n)=>({hookSpecificOutput:{hookEventName:It,permissionDecision:"deny",permissionDecisionReason:n}}),isSupported:(n)=>n.hook_event_name===It,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:Zs(t)}),getContext:(n,t,e,r)=>I(n.cwd,t,e,r),getSessionId:(n)=>n.session_id})}var Qs=new Map([["bash","auto"],["Bash","auto"]]);function Xs(n){return Q(n,Qs)}async function Da(){await X({agent:"copilot-cli",createDenyOutput:(n)=>({permissionDecision:"deny",permissionDecisionReason:n}),isSupported:()=>!0,getToolName:(n)=>n.toolName,getToolInput:(n,t,e)=>{if(typeof n.toolArgs!=="string")return e({reason:"Failed to parse toolArgs JSON."}),{ok:!1};let r=_t(n.toolArgs,e,"Failed to parse toolArgs JSON.");if(r===void 0)return{ok:!1};return{ok:!0,input:r,route:Xs(t)}},getContext:(n,t,e,r)=>I(n.cwd,t,e,r),getSessionId:(n)=>typeof n.sessionId==="string"&&n.sessionId.trim()?n.sessionId:void 0})}var Ys=new Map([["Shell","auto"]]);function Rs(n){return Q(n,Ys)}async function ka(){await X({agent:"cursor",createDenyOutput:(n)=>({permission:"deny",user_message:n,agent_message:n}),createAllowOutput:()=>({permission:"allow"}),isSupported:()=>!0,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:Rs(t)}),getContext:As,getSessionId:(n)=>n.conversation_id})}function As(n,t,e,r){let a=Hs(n);if(!a[0])return R(r,t,e),null;let l=vn(Ws(n.cwd),a);if(!l)return R(r,t,e,typeof n.cwd==="string"?n.cwd:void 0),null;if(t===null||typeof t!=="object"||Array.isArray(t))return{configCwd:l,executionCwd:l,policyConfigCwds:a};if(!Object.hasOwn(t,"working_directory"))return{configCwd:l,executionCwd:l,policyConfigCwds:a};let d=t.working_directory;if(typeof d!=="string"||d.trim()==="")return R(r,t,e),null;let s=vn(d,a);if(!s)return R(r,t,e,d),null;return{configCwd:l,executionCwd:s,policyConfigCwds:a}}function Hs(n){return Ms(n).flatMap((t)=>{let e=c2([t]);return e?[e]:[]})}function Ms(n){if(n.workspace_roots===void 0)return typeof n.cwd==="string"&&n.cwd.trim()!==""?[n.cwd]:[];if(!Array.isArray(n.workspace_roots))return[];return n.workspace_roots.filter((t)=>typeof t==="string"&&t.trim()!=="")}function Ws(n){return typeof n==="string"&&n.trim()!==""?n:"."}var Vs=new Map([["run_shell_command","auto"]]);function Ks(n){return Q(n,Vs)}async function qa(){await X({agent:"gemini-cli",createDenyOutput:(n)=>({decision:"deny",reason:n,systemMessage:n}),isSupported:(n)=>n.hook_event_name===ma,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:Ks(t)}),getContext:(n,t,e,r)=>I(n.cwd,t,e,r),getSessionId:(n)=>n.session_id})}import{resolve as Cs}from"node:path";var Gs=new Map([["terminal","posix"]]);async function ja(){await X({agent:"hermes-agent",createDenyOutput:(n)=>({action:"block",message:n}),isSupported:(n)=>n.hook_event_name===ga,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:Q(t,Gs)}),getContext:Us,getSessionId:(n)=>n.session_id})}function Us(n,t,e,r){let a=I(n.cwd,t,e,r);if(!a)return null;if(!t||typeof t!=="object"||Array.isArray(t))return a;if(!Object.hasOwn(t,"workdir"))return a;let l=t.workdir;if(typeof l!=="string"||l.trim()==="")return R(r,t,e),null;let d=c2([Cs(a.configCwd,l)]);if(!d)return R(r,t,e,l),null;return{...a,executionCwd:d}}var Os=new Map([["Bash","posix"]]);function Ts(n){return Q(n,Os)}async function Fa(){await X({agent:"kimi-code",createDenyOutput:(n)=>({hookSpecificOutput:{hookEventName:Nt,permissionDecision:"deny",permissionDecisionReason:n}}),isSupported:(n)=>n.hook_event_name===Nt,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:Ts(t)}),getContext:(n,t,e,r)=>I(n.cwd,t,e,r),getSessionId:(n)=>n.session_id})}var Es={"antigravity-cli":va,"claude-code":$a,"copilot-cli":Da,cursor:ka,"gemini-cli":qa,"hermes-agent":ja,"kimi-code":Fa},C2=ha.map((n)=>({...n,run:Es[n.id]}));function za(n){let t=j({label:"hook",booleans:Object.fromEntries(C2.map((r)=>[r.id,[...r.flags,...r.legacyFlags]]))},n);if(t.errors.length>0)return;let e=C2.filter((r)=>t.flags[r.id]);return e.length===1?e[0]:void 0}function Ba(n){return C2.find((t)=>t.legacyTopLevelFlags.some((e)=>e===n))}var _s=C2.map((n)=>({flags:n.flags.join(", "),description:n.description})),Ps=C2.flatMap((n)=>n.flags.map((t)=>`cc-safety-net hook ${t}`)),Ja={name:"hook",description:"Run as an agent CLI hook (reads JSON from stdin)",usage:"hook INTEGRATION_FLAG",options:[..._s,{flags:"-h, --help",description:"Show this help"}],examples:Ps};var Sa={name:"install",description:"Install CC Safety Net into a coding agent CLI",usage:"install [TARGET_FLAG]",options:[...i2.map((n)=>({flags:n.flag,description:`Install ${n.helpTarget}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net install",...i2.map((n)=>`cc-safety-net install ${n.flag}`)]},Za={name:"uninstall",description:"Uninstall CC Safety Net from a coding agent CLI",usage:"uninstall [TARGET_FLAG]",options:[...i2.map((n)=>({flags:n.flag,description:`Uninstall ${n.helpTarget}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net uninstall",...i2.map((n)=>`cc-safety-net uninstall ${n.flag}`)]},Qa={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 Xa={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 G2={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 Ya={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 Ra={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 Aa=[Ya,ta,Xa,ea,G2,Sa,Qa,Za,Ja,ra,Ra];function Is(n){return n.aliases??[]}function Ns(n){return!n.hidden}function Yn(n){let t=n.toLowerCase();return Aa.find((e)=>e.name.toLowerCase()===t||Is(e).some((r)=>r.toLowerCase()===t))}function Ha(){return Aa.filter(Ns)}import{readFileSync as n3}from"node:fs";import{basename as t3}from"node:path";function Rn(n=7,t=s2()){let e=Date.now()-n*24*60*60*1000,r=[],a=new Set,l=0,d,s,c,i;if(t)y2(t);let L={count:0},u=t?o2(t,L):[];for(let o of u)try{let v=n3(o,"utf-8").trim().split(`
6
- `).filter(Boolean);for(let f of v)try{let w=JSON.parse(f);if(w.decision==="allow")continue;let x=new Date(w.ts).getTime();if(x>=e){if(l++,a.add(w.sessionId??t3(o,".jsonl")),s===void 0||x<=s)d=w.ts,s=x;if(i===void 0||x>i)c=w.ts,i=x;e3(r,w,x)}}catch{L.count++}}catch{L.count++}let p=r.map((o)=>({timestamp:o.ts,command:o.command,reason:o.reason,relativeTime:yt(new Date(o.ts))}));return{totalBlocked:l,sessionCount:a.size,recentEntries:p,oldestEntry:d,newestEntry:c,unreadable:L.count}}function e3(n,t,e){let r=n.findIndex((a)=>e>new Date(a.ts).getTime());if(r===-1){if(n.length<3)n.push(t);return}if(n.splice(r,0,t),n.length>3)n.pop()}import{dirname as r3}from"node:path";function Ma(n,t,e,r,a){let l;try{if(m(r)===null)return{path:n,exists:!1,valid:!1,ruleCount:0};l=a2(r),l.errors.push(...l2(n,t,{userConfigDir:e},a))}catch(d){if(!(d instanceof S))throw d;l={errors:[d.message],ruleNames:new Set}}return{path:n,exists:!0,valid:l.errors.length===0,ruleCount:l.ruleNames.size,...l.errors.length>0?{errors:l.errors}:{}}}function a3(n,t){return{source:t,name:n.name,command:n.command,subcommand:n.subcommand,blockArgs:[...n.block_args],reason:n.reason}}function Wa(n,t){let e=t?.userConfigPath??_(),r=t?.projectConfigPath??E(n),a=r3(e),l=u2({cwd:n,userConfigPath:e,projectConfigPath:r,userConfigDir:a}),d=P({cwd:n,userConfigPath:e,projectConfigPath:r,userConfigDir:a}),s=new Map(l.rulebooks.flatMap((c)=>c.rules.map((i)=>[i,c.source])));return{userConfig:Ma(e,R2({userConfigPath:e}),a,d.userConfigTarget,d.userScope),projectConfig:Ma(r,A2(r),a,d.projectConfigTarget,d.projectScope),effectiveRules:l.rules.map((c)=>a3(c,s.get(c.name)??"project")),shadowedRules:[]}}var l3=[{flag:D.level,description:"Safety level preset: standard, strict, or paranoid",defaultBehavior:"standard"},{flag:D.strict,description:"Legacy; equivalent to safety.overrides.fail_closed",defaultBehavior:"permissive"},{flag:D.paranoid,description:"Legacy; equivalent to safety.overrides.paranoid_rm and paranoid_interpreters",defaultBehavior:"off"},{flag:D.paranoidRm,description:"Legacy; equivalent to safety.overrides.paranoid_rm",defaultBehavior:"off"},{flag:D.paranoidInterpreters,description:"Legacy; equivalent to safety.overrides.paranoid_interpreters",defaultBehavior:"off"},{flag:D.worktree,description:"Allow local git discards in linked worktrees",defaultBehavior:"off"},{flag:D.debug,description:"Print diagnostic messages to stderr",defaultBehavior:"off"},{flag:D.auditScope,description:"Command decisions recorded: all, or blocked (privacy-minimizing, denials only)",defaultBehavior:"all"}];function Va(){return[...l3.map((n)=>({name:n.flag.name,value:Kt(n.flag),isSet:Ct(n.flag),legacyName:n.flag.legacyName,legacyValue:n.flag.legacyName?process.env[n.flag.legacyName]:void 0,legacyIsSet:n.flag.legacyName?process.env[n.flag.legacyName]!==void 0:void 0,description:n.description,defaultBehavior:n.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 Ka={error:0,warning:1,info:2},d3=["policy","config","audit"];function s3(n){return n.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 c3=[{derive:(n)=>n.hooks.length>0&&n.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:(n)=>n.hooks.filter((t)=>t.inspectionStatus==="failed").map((t)=>{let e=p2(t.platform);return{checkId:"integration.inspection-failed",severity:"error",title:`${e} inspection failed`,detail:`Doctor could not verify the ${e} integration configuration.`,fixHint:`Correct the reported ${e} configuration error, then run \`cc-safety-net doctor\` again.`,integration:t.platform}})},{derive:(n)=>n.userConfig.exists&&!n.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:n.userConfig.path}]:[]},{derive:(n)=>n.projectConfig.exists&&!n.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:n.projectConfig.path}]:[]},{derive:(n)=>n.configState.state==="degraded"?[{checkId:"config.runtime-degraded",severity:"warning",title:"Runtime is enforcing a fallback configuration",detail:`The rejected candidate configuration is not active: ${n.configState.reason}`,fixHint:"Correct the named source, run `cc-safety-net rule sync` for a rule source, then rerun doctor."}]:[]},{derive:(n)=>{let t=n.environment.find((e)=>e.name==="CC_SAFETY_NET_AUDIT_SCOPE");return Vt(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."}]:[]}},...d3.map((n)=>({derive:(t)=>t.posture.directories.filter((e)=>e.kind===n&&e.status==="unsafe").map((e)=>({checkId:`posture.${n}-directory-unsafe`,severity:"error",title:`${n[0]?.toUpperCase()}${n.slice(1)} directory is unsafe`,detail:`The ${n} directory ${s3(e.issues)}.`,fixHint:"Ensure this is a real directory owned by the current user with no group or other write access, then rerun doctor.",...e.path?{path:e.path}:{}}))})),{derive:(n)=>{let t=[...n.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 Ca(n){return c3.flatMap((t,e)=>t.derive(n).map((r,a)=>({finding:r,catalogOrder:e,occurrence:a}))).sort((t,e)=>Ka[t.finding.severity]-Ka[e.finding.severity]||t.catalogOrder-e.catalogOrder||t.occurrence-e.occurrence).map((t)=>t.finding)}function N(){return Boolean(process.stdout.isTTY&&!process.env.NO_COLOR)}var i3=(n)=>N()?`\x1B[32m${n}\x1B[0m`:n,L3=(n)=>N()?`\x1B[33m${n}\x1B[0m`:n,o3=(n)=>N()?`\x1B[34m${n}\x1B[0m`:n,u3=(n)=>N()?`\x1B[35m${n}\x1B[0m`:n,p3=(n)=>N()?`\x1B[36m${n}\x1B[0m`:n,v3=(n)=>N()?`\x1B[31m${n}\x1B[0m`:n,b3=(n)=>N()?`\x1B[2m${n}\x1B[0m`:n,f3=(n)=>N()?`\x1B[1m${n}\x1B[0m`:n,h={green:i3,yellow:L3,blue:o3,magenta:u3,cyan:p3,red:v3,dim:b3,bold:f3},h3="\x1B[0m",y3=[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 w3(n){let t=n;return()=>{return t=(t*1664525+1013904223)%4294967296,t/4294967296}}function x3(n){let t=[...y3],e=w3(n);for(let r=t.length-1;r>0;r--){let a=Math.floor(e()*(r+1)),l=t[r];t[r]=t[a],t[a]=l}return t}function m3(n,t=0){if(!N())return"";let e=x3(t);return`\x1B[38;5;${e[n%e.length]}m`}function Ga(n,t,e=0){if(!N())return`"${n}"`;return`${m3(t,e)}"${n}"${h3}`}var g3=new RegExp("\x1B\\[[0-9;]*m","g"),ne=(n)=>n.replace(g3,"").length;function g2(n){let t=(n.headers??n.rows[0]??[]).map((d,s)=>{let c=Math.max(...n.rows.map((i)=>ne(i[s]??"")));return Math.max(ne(d),c)}),e=(d,s)=>d+" ".repeat(Math.max(0,s-ne(d))),r=(d,s)=>s[0]+t.map((c)=>d.repeat(c+2)).join(s[1])+s[2],a=(d)=>`│ ${d.map((s,c)=>e(s,t[c]??0)).join(" │ ")} │`,l=n.headers?[` ${a(n.headers)}`,` ${r("─",["├","┼","┤"])}`]:[];return[` ${r("─",["┌","┬","┐"])}`,...l,...n.rows.map((d)=>` ${a(d)}`),` ${r("─",["└","┴","┘"])}`].join(`
7
- `)}function Ua(n){let t=[];t.push("Hook Integration"),t.push($3(n));let e=[],r=[];for(let a of n){let l=p2(a.platform);if(a.errors&&a.errors.length>0)for(let d of a.errors)if(a.configured)e.push({platform:l,message:d});else r.push({platform:l,message:d})}for(let a of e)t.push(` Warning (${a.platform}): ${a.message}`);for(let a of r)t.push(h.red(` Error (${a.platform}): ${a.message}`));return t.join(`
8
- `)}function $3(n){let t=["Platform","Discovery","Configuration","Inspection"],e=n.map((r)=>{let a=p2(r.platform);if(r.inspectionStatus==="not-inspected"){let c=h.dim("Not inspected");return[a,c,c,c]}let l=r.detected?h.green("Detected"):r.inspectionStatus==="failed"?h.red("Unknown"):h.dim("Not detected"),d=r.configured?h.green("Configured"):r.detected?h.yellow("Not configured"):r.inspectionStatus==="failed"?h.red("Unknown"):h.dim("Not applicable"),s=r.inspectionStatus==="verified"?h.green("Verified"):r.inspectionStatus==="failed"?h.red("Failed"):h.dim("Not applicable");return[a,l,d,s]});return g2({headers:t,rows:e})}function Oa(n){let e=["Guard Engine Verification",` Synthetic self-test: ${n.failed>0?h.red(`${n.passed}/${n.total} FAIL`):h.green(`${n.passed}/${n.total} passed`)}`],r=n.results.filter((a)=>!a.passed);if(r.length>0){e.push(""),e.push(h.red(" Failures:"));for(let a of r)e.push(h.red(` • ${a.description}`)),e.push(h.red(` expected ${a.expected}, got ${a.actual}`))}return e.join(`
9
- `)}function D3(n){if(n.length===0)return" (no custom rules)";let t=["Source","Name","Command","Block Args"],e=n.map((r)=>[r.source,r.name,r.subcommand?`${r.command} ${r.subcommand}`:r.command,r.blockArgs.join(", ")]);return g2({headers:t,rows:e})}function Ta(n){let t=[];if(t.push("Configuration"),t.push(k3(n.userConfig,n.projectConfig)),t.push(""),n.effectiveRules.length>0)t.push(` Effective rules (${n.effectiveRules.length} total):`),t.push(D3(n.effectiveRules));else t.push(" Effective rules: (none - using built-in rules only)");for(let e of n.shadowedRules)t.push(""),t.push(` Note: Project rule "${e.name}" shadows user rule with same name`);return t.join(`
10
- `)}function k3(n,t){let e=["Scope","Status"],r=(l)=>{if(!l.exists)return h.dim("N/A");if(!l.valid)return h.red(`Invalid (${l.errors?.[0]??"unknown error"})`);return h.green("Configured")},a=[["User",r(n)],["Project",r(t)]];return g2({headers:e,rows:a})}function Ea(n){let t=[];return t.push("Environment"),t.push(q3(n)),t.join(`
11
- `)}function _a(n){let t=["Effective Safety",` Selected preset: ${n.effectiveSafety.selectedPreset}`,` Effective: ${n.effectiveSafety.level}`],e=[["fail_closed","fail_closed"],["paranoid_rm","paranoid_rm"],["paranoid_interpreters","paranoid_interpreters"]];for(let[r,a]of e){let l=n.effectiveSafety.capabilities[r],d=l.enabled?h.green("ON"):h.dim("OFF"),s=l.sources.length>0?` (${l.sources.join(", ")})`:"";t.push(` ${a}: ${d} via ${l.source}${s}`)}t.push(` Stored rule customizations: ${n.effectiveSafety.ruleCounts.stored}`),t.push(` Effective rule customizations: ${n.effectiveSafety.ruleCounts.effective}`);for(let[r,a]of Object.entries(n.effectiveSafety.ruleOverrides))t.push(` ${r}: ${a}`);return t.join(`
12
- `)}function Pa(n){let t=["Findings"];if(n.length===0)return t.push(" No findings from inspected doctor facts."),t.join(`
13
- `);for(let e of n){let r=`[${e.severity.toUpperCase()}] ${e.checkId}: ${F(e.title)}`,a=e.severity==="error"?h.red:e.severity==="warning"?h.yellow:h.blue;if(t.push(` ${a(r)}`),t.push(` ${F(e.detail)}`),e.path)t.push(` Path: ${F(e.path)}`);if(e.fixHint)t.push(` Fix: ${F(e.fixHint)}`)}return t.join(`
14
- `)}function q3(n){let t=["Variable","Status","Legacy"],e=n.map((r)=>{let a=r.isSet?h.green("✓"):h.dim("✗"),l=r.legacyName&&r.legacyIsSet?`${r.legacyName} ${h.green("✓")}`:r.legacyName??"";return[r.name,a,l]});return g2({headers:t,rows:e})}function Ia(n){let t=[];if(n.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 (${n.totalBlocked} blocked / ${n.sessionCount} sessions)`),t.push(j3(n.recentEntries));if(n.unreadable>0)t.push(` Warning: ${n.unreadable} audit log ${n.unreadable===1?"source":"sources"} could not be read; this summary is incomplete`);return t.join(`
15
- `)}function j3(n){let t=["Time","Command"],e=n.map((r)=>{let a=F(r.command.replace(/\r\n|\r|\n/g," ↵ ").replace(/\t/g," ")),l=a.length>40?`${a.slice(0,37)}...`:a;return[r.relativeTime,l]});return g2({headers:t,rows:e})}function Na(n){let t=[];if(t.push("Update Check"),n.latestVersion===null&&!n.error)return t.push(An([["Status",h.dim("Skipped")],["Installed",n.currentVersion]])),t.join(`
16
- `);if(n.error)return t.push(An([["Status",`${h.yellow("⚠")} Error`],["Installed",n.currentVersion],["Error",h.dim(n.error)]])),t.join(`
17
- `);if(n.updateAvailable)return t.push(An([["Status",`${h.yellow("⚠")} Update Available`],["Current",n.currentVersion],["Latest",h.green(n.latestVersion??"")]])),t.push(""),t.push(" Run: bunx cc-safety-net@latest doctor"),t.push(" Or: npx cc-safety-net@latest doctor"),t.join(`
18
- `);return t.push(An([["Status",`${h.green("✓")} Up to date`],["Version",n.currentVersion]])),t.join(`
19
- `)}function An(n){return g2({rows:n})}function n1(n){let t=[];return t.push("System Info"),t.push(F3(n)),t.join(`
20
- `)}function F3(n){let t=["Component","Version"],e=(l)=>{if(l===null)return h.dim("not found");return l},a=[{label:"cc-safety-net",value:n.version},{label:"Claude Code",value:n.claudeCodeVersion},{label:"Amp Code",value:n.ampVersion},{label:"Antigravity CLI",value:n.antigravityCliVersion},{label:"Codex",value:n.codexCliVersion},{label:"Cursor",value:n.cursorVersion},{label:"Gemini CLI",value:n.geminiCliVersion},{label:"GitHub Copilot CLI",value:n.copilotCliVersion},{label:"Hermes Agent",value:n.hermesAgentVersion},{label:"Kimi Code",value:n.kimiCodeVersion},{label:"OpenClaw",value:n.openClawVersion},{label:"OpenCode",value:n.openCodeVersion},{label:"Pi",value:n.piCliVersion},{label:"Node.js",value:n.nodeVersion},{label:"npm",value:n.npmVersion},{label:"Bun",value:n.bunVersion},{label:"Platform",value:n.platform}].map((l)=>[l.label,e(l.value)]);return g2({headers:t,rows:a})}function t1(n){if(n.findings.length===0)return h.green(`
21
- No findings from inspected doctor facts.`);let t={error:n.findings.filter((l)=>l.severity==="error").length,warning:n.findings.filter((l)=>l.severity==="warning").length,info:n.findings.filter((l)=>l.severity==="info").length},e=["error","warning","info"].filter((l)=>t[l]>0).map((l)=>`${t[l]} ${l}`),r=n.findings.length===1?"finding":"findings",a=`
22
- ${n.findings.length} ${r}: ${e.join(", ")}.`;if(t.error>0)return h.red(a);if(t.warning>0)return h.yellow(a);return h.blue(a)}import{lstatSync as z3}from"node:fs";import{dirname as te}from"node:path";function ee(n,t){try{let e=z3(t);if(e.isSymbolicLink())return{kind:n,path:t,status:"unsafe",issues:["symlink"]};if(!e.isDirectory())return{kind:n,path:t,status:"unsafe",issues:["not-directory"]};if(process.platform==="win32"||typeof process.getuid!=="function")return{kind:n,path:t,status:"unknown",issues:[]};let r=[...e.uid!==process.getuid()?["ownership"]:[],...(e.mode&18)!==0?["permissions"]:[]];return{kind:n,path:t,status:r.length>0?"unsafe":"safe",issues:r}}catch(e){if(typeof e==="object"&&e!==null&&"code"in e&&e.code==="ENOENT")return{kind:n,path:t,status:"not-applicable",issues:[]};return{kind:n,path:t,status:"unknown",issues:[]}}}function e1(n){let t=s2();return{directories:[ee("policy",te(te(n))),ee("config",te(n)),...t?[ee("audit",t)]:[{kind:"audit",status:"unknown",issues:[]}]]}}import{spawn as B3}from"node:child_process";import{existsSync as r1}from"node:fs";import{delimiter as J3,extname as S3,join as Z3}from"node:path";import{stripVTControlCharacters as a1}from"node:util";var d1="2.0.1",Q3=5000,X3="_CC_SAFETY_NET_TEST_SPAWN_PLATFORM";function z(){return d1}function re(n,t){let e=n[t];if(e)return e;let r=Object.keys(n).find((a)=>a.toLowerCase()===t.toLowerCase()&&!!n[a]);return r?n[r]:e}function Y3(n){return(re(n,"PATHEXT")||".COM;.EXE;.BAT;.CMD").split(";").filter((t)=>t.length>0)}function R3(n,t){let e=S3(n)?[n]:[...Y3(t).map((r)=>`${n}${r}`),n];if(n.includes("/")||n.includes("\\"))return e.find((r)=>r1(r))??n;return(re(t,"PATH")??"").split(J3).flatMap((r)=>e.map((a)=>Z3(r,a))).find((r)=>r1(r))??n}function l1(n){if(!/[\s"&|<>^]/.test(n))return n;return`"${n.replace(/"/g,'""')}"`}function A3(n,t){let[e,...r]=n,a=t[X3]==="win32"?"win32":process.platform;if(!e||a!=="win32")return{cmd:e??"",args:r};let l=R3(e,t);if(!/\.(?:bat|cmd)$/i.test(l))return{cmd:l,args:r};return{cmd:re(t,"COMSPEC")??"cmd.exe",args:["/d","/c",["call",l1(l),...r.map(l1)].join(" ")]}}var Hn=async(n,t=Q3)=>{let e=await H3(n,{timeoutMs:t});if(e.code!==0)return null;return a1(e.stdout).trim()||a1(e.stderr).trim()||null};function H3(n,t){let[e,...r]=n;if(!e)return Promise.resolve({code:null,stdout:"",stderr:""});return new Promise((a)=>{try{let l=A3([e,...r],process.env),d=B3(l.cmd,l.args,{stdio:["ignore","pipe","pipe"]}),s=!1,c="",i="";d.stdout.on("data",(p)=>{c+=p.toString()}),d.stderr.on("data",(p)=>{i+=p.toString()});let L=(p)=>{if(s)return;s=!0,clearTimeout(u),a(p)},u=setTimeout(()=>{d.kill(),L({code:null,stdout:c,stderr:i})},t.timeoutMs);d.on("close",(p)=>{L({code:p,stdout:c,stderr:i})}),d.on("error",()=>{L({code:null,stdout:c,stderr:i})})}catch{a({code:null,stdout:"",stderr:""})}})}function Z(n){if(!n)return null;let t=/Claude Code\s+(\d+\.\d+\.\d+)/i.exec(n);if(t)return t[1]??null;let e=/v?(\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)/i.exec(n);if(e)return e[1]??null;return n.split(`
23
- `)[0]?.trim()||null}async function bn(n=Hn){let[t,e,r,a,l,d,s,c,i,L,u,p,o,b,v,f]=await Promise.all([n(["claude","--version"]),n(["agy","--version"]),n(["opencode","--version"]),n(["codex","--version"]),n(["codex","plugin","list"]),n(["gemini","--version"]),n(["copilot","--binary-version"]),n(["hermes","--version"]),n(["kimi","--version"]),n(["openclaw","--version"]),n(["pi","--version"]),n(["cursor","--version"]),n(["amp","--version"]),n(["node","--version"]),n(["npm","--version"]),n(["bun","--version"])]);return{version:d1,claudeCodeVersion:Z(t),antigravityCliVersion:Z(e),openCodeVersion:Z(r),codexCliVersion:Z(a),codexPluginListOutput:l,geminiCliVersion:Z(d),copilotCliVersion:Z(s),hermesAgentVersion:Z(c),kimiCodeVersion:Z(i),openClawVersion:Z(L),piCliVersion:Z(u),cursorVersion:Z(p),ampVersion:Z(o),nodeVersion:Z(b),npmVersion:Z(v),bunVersion:Z(f),platform:`${process.platform} ${process.arch}`}}function ae(n,t){if(t==="dev")return!1;let e=n.split(".").map(Number),r=t.split(".").map(Number),[a=0,l=0,d=0]=e,[s=0,c=0,i=0]=r;if(a!==s)return a>s;if(l!==c)return l>c;return d>i}async function U2(){let n=z(),t=new AbortController,e=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:n,latestVersion:null,updateAvailable:!1,error:`npm registry returned ${r.status}`};let a=await r.json(),l=ae(a.version,n);return{currentVersion:n,latestVersion:a.version,updateAvailable:l}}catch(r){return{currentVersion:n,latestVersion:null,updateAvailable:!1,error:r instanceof Error?r.message:"Network error"}}finally{clearTimeout(e)}}import*as v1 from"node:readline";var L1=(n)=>`\x1B[${n}B`,M3=(n)=>`\x1B[${n}A`;var s1=["░","▒","▓","╱","╲","┃","━","┏","┓","┗","┛","╋"];function W3(n){return new Promise((t)=>setTimeout(t,n))}function V3(n,t,e){if(!e)return t(n);if(e.aborted)return Promise.resolve();return new Promise((r,a)=>{let l=()=>e.removeEventListener("abort",d),d=()=>{l(),r()};e.addEventListener("abort",d,{once:!0}),t(n).then(()=>{l(),r()},(s)=>{l(),a(s)})})}function fn(n,t){return n&&n>0?n:t}function Mn(n){return Math.max(0,Math.min(1,n))}function O2(n){return Math.max(0,Math.min(255,Math.round(n)))}function le(n){return n<=0.0031308?12.92*n:1.055*n**0.4166666666666667-0.055}function K3(n,t,e){let r=e*Math.PI/180,a=t*Math.cos(r),l=t*Math.sin(r),d=(n+0.3963377774*a+0.2158037573*l)**3,s=(n-0.1055613458*a-0.0638541728*l)**3,c=(n-0.0894841775*a-1.291485548*l)**3;return{blue:O2(le(Mn(-0.0041960863*d-0.7034186147*s+1.707614701*c))*255),green:O2(le(Mn(-1.2684380046*d+2.6097574011*s-0.3413193965*c))*255),red:O2(le(Mn(4.0767416621*d-3.3077115913*s+0.2309699292*c))*255)}}function de(n,t){let e=(t*n*180/Math.PI%360+360)%360;return K3(0.72,0.15,e)}function o1(n,t=0.1){let e=de(t,n);return`\x1B[38;2;${e.red};${e.green};${e.blue}m`}function C3(n,t){return{blue:O2(n.blue+(255-n.blue)*t),green:O2(n.green+(255-n.green)*t),red:O2(n.red+(255-n.red)*t)}}function u1(n,t,e){let r=Math.imul(n+2654435769,2246822507)^Math.imul(t+3266489909,668265263)^Math.imul(e+374761393,2654435761),a=r^r>>>15,l=Math.imul(a,739982445),d=l^l>>>12,s=Math.imul(d,695872825);return((s^s>>>15)>>>0)/4294967296}function G3(n,t,e){let r=Math.floor(u1(n,t,e)*s1.length);return s1[r]??"░"}function c1(n){let t=Mn(n);return t*t*t*(t*(t*6-15)+10)}function U3(n){if(n.length===0)return"";let t=[],e=!1,r="";for(let a of n){let l=`${a.red};${a.green};${a.blue}`;if(a.bold!==e)t.push(a.bold?"\x1B[1m":"\x1B[22m"),e=a.bold;if(l!==r)t.push(`\x1B[38;2;${l}m`),r=l;t.push(a.character)}return`${t.join("")}\x1B[22m\x1B[39m`}function O3(n,t,e,r,a){return n.map((l,d)=>({...de(e,r+t+d/a),bold:!1,character:l}))}function T3(n,t,e,r,a,l,d,s){let c=Math.max(1,r*0.75),i=Math.min(1,e/c),L=a*c1(i),u=Math.max(0,(e-c)/Math.max(1,r-c)),p=(1-c1(e/r))*s*2,o=0.35*Math.max(0,1-u*2),b=i>=1,v=Math.min(n.length,Math.ceil(L+2+1));return n.slice(0,v).map((f,w)=>{let x=de(l,d+t+w/s+p),y=w+u1(t,w,7919)*2-1;if(y>L+2)return{...x,bold:!1,character:" "};let J=L-y,z2=0.8*Math.exp(-(J*J)/12.5),tn=Math.min(0.9,z2+o),ft=!b&&y>L-4;return{...C3(x,tn),bold:tn>0.3,character:ft?G3(t,w,e):f}})}function i1(n){return`\x1B[?2026h${n.map((t,e)=>`\x1B8${e>0?L1(e):""}${U3(t)}`).join("")}\x1B[?2026l`}async function se(n,t={}){if(!n)return;let e=t.output??process.stdout,r=t.sleep??W3,a=fn(t.frequency,0.1),l=t.seed??0,d=fn(t.speed,40),s=fn(t.spread,3),c=fn(t.frameRate,60),i=Math.max(1,Math.floor(fn(t.duration,12))),L=n.split(`
24
- `).map((v)=>Array.from(v)),u=Math.max(...L.map((v)=>v.length)),p=1000*i*L.filter((v)=>v.length>0).length/d,o=u>0?Math.max(1,Math.ceil(p/(1000/c))):0,b=o>0?p/o:0;e.write(`\x1B[?25l${L.length>1?`${`
25
- `.repeat(L.length-1)}${M3(L.length-1)}`:""}\x1B7`);try{for(let v=1;v<=o;v+=1){if(t.signal?.aborted)break;e.write(i1(L.map((f,w)=>T3(f,w,v,o,u,a,l,s)))),await V3(b,r,t.signal)}}finally{if(e.write(i1(L.map((v,f)=>O3(v,f,a,l,s)))),e.write("\x1B8"),L.length>1)e.write(L1(L.length-1));e.write(`
26
- \x1B[0m\x1B[?25h`)}}var p1=["┏━┛┏━┛ ┏━┛┏━┃┏━┛┏━┛━┏┛┃ ┃ ┏━ ┏━┛━┏┛","┃ ┃ ━━┃┏━┃┏━┛┏━┛ ┃ ━┏┛ ┃ ┃┏━┛ ┃ ","━━┛━━┛ ━━┛┛ ┛┛ ━━┛ ┛ ┛ ┛ ┛━━┛ ┛ "].join(`
27
- `);function E3(n){return Boolean(n.isTTY)}async function Wn(n={}){let t=n.output??process.stdout;if(!E3(t))return;let e=n.input??process.stdin,r={duration:n.duration,frequency:n.frequency,output:t,seed:n.seed??Math.random()*8192,sleep:n.sleep,speed:n.speed,spread:n.spread};if(!e.isTTY||typeof e.setRawMode!=="function"){await se(p1,r);return}let a=new AbortController,l=e.readableFlowing===!0,d=e.isRaw===!0,s=!1,c=(i,L)=>{if(L.ctrl&&L.name==="c")s=!0;if(s||L.name==="return"||L.name==="enter")a.abort()};v1.emitKeypressEvents(e),e.on("keypress",c),e.setRawMode(!0),e.resume();try{await se(p1,{...r,signal:a.signal})}finally{if(e.off("keypress",c),e.setRawMode(d),!l)e.pause()}if(!s)return;if(n.onInterrupt){n.onInterrupt();return}process.kill(process.pid,"SIGINT")}var b1="\r\x1B[2K",_3="\x1B[?25l",P3="\x1B[39m",I3="\x1B[?25h",N3=100,nc=0.55,tc=80,f1=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function ec(n){return new Promise((t)=>setTimeout(t,n))}async function rc(n,t){let e=t.output??process.stdout;if(!e.isTTY){await n;return}let r=t.sleep??ec,a=!1,l=n.then((s)=>{return a=!0,s},(s)=>{throw a=!0,s});if(await Promise.race([l.then(()=>!0),r(N3).then(()=>!1)]))return;e.write(_3);try{for(let s=0;!a;s+=1)e.write(`${b1}${o1(s*nc)}${f1[s%f1.length]}${P3} ${t.loadingMessage??"Loading…"}`),await Promise.race([l,r(tc)]);await l}finally{e.write(`${b1}${I3}`)}}async function Vn(n,t,e,r={}){let a=t();if(n)await e();if(n&&a.ready)await rc(a.ready,r);return a.finish()}import{homedir as mi}from"node:os";import{lstatSync as uc,readFileSync as pc}from"node:fs";var hn="// cc-safety-net managed Amp plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --amp";import{existsSync as dc,lstatSync as y1,mkdirSync as sc,readFileSync as ce,rmSync as cc}from"node:fs";import{dirname as w1,join as Kn}from"node:path";import{fileURLToPath as ic}from"node:url";import{renameSync as ac,writeFileSync as lc}from"node:fs";function B(n,t){let e=`${n}.${process.pid}.tmp`;lc(e,t),ac(e,n)}var h1=Kn("amp","cc-safety-net.ts");function Cn(n){return Kn(n,".config","amp","plugins","cc-safety-net.ts")}function Lc(){let n=w1(ic(import.meta.url));return[Kn(n,"..",h1),Kn(n,"..","..","..","dist",h1)]}function oc(n=Lc()){let t=n.find((e)=>dc(e)&&y1(e).isFile());if(!t)throw Error("Packaged Amp plugin artifact not found. Reinstall cc-safety-net and try again.");return t}function x1(n){try{return y1(n)}catch{return}}function m1(n){return n.subarray(0,Buffer.byteLength(hn)).toString("utf-8")===hn}function g1(n,t=oc()){let e=ce(t),r=Cn(n),a=x1(r);if(!a)return sc(w1(r),{recursive:!0}),B(r,e),{path:r,alreadyInstalled:!1};if(a.isSymbolicLink()||!a.isFile())throw Error(`Refusing to overwrite ${r}: not a regular file. Move or remove it and rerun install --amp.`);let l=ce(r);if(l.equals(e))return{path:r,alreadyInstalled:!0};if(m1(l))return B(r,e),{path:r,alreadyInstalled:!1};throw Error(`Refusing to overwrite unmanaged file at ${r}. Move or remove it and rerun install --amp.`)}function $1(n){let t=Cn(n),e=x1(t);if(!e)return{path:t,alreadyInstalled:!1};if(e.isSymbolicLink()||!e.isFile())throw Error(`Refusing to remove ${t}: not a regular file. Move or remove it manually.`);if(!m1(ce(t)))throw Error(`Refusing to remove unmanaged file at ${t}. Move or remove it manually.`);return cc(t),{path:t,alreadyInstalled:!0}}function vc(n){return/^\/\/ version:\s*(.+)$/m.exec(n)?.[1]?.trim()}function D1(n){let t=Cn(n.homeDir),e=(()=>{try{return uc(t)}catch{return}})();if(!e)return{platform:"amp",status:"n/a",configPath:t};if(e.isSymbolicLink()||!e.isFile())return{platform:"amp",status:"n/a",configPath:t,errors:[`${t} is a symlink or not a regular file; move or remove it before installing`]};let r;try{r=pc(t,"utf-8")}catch(l){return{platform:"amp",status:"n/a",configPath:t,errors:[`Failed to read ${t}: ${l instanceof Error?l.message:String(l)}`]}}if(!r.startsWith(hn))return{platform:"amp",status:"n/a",configPath:t,errors:[`Unmanaged file occupies ${t}; move or remove it before installing`]};let a=vc(r)!==z();return{platform:"amp",status:"configured",method:"plugin file",configPath:t,errors:a?["Installed Amp plugin is outdated; run install --amp to update"]:void 0}}import{existsSync as fc,readFileSync as hc}from"node:fs";import{join as bc}from"node:path";function yn(n){return bc(n,".gemini","config","hooks.json")}var yc=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*(?:--agy-cli|-ac)(\s|["']|$)/;function wc(n){if(!n||typeof n!=="object"||Array.isArray(n))return[];return Object.values(n).flatMap((t)=>{if(!t||typeof t!=="object"||Array.isArray(t))return[];let e=t,r=e.PreToolUse;if(!Array.isArray(r))return[];return r.flatMap((a)=>{if(!a||typeof a!=="object"||Array.isArray(a))return[];let l=a.hooks;if(!Array.isArray(l))return[];return l.flatMap((d)=>{if(!d||typeof d!=="object"||Array.isArray(d))return[];let s=d.command;if(typeof s!=="string"||!yc.test(s))return[];return[{command:s,enabled:e.enabled!==!1}]})})})}function k1(n){let t=yn(n.homeDir);if(!fc(t))return{platform:"antigravity-cli",status:"n/a",configPath:t};let e;try{e=wc(JSON.parse(hc(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(e.some((r)=>r.enabled))return{platform:"antigravity-cli",status:"configured",method:"hook config",configPath:t};if(e.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 q1}from"node:path";import{existsSync as xc,lstatSync as mc,readFileSync as gc}from"node:fs";function n2(n,t=(e)=>e){if(!xc(n))return{kind:"missing"};try{return{kind:"ok",value:JSON.parse(t(gc(n,"utf-8")))}}catch{return{kind:"unreadable"}}}function Y(n){try{return mc(n)}catch{return}}function Gn(n,t){let e=Y(t);if(!e)return{platform:n,status:"n/a",configPath:t};if(!e.isSymbolicLink()&&e.isDirectory())return;return{platform:n,status:"n/a",configPath:t,errors:[`${t} is a symlink or not a directory; move or remove it before installing`]}}function g(n,t){return typeof n==="object"&&n!==null?n[t]:void 0}var ie="cc-safety-net@cc-marketplace";function j1(n){return q1(n,".claude","plugins","installed_plugins.json")}function F1(n,t){let e=g(g(n,"plugins"),t);return Array.isArray(e)&&e.length>0}function Un(n,t){let e=n2(j1(n));return e.kind==="ok"&&F1(e.value,t)}function Le(n){let t=j1(n),e=n2(t);if(e.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(e.kind==="missing")return{platform:"claude-code",status:"n/a"};if(!F1(e.value,ie))return{platform:"claude-code",status:"n/a"};let r=q1(n,".claude","settings.json"),a=n2(r);if(a.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(!(a.kind==="ok"&&g(g(a.value,"enabledPlugins"),ie)===!0))return{platform:"claude-code",status:"disabled",method:"plugin config",configPath:r,errors:[`${ie} is installed but not enabled in Claude Code`]};return{platform:"claude-code",status:"configured",method:"plugin config",configPath:t}}function z1(n){return Le(n.homeDir)}function B1(n){if(!n.codexPluginListOutput)return{platform:"codex",status:"n/a"};let t=n.codexPluginListOutput.split(`
28
- `).find((e)=>e.includes("https://github.com/kenryu42/cc-safety-net.git"));if(!t)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 En,readdirSync as $c,readFileSync as Dc}from"node:fs";import{join as W}from"node:path";var t2="cc-safety-net@cc-marketplace",On=["cc-marketplace","cc-safety-net"],J1=["_direct","copilot-safety-net"],S1=["cc-marketplace","safety-net"],Z1="safety-net@cc-marketplace";function Tn(n,t){let e=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(^|[^a-z0-9-])${e}([^a-z0-9-]|$)`,"m").test(n??"")}function Q1(n){return Tn(n,"cc-safety-net@cc-marketplace")}function X1(n){return Tn(n,"cc-marketplace")}function Y1(n){return Tn(n,"copilot-safety-net")}function R1(n){return Tn(n,"safety-net@cc-marketplace")}function M(n){let t="",e=0,r=!1,a=!1,l=-1;while(e<n.length){let d=n[e],s=n[e+1];if(a){t+=d,a=!1,e++;continue}if(d==='"'&&!r){r=!0,l=-1,t+=d,e++;continue}if(d==='"'&&r){r=!1,t+=d,e++;continue}if(d==="\\"&&r){a=!0,t+=d,e++;continue}if(r){t+=d,e++;continue}if(d==="/"&&s==="/"){while(e<n.length&&n[e]!==`
29
- `)e++;continue}if(d==="/"&&s==="*"){e+=2;while(e<n.length-1){if(n[e]==="*"&&n[e+1]==="/"){e+=2;break}e++}continue}if(d===","){l=t.length,t+=d,e++;continue}if(d==="}"||d==="]"){if(l!==-1){let c=t.slice(l+1);if(/^\s*$/.test(c))t=t.slice(0,l)+c}l=-1,t+=d,e++;continue}if(!/\s/.test(d))l=-1;t+=d,e++}return t}function oe(n){if(!n?.includes("cc-safety-net"))return!1;return/(^|\s)hook\s+(?:[^\s]+\s+)*(--copilot-cli|-cp)(\s|$)/.test(n)}function H1(n,t){if(!n)return null;let e=n.match(/(\d+)\.(\d+)\.(\d+)/);if(!e)return null;let r=[Number(e[1]),Number(e[2]),Number(e[3])];for(let a=0;a<t.length;a++){let l=r[a]??0,d=t[a]??0;if(l!==d)return l>d}return!0}function kc(n){return H1(n,[0,0,422])}function qc(n){return H1(n,[1,0,8])}function wn(n){return process.env.COPILOT_HOME||W(n,".copilot")}function pe(n){return(n.hooks?.preToolUse??[]).some((e)=>{if(e.type!=="command")return!1;return oe(e.command)||oe(e.bash)||oe(e.powershell)})}function ve(n,t){try{return JSON.parse(M(Dc(n,"utf-8")))}catch(e){t?.push(`Failed to parse ${n}: ${e instanceof Error?e.message:String(e)}`);return}}function M1(n,t){try{return $c(n).filter((e)=>e.endsWith(".json")).sort((e,r)=>e.localeCompare(r))}catch(e){return t?.push(`Failed to read ${n}: ${e instanceof Error?e.message:String(e)}`),[]}}function jc(n,t){if(!En(n))return[];let e=[];for(let r of M1(n,t)){let a=W(n,r),l=ve(a,t);if(l&&pe(l))e.push(a)}return e}function ue(n,t){if(!En(n))return;let e=ve(n,t);if(!e)return;return{path:n,config:e}}function A1(n,t,e,r){if(t){n.push(`GitHub Copilot CLI ${t} does not support ${e}; requires ${r}+`);return}n.push(`GitHub Copilot CLI version unavailable; skipping ${e} because it requires ${r}+`)}function Fc(n){let t=[n.localSettings,n.repoSettings,n.userConfig];for(let e of t){if(e?.config.disableAllHooks===!0)return e.path;if(e?.config.disableAllHooks===!1)return}return}function zc(n,t,e,r){let a=wn(n),l=W(t,".github","hooks"),d=W(a,"hooks"),s=W(t,".github","copilot"),c=qc(e),i=c===!0?r:void 0,L={userConfig:ue(W(a,"config.json"),i),repoSettings:ue(W(s,"settings.json"),i),localSettings:ue(W(s,"settings.local.json"),i)};if(c!==!1){let x=Fc(L);if(x){if(c===null)r.push(`GitHub Copilot CLI version unavailable; treating disableAllHooks in ${x} as active`);return{activeConfigPaths:[],disabledBy:x}}}let u=jc(l,r),p=kc(e),o=p===!0?r:void 0,b=En(d)?M1(d,o):[],v=[];for(let x of b){let y=W(d,x),J=ve(y,o);if(J&&pe(J))v.push(y)}if(p!==!0&&v.length>0)A1(r,e,`user hook files in ${d}`,"0.0.422"),v.length=0;let f=[],w=[L.localSettings,L.repoSettings,L.userConfig];for(let x of w){if(!x)continue;if(!pe(x.config))continue;if(c===!0){f.push(x.path);continue}A1(r,e,"inline hook definitions in Copilot config files","1.0.8");break}return{activeConfigPaths:[...f.filter((x)=>x.endsWith("settings.local.json")),...f.filter((x)=>x.endsWith("settings.json")),...u,...f.filter((x)=>x.endsWith("config.json")),...v]}}function W1(n){let t=[],e=zc(n.homeDir,n.cwd,n.copilotCliVersion,t);if(e.disabledBy)return{platform:"copilot-cli",status:"disabled",method:"hook config",configPath:e.disabledBy,configPaths:[e.disabledBy],errors:t.length>0?t:void 0};let r=wn(n.homeDir),a=W(r,"installed-plugins",...On),l=En(a),d=W(r,"settings.json"),s=n2(d,M);if(l&&s.kind==="unreadable")return{platform:"copilot-cli",status:"not-inspected"};if(l&&s.kind==="ok"&&g(g(s.value,"enabledPlugins"),t2)===!1)return{platform:"copilot-cli",status:"disabled",method:"plugin config",configPath:d,errors:[`${t2} is installed but not enabled in Copilot CLI`]};if(l||e.activeConfigPaths.length>0){let c=l,i=e.activeConfigPaths[0];return{platform:"copilot-cli",status:"configured",method:c?"plugin config":"hook config",configPath:i??(c?a:void 0),configPaths:e.activeConfigPaths.length>0?e.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 Rc,readFileSync as Ac}from"node:fs";import{existsSync as V1,mkdirSync as Bc,readFileSync as Jc}from"node:fs";import{dirname as Sc,join as Zc}from"node:path";var xn="npx -y cc-safety-net hook --cursor",K1=30;function Pn(n){return Zc(n,".cursor","hooks.json")}function $2(n){return typeof n==="object"&&n!==null&&!Array.isArray(n)}function be(){return{command:xn,timeout:K1,failClosed:!0}}function _n(n){return $2(n)&&n.command===xn}function Qc(n){return Object.keys(n).length===3&&n.command===xn&&n.timeout===K1&&n.failClosed===!0}function Xc(n){try{return JSON.parse(Jc(n,"utf-8"))}catch(t){if(t instanceof SyntaxError)throw Error(`Failed to parse Cursor hooks config ${n}: ${t.message}`);throw t}}function C1(n){let t=Xc(n);if(!$2(t))throw Error(`Cursor hooks config ${n} must be a JSON object`);if(t.version!==1)throw Error(`Cursor hooks config ${n} must set "version": 1`);if(t.hooks!==void 0&&!$2(t.hooks))throw Error(`Cursor hooks config ${n} "hooks" must be an object`);let e=$2(t.hooks)?t.hooks.preToolUse:void 0;if(e!==void 0&&!Array.isArray(e))throw Error(`Cursor hooks config ${n} "hooks.preToolUse" must be an array`);return t}function G1(n){let t=$2(n.hooks)?n.hooks.preToolUse:void 0;return Array.isArray(t)?t:[]}function Yc(n){if(!n.some(_n))return[...n,be()];return n.reduce((t,e)=>{if(!_n(e))return t.result.push(e),t;if(!t.inserted)t.result.push(be()),t.inserted=!0;return t},{result:[],inserted:!1}).result}function U1(n,t,e){let r=$2(t.hooks)?t.hooks:{},a={...t,hooks:{...r,preToolUse:e}};B(n,`${JSON.stringify(a,null,2)}
30
- `)}function O1(n){let t=Pn(n);if(!V1(t))return Bc(Sc(t),{recursive:!0}),B(t,`${JSON.stringify({version:1,hooks:{preToolUse:[be()]}},null,2)}
31
- `),{path:t,alreadyInstalled:!1};let e=C1(t),r=G1(e),a=r.filter(_n);if($2(e.hooks)&&Array.isArray(e.hooks.preToolUse)&&a.length===1&&a[0]!==void 0&&Qc(a[0]))return{path:t,alreadyInstalled:!0};return U1(t,e,Yc(r)),{path:t,alreadyInstalled:!1}}function T1(n){let t=Pn(n);if(!V1(t))return{path:t,alreadyInstalled:!1};let e=C1(t),r=G1(e),a=r.filter((l)=>!_n(l));if(a.length===r.length)return{path:t,alreadyInstalled:!1};return U1(t,e,a),{path:t,alreadyInstalled:!0}}function Hc(n){if(!n||typeof n!=="object"||Array.isArray(n))return[];let t=n.hooks;if(!t||typeof t!=="object"||Array.isArray(t))return[];let e=t.preToolUse;if(!Array.isArray(e))return[];return e.filter((r)=>!!r&&typeof r==="object"&&!Array.isArray(r)&&r.command===xn)}function Mc(n){let t=[];if(n.length>1)t.push("Multiple managed cc-safety-net hooks found; reinstall to collapse duplicates");let e=n[0];if(e&&e.failClosed!==!0)t.push('Managed hook is missing "failClosed": true; reinstall to repair');if(e&&e.timeout!==30)t.push('Managed hook "timeout" is not 30; reinstall to repair');return t}function E1(n){let t=Pn(n.homeDir);if(!Rc(t))return{platform:"cursor",status:"n/a",configPath:t};let e;try{e=JSON.parse(Ac(t,"utf-8"))}catch(l){return{platform:"cursor",status:"n/a",configPath:t,errors:[`Failed to parse Cursor hooks config ${t}: ${l instanceof Error?l.message:String(l)}`]}}let r=Hc(e);if(r.length===0)return{platform:"cursor",status:"n/a",configPath:t};let a=Mc(r);return{platform:"cursor",status:"configured",method:"hook config",configPath:t,errors:a.length>0?a:void 0}}import{existsSync as Wc}from"node:fs";import{join as fe}from"node:path";var he="gemini-safety-net";function ye(n){let t=fe(n,".gemini","extensions"),e=fe(t,he);if(!Wc(e))return{platform:"gemini-cli",status:"n/a"};let r=fe(t,"extension-enablement.json"),a=n2(r);if(a.kind==="unreadable")return{platform:"gemini-cli",status:"not-inspected"};let l=a.kind==="ok"?g(g(a.value,he),"overrides"):void 0;if(Array.isArray(l)&&l.some((s)=>typeof s==="string"&&s.startsWith("!")))return{platform:"gemini-cli",status:"disabled",method:"extension config",configPath:r,errors:[`${he} is disabled in Gemini CLI`]};return{platform:"gemini-cli",status:"configured",method:"extension config",configPath:e}}function _1(n){return ye(n.homeDir)}import{readFileSync as l0}from"node:fs";import{join as d0}from"node:path";var V="cc-safety-net",P1="# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent";function I1(n){return`# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent
2
+ import{$ as nr,$a as Ue,A as Ln,Aa as Ze,B as Nl,Ba as Nt,C as P,Ca as Qe,D as U,Da as Xe,E as Mt,Ea as O,F as Qt,Fa as Ht,G as Hn,Ga as Gt,H as Xt,Ha as Ct,I as G2,Ia as T,J as $2,Ja as g3,K as Ut,Ka as vn,L as s2,La as D3,M as b1,Ma as fe,N as It,Na as m3,O as An,Oa as k3,P as f1,Pa as q3,Q as y1,Qa as ct,R as Rn,Ra as j3,S as Vn,Sa as F3,T as fn,Ta as r1,U as yn,Ua as e1,V as Ee,Va as a1,W as pn,Wa as l1,X as g2,Xa as r3,Y as Ot,Ya as Ge,Z as C2,Za as Ce,_ as h1,_a as At,aa as $1,ab as Oe,b as $e,ba as g1,bb as o2,c as ge,ca as _e,cb as x2,d as A,da as je,db as l2,e as De,ea as Pe,eb as Te,f as zt,fa as Ne,fb as W,g as Z,ga as Ie,gb as bn,h as D,ha as Tt,hb as un,i as dn,ia as Fe,ib as x1,j as g,ja as m,jb as hn,k as w2,ka as Et,kb as c2,l as Ae,la as w1,lb as B1,m as A2,ma as d2,mb as Wn,n as sn,na as on,o as s3,oa as _t,p as Zt,pa as Pt,q as We,qa as n1,r as cn,ra as t1,s as Re,sa as ze,t as Kt,ta as K2,u as Ve,ua as Yt,v as Ke,va as St,w as E,wa as Me,x as _,xa as S2,y as R2,ya as $3,z as V2,za as Je}from"../chunks/index-3k09xczv.js";var X3=["-h","--help"];function F(n,t){let r=Object.entries(n.booleans??{}),e=Object.entries(n.values??{}),a=Object.fromEntries(r.map(([i])=>[i,!1])),l={},d=[],s=[],c=!1,L=-1;for(let[i,u]of t.entries()){if(i<=L)continue;if(u==="--"){d.push(...t.slice(i+1));break}if(X3.includes(u)){c=!0;continue}let v=r.find(([,f])=>f.includes(u));if(v){a[v[0]]=!0;continue}let p=e.find(([,f])=>f.includes(u));if(p){let f=t[i+1];if(f===void 0||f.startsWith("-")){s.push(`${u} requires a value`);continue}l[p[0]]=f,L=i+1;continue}if(u.startsWith("-")){s.push(`Unknown option for ${n.label}: ${u}`);continue}if(n.positionals==="tail"){d.push(...t.slice(i));break}d.push(u)}if(n.positionals!=="list"&&n.positionals!=="tail")s.push(...d.map((i)=>`Unexpected argument for ${n.label}: ${i}`));return{flags:a,values:l,positionals:d,help:c,errors:s}}function e2(n){for(let t of n)console.error(t);return n.length>0}import{readdirSync as wd,statSync as s1,unlinkSync as xd}from"node:fs";import{basename as c1,dirname as $d,join as gd,resolve as Dd}from"node:path";function z(n){return Array.from(n,(t)=>{let r=t.charCodeAt(0);if(r<=31||r>=127&&r<=159)return`\\x${r.toString(16).padStart(2,"0")}`;return t}).join("")}var kt=(n)=>{let t=Date.now()-new Date(n).getTime();if(!Number.isFinite(t))return"";let r=Math.floor(t/60000),e=Math.floor(r/60),a=Math.floor(e/24);if(a>0)return`${a}d ago`;if(e>0)return`${e}h ago`;if(r>0)return`${r}m ago`;return"just now"},Q2=(n)=>{let t=(n??"").trim().split(/\s+/).filter((a)=>a&&!/^[A-Za-z_][A-Za-z0-9_]*=/.test(a)),r=t[0]?.split("/").pop();if(!r)return null;let e=t[1];return e&&/^[a-z][a-z0-9-]*$/.test(e)?`${r} ${e}`:r};import{existsSync as Y3,readdirSync as S3,readFileSync as H3}from"node:fs";import{join as A3}from"node:path";function u2(n,t){try{return S3(n,{withFileTypes:!0,encoding:"utf8"}).flatMap((r)=>{let e=A3(n,r.name);if(r.isDirectory())return u2(e,t);if(r.name.endsWith(".jsonl"))return[e];return[]})}catch{if(t&&Y3(n))t.count++;return[]}}function qt(n){let t=(a)=>`${a.sessionId}
3
+ ${Q2(a.segment||a.command)}`,r=n.filter((a)=>a.decision!=="allow"),e=r.filter((a)=>a.sessionId).reduce((a,l)=>a.set(t(l),(a.get(t(l))??0)+1),new Map);return new Set(r.filter((a)=>a.failureStage||(e.get(t(a))??0)>=2))}function ln(n,t){try{return H3(n,"utf-8").split(`
4
+ `).filter(Boolean).flatMap((r)=>{try{return[JSON.parse(r)]}catch{if(t)t.count++;return[]}})}catch{if(t)t.count++;return[]}}import{resolve as pd}from"node:path";var W3=["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 me(n){let t=0,r={allocateSegment(){return t++},getNextSegmentIndex(){return t},recordGlobal(e){n.record({kind:"step",scope:"global",step:e})},recordSegment(e,a=r.currentSegmentIndex){if(a===void 0)return;n.record({kind:"step",scope:"segment",segmentIndex:a,step:e})}};return r}function ke(n={}){let t=[],r=n.maxEvents??512,e={maxTextLength:n.maxTextLength??2048,maxListLength:n.maxListLength??128,maxObjectProperties:n.maxObjectProperties??n.maxListLength??128,maxDepth:n.maxDepth??16},a=0,l,d=new Set;return{record(s){if(l)return;try{if(!s||t.length>=r){a++;return}t.push(Ft(R3(s,e,d)))}catch{a++}},finish(s){if(l)return l;try{l=Ft({events:Object.freeze(t),droppedEvents:a,terminal:V3(s,e,d)})}catch{a++,l=Object.freeze({events:Object.freeze(t),droppedEvents:a,terminal:Object.freeze({result:"blocked",reason:"trace unavailable".slice(0,e.maxTextLength),segment:"trace unavailable".slice(0,e.maxTextLength)})})}return l}}}function R3(n,t,r){if(n.kind!=="step")throw TypeError("invalid trace event");let{scope:e,step:a}=n;Xn(a,r,t);let l=X2(a,t,r);if(e==="global")return{kind:"step",scope:"global",step:l};if(e!=="segment")throw TypeError("invalid trace event scope");return{kind:"step",scope:"segment",segmentIndex:n.segmentIndex,step:l}}function V3(n,t,r){let e=n.result;if(e==="allowed")return Object.freeze({result:"allowed"});if(e!=="blocked")throw TypeError("invalid trace terminal");let a=n.ruleId;return Object.freeze({result:"blocked",reason:X2(n.reason,t,r),segment:X2(n.segment,t,r),...a?{ruleId:X2(a,t,r)}:{}})}function Xn(n,t,r,e=0,a=new WeakSet){if(typeof n==="string"){let s=n.slice(0,r.maxTextLength);if(!zt(s))return;for(let c of De(s))for(let L of c.match(/[^\s"'()$]+/g)??[])t.add(qe(L));return}if(!n||typeof n!=="object"||e>=r.maxDepth||a.has(n))return;if(a.add(n),Array.isArray(n)){let s=Math.min(n.length,r.maxListLength);for(let c=0;c<s;c++)Xn(n[c],t,r,e+1,a);return}let l=0,d=new Set;for(let s in n){if(!Object.hasOwn(n,s))continue;if(l>=r.maxObjectProperties)break;l++,Xn(s,t,r);let c=jt(s,r,t);if(d.has(c))continue;d.add(c),Xn(n[s],t,r,e+1,a)}}function X2(n,t,r,e=0,a=new WeakSet){if(typeof n==="string")return jt(n,t,r);if(!n||typeof n!=="object")return n;if(e>=t.maxDepth)return;if(a.has(n))return;if(a.add(n),Array.isArray(n)){let s=[],c=Math.min(n.length,t.maxListLength);for(let L=0;L<c;L++)s.push(X2(n[L],t,r,e+1,a));return s}let l={},d=0;for(let s in n){if(!Object.hasOwn(n,s))continue;if(d>=t.maxObjectProperties)break;d++;let c=jt(s,t,r);if(Object.hasOwn(l,c))continue;Object.defineProperty(l,c,{value:X2(n[s],t,r,e+1,a),enumerable:!0,configurable:!0,writable:!0})}return l}function jt(n,t,r){let e=n.slice(0,t.maxTextLength),a=zt(e)?ge(e):e,l=r.size>0?M3(a,r):a;return(K3(l)?$e(l):l).slice(0,t.maxTextLength)}function K3(n){return n.includes("PRIVATE KEY")||n.includes("://")||n.includes("eyJ")||n.includes(":")&&/(?:authorization|cookie|x-api-key|api-key|(?:^|\s)(?:-u|--user)(?:\s|=))/i.test(n)||n.length>=14&&W3.some((t)=>n.includes(t))||n.length>=49&&/\b[a-f0-9]{32}\.[A-Za-z0-9]{16}\b/.test(n)}function M3(n,t){return n.replace(/[^\s"'()$]+/g,(r)=>t.has(qe(r))?"<redacted>":r)}function qe(n){let t=2166136261,r=2166136261;for(let e=0;e<n.length;e++)t=Math.imul(t^n.charCodeAt(e),16777619),r=Math.imul(r^n.charCodeAt(n.length-e-1),16777619);return`${t>>>0}:${r>>>0}:${n.length}`}function Ft(n){if(n&&typeof n==="object"&&!Object.isFrozen(n)){for(let t of Object.values(n))Ft(t);Object.freeze(n)}return n}function Be(n,t,r,e){let a=e??je(),l=r??a.getCommandProgram(n,t.shell??"auto"),d=ke(),s=me(d),c=l.dialect==="powershell"?a.getCommandProgram(n,"posix"):l,L=Fe(c);s.recordGlobal({type:"parse",input:n,segments:L.map((v)=>[...v])});let i=ze(n,{...t,analyzePartialProgram:!0,trace:s},l,a),u=s.getNextSegmentIndex();if(i&&u>0&&u<L.length)s.recordSegment({type:"segment-skipped",index:u,reason:"prior-segment-blocked"},u);return Object.freeze({decision:i,trace:d.finish(i?{result:"blocked",reason:i.reason,segment:i.evidence.find((v)=>v.kind==="command")?.segment??n,...i.ruleId?{ruleId:i.ruleId}:{}}:{result:"allowed"}),program:l})}import{resolve as G3}from"node:path";function Bt(n){let t=Je().safeParse(n);return{errors:t.success?[]:Qe(t.error.issues),ruleNames:new Set(Ze(n).map((r)=>r.toLowerCase()))}}function Jt(n){let t=Ye(n);if(!t.ok)return t.result;return Bt(t.parsed)}function Ye(n){let t=[],r=new Set;try{let e=typeof n==="string"?dn(n):n,a=g(e);if(a===null)return t.push(`File not found: ${e.path}`),{ok:!1,result:{errors:t,ruleNames:r}};if(!a.trim())return t.push("Config file is empty"),{ok:!1,result:{errors:t,ruleNames:r}};return{ok:!0,parsed:JSON.parse(a)}}catch(e){return t.push(e instanceof Z?e.message:"Invalid JSON"),{ok:!1,result:{errors:t,ruleNames:r}}}}function Se(n){return G3(n??process.cwd(),".safety-net.json")}function a2(n){let t=Ye(n);if(!t.ok)return t.result;let r=Xe(t.parsed);return{errors:r.errors,ruleNames:r.sources}}import{isAbsolute as C3,join as Yn,relative as U3,resolve as He,sep as O3}from"node:path";async function W2(n={}){let t=Rt(n);return T3(t,await Sn(t,S2()))}function T3(n,t){if(!t.ok)return t;let r=U(n),e=[...new Set(l2(r.configPath,r.lockPath,n,r.filesystemScope))];if(e.length===0)return t;return{ok:!1,errors:e,warnings:t.warnings,entries:t.entries}}async function Sn(n,t,r,e={}){let a=null,l=!1;try{let d=U(n),s=Ht(d.configTarget);if(!s.ok)return s.result;let c=s.config;if(n.check)return nd(c,d,n);a={target:d.lockTarget,content:g(d.lockTarget)};let L=At(d.lockTarget);if(L.errors.some((y)=>y.startsWith("Unable to access ")))return{ok:!1,errors:L.errors,warnings:[],entries:[]};if(n.only&&L.errors.length>0)return{ok:!1,errors:L.errors,warnings:[],entries:[]};let i=L.errors.length>0?null:L.lock,u=n.only?Ge(c,i,n.only):{ok:!0,specs:c.rules};if(!u.ok)return u.result;if(n.only&&!i&&u.specs.length<c.rules.length)return{ok:!1,errors:[`No lockfile available for partial update; run ${Ke}`],warnings:[],entries:[]};let v=(await _3(u.specs,(y)=>Ue(y,d.configDir,n,i,d.filesystemScope,t),t)).map((y)=>td(y,i,r));for(let y of v)ad(y.content,y.entry,d.configDir,n,d.filesystemScope);let p=n.only?rd(c,i,v):v.map((y)=>y.entry);l=!0,T(d.lockTarget,{version:1,rulebooks:p},void 0,e._testAfterPolicyRename);let f=new Map(v.map((y)=>[y.entry.spec,y.rulebook.rules.length])),o=ld(p,d.configDir,n,d.filesystemScope,e);return{ok:!0,errors:[],warnings:o,entries:p.map((y)=>ed(y,f))}}catch(d){if(l&&a)try{Y2(a.target,a.content)}catch(s){return H2(s)}return H2(d)}}async function Wt(n,t={}){return E3(n,Rt(t),S2())}async function E3(n,t,r,e={}){let a=null,l=!1;try{let d=U(t),s=g(d.configTarget);a={target:d.configTarget,content:s};let c=Ht(d.configTarget);if(!c.ok)return c.result;let L=c.config,i=Ve(n)?await Oe(n,r):[{spec:n}],u=i.map((f)=>f.spec),v=[...new Set([...L.rules,...u])];if(v.length>Yt)return P3();if(v.length!==L.rules.length)l=!0,T(d.configTarget,{version:1,rules:v,overrides:L.overrides??{},transparent_wrappers:L.transparent_wrappers??[]},void 0,e._testAfterPolicyRename);let p=await Sn(t,r,new Map(i.filter((f)=>!!f.display_ref).map((f)=>[f.spec,f.display_ref])),e);if(!p.ok)Y2(d.configTarget,s);return p}catch(d){if(l&&a)try{Y2(a.target,a.content)}catch(s){return H2(s)}return H2(d)}}async function _3(n,t,r=S2()){if(n.length>Yt)throw Error(St);let e=Array(n.length),a=0,l,d=Array.from({length:Math.min(n.length,Me.concurrency)},async()=>{while(!l){let s=a;if(s>=n.length)return;a++;try{e[s]=await t(n[s],s,r.controller.signal)}catch(c){if(!l)l={value:c},a=n.length,r.controller.abort(c);return}}});if(await Promise.all(d),l)throw l.value;return e}function P3(){return{ok:!1,errors:[St],warnings:[],entries:[]}}function Rt(n){return{cwd:n.cwd,cacheConfigDir:n.cacheConfigDir,userConfigDir:n.userConfigDir,userConfigPath:n.userConfigPath,projectConfigPath:n.projectConfigPath,global:n.global,check:n.check,only:n.only,refresh:n.refresh}}function N3(n){return{...Rt(n),deleteSource:n.deleteSource}}async function Vt(n,t={}){try{return await I3(n,N3(t),{})}catch(r){return H2(r)}}async function I3(n,t,r){let e=U(t),a=O(e.configTarget);if(a.errors.length>0)return{ok:!1,errors:a.errors,warnings:[],entries:[]};if(!a.config)return{ok:!1,errors:[`No config found at ${e.configPath}`],warnings:[],entries:[]};let l=At(e.lockTarget);if(l.errors.length>0)return{ok:!1,errors:l.errors,warnings:[],entries:[]};let d=Ce(a.config.rules,l.lock,n);if(!d.ok)return d.result;let s=t.deleteSource?dd(e.configDir,d.specs,l.lock,e.filesystemScope):{ok:!0,dirs:[]};if(!s.ok)return s.result;let c=g(e.configTarget);if(c===null)return H2(Error("Rules config is unavailable."));try{T(e.configTarget,{version:1,rules:a.config.rules.filter((u)=>!d.specs.includes(u)),overrides:a.config.overrides??{},transparent_wrappers:a.config.transparent_wrappers??[]},void 0,r._testAfterPolicyRename)}catch(u){throw Y2(e.configTarget,c),u}let L=await Sn(t,S2(),void 0,r);if(!L.ok)return Y2(e.configTarget,c),L;let i=cd(s.dirs,r,e.filesystemScope);if(!i.ok){Y2(e.configTarget,c);let u=await Sn(t,S2(),void 0,r);if(!u.ok)return{ok:!1,errors:[...i.result.errors,...u.errors],warnings:u.warnings,entries:u.entries};return i.result}return L}async function nd(n,t,r){let e=Te(n,t.lockPath,t.configDir,r,r.global?"user":"project",t.filesystemScope);return{ok:e.errors.length===0&&e.warnings.length===0,errors:[...e.errors,...e.warnings],warnings:[],entries:e.entries}}function td(n,t,r){let e=t?.rulebooks.find((l)=>l.spec===n.entry.spec&&l.kind==="github"),a=r?.get(n.entry.spec)??(e?.kind==="github"?e.display_ref:void 0);if(!a||n.entry.kind!=="github")return n;return{...n,entry:{...n.entry,display_ref:a}}}function rd(n,t,r){let e=new Set(n.rules),a=new Set(t?.rulebooks.map((d)=>d.spec)??[]),l=new Map(r.map((d)=>[d.entry.spec,d.entry]));return[...(t?.rulebooks.filter((d)=>e.has(d.spec))??[]).map((d)=>l.get(d.spec)??d),...r.filter((d)=>!a.has(d.entry.spec)).map((d)=>d.entry)]}function ed(n,t){return{...n,ruleCount:t.get(n.spec)}}function ad(n,t,r,e,a){let l=Qt(t,Xt(r,e));w2(D(a,l),n)}function ld(n,t,r,e,a){let l=Xt(t,r),d=Hn(l),s=D(e,d),c=A2(s);if(!c)return[];let L=n.map((u)=>D(e,Qt(u,l))),i=c.filter((u)=>u.kind==="directory").map((u)=>({directory:D(e,Yn(d,u.name)),identity:D(e,Yn(d,u.name,Re))})).filter((u)=>!L.some((v)=>Ae(u.identity,v))).map((u)=>u.directory);for(let u of i)We(u);return i.flatMap((u)=>{try{return Ld(u,a),[]}catch{return["Unable to prune rules policy cache safely."]}})}function dd(n,t,r,e){let a=new Map(r?.rulebooks.map((L)=>[L.spec,L])??[]),l=t.flatMap((L)=>{let i=a.get(L);if(!i)return cn.test(L)?[]:["--delete-source can only delete local rulebook sources"];return i.kind==="local-directory"?[]:["--delete-source can only delete local rulebook sources"]}),d=t.map((L)=>{let i=a.get(L);return Yn(n,i?.kind==="local-directory"?i.path:L)}),s=l.length>0?[]:d.flatMap((L)=>sd(n,L,e)),c=[...l,...s];return c.length>0?{ok:!1,result:{ok:!1,errors:c,warnings:[],entries:[]}}:{ok:!0,dirs:d}}function sd(n,t,r){let e=He(n),a=He(t),l=U3(e,a);if(l===""||l===".."||l.startsWith(`..${O3}`)||C3(l))return[`Refusing to delete local rulebook source outside ${n}: ${t}`];let d=D(r,a),s=A2(d);if(!s)return[`Local rulebook source directory not found: ${t}`];let c=s.find((L)=>L.name==="rulebook.json");if(!c)return[`Local rulebook source directory is missing rulebook.json: ${t}`];if(c.kind!=="file")throw new Z(r.label);if(g(D(r,Yn(a,"rulebook.json"))),s.length>1)return[`Local rulebook source directory contains extra files: ${t}. delete manually if you really want to remove the directory.`];return[]}function cd(n,t,r){let e=n.flatMap((a)=>{try{return id(D(r,a),t),[]}catch(l){return[`Failed to delete local rulebook source ${a}: ${l instanceof Error?l.message:String(l)}`]}});return e.length>0?{ok:!1,result:{ok:!1,errors:e,warnings:[],entries:[]}}:{ok:!0}}function Ld(n,t){if(t._testPruneRulebookCacheDir){t._testPruneRulebookCacheDir(n.path);return}Zt(n)}function id(n,t){if(t._testDeleteLocalSourceDir){t._testDeleteLocalSourceDir(n.path);return}Zt(n)}function Y2(n,t){if(t===null){sn(n);return}w2(n,t)}function H2(n){return{ok:!1,errors:[n instanceof Error?n.message:String(n)],warnings:[],entries:[]}}function M2(n,t){let r=od(t),e=n1(r),a={effectiveLevel:e.effectiveLevel,selectedPreset:r.policySnapshot.policy.safety.level??"standard",effectiveCapabilities:e.effectiveCapabilities,destructiveCommandRuleOverrides:r.policySnapshot.policy.destructiveCommandRuleOverrides},{configSource:l,configValid:d}=ud({cwd:t?.cwd,userConfigDir:t?.userConfigDir});if(!n||!n.trim())return{trace:{steps:[{type:"error",message:"No command provided"}],segments:[]},result:"allowed",configSource:l,configValid:d,...a};let s=vd(n,r);if(s)return{trace:{steps:[],segments:[{index:0,steps:[{type:"rule-check",ruleModule:s.ruleModule,ruleFunction:s.ruleFunction,matched:!0,reason:s.reason}]}]},result:"blocked",reason:A(s.reason),segment:A(s.target),...s.ruleId?{ruleId:A(s.ruleId)}:{},configSource:l,configValid:d,...a};let c=Be(n,r),L=c.decision,i=L?.ruleId??bd(n,r),u=pn.find((p)=>p.id===i&&p.activationCapability),v=u?e.policy.effectiveDestructiveCommandRules[u.id]:void 0;return{trace:yd(c.trace),result:L?"blocked":"allowed",reason:L?A(L.reason):void 0,segment:L?A(L.evidence.find((p)=>p.kind==="command")?.segment??n):void 0,ruleId:L?.ruleId?A(L.ruleId):void 0,customRule:fd(hd(L?.ruleId,r.policySnapshot)),configSource:l,configValid:d,...a,...u&&v?{ruleActivation:{id:u.id,...v}}:{}}}function ud(n){let t=E(n?.cwd),r=n?.userConfigPath??_(n),e=P({cwd:n?.cwd,userConfigDir:n?.userConfigDir,userConfigPath:n?.userConfigPath});try{if(g(e.projectConfigTarget)!==null){if(a2(e.projectConfigTarget).errors.length===0)return{configSource:t,configValid:!0};return{configSource:t,configValid:!1}}}catch(a){if(a instanceof Z)return{configSource:t,configValid:!1};throw a}try{if(g(e.userConfigTarget)!==null){let a=a2(e.userConfigTarget);return{configSource:r,configValid:a.errors.length===0}}return{configSource:null,configValid:!0}}catch(a){if(a instanceof Z)return{configSource:r,configValid:!1};throw a}}function od(n){let t=pd(n?.cwd??process.cwd()),r=n?.policySnapshot??W({cwd:t,userConfigDir:n?.userConfigDir}),e=d2(r.policy);return{cwd:t,effectiveCwd:t,policySnapshot:r,environment:Ee(),protectedGitMetadata:Ie(t),effectiveCapabilities:e.capabilities,strict:n?.strict??e.strict,paranoidRm:e.paranoidRm,paranoidInterpreters:e.paranoidInterpreters,worktreeMode:e.worktreeMode}}function vd(n,t){let r=t.cwd??process.cwd(),e=_e(K2("",{command:n},{kind:"command",shell:"posix"},{executionCwd:r,configCwd:r},n)),a=e1(e);if(a)return{reason:r1,target:a.target,ruleId:"policy-protection",ruleModule:"policy-protection",ruleFunction:"findPolicyConfigMutationTarget"};let l=Ne(e,t.protectedGitMetadata);if(l)return{reason:Pe,target:l.target,ruleId:"git-metadata-protection",ruleModule:"git-metadata-protection",ruleFunction:"findGitMetadataMutationTarget"};let d=t.policySnapshot.policy,s=d.secretProtection.enabled===!1?null:l1(e,d.secretProtection,{strict:t.strict});if(s)return{reason:a1,target:s.target,ruleId:s.ruleId,ruleModule:"secret-protection",ruleFunction:"findSensitiveTarget"};return null}function bd(n,t){let r=t.policySnapshot.policy,e=un({...r,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:{...r.destructiveCommandRuleOverrides,...Object.fromEntries(pn.flatMap((a)=>a.activationCapability?[[a.id,"on"]]:[]))}},t.policySnapshot.state==="degraded"?{diagnostics:t.policySnapshot.diagnostics,reason:t.policySnapshot.reason}:void 0);return t1(n,{...t,policySnapshot:e,strict:!0,paranoidRm:!0,paranoidInterpreters:!0})?.ruleId}function fd(n){if(!n)return;return{id:A(n.id),...n.rulebook?{rulebook:{name:A(n.rulebook.name),version:A(n.rulebook.version)}}:{},...n.source?{source:A(n.source)}:{},...n.override?{override:{type:"reason",reason:A(n.override.reason)}}:{}}}function yd(n){let t=n.events.flatMap((e)=>e.kind==="step"&&e.scope==="global"?[e.step]:[]),r=new Map;for(let e of n.events){if(e.kind!=="step"||e.scope!=="segment")continue;let a=r.get(e.segmentIndex)??{index:e.segmentIndex,steps:[]};a.steps.push(e.step),r.set(e.segmentIndex,a)}return{steps:t,segments:[...r.values()]}}function hd(n,t){let r=n?.replace(/^custom\./,"");if(!r||!t.policy.rules.some((e)=>e.name===r))return;return t.ruleMetadata[r]??Object.freeze({id:r})}function md(n){let t=G2(),r=F({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"]}},n);if(e2(r.errors))return null;if(r.values.id!==void 0&&!/^[a-f0-9]{16}$/.test(r.values.id))return console.error("--id must be 16 hexadecimal characters"),null;let e=r.values.limit===void 0?20:d1(r.values.limit);if(e===null)return console.error("--limit must be a positive number"),null;let a=r.values.since===void 0?Math.min(30,t):d1(r.values.since);if(a===null||a>t)return console.error(`--since must be a positive number of days no greater than ${t}`),null;let l={limit:e,limitExplicit:r.values.limit!==void 0,since:a,sinceExplicit:r.values.since!==void 0,all:r.flags.all,json:r.flags.json,suspect:r.flags.suspect,pruneLegacy:r.flags.pruneLegacy,dryRun:r.flags.dryRun,id:r.values.id,agent:r.values.agent,rule:r.values.rule,session:r.values.session,project:r.values.project===void 0?void 0:Dd(r.values.project)};if(l.id&&(l.agent!==void 0||l.rule!==void 0||l.session!==void 0||l.project!==void 0||l.suspect||l.sinceExplicit||l.limitExplicit))return console.error("--id cannot be combined with --agent, --rule, --session, --project, --suspect, --since, or --limit"),null;if(l.pruneLegacy&&(l.id!==void 0||l.agent!==void 0||l.rule!==void 0||l.session!==void 0||l.project!==void 0||l.suspect||l.all||l.sinceExplicit||l.limitExplicit))return console.error("--prune-legacy cannot be combined with --id, --agent, --rule, --session, --project, --suspect, --all, --since, or --limit"),null;if(l.dryRun&&!l.pruneLegacy)return console.error("--dry-run requires --prune-legacy"),null;return l}async function L1(n,t={}){let r=md(n);if(!r)return 1;let e=t.logsDir??s2();if(r.pruneLegacy)return kd(e,r.json,r.dryRun);if(!e)return console.log(r.json?"[]":r.id?`No retained audit log entry found for id ${z(r.id)}.`:"No audit log entries found."),0;$2(e);let a={count:0},l=u2(e,a).flatMap((i)=>ln(i,a).map((u)=>({entry:u,file:i})));if(a.count>0)console.error(`warning: ${a.count} audit log ${a.count===1?"source":"sources"} could not be read; these results are incomplete`);if(r.id)return zd(l,r,t.timeZone);let d=Date.now()-r.since*24*60*60*1000,s=l.filter((i)=>Bd(i,r,e,d)),c=r.suspect?qt(s.map((i)=>i.entry)):null,L=(c?s.filter((i)=>c.has(i.entry)):s).sort((i,u)=>Date.parse(u.entry.ts)-Date.parse(i.entry.ts)).slice(0,r.limit);if(r.json)return console.log(JSON.stringify(L.map((i)=>i.entry),null,2)),0;if(L.length===0)return console.log("No audit log entries found."),0;for(let i of L)console.log(Qd(i.entry,t.timeZone));return 0}function kd(n,t,r){let e=n?jd(n).map((s)=>gd(n,s)):[];if(r)return qd(e,t);let a=[],l=0,d=0;for(let s of e){let c=s1(s,{throwIfNoEntry:!1})?.size??0,L=Fd(s);if(L){a.push(`${c1(s)}: ${L}`);continue}l++,d+=c}if(t)return console.log(JSON.stringify({removedFiles:l,removedBytes:d,failedFiles:a.length})),a.length===0?0:1;console.log(l===0&&a.length===0?"No legacy audit log files found.":`Removed ${l} legacy audit log ${l===1?"file":"files"} (${i1(d)}).`);for(let s of a)console.error(`Could not remove ${z(s)}`);if(console.log("Nested v2 audit logs were not changed."),l>0)console.log("This deletion cannot be undone.");return a.length===0?0:1}function qd(n,t){let r=n.reduce((e,a)=>e+(s1(a,{throwIfNoEntry:!1})?.size??0),0);if(t)return console.log(JSON.stringify({dryRun:!0,files:n.length,bytes:r})),0;if(console.log(n.length===0?"No legacy audit log files found.":`Would remove ${n.length} legacy audit log ${n.length===1?"file":"files"} (${i1(r)}).`),console.log("Nested v2 audit logs are not included."),n.length>0)console.log("Run the same command without --dry-run to delete them.");return 0}function jd(n){try{return wd(n,{withFileTypes:!0}).filter((t)=>t.isFile()&&t.name.endsWith(".jsonl")).map((t)=>t.name)}catch{return[]}}function Fd(n){try{return xd(n),null}catch(t){return t instanceof Error?t.message:String(t)}}function i1(n){let t=["B","KiB","MiB","GiB"],r=Math.min(Math.floor(Math.log2(Math.max(n,1))/10),t.length-1);return`${Math.round(n/1024**r*10)/10} ${t[r]}`}function zd(n,t,r){let e=n.filter((l)=>l.entry.id===t.id);if(e.length>1)return console.error(`Multiple audit log entries found for id ${z(t.id??"")}.`),1;if(t.json)return console.log(JSON.stringify(e.map((l)=>l.entry),null,2)),0;let a=e[0];if(!a)return console.log(`No retained audit log entry found for id ${z(t.id??"")}.`),0;return console.log(Xd(a.entry,r)),0}function Bd(n,t,r,e){if(!t.all&&n.entry.decision==="allow")return!1;if(Date.parse(n.entry.ts)<e)return!1;if(t.agent!==void 0&&n.entry.agent!==t.agent)return!1;if(t.rule!==void 0&&n.entry.ruleId!==t.rule)return!1;if(t.session!==void 0&&!Jd(n,r,t.session))return!1;if(t.project!==void 0&&!Zd(n.entry.cwd,t.project))return!1;return!0}function Jd(n,t,r){if(n.entry.sessionId===r)return!0;return $d(n.file)===t&&c1(n.file,".jsonl")===r}function Zd(n,t){if(!n)return!1;return n===t||n.startsWith(`${t}/`)}function Qd(n,t){let r=z(n.id??"-"),e=z(n.decision??"deny"),a=n.cwd?` [${z(n.cwd)}]`:"",l=n.segment||n.command,d=l===n.command?"":"↳ ",s=l.length>50?`${l.slice(0,50)}…`:l;return`${r.padEnd(16)} ${z(p1(n.ts,t))} ${e.padEnd(5)} ${z(n.agent??"-").padEnd(15)} ${z(n.ruleId??"-").padEnd(20)} ${d}${z(s)}${a}`}function Xd(n,t){let r=(a)=>z(a===void 0||a===null||a===""?"-":a),e=n.shape?`${n.agent??"-"} (shape: ${n.shape})`:n.agent??"-";return[`id: ${r(n.id)}`,`ts: ${r(p1(n.ts,t))}`,`decision: ${r(n.decision)}`,`agent: ${r(e)}`,`level: ${r(n.level)}`,`tool: ${r(n.toolName)}`,`rule: ${r(n.ruleId)}`,`intent: ${r(n.intent)}`,`stage: ${r(n.failureStage)}`,`error: ${r(n.errorCode)}`,`session: ${r(n.sessionId)}`,`cwd: ${r(n.cwd)}`,`version: ${r(n.v)}`,`truncated: ${r(n.truncated===!0?"yes":void 0)}`,`reason: ${r(n.reason)}`,`command: ${r(n.command)}`,`segment: ${r(n.segment)}`].join(`
5
+ `)}function p1(n,t){let r=new Date(n);if(Number.isNaN(r.getTime()))return n;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(r)}function d1(n){let t=Number(n);return Number.isFinite(t)&&t>0?t:null}var u1={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 o1={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 v1={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 D1,relative as Cd}from"node:path";var Yd=8388608;function Sd(n,t){console.log(JSON.stringify(n(f1(t))))}async function Hd(n){let t;try{t=(await tr(process.stdin)).trim()}catch{n({reason:"Failed to parse hook input JSON."});return}if(!t){n({reason:"Missing hook input JSON."});return}return rr(t,n,"Failed to parse hook input JSON.")}async function tr(n){let t=[],r=0;for await(let e of n){let a=typeof e==="string"?Buffer.from(e,"utf-8"):Buffer.from(e.buffer,e.byteOffset,e.byteLength);if(r+=a.byteLength,r>Yd)throw Ad(n),Error("hook input byte limit exceeded");t.push(a)}return Buffer.concat(t,r).toString("utf-8")}function Ad(n){let t=n.destroy??n.cancel;if(!t)return;try{Promise.resolve(t.call(n)).catch(()=>{})}catch{}}function rr(n,t,r){try{return JSON.parse(n)}catch{t({reason:r});return}}function X(n,t){let r=t.get(n);return r?{kind:"command",shell:r}:{kind:h1(n)}}function N(n,t,r,e){let a=n===void 0?process.cwd():n,l=typeof a==="string"&&a.trim()!==""?c2([a]):void 0;if(l)return{configCwd:l,executionCwd:l};return H(e,t,r,Kd(a)),null}function H(n,t,r,e){let a;try{a=nr(t)}catch(l){if(!(l instanceof C2))throw l}n(An({command:a,segment:e,toolName:r}))}async function Wd(n){let t=await Hd(n.outputDeny);if(t===void 0)return;if(!t||typeof t!=="object"||Array.isArray(t)){H(n.outputDeny);return}if(!n.isSupported(t))return;let r=n.getAgent?.(t)??n.agent,e=n.agent===r?void 0:n.agent,a=Gd(t),l=(p,f)=>{b1(p,()=>n.getSessionId(t),{agent:r,shape:e,toolName:f,cwd:a}),n.outputDeny(p)},d=n.getToolName(t);if(typeof d!=="string"||d.trim()===""){H((p)=>l(p),Md(t));return}let s=d,c=(p)=>l(p,s),L;try{L=n.getToolInput(t,s,c)}catch(p){if(!(p instanceof C2))throw p;H(c,void 0,s);return}if(!L.ok)return;let i=n.getContext(t,L.input,s,c);if(!i)return;let u;try{u=nr(L.input)}catch(p){if(!(p instanceof C2))throw p;H(c,void 0,s);return}let v=K2(s,L.input,L.route,i,u??null);try{let p=Wn(v,{guard:{auditAllowed:w1(),dependencies:n.guardDependencies},audit:{agent:r,shape:e,getSessionId:()=>n.getSessionId(t)}}),f=It(p,{includeEvidence:!0,toolName:p.stage==="command-analysis"?void 0:s});if(f){n.outputDeny(f);return}n.outputAllow?.()}catch(p){if(!(p instanceof x1))throw p;Rd(p);let f=It(p.evaluation,{includeEvidence:!0,toolName:p.evaluation.stage==="command-analysis"?void 0:s});if(f)n.outputDeny(f);return}}function Rd(n){if(!on(m.debug))return;console.error(`CC Safety Net debug: ${Vd(n.stage)}: ${y1(n.cause)}`)}function Vd(n){if(n==="policy-protection")return"hook policy protection failed";if(n==="config-load")return"hook config loading failed";if(n==="secret-protection")return"hook secret protection failed";return"hook analysis failed"}function Kd(n){return typeof n==="string"?n:void 0}function Md(n){if(!n||typeof n!=="object"||Array.isArray(n))return;if(Object.hasOwn(n,"tool_input"))return n.tool_input;let t=n.toolCall;if(t&&typeof t==="object"&&!Array.isArray(t))return t.args;return}function Gd(n){if(!n||typeof n!=="object"||Array.isArray(n))return null;let t=n.cwd;if(typeof t==="string")return t;let r=n.toolCall;if(!r||typeof r!=="object"||Array.isArray(r))return null;let e=r.args;if(!e||typeof e!=="object"||Array.isArray(e))return null;let a=e.Cwd;return typeof a==="string"?a:null}async function Y(n){let t=(a)=>Sd(n.createDenyOutput,a),r=n.createAllowOutput;await Wd({...n,outputDeny:t,outputAllow:r?()=>console.log(JSON.stringify(r())):void 0})}var Ud=new Map([["run_command","auto"]]),Od=new Set(["absolutepath","directorypath","file_path","filepath","path","searchdirectory","searchpath","target_file","targetfile"]);function m1(n){return X(n,Ud)}async function k1(){await Y({agent:"antigravity-cli",createDenyOutput:(n)=>({decision:"deny",reason:n}),isSupported:()=>!0,getToolName:(n)=>n.toolCall?.name,getToolInput:(n,t)=>({ok:!0,input:Nd(n.toolCall?.args,t),route:m1(t)}),getContext:Td,getSessionId:(n)=>n.conversationId})}function Td(n,t,r,e){let l=Pd(n).flatMap((L)=>{let i=c2([L]);return i?[i]:[]});if(!l[0])return D2(e,t,r),null;if(r!=="run_command"){let L;try{L=Ed(t,r,l)}catch(i){if(i instanceof C2)return D2(e,void 0,r),null;if(!(i instanceof Rn))throw i;return D2(e,t,r),null}if(!L)return D2(e,t,r),null;return{configCwd:L,executionCwd:L,policyConfigCwds:l}}let d=n.toolCall?.args;if(!d||!Object.hasOwn(d,"Cwd"))return{configCwd:l[0],executionCwd:l[0],policyConfigCwds:l};let s=d.Cwd;if(typeof s!=="string"||s.trim()==="")return D2(e,t,r),null;let c=hn(s,l);if(c){let L=q1(c,l);if(!L)return D2(e,t,r,s),null;return{configCwd:L,executionCwd:c,policyConfigCwds:l}}return D2(e,t,r,s),null}function Ed(n,t,r){let e=m1(t),a=[...$1(n,Od),...e.kind==="patch"?g1(n):[]].filter(D1),l=Vn(),d=new Set(a.flatMap((s)=>{let c=q1(fn(s,yn,l),r);return c?[c]:[]}));if(d.size>1)return null;return[...d][0]??r[0]??null}function q1(n,t){return t.filter((r)=>_d(n,r)).reduce((r,e)=>e.length>r.length?e:r,"")||null}function _d(n,t){let r=Cd(t,n);return r===""||!r.startsWith("..")&&!D1(r)}function D2(n,t,r,e){let a=t&&typeof t==="object"?t.command:void 0;n(An({command:typeof a==="string"?a:void 0,segment:e,toolName:r}))}function Pd(n){if(n.workspacePaths===void 0)return[process.cwd()];let t=Array.isArray(n.workspacePaths)?n.workspacePaths.filter((r)=>typeof r==="string"&&r.trim()!==""):[];return c2(t)?t:[]}function Nd(n,t){if(!n)return;if(t!=="run_command")return n;return{...n,command:typeof n.CommandLine==="string"&&n.CommandLine!==""?n.CommandLine:void 0}}var U2=[{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",installLabel:"Antigravity CLI",helpTarget:"Antigravity CLI 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",installLabel:"Claude Code",helpTarget:"Claude Code plugin",probeCommand:["claude","--version"]}},{id:"codex",displayName:"Codex",doctorOrder:4,install:{order:4,flag:"--codex",installLabel:"Codex",helpTarget:"Codex 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",installLabel:"GitHub Copilot CLI",helpTarget:"GitHub Copilot CLI 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",installLabel:"Gemini CLI",helpTarget:"Gemini CLI 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",installLabel:"Hermes Agent",helpTarget:"Hermes Agent 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",installLabel:"Kimi Code",helpTarget:"Kimi Code hook config",probeCommand:["kimi","--version"]}},{id:"openclaw",displayName:"OpenClaw",doctorOrder:10,install:{order:10,flag:"--openclaw",installLabel:"OpenClaw",helpTarget:"OpenClaw plugin",probeCommand:["openclaw","--version"]}},{id:"opencode",displayName:"OpenCode",doctorOrder:11,install:{order:11,flag:"--opencode",installLabel:"OpenCode",helpTarget:"OpenCode plugin",probeCommand:["opencode","--version"]}},{id:"pi",displayName:"Pi",doctorOrder:12,install:{order:12,flag:"--pi",installLabel:"Pi",helpTarget:"Pi 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",installLabel:"Cursor",helpTarget:"Cursor hook config",probeCommand:["cursor","--version"]}},{id:"amp",displayName:"Amp Code",doctorOrder:2,install:{order:1,flag:"--amp",installLabel:"Amp Code",helpTarget:"Amp Code plugin",probeCommand:["amp","--version"]}}],j1=U2.slice().sort((n,t)=>n.doctorOrder-t.doctorOrder).map((n)=>n.id),F1=U2.filter((n)=>("runtime"in n)).slice().sort((n,t)=>n.runtime.order-t.runtime.order).map((n)=>({id:n.id,displayName:"displayName"in n.runtime?n.runtime.displayName:n.displayName,flags:n.runtime.flags,legacyFlags:"legacyFlags"in n.runtime?n.runtime.legacyFlags:[],description:n.runtime.description,legacyTopLevelFlags:n.runtime.legacyTopLevelFlags})),L2=U2.slice().sort((n,t)=>n.install.order-t.install.order).map((n)=>({id:n.id,...n.install})).map(({order:n,...t})=>t),z6=Object.fromEntries(U2.map((n)=>[n.id,n.displayName]));function v2(n){return U2.find((t)=>t.id===n)?.displayName??n}function b2(n){return U2.find((t)=>t.id===n)?.install.installLabel??n}import{homedir as Id}from"node:os";import{isAbsolute as z1,join as er}from"node:path";function J1(n){if(n!==void 0&&n!==null&&!z1(n))return"unknown";try{let t=Vn(),r=n?fn(n,yn,t):void 0,e=process.env.HOME||Id(),a=[["codex",process.env.CODEX_HOME||er(e,".codex")],["copilot-cli",process.env.COPILOT_HOME||er(e,".copilot")],["claude-code",process.env.CLAUDE_CONFIG_DIR||er(e,".claude")]],l=r?a.flatMap(([d,s])=>{if(!z1(s))return[];return B1(r,fn(s,yn,t))?[d]:[]}):[];if(l.length===1)return l[0]??"unknown";if(l.length>1)return"unknown"}catch(t){if(t instanceof Rn)return"unknown";return"unknown"}if(process.env.CLAUDECODE==="1"||Boolean(process.env.CLAUDE_CODE_ENTRYPOINT))return"claude-code";return"unknown"}var ar="PreToolUse",Z1="BeforeTool",Q1="pre_tool_call",lr="PreToolUse";var ns=new Map([["Bash","posix"],["PowerShell","powershell"]]);function ts(n){return X(n,ns)}async function X1(){await Y({agent:"claude-code",getAgent:(n)=>J1(n.transcript_path),createDenyOutput:(n)=>({hookSpecificOutput:{hookEventName:ar,permissionDecision:"deny",permissionDecisionReason:n}}),isSupported:(n)=>n.hook_event_name===ar,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:ts(t)}),getContext:(n,t,r,e)=>N(n.cwd,t,r,e),getSessionId:(n)=>n.session_id})}var rs=new Map([["bash","auto"],["Bash","auto"]]);function es(n){return X(n,rs)}async function Y1(){await Y({agent:"copilot-cli",createDenyOutput:(n)=>({permissionDecision:"deny",permissionDecisionReason:n}),isSupported:()=>!0,getToolName:(n)=>n.toolName,getToolInput:(n,t,r)=>{if(typeof n.toolArgs!=="string")return r({reason:"Failed to parse toolArgs JSON."}),{ok:!1};let e=rr(n.toolArgs,r,"Failed to parse toolArgs JSON.");if(e===void 0)return{ok:!1};return{ok:!0,input:e,route:es(t)}},getContext:(n,t,r,e)=>N(n.cwd,t,r,e),getSessionId:(n)=>typeof n.sessionId==="string"&&n.sessionId.trim()?n.sessionId:void 0})}var as=new Map([["Shell","auto"]]);function ls(n){return X(n,as)}async function S1(){await Y({agent:"cursor",createDenyOutput:(n)=>({permission:"deny",user_message:n,agent_message:n}),createAllowOutput:()=>({permission:"allow"}),isSupported:()=>!0,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:ls(t)}),getContext:ds,getSessionId:(n)=>n.conversation_id})}function ds(n,t,r,e){let a=ss(n);if(!a[0])return H(e,t,r),null;let l=hn(Ls(n.cwd),a);if(!l)return H(e,t,r,typeof n.cwd==="string"?n.cwd:void 0),null;if(t===null||typeof t!=="object"||Array.isArray(t))return{configCwd:l,executionCwd:l,policyConfigCwds:a};if(!Object.hasOwn(t,"working_directory"))return{configCwd:l,executionCwd:l,policyConfigCwds:a};let d=t.working_directory;if(typeof d!=="string"||d.trim()==="")return H(e,t,r),null;let s=hn(d,a);if(!s)return H(e,t,r,d),null;return{configCwd:l,executionCwd:s,policyConfigCwds:a}}function ss(n){return cs(n).flatMap((t)=>{let r=c2([t]);return r?[r]:[]})}function cs(n){if(n.workspace_roots===void 0)return typeof n.cwd==="string"&&n.cwd.trim()!==""?[n.cwd]:[];if(!Array.isArray(n.workspace_roots))return[];return n.workspace_roots.filter((t)=>typeof t==="string"&&t.trim()!=="")}function Ls(n){return typeof n==="string"&&n.trim()!==""?n:"."}var is=new Map([["run_shell_command","auto"]]);function ps(n){return X(n,is)}async function H1(){await Y({agent:"gemini-cli",createDenyOutput:(n)=>({decision:"deny",reason:n,systemMessage:n}),isSupported:(n)=>n.hook_event_name===Z1,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:ps(t)}),getContext:(n,t,r,e)=>N(n.cwd,t,r,e),getSessionId:(n)=>n.session_id})}import{resolve as us}from"node:path";var os=new Map([["terminal","posix"]]);async function A1(){await Y({agent:"hermes-agent",createDenyOutput:(n)=>({action:"block",message:n}),isSupported:(n)=>n.hook_event_name===Q1,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:X(t,os)}),getContext:vs,getSessionId:(n)=>n.session_id})}function vs(n,t,r,e){let a=N(n.cwd,t,r,e);if(!a)return null;if(!t||typeof t!=="object"||Array.isArray(t))return a;if(!Object.hasOwn(t,"workdir"))return a;let l=t.workdir;if(typeof l!=="string"||l.trim()==="")return H(e,t,r),null;let d=c2([us(a.configCwd,l)]);if(!d)return H(e,t,r,l),null;return{...a,executionCwd:d}}var bs=new Map([["Bash","posix"]]);function fs(n){return X(n,bs)}async function W1(){await Y({agent:"kimi-code",createDenyOutput:(n)=>({hookSpecificOutput:{hookEventName:lr,permissionDecision:"deny",permissionDecisionReason:n}}),isSupported:(n)=>n.hook_event_name===lr,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:fs(t)}),getContext:(n,t,r,e)=>N(n.cwd,t,r,e),getSessionId:(n)=>n.session_id})}var ys={"antigravity-cli":k1,"claude-code":X1,"copilot-cli":Y1,cursor:S1,"gemini-cli":H1,"hermes-agent":A1,"kimi-code":W1},O2=F1.map((n)=>({...n,run:ys[n.id]}));function R1(n){let t=F({label:"hook",booleans:Object.fromEntries(O2.map((e)=>[e.id,[...e.flags,...e.legacyFlags]]))},n);if(t.errors.length>0)return;let r=O2.filter((e)=>t.flags[e.id]);return r.length===1?r[0]:void 0}function V1(n){return O2.find((t)=>t.legacyTopLevelFlags.some((r)=>r===n))}var hs=O2.map((n)=>({flags:n.flags.join(", "),description:n.description})),ws=O2.flatMap((n)=>n.flags.map((t)=>`cc-safety-net hook ${t}`)),K1={name:"hook",description:"Run as an agent CLI hook (reads JSON from stdin)",usage:"hook INTEGRATION_FLAG",options:[...hs,{flags:"-h, --help",description:"Show this help"}],examples:ws};var M1={name:"install",description:"Install CC Safety Net into a coding agent CLI",usage:"install [TARGET_FLAG]",options:[...L2.map((n)=>({flags:n.flag,description:`Install ${n.helpTarget}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net install",...L2.map((n)=>`cc-safety-net install ${n.flag}`)]},G1={name:"uninstall",description:"Uninstall CC Safety Net from a coding agent CLI",usage:"uninstall [TARGET_FLAG]",options:[...L2.map((n)=>({flags:n.flag,description:`Uninstall ${n.helpTarget}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net uninstall",...L2.map((n)=>`cc-safety-net uninstall ${n.flag}`)]},C1={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 U1={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 T2={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 O1={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 T1={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 E1=[O1,u1,U1,o1,T2,M1,C1,G1,K1,v1,T1];function xs(n){return n.aliases??[]}function $s(n){return!n.hidden}function Kn(n){let t=n.toLowerCase();return E1.find((r)=>r.name.toLowerCase()===t||xs(r).some((e)=>e.toLowerCase()===t))}function _1(){return E1.filter($s)}import{readFileSync as gs}from"node:fs";import{basename as Ds}from"node:path";function Mn(n=7,t=s2()){let r=Date.now()-n*24*60*60*1000,e=[],a=new Set,l=0,d,s,c,L;if(t)$2(t);let i={count:0},u=t?u2(t,i):[];for(let p of u)try{let o=gs(p,"utf-8").trim().split(`
6
+ `).filter(Boolean);for(let y of o)try{let x=JSON.parse(y);if(x.decision==="allow")continue;let w=new Date(x.ts).getTime();if(w>=r){if(l++,a.add(x.sessionId??Ds(p,".jsonl")),s===void 0||w<=s)d=x.ts,s=w;if(L===void 0||w>L)c=x.ts,L=w;ms(e,x,w)}}catch{i.count++}}catch{i.count++}let v=e.map((p)=>({timestamp:p.ts,command:p.command,reason:p.reason,relativeTime:kt(new Date(p.ts))}));return{totalBlocked:l,sessionCount:a.size,recentEntries:v,oldestEntry:d,newestEntry:c,unreadable:i.count}}function ms(n,t,r){let e=n.findIndex((a)=>r>new Date(a.ts).getTime());if(e===-1){if(n.length<3)n.push(t);return}if(n.splice(e,0,t),n.length>3)n.pop()}import{dirname as ks}from"node:path";function P1(n,t,r,e,a){let l;try{if(g(e)===null)return{path:n,exists:!1,valid:!1,ruleCount:0};l=a2(e),l.errors.push(...l2(n,t,{userConfigDir:r},a))}catch(d){if(!(d instanceof Z))throw d;l={errors:[d.message],ruleNames:new Set}}return{path:n,exists:!0,valid:l.errors.length===0,ruleCount:l.ruleNames.size,...l.errors.length>0?{errors:l.errors}:{}}}function qs(n,t){return{source:t,name:n.name,command:n.command,subcommand:n.subcommand,blockArgs:[...n.block_args],reason:n.reason}}function N1(n,t){let r=t?.userConfigPath??_(),e=t?.projectConfigPath??E(n),a=ks(r),l=o2({cwd:n,userConfigPath:r,projectConfigPath:e,userConfigDir:a}),d=P({cwd:n,userConfigPath:r,projectConfigPath:e,userConfigDir:a}),s=new Map(l.rulebooks.flatMap((c)=>c.rules.map((L)=>[L,c.source])));return{userConfig:P1(r,R2({userConfigPath:r}),a,d.userConfigTarget,d.userScope),projectConfig:P1(e,V2(e),a,d.projectConfigTarget,d.projectScope),effectiveRules:l.rules.map((c)=>qs(c,s.get(c.name)??"project")),shadowedRules:[]}}var js=[{flag:m.level,description:"Safety level preset: standard, strict, or paranoid",defaultBehavior:"standard"},{flag:m.strict,description:"Legacy; equivalent to safety.overrides.fail_closed",defaultBehavior:"permissive"},{flag:m.paranoid,description:"Legacy; equivalent to safety.overrides.paranoid_rm and paranoid_interpreters",defaultBehavior:"off"},{flag:m.paranoidRm,description:"Legacy; equivalent to safety.overrides.paranoid_rm",defaultBehavior:"off"},{flag:m.paranoidInterpreters,description:"Legacy; equivalent to safety.overrides.paranoid_interpreters",defaultBehavior:"off"},{flag:m.worktree,description:"Allow local git discards in linked worktrees",defaultBehavior:"off"},{flag:m.debug,description:"Print diagnostic messages to stderr",defaultBehavior:"off"},{flag:m.auditScope,description:"Command decisions recorded: all, or blocked (privacy-minimizing, denials only)",defaultBehavior:"all"}];function I1(){return[...js.map((n)=>({name:n.flag.name,value:_t(n.flag),isSet:Pt(n.flag),legacyName:n.flag.legacyName,legacyValue:n.flag.legacyName?process.env[n.flag.legacyName]:void 0,legacyIsSet:n.flag.legacyName?process.env[n.flag.legacyName]!==void 0:void 0,description:n.description,defaultBehavior:n.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 na={error:0,warning:1,info:2},Fs=["policy","config","audit"];function zs(n){return n.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 Bs=[{derive:(n)=>n.hooks.length>0&&n.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:(n)=>n.hooks.filter((t)=>t.inspectionStatus==="failed").map((t)=>{let r=v2(t.platform);return{checkId:"integration.inspection-failed",severity:"error",title:`${r} inspection failed`,detail:`Doctor could not verify the ${r} integration configuration.`,fixHint:`Correct the reported ${r} configuration error, then run \`cc-safety-net doctor\` again.`,integration:t.platform}})},{derive:(n)=>n.userConfig.exists&&!n.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:n.userConfig.path}]:[]},{derive:(n)=>n.projectConfig.exists&&!n.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:n.projectConfig.path}]:[]},{derive:(n)=>n.configState.state==="degraded"?[{checkId:"config.runtime-degraded",severity:"warning",title:"Runtime is enforcing a fallback configuration",detail:`The rejected candidate configuration is not active: ${n.configState.reason}`,fixHint:"Correct the named source, run `cc-safety-net rule sync` for a rule source, then rerun doctor."}]:[]},{derive:(n)=>{let t=n.environment.find((r)=>r.name==="CC_SAFETY_NET_AUDIT_SCOPE");return Et(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."}]:[]}},...Fs.map((n)=>({derive:(t)=>t.posture.directories.filter((r)=>r.kind===n&&r.status==="unsafe").map((r)=>({checkId:`posture.${n}-directory-unsafe`,severity:"error",title:`${n[0]?.toUpperCase()}${n.slice(1)} directory is unsafe`,detail:`The ${n} directory ${zs(r.issues)}.`,fixHint:"Ensure this is a real directory owned by the current user with no group or other write access, then rerun doctor.",...r.path?{path:r.path}:{}}))})),{derive:(n)=>{let t=[...n.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 ta(n){return Bs.flatMap((t,r)=>t.derive(n).map((e,a)=>({finding:e,catalogOrder:r,occurrence:a}))).sort((t,r)=>na[t.finding.severity]-na[r.finding.severity]||t.catalogOrder-r.catalogOrder||t.occurrence-r.occurrence).map((t)=>t.finding)}function I(){return Boolean(process.stdout.isTTY&&!process.env.NO_COLOR)}var Js=(n)=>I()?`\x1B[32m${n}\x1B[0m`:n,Zs=(n)=>I()?`\x1B[33m${n}\x1B[0m`:n,Qs=(n)=>I()?`\x1B[34m${n}\x1B[0m`:n,Xs=(n)=>I()?`\x1B[35m${n}\x1B[0m`:n,Ys=(n)=>I()?`\x1B[36m${n}\x1B[0m`:n,Ss=(n)=>I()?`\x1B[31m${n}\x1B[0m`:n,Hs=(n)=>I()?`\x1B[2m${n}\x1B[0m`:n,As=(n)=>I()?`\x1B[1m${n}\x1B[0m`:n,b={green:Js,yellow:Zs,blue:Qs,magenta:Xs,cyan:Ys,red:Ss,dim:Hs,bold:As},Ws="\x1B[0m",Rs=[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 Vs(n){let t=n;return()=>{return t=(t*1664525+1013904223)%4294967296,t/4294967296}}function Ks(n){let t=[...Rs],r=Vs(n);for(let e=t.length-1;e>0;e--){let a=Math.floor(r()*(e+1)),l=t[e];t[e]=t[a],t[a]=l}return t}function Ms(n,t=0){if(!I())return"";let r=Ks(t);return`\x1B[38;5;${r[n%r.length]}m`}function ra(n,t,r=0){if(!I())return`"${n}"`;return`${Ms(t,r)}"${n}"${Ws}`}var Gs=new RegExp("\x1B\\[[0-9;]*m","g"),dr=(n)=>n.replace(Gs,"").length;function m2(n){let t=(n.headers??n.rows[0]??[]).map((d,s)=>{let c=Math.max(...n.rows.map((L)=>dr(L[s]??"")));return Math.max(dr(d),c)}),r=(d,s)=>d+" ".repeat(Math.max(0,s-dr(d))),e=(d,s)=>s[0]+t.map((c)=>d.repeat(c+2)).join(s[1])+s[2],a=(d)=>`│ ${d.map((s,c)=>r(s,t[c]??0)).join(" │ ")} │`,l=n.headers?[` ${a(n.headers)}`,` ${e("─",["├","┼","┤"])}`]:[];return[` ${e("─",["┌","┬","┐"])}`,...l,...n.rows.map((d)=>` ${a(d)}`),` ${e("─",["└","┴","┘"])}`].join(`
7
+ `)}function ea(n){let t=[];t.push("Hook Integration"),t.push(Cs(n));let r=[],e=[];for(let a of n){let l=v2(a.platform);if(a.errors&&a.errors.length>0)for(let d of a.errors)if(a.configured)r.push({platform:l,message:d});else e.push({platform:l,message:d})}for(let a of r)t.push(` Warning (${a.platform}): ${a.message}`);for(let a of e)t.push(b.red(` Error (${a.platform}): ${a.message}`));return t.join(`
8
+ `)}function Cs(n){let t=["Platform","Discovery","Configuration","Inspection"],r=n.map((e)=>{let a=v2(e.platform);if(e.inspectionStatus==="not-inspected"){let c=b.dim("Not inspected");return[a,c,c,c]}let l=e.detected?b.green("Detected"):e.inspectionStatus==="failed"?b.red("Unknown"):b.dim("Not detected"),d=e.configured?b.green("Configured"):e.detected?b.yellow("Not configured"):e.inspectionStatus==="failed"?b.red("Unknown"):b.dim("Not applicable"),s=e.inspectionStatus==="verified"?b.green("Verified"):e.inspectionStatus==="failed"?b.red("Failed"):b.dim("Not applicable");return[a,l,d,s]});return m2({headers:t,rows:r})}function aa(n){let r=["Guard Engine Verification",` Synthetic self-test: ${n.failed>0?b.red(`${n.passed}/${n.total} FAIL`):b.green(`${n.passed}/${n.total} passed`)}`],e=n.results.filter((a)=>!a.passed);if(e.length>0){r.push(""),r.push(b.red(" Failures:"));for(let a of e)r.push(b.red(` • ${a.description}`)),r.push(b.red(` expected ${a.expected}, got ${a.actual}`))}return r.join(`
9
+ `)}function Us(n){if(n.length===0)return" (no custom rules)";let t=["Source","Name","Command","Block Args"],r=n.map((e)=>[e.source,e.name,e.subcommand?`${e.command} ${e.subcommand}`:e.command,e.blockArgs.join(", ")]);return m2({headers:t,rows:r})}function la(n){let t=[];if(t.push("Configuration"),t.push(Os(n.userConfig,n.projectConfig)),t.push(""),n.effectiveRules.length>0)t.push(` Effective rules (${n.effectiveRules.length} total):`),t.push(Us(n.effectiveRules));else t.push(" Effective rules: (none - using built-in rules only)");for(let r of n.shadowedRules)t.push(""),t.push(` Note: Project rule "${r.name}" shadows user rule with same name`);return t.join(`
10
+ `)}function Os(n,t){let r=["Scope","Status"],e=(l)=>{if(!l.exists)return b.dim("N/A");if(!l.valid)return b.red(`Invalid (${l.errors?.[0]??"unknown error"})`);return b.green("Configured")},a=[["User",e(n)],["Project",e(t)]];return m2({headers:r,rows:a})}function da(n){let t=[];return t.push("Environment"),t.push(Ts(n)),t.join(`
11
+ `)}function sa(n){let t=["Effective Safety",` Selected preset: ${n.effectiveSafety.selectedPreset}`,` Effective: ${n.effectiveSafety.level}`],r=[["fail_closed","fail_closed"],["paranoid_rm","paranoid_rm"],["paranoid_interpreters","paranoid_interpreters"]];for(let[e,a]of r){let l=n.effectiveSafety.capabilities[e],d=l.enabled?b.green("ON"):b.dim("OFF"),s=l.sources.length>0?` (${l.sources.join(", ")})`:"";t.push(` ${a}: ${d} via ${l.source}${s}`)}t.push(` Stored rule customizations: ${n.effectiveSafety.ruleCounts.stored}`),t.push(` Effective rule customizations: ${n.effectiveSafety.ruleCounts.effective}`);for(let[e,a]of Object.entries(n.effectiveSafety.ruleOverrides))t.push(` ${e}: ${a}`);return t.join(`
12
+ `)}function ca(n){let t=["Findings"];if(n.length===0)return t.push(" No findings from inspected doctor facts."),t.join(`
13
+ `);for(let r of n){let e=`[${r.severity.toUpperCase()}] ${r.checkId}: ${z(r.title)}`,a=r.severity==="error"?b.red:r.severity==="warning"?b.yellow:b.blue;if(t.push(` ${a(e)}`),t.push(` ${z(r.detail)}`),r.path)t.push(` Path: ${z(r.path)}`);if(r.fixHint)t.push(` Fix: ${z(r.fixHint)}`)}return t.join(`
14
+ `)}function Ts(n){let t=["Variable","Status","Legacy"],r=n.map((e)=>{let a=e.isSet?b.green("✓"):b.dim("✗"),l=e.legacyName&&e.legacyIsSet?`${e.legacyName} ${b.green("✓")}`:e.legacyName??"";return[e.name,a,l]});return m2({headers:t,rows:r})}function La(n){let t=[];if(n.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 (${n.totalBlocked} blocked / ${n.sessionCount} sessions)`),t.push(Es(n.recentEntries));if(n.unreadable>0)t.push(` Warning: ${n.unreadable} audit log ${n.unreadable===1?"source":"sources"} could not be read; this summary is incomplete`);return t.join(`
15
+ `)}function Es(n){let t=["Time","Command"],r=n.map((e)=>{let a=z(e.command.replace(/\r\n|\r|\n/g," ↵ ").replace(/\t/g," ")),l=a.length>40?`${a.slice(0,37)}...`:a;return[e.relativeTime,l]});return m2({headers:t,rows:r})}function ia(n){let t=[];if(t.push("Update Check"),n.latestVersion===null&&!n.error)return t.push(Gn([["Status",b.dim("Skipped")],["Installed",n.currentVersion]])),t.join(`
16
+ `);if(n.error)return t.push(Gn([["Status",`${b.yellow("⚠")} Error`],["Installed",n.currentVersion],["Error",b.dim(n.error)]])),t.join(`
17
+ `);if(n.updateAvailable)return t.push(Gn([["Status",`${b.yellow("⚠")} Update Available`],["Current",n.currentVersion],["Latest",b.green(n.latestVersion??"")]])),t.push(""),t.push(" Run: bunx cc-safety-net@latest doctor"),t.push(" Or: npx cc-safety-net@latest doctor"),t.join(`
18
+ `);return t.push(Gn([["Status",`${b.green("✓")} Up to date`],["Version",n.currentVersion]])),t.join(`
19
+ `)}function Gn(n){return m2({rows:n})}function pa(n){let t=[];return t.push("System Info"),t.push(_s(n)),t.join(`
20
+ `)}function _s(n){let t=["Component","Version"],r=(l)=>{if(l===null)return b.dim("not found");return l},a=[{label:"cc-safety-net",value:n.version},{label:"Claude Code",value:n.claudeCodeVersion},{label:"Amp Code",value:n.ampVersion},{label:"Antigravity CLI",value:n.antigravityCliVersion},{label:"Codex",value:n.codexCliVersion},{label:"Cursor",value:n.cursorVersion},{label:"Gemini CLI",value:n.geminiCliVersion},{label:"GitHub Copilot CLI",value:n.copilotCliVersion},{label:"Hermes Agent",value:n.hermesAgentVersion},{label:"Kimi Code",value:n.kimiCodeVersion},{label:"OpenClaw",value:n.openClawVersion},{label:"OpenCode",value:n.openCodeVersion},{label:"Pi",value:n.piCliVersion},{label:"Node.js",value:n.nodeVersion},{label:"npm",value:n.npmVersion},{label:"Bun",value:n.bunVersion},{label:"Platform",value:n.platform}].map((l)=>[l.label,r(l.value)]);return m2({headers:t,rows:a})}function ua(n){if(n.findings.length===0)return b.green(`
21
+ No findings from inspected doctor facts.`);let t={error:n.findings.filter((l)=>l.severity==="error").length,warning:n.findings.filter((l)=>l.severity==="warning").length,info:n.findings.filter((l)=>l.severity==="info").length},r=["error","warning","info"].filter((l)=>t[l]>0).map((l)=>`${t[l]} ${l}`),e=n.findings.length===1?"finding":"findings",a=`
22
+ ${n.findings.length} ${e}: ${r.join(", ")}.`;if(t.error>0)return b.red(a);if(t.warning>0)return b.yellow(a);return b.blue(a)}import{lstatSync as Ps}from"node:fs";import{dirname as sr}from"node:path";function cr(n,t){try{let r=Ps(t);if(r.isSymbolicLink())return{kind:n,path:t,status:"unsafe",issues:["symlink"]};if(!r.isDirectory())return{kind:n,path:t,status:"unsafe",issues:["not-directory"]};if(process.platform==="win32"||typeof process.getuid!=="function")return{kind:n,path:t,status:"unknown",issues:[]};let e=[...r.uid!==process.getuid()?["ownership"]:[],...(r.mode&18)!==0?["permissions"]:[]];return{kind:n,path:t,status:e.length>0?"unsafe":"safe",issues:e}}catch(r){if(typeof r==="object"&&r!==null&&"code"in r&&r.code==="ENOENT")return{kind:n,path:t,status:"not-applicable",issues:[]};return{kind:n,path:t,status:"unknown",issues:[]}}}function oa(n){let t=s2();return{directories:[cr("policy",sr(sr(n))),cr("config",sr(n)),...t?[cr("audit",t)]:[{kind:"audit",status:"unknown",issues:[]}]]}}import{spawn as Ns}from"node:child_process";import{existsSync as va}from"node:fs";import{delimiter as Is,extname as nc,join as tc}from"node:path";import{stripVTControlCharacters as ba}from"node:util";var ya="2.0.3",rc=5000,ec="_CC_SAFETY_NET_TEST_SPAWN_PLATFORM";function j(){return ya}function Lr(n,t){let r=n[t];if(r)return r;let e=Object.keys(n).find((a)=>a.toLowerCase()===t.toLowerCase()&&!!n[a]);return e?n[e]:r}function ac(n){return(Lr(n,"PATHEXT")||".COM;.EXE;.BAT;.CMD").split(";").filter((t)=>t.length>0)}function lc(n,t){let r=nc(n)?[n]:[...ac(t).map((e)=>`${n}${e}`),n];if(n.includes("/")||n.includes("\\"))return r.find((e)=>va(e))??n;return(Lr(t,"PATH")??"").split(Is).flatMap((e)=>r.map((a)=>tc(e,a))).find((e)=>va(e))??n}function fa(n){if(!/[\s"&|<>^]/.test(n))return n;return`"${n.replace(/"/g,'""')}"`}function f2(n,t){let[r,...e]=n,a=t[ec]==="win32"?"win32":process.platform;if(!r||a!=="win32")return{cmd:r??"",args:e};let l=lc(r,t);if(!/\.(?:bat|cmd)$/i.test(l))return{cmd:l,args:e};return{cmd:Lr(t,"COMSPEC")??"cmd.exe",args:["/d","/c",["call",fa(l),...e.map(fa)].join(" ")]}}var wn=async(n,t=rc)=>{let r=await dc(n,{timeoutMs:t});if(r.code!==0)return null;return ba(r.stdout).trim()||ba(r.stderr).trim()||null};function dc(n,t){let[r,...e]=n;if(!r)return Promise.resolve({code:null,stdout:"",stderr:""});return new Promise((a)=>{try{let l=f2([r,...e],process.env),d=Ns(l.cmd,l.args,{stdio:["ignore","pipe","pipe"]}),s=!1,c="",L="";d.stdout.on("data",(v)=>{c+=v.toString()}),d.stderr.on("data",(v)=>{L+=v.toString()});let i=(v)=>{if(s)return;s=!0,clearTimeout(u),a(v)},u=setTimeout(()=>{d.kill(),i({code:null,stdout:c,stderr:L})},t.timeoutMs);d.on("close",(v)=>{i({code:v,stdout:c,stderr:L})}),d.on("error",()=>{i({code:null,stdout:c,stderr:L})})}catch{a({code:null,stdout:"",stderr:""})}})}function Q(n){if(!n)return null;let t=/Claude Code\s+(\d+\.\d+\.\d+)/i.exec(n);if(t)return t[1]??null;let r=/v?(\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)/i.exec(n);if(r)return r[1]??null;return n.split(`
23
+ `)[0]?.trim()||null}async function xn(n=wn){let[t,r,e,a,l,d,s,c,L,i,u,v,p,f,o,y,x]=await Promise.all([n(["claude","--version"]),n(["agy","--version"]),n(["opencode","--version"]),n(["codex","--version"]),n(["codex","plugin","list"]),n(["gemini","--version"]),n(["copilot","--binary-version"]),n(["hermes","--version"]),n(["kimi","--version"]),n(["openclaw","--version"]),n(["pi","--version"]),n(["cursor","--version"]),n(["amp","--version"]),n(["amp","plugins","list"],30000),n(["node","--version"]),n(["npm","--version"]),n(["bun","--version"])]);return{version:ya,claudeCodeVersion:Q(t),antigravityCliVersion:Q(r),openCodeVersion:Q(e),codexCliVersion:Q(a),codexPluginListOutput:l,geminiCliVersion:Q(d),copilotCliVersion:Q(s),hermesAgentVersion:Q(c),kimiCodeVersion:Q(L),openClawVersion:Q(i),piCliVersion:Q(u),cursorVersion:Q(v),ampVersion:Q(p),ampPluginListOutput:f,nodeVersion:Q(o),npmVersion:Q(y),bunVersion:Q(x),platform:`${process.platform} ${process.arch}`}}function ir(n,t){if(t==="dev")return!1;let r=n.split(".").map(Number),e=t.split(".").map(Number),[a=0,l=0,d=0]=r,[s=0,c=0,L=0]=e;if(a!==s)return a>s;if(l!==c)return l>c;return d>L}async function E2(){let n=j(),t=new AbortController,r=setTimeout(()=>t.abort(),3000);try{let e=await fetch("https://registry.npmjs.org/cc-safety-net/latest",{signal:t.signal});if(!e.ok)return{currentVersion:n,latestVersion:null,updateAvailable:!1,error:`npm registry returned ${e.status}`};let a=await e.json(),l=ir(a.version,n);return{currentVersion:n,latestVersion:a.version,updateAvailable:l}}catch(e){return{currentVersion:n,latestVersion:null,updateAvailable:!1,error:e instanceof Error?e.message:"Network error"}}finally{clearTimeout(r)}}import*as ka from"node:readline";var $a=(n)=>`\x1B[${n}B`,sc=(n)=>`\x1B[${n}A`;var ha=["░","▒","▓","╱","╲","┃","━","┏","┓","┗","┛","╋"];function cc(n){return new Promise((t)=>setTimeout(t,n))}function Lc(n,t,r){if(!r)return t(n);if(r.aborted)return Promise.resolve();return new Promise((e,a)=>{let l=()=>r.removeEventListener("abort",d),d=()=>{l(),e()};r.addEventListener("abort",d,{once:!0}),t(n).then(()=>{l(),e()},(s)=>{l(),a(s)})})}function $n(n,t){return n&&n>0?n:t}function Cn(n){return Math.max(0,Math.min(1,n))}function _2(n){return Math.max(0,Math.min(255,Math.round(n)))}function pr(n){return n<=0.0031308?12.92*n:1.055*n**0.4166666666666667-0.055}function ic(n,t,r){let e=r*Math.PI/180,a=t*Math.cos(e),l=t*Math.sin(e),d=(n+0.3963377774*a+0.2158037573*l)**3,s=(n-0.1055613458*a-0.0638541728*l)**3,c=(n-0.0894841775*a-1.291485548*l)**3;return{blue:_2(pr(Cn(-0.0041960863*d-0.7034186147*s+1.707614701*c))*255),green:_2(pr(Cn(-1.2684380046*d+2.6097574011*s-0.3413193965*c))*255),red:_2(pr(Cn(4.0767416621*d-3.3077115913*s+0.2309699292*c))*255)}}function ur(n,t){let r=(t*n*180/Math.PI%360+360)%360;return ic(0.72,0.15,r)}function ga(n,t=0.1){let r=ur(t,n);return`\x1B[38;2;${r.red};${r.green};${r.blue}m`}function pc(n,t){return{blue:_2(n.blue+(255-n.blue)*t),green:_2(n.green+(255-n.green)*t),red:_2(n.red+(255-n.red)*t)}}function Da(n,t,r){let e=Math.imul(n+2654435769,2246822507)^Math.imul(t+3266489909,668265263)^Math.imul(r+374761393,2654435761),a=e^e>>>15,l=Math.imul(a,739982445),d=l^l>>>12,s=Math.imul(d,695872825);return((s^s>>>15)>>>0)/4294967296}function uc(n,t,r){let e=Math.floor(Da(n,t,r)*ha.length);return ha[e]??"░"}function wa(n){let t=Cn(n);return t*t*t*(t*(t*6-15)+10)}function oc(n){if(n.length===0)return"";let t=[],r=!1,e="";for(let a of n){let l=`${a.red};${a.green};${a.blue}`;if(a.bold!==r)t.push(a.bold?"\x1B[1m":"\x1B[22m"),r=a.bold;if(l!==e)t.push(`\x1B[38;2;${l}m`),e=l;t.push(a.character)}return`${t.join("")}\x1B[22m\x1B[39m`}function vc(n,t,r,e,a){return n.map((l,d)=>({...ur(r,e+t+d/a),bold:!1,character:l}))}function bc(n,t,r,e,a,l,d,s){let c=Math.max(1,e*0.75),L=Math.min(1,r/c),i=a*wa(L),u=Math.max(0,(r-c)/Math.max(1,e-c)),v=(1-wa(r/e))*s*2,p=0.35*Math.max(0,1-u*2),f=L>=1,o=Math.min(n.length,Math.ceil(i+2+1));return n.slice(0,o).map((y,x)=>{let w=ur(l,d+t+x/s+v),h=x+Da(t,x,7919)*2-1;if(h>i+2)return{...w,bold:!1,character:" "};let J=i-h,Z2=0.8*Math.exp(-(J*J)/12.5),an=Math.min(0.9,Z2+p),Dt=!f&&h>i-4;return{...pc(w,an),bold:an>0.3,character:Dt?uc(t,x,r):y}})}function xa(n){return`\x1B[?2026h${n.map((t,r)=>`\x1B8${r>0?$a(r):""}${oc(t)}`).join("")}\x1B[?2026l`}async function or(n,t={}){if(!n)return;let r=t.output??process.stdout,e=t.sleep??cc,a=$n(t.frequency,0.1),l=t.seed??0,d=$n(t.speed,40),s=$n(t.spread,3),c=$n(t.frameRate,60),L=Math.max(1,Math.floor($n(t.duration,12))),i=n.split(`
24
+ `).map((o)=>Array.from(o)),u=Math.max(...i.map((o)=>o.length)),v=1000*L*i.filter((o)=>o.length>0).length/d,p=u>0?Math.max(1,Math.ceil(v/(1000/c))):0,f=p>0?v/p:0;r.write(`\x1B[?25l${i.length>1?`${`
25
+ `.repeat(i.length-1)}${sc(i.length-1)}`:""}\x1B7`);try{for(let o=1;o<=p;o+=1){if(t.signal?.aborted)break;r.write(xa(i.map((y,x)=>bc(y,x,o,p,u,a,l,s)))),await Lc(f,e,t.signal)}}finally{if(r.write(xa(i.map((o,y)=>vc(o,y,a,l,s)))),r.write("\x1B8"),i.length>1)r.write($a(i.length-1));r.write(`
26
+ \x1B[0m\x1B[?25h`)}}var ma=["┏━┛┏━┛ ┏━┛┏━┃┏━┛┏━┛━┏┛┃ ┃ ┏━ ┏━┛━┏┛","┃ ┃ ━━┃┏━┃┏━┛┏━┛ ┃ ━┏┛ ┃ ┃┏━┛ ┃ ","━━┛━━┛ ━━┛┛ ┛┛ ━━┛ ┛ ┛ ┛ ┛━━┛ ┛ "].join(`
27
+ `);function fc(n){return Boolean(n.isTTY)}async function Un(n={}){let t=n.output??process.stdout;if(!fc(t))return;let r=n.input??process.stdin,e={duration:n.duration,frequency:n.frequency,output:t,seed:n.seed??Math.random()*8192,sleep:n.sleep,speed:n.speed,spread:n.spread};if(!r.isTTY||typeof r.setRawMode!=="function"){await or(ma,e);return}let a=new AbortController,l=r.readableFlowing===!0,d=r.isRaw===!0,s=!1,c=(L,i)=>{if(i.ctrl&&i.name==="c")s=!0;if(s||i.name==="return"||i.name==="enter")a.abort()};ka.emitKeypressEvents(r),r.on("keypress",c),r.setRawMode(!0),r.resume();try{await or(ma,{...e,signal:a.signal})}finally{if(r.off("keypress",c),r.setRawMode(d),!l)r.pause()}if(!s)return;if(n.onInterrupt){n.onInterrupt();return}process.kill(process.pid,"SIGINT")}var qa="\r\x1B[2K",yc="\x1B[?25l",hc="\x1B[39m",wc="\x1B[?25h",xc=100,$c=0.55,gc=80,ja=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function Dc(n){return new Promise((t)=>setTimeout(t,n))}async function vr(n,t={}){let r=t.output??process.stdout;if(!r.isTTY)return n;let e=t.sleep??Dc,a=!1,l=n.then((s)=>{return a=!0,s},(s)=>{throw a=!0,s});if(await Promise.race([l.then(()=>!0),e(xc).then(()=>!1)]))return l;r.write(yc);try{for(let s=0;!a;s+=1)r.write(`${qa}${ga(s*$c)}${ja[s%ja.length]}${hc} ${t.loadingMessage??"Loading…"}`),await Promise.race([l,e(gc)]);return await l}finally{r.write(`${qa}${wc}`)}}async function On(n,t,r,e={}){let a=t();if(n)await r();if(n&&a.ready)await vr(a.ready,e);return a.finish()}import{homedir as XL}from"node:os";import{stripVTControlCharacters as mc}from"node:util";var Tn="amp plugins list",kc=/^\s*[✓✗]\s+cc-safety-net(?:\.ts)?\s+\(User Plugins\)\s+(\S+)\s*$/;function Fa(n){if(!n.ampPluginListOutput)return{platform:"amp",status:"n/a"};let t=mc(n.ampPluginListOutput).split(`
28
+ `).map((r)=>kc.exec(r)?.[1]).find((r)=>r!==void 0);if(!t)return{platform:"amp",status:"n/a"};if(t!=="active")return{platform:"amp",status:"disabled",method:Tn,configPath:Tn,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:Tn,configPath:Tn}}import{existsSync as jc,readFileSync as Fc}from"node:fs";import{join as qc}from"node:path";function gn(n){return qc(n,".gemini","config","hooks.json")}var zc=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*(?:--agy-cli|-ac)(\s|["']|$)/;function Bc(n){if(!n||typeof n!=="object"||Array.isArray(n))return[];return Object.values(n).flatMap((t)=>{if(!t||typeof t!=="object"||Array.isArray(t))return[];let r=t,e=r.PreToolUse;if(!Array.isArray(e))return[];return e.flatMap((a)=>{if(!a||typeof a!=="object"||Array.isArray(a))return[];let l=a.hooks;if(!Array.isArray(l))return[];return l.flatMap((d)=>{if(!d||typeof d!=="object"||Array.isArray(d))return[];let s=d.command;if(typeof s!=="string"||!zc.test(s))return[];return[{command:s,enabled:r.enabled!==!1}]})})})}function za(n){let t=gn(n.homeDir);if(!jc(t))return{platform:"antigravity-cli",status:"n/a",configPath:t};let r;try{r=Bc(JSON.parse(Fc(t,"utf-8")))}catch(e){return{platform:"antigravity-cli",status:"n/a",configPath:t,errors:[`Failed to parse Antigravity hooks config ${t}: ${e instanceof Error?e.message:String(e)}`]}}if(r.some((e)=>e.enabled))return{platform:"antigravity-cli",status:"configured",method:"hook config",configPath:t};if(r.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 Ba}from"node:path";import{existsSync as Jc,lstatSync as Zc,readFileSync as Qc}from"node:fs";function n2(n,t=(r)=>r){if(!Jc(n))return{kind:"missing"};try{return{kind:"ok",value:JSON.parse(t(Qc(n,"utf-8")))}}catch{return{kind:"unreadable"}}}function S(n){try{return Zc(n)}catch{return}}function En(n,t){let r=S(t);if(!r)return{platform:n,status:"n/a",configPath:t};if(!r.isSymbolicLink()&&r.isDirectory())return;return{platform:n,status:"n/a",configPath:t,errors:[`${t} is a symlink or not a directory; move or remove it before installing`]}}function $(n,t){return typeof n==="object"&&n!==null?n[t]:void 0}var br="cc-safety-net@cc-marketplace";function Ja(n){return Ba(n,".claude","plugins","installed_plugins.json")}function Za(n,t){let r=$($(n,"plugins"),t);return Array.isArray(r)&&r.length>0}function _n(n,t){let r=n2(Ja(n));return r.kind==="ok"&&Za(r.value,t)}function fr(n){let t=Ja(n),r=n2(t);if(r.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(r.kind==="missing")return{platform:"claude-code",status:"n/a"};if(!Za(r.value,br))return{platform:"claude-code",status:"n/a"};let e=Ba(n,".claude","settings.json"),a=n2(e);if(a.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(!(a.kind==="ok"&&$($(a.value,"enabledPlugins"),br)===!0))return{platform:"claude-code",status:"disabled",method:"plugin config",configPath:e,errors:[`${br} is installed but not enabled in Claude Code`]};return{platform:"claude-code",status:"configured",method:"plugin config",configPath:t}}function Qa(n){return fr(n.homeDir)}function Xa(n){if(!n.codexPluginListOutput)return{platform:"codex",status:"n/a"};let t=n.codexPluginListOutput.split(`
29
+ `).find((r)=>r.includes("https://github.com/kenryu42/cc-safety-net.git"));if(!t)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 In,readdirSync as Xc,readFileSync as Yc}from"node:fs";import{join as V}from"node:path";var t2="cc-safety-net@cc-marketplace",Pn=["cc-marketplace","cc-safety-net"],Ya=["_direct","copilot-safety-net"],Sa=["cc-marketplace","safety-net"],Ha="safety-net@cc-marketplace";function Nn(n,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(^|[^a-z0-9-])${r}([^a-z0-9-]|$)`,"m").test(n??"")}function Aa(n){return Nn(n,"cc-safety-net@cc-marketplace")}function Wa(n){return Nn(n,"cc-marketplace")}function Ra(n){return Nn(n,"copilot-safety-net")}function Va(n){return Nn(n,"safety-net@cc-marketplace")}function R(n){let t="",r=0,e=!1,a=!1,l=-1;while(r<n.length){let d=n[r],s=n[r+1];if(a){t+=d,a=!1,r++;continue}if(d==='"'&&!e){e=!0,l=-1,t+=d,r++;continue}if(d==='"'&&e){e=!1,t+=d,r++;continue}if(d==="\\"&&e){a=!0,t+=d,r++;continue}if(e){t+=d,r++;continue}if(d==="/"&&s==="/"){while(r<n.length&&n[r]!==`
30
+ `)r++;continue}if(d==="/"&&s==="*"){r+=2;while(r<n.length-1){if(n[r]==="*"&&n[r+1]==="/"){r+=2;break}r++}continue}if(d===","){l=t.length,t+=d,r++;continue}if(d==="}"||d==="]"){if(l!==-1){let c=t.slice(l+1);if(/^\s*$/.test(c))t=t.slice(0,l)+c}l=-1,t+=d,r++;continue}if(!/\s/.test(d))l=-1;t+=d,r++}return t}function yr(n){if(!n?.includes("cc-safety-net"))return!1;return/(^|\s)hook\s+(?:[^\s]+\s+)*(--copilot-cli|-cp)(\s|$)/.test(n)}function Ma(n,t){if(!n)return null;let r=n.match(/(\d+)\.(\d+)\.(\d+)/);if(!r)return null;let e=[Number(r[1]),Number(r[2]),Number(r[3])];for(let a=0;a<t.length;a++){let l=e[a]??0,d=t[a]??0;if(l!==d)return l>d}return!0}function Sc(n){return Ma(n,[0,0,422])}function Hc(n){return Ma(n,[1,0,8])}function Dn(n){return process.env.COPILOT_HOME||V(n,".copilot")}function wr(n){return(n.hooks?.preToolUse??[]).some((r)=>{if(r.type!=="command")return!1;return yr(r.command)||yr(r.bash)||yr(r.powershell)})}function xr(n,t){try{return JSON.parse(R(Yc(n,"utf-8")))}catch(r){t?.push(`Failed to parse ${n}: ${r instanceof Error?r.message:String(r)}`);return}}function Ga(n,t){try{return Xc(n).filter((r)=>r.endsWith(".json")).sort((r,e)=>r.localeCompare(e))}catch(r){return t?.push(`Failed to read ${n}: ${r instanceof Error?r.message:String(r)}`),[]}}function Ac(n,t){if(!In(n))return[];let r=[];for(let e of Ga(n,t)){let a=V(n,e),l=xr(a,t);if(l&&wr(l))r.push(a)}return r}function hr(n,t){if(!In(n))return;let r=xr(n,t);if(!r)return;return{path:n,config:r}}function Ka(n,t,r,e){if(t){n.push(`GitHub Copilot CLI ${t} does not support ${r}; requires ${e}+`);return}n.push(`GitHub Copilot CLI version unavailable; skipping ${r} because it requires ${e}+`)}function Wc(n){let t=[n.localSettings,n.repoSettings,n.userConfig];for(let r of t){if(r?.config.disableAllHooks===!0)return r.path;if(r?.config.disableAllHooks===!1)return}return}function Rc(n,t,r,e){let a=Dn(n),l=V(t,".github","hooks"),d=V(a,"hooks"),s=V(t,".github","copilot"),c=Hc(r),L=c===!0?e:void 0,i={userConfig:hr(V(a,"config.json"),L),repoSettings:hr(V(s,"settings.json"),L),localSettings:hr(V(s,"settings.local.json"),L)};if(c!==!1){let w=Wc(i);if(w){if(c===null)e.push(`GitHub Copilot CLI version unavailable; treating disableAllHooks in ${w} as active`);return{activeConfigPaths:[],disabledBy:w}}}let u=Ac(l,e),v=Sc(r),p=v===!0?e:void 0,f=In(d)?Ga(d,p):[],o=[];for(let w of f){let h=V(d,w),J=xr(h,p);if(J&&wr(J))o.push(h)}if(v!==!0&&o.length>0)Ka(e,r,`user hook files in ${d}`,"0.0.422"),o.length=0;let y=[],x=[i.localSettings,i.repoSettings,i.userConfig];for(let w of x){if(!w)continue;if(!wr(w.config))continue;if(c===!0){y.push(w.path);continue}Ka(e,r,"inline hook definitions in Copilot config files","1.0.8");break}return{activeConfigPaths:[...y.filter((w)=>w.endsWith("settings.local.json")),...y.filter((w)=>w.endsWith("settings.json")),...u,...y.filter((w)=>w.endsWith("config.json")),...o]}}function Ca(n){let t=[],r=Rc(n.homeDir,n.cwd,n.copilotCliVersion,t);if(r.disabledBy)return{platform:"copilot-cli",status:"disabled",method:"hook config",configPath:r.disabledBy,configPaths:[r.disabledBy],errors:t.length>0?t:void 0};let e=Dn(n.homeDir),a=V(e,"installed-plugins",...Pn),l=In(a),d=V(e,"settings.json"),s=n2(d,R);if(l&&s.kind==="unreadable")return{platform:"copilot-cli",status:"not-inspected"};if(l&&s.kind==="ok"&&$($(s.value,"enabledPlugins"),t2)===!1)return{platform:"copilot-cli",status:"disabled",method:"plugin config",configPath:d,errors:[`${t2} is installed but not enabled in Copilot CLI`]};if(l||r.activeConfigPaths.length>0){let c=l,L=r.activeConfigPaths[0];return{platform:"copilot-cli",status:"configured",method:c?"plugin config":"hook config",configPath:L??(c?a:void 0),configPaths:r.activeConfigPaths.length>0?r.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 _c,readFileSync as Pc}from"node:fs";import{existsSync as Ua,mkdirSync as Mc,readFileSync as Gc}from"node:fs";import{dirname as Cc,join as Uc}from"node:path";import{renameSync as Vc,writeFileSync as Kc}from"node:fs";function B(n,t){let r=`${n}.${process.pid}.tmp`;Kc(r,t),Vc(r,n)}var mn="npx -y cc-safety-net hook --cursor",Oa=30;function tt(n){return Uc(n,".cursor","hooks.json")}function k2(n){return typeof n==="object"&&n!==null&&!Array.isArray(n)}function $r(){return{command:mn,timeout:Oa,failClosed:!0}}function nt(n){return k2(n)&&n.command===mn}function Oc(n){return Object.keys(n).length===3&&n.command===mn&&n.timeout===Oa&&n.failClosed===!0}function Tc(n){try{return JSON.parse(Gc(n,"utf-8"))}catch(t){if(t instanceof SyntaxError)throw Error(`Failed to parse Cursor hooks config ${n}: ${t.message}`);throw t}}function Ta(n){let t=Tc(n);if(!k2(t))throw Error(`Cursor hooks config ${n} must be a JSON object`);if(t.version!==1)throw Error(`Cursor hooks config ${n} must set "version": 1`);if(t.hooks!==void 0&&!k2(t.hooks))throw Error(`Cursor hooks config ${n} "hooks" must be an object`);let r=k2(t.hooks)?t.hooks.preToolUse:void 0;if(r!==void 0&&!Array.isArray(r))throw Error(`Cursor hooks config ${n} "hooks.preToolUse" must be an array`);return t}function Ea(n){let t=k2(n.hooks)?n.hooks.preToolUse:void 0;return Array.isArray(t)?t:[]}function Ec(n){if(!n.some(nt))return[...n,$r()];return n.reduce((t,r)=>{if(!nt(r))return t.result.push(r),t;if(!t.inserted)t.result.push($r()),t.inserted=!0;return t},{result:[],inserted:!1}).result}function _a(n,t,r){let e=k2(t.hooks)?t.hooks:{},a={...t,hooks:{...e,preToolUse:r}};B(n,`${JSON.stringify(a,null,2)}
31
+ `)}function Pa(n){let t=tt(n);if(!Ua(t))return Mc(Cc(t),{recursive:!0}),B(t,`${JSON.stringify({version:1,hooks:{preToolUse:[$r()]}},null,2)}
32
+ `),{path:t,alreadyInstalled:!1};let r=Ta(t),e=Ea(r),a=e.filter(nt);if(k2(r.hooks)&&Array.isArray(r.hooks.preToolUse)&&a.length===1&&a[0]!==void 0&&Oc(a[0]))return{path:t,alreadyInstalled:!0};return _a(t,r,Ec(e)),{path:t,alreadyInstalled:!1}}function Na(n){let t=tt(n);if(!Ua(t))return{path:t,alreadyInstalled:!1};let r=Ta(t),e=Ea(r),a=e.filter((l)=>!nt(l));if(a.length===e.length)return{path:t,alreadyInstalled:!1};return _a(t,r,a),{path:t,alreadyInstalled:!0}}function Nc(n){if(!n||typeof n!=="object"||Array.isArray(n))return[];let t=n.hooks;if(!t||typeof t!=="object"||Array.isArray(t))return[];let r=t.preToolUse;if(!Array.isArray(r))return[];return r.filter((e)=>!!e&&typeof e==="object"&&!Array.isArray(e)&&e.command===mn)}function Ic(n){let t=[];if(n.length>1)t.push("Multiple managed cc-safety-net hooks found; reinstall to collapse duplicates");let r=n[0];if(r&&r.failClosed!==!0)t.push('Managed hook is missing "failClosed": true; reinstall to repair');if(r&&r.timeout!==30)t.push('Managed hook "timeout" is not 30; reinstall to repair');return t}function Ia(n){let t=tt(n.homeDir);if(!_c(t))return{platform:"cursor",status:"n/a",configPath:t};let r;try{r=JSON.parse(Pc(t,"utf-8"))}catch(l){return{platform:"cursor",status:"n/a",configPath:t,errors:[`Failed to parse Cursor hooks config ${t}: ${l instanceof Error?l.message:String(l)}`]}}let e=Nc(r);if(e.length===0)return{platform:"cursor",status:"n/a",configPath:t};let a=Ic(e);return{platform:"cursor",status:"configured",method:"hook config",configPath:t,errors:a.length>0?a:void 0}}import{existsSync as nL}from"node:fs";import{join as gr}from"node:path";var Dr="gemini-safety-net";function mr(n){let t=gr(n,".gemini","extensions"),r=gr(t,Dr);if(!nL(r))return{platform:"gemini-cli",status:"n/a"};let e=gr(t,"extension-enablement.json"),a=n2(e);if(a.kind==="unreadable")return{platform:"gemini-cli",status:"not-inspected"};let l=a.kind==="ok"?$($(a.value,Dr),"overrides"):void 0;if(Array.isArray(l)&&l.some((s)=>typeof s==="string"&&s.startsWith("!")))return{platform:"gemini-cli",status:"disabled",method:"extension config",configPath:e,errors:[`${Dr} is disabled in Gemini CLI`]};return{platform:"gemini-cli",status:"configured",method:"extension config",configPath:r}}function n0(n){return mr(n.homeDir)}import{readFileSync as L0}from"node:fs";import{join as i0}from"node:path";var K="cc-safety-net",t0="# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent";function r0(n){return`# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent
32
33
  # version: ${n}
33
- `}function Vc(n){return`${I1(n)}name: cc-safety-net
34
+ `}function tL(n){return`${r0(n)}name: cc-safety-net
34
35
  version: "${n}"
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 Kc(n){return`${I1(n)}"""CC Safety Net guard for Hermes Agent.
40
+ `}function rL(n){return`${r0(n)}"""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
@@ -168,65 +169,82 @@ def _pre_tool_call(tool_name="", args=None, session_id="", task_id="", **_):
168
169
 
169
170
  def register(ctx):
170
171
  ctx.register_hook("pre_tool_call", _pre_tool_call)
171
- `}function mn(n){return[{name:"__init__.py",content:Kc(n)},{name:"plugin.yaml",content:Vc(n)}]}import{mkdirSync as Cc,readdirSync as Gc,readFileSync as Uc,rmSync as we}from"node:fs";import{join as D2}from"node:path";var Oc="__pycache__";function xe(n){let t=process.env.HERMES_HOME?.trim();return t?t:D2(n,".hermes")}function me(n){return D2(xe(n),"plugins",V)}function ge(n){return n.startsWith(P1)}function $e(n,t){let e=me(n),r=Y(e);if(r&&(r.isSymbolicLink()||!r.isDirectory()))throw Error(`Refusing to ${t} ${e}: not a regular directory. Move or remove it and rerun ${t==="install"?"install":"uninstall"} --hermes-agent.`);return e}function N1(n,t){let e=Y(n);if(!e)return;if(e.isSymbolicLink()||!e.isFile())throw Error(`Refusing to ${t} ${n}: not a regular file. Move or remove it.`);let r=Uc(n,"utf-8");if(!ge(r))throw Error(`Refusing to ${t} unmanaged file at ${n}. Move or remove it.`);return r}function n0(n){let t=$e(n,"install"),e=mn(z());if(e.map((a)=>N1(D2(t,a.name),"overwrite")).every((a,l)=>a===e[l]?.content))return{path:t,alreadyInstalled:!0};return Cc(t,{recursive:!0}),e.forEach((a)=>{B(D2(t,a.name),a.content)}),{path:t,alreadyInstalled:!1}}function De(n){let t=$e(n,"remove");if(!Y(t))return[];return mn(z()).filter((e)=>N1(D2(t,e.name),"remove")!==void 0)}function t0(n){let t=$e(n,"remove");if(!Y(t))return{path:t,alreadyInstalled:!1};let e=De(n);if(e.forEach((r)=>{we(D2(t,r.name))}),we(D2(t,Oc),{recursive:!0,force:!0}),Gc(t).length===0)we(t,{recursive:!0});return{path:t,alreadyInstalled:e.length>0}}var In="hermes-agent",e0=/^([^\s#][^:]*):/,Tc=/^\s+([A-Za-z_][\w-]*):/,r0=/^\s+-\s*(.*)$/;function Ec(n){return n.trim().replace(/^(["'])(.*)\1$/,"$2")}function _c(n){let t=n.split(/\r?\n/),e=t.findIndex((l)=>e0.exec(l)?.[1]?.trim()==="plugins");if(e===-1)return[];let r=t.slice(e+1),a=r.findIndex((l)=>e0.test(l));return a===-1?r:r.slice(0,a)}function a0(n,t){let e=_c(n),r=e.findIndex((d)=>Tc.exec(d)?.[1]===t);if(r===-1)return[];let a=e.slice(r+1),l=a.findIndex((d)=>!r0.test(d));return(l===-1?a:a.slice(0,l)).map((d)=>Ec(r0.exec(d)?.[1]??""))}function Pc(n){try{return l0(d0(xe(n),"config.yaml"),"utf-8")}catch{return}}function ke(n){let t=Pc(n)??"";return a0(t,"enabled").includes(V)&&!a0(t,"disabled").includes(V)}function s0(n){return/^# version:\s*(.+)$/m.exec(n)?.[1]?.trim()}function Ic(n,t){let e=Y(n);if(!e)return{error:`${t.name} is missing from ${n}; run install --hermes-agent`};if(e.isSymbolicLink()||!e.isFile())return{error:`${n} is a symlink or not a regular file; move or remove it`};try{let r=l0(n,"utf-8");if(!ge(r))return{error:`Unmanaged ${t.name} occupies ${n}; move or remove it`};if(s0(r)===z()&&r!==t.content)return{error:`Modified ${t.name} occupies ${n}; run install --hermes-agent to restore it`};return{content:r}}catch(r){return{error:`Failed to read ${n}: ${r instanceof Error?r.message:String(r)}`}}}function c0(n){let t=me(n.homeDir),e=Gn(In,t);if(e)return e;let r=mn(z()).map((s)=>Ic(d0(t,s.name),s)),a=r.flatMap((s)=>("error"in s)?[s.error]:[]);if(a.length>0)return{platform:In,status:"n/a",configPath:t,errors:a};let l=r.some((s)=>("content"in s)&&s0(s.content)!==z()),d=l?["Installed Hermes Agent plugin is outdated; run install --hermes-agent to update"]:[];if(!ke(n.homeDir))return{platform:In,status:"disabled",method:"plugin directory",configPath:t,errors:[`${V} is not enabled in Hermes; run \`hermes plugins enable ${V}\``,...d]};return{platform:In,status:"configured",method:"plugin directory",configPath:t,errors:l?d:void 0}}import{existsSync as Nc,readFileSync as ni}from"node:fs";import{join as i0}from"node:path";var ti=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*--kimi-code(\s|["']|$)/;function ei(n){return i0(process.env.KIMI_CODE_HOME||i0(n,".kimi-code"),"config.toml")}function L0(n){let t=ei(n.homeDir);if(!Nc(t))return{platform:"kimi-code",status:"n/a",configPath:t};try{if(!ti.test(ni(t,"utf-8")))return{platform:"kimi-code",status:"n/a",configPath:t}}catch(e){return{platform:"kimi-code",status:"n/a",configPath:t,errors:[`Failed to read ${t}: ${e instanceof Error?e.message:String(e)}`]}}return{platform:"kimi-code",status:"configured",method:"hook config",configPath:t}}import{readFileSync as m0}from"node:fs";import{join as $n}from"node:path";var q="cc-safety-net",K="index.js",T2="openclaw.plugin.json",E2="package.json";var Nn="// cc-safety-net managed OpenClaw plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --openclaw";import{existsSync as li,lstatSync as di,readdirSync as si,readFileSync as ci}from"node:fs";import{dirname as v0,join as k2}from"node:path";import{fileURLToPath as ii}from"node:url";import{spawnSync as ri}from"node:child_process";function ai(n){return n.join(" ")}function o0(n,t,e){return[`Failed to run ${ai(n)}${t===null?"":` (exit ${t})`}.`,e.trim()].filter(Boolean).join(`
172
- `)}function e2(n,t){let e=ri(n[0],n.slice(1),{encoding:"utf-8",stdio:"pipe"}),r=[e.stdout,e.stderr].filter(Boolean).join(`
173
- `);if(e.error)throw Error(o0(n,null,`${e.error.message}
174
- ${r}`.trim()));if(e.status!==0)throw Error(o0(n,e.status,r));return t?.stdoutOnly?e.stdout:r}function qe(n){n.forEach((t)=>{e2(t)})}function u0(n){n.forEach((t)=>{try{e2(t)}catch(e){console.warn(e instanceof Error?e.message:String(e))}})}var p0=k2("openclaw",q),Li=[K,T2,E2];function b0(n){let t=process.env.OPENCLAW_STATE_DIR?.trim();if(t)return t;let e=process.env.OPENCLAW_CONFIG_PATH?.trim();return e?v0(e):k2(n,".openclaw")}function f0(n){let t=process.env.OPENCLAW_CONFIG_PATH?.trim();return t?t:k2(b0(n),"openclaw.json")}function je(n){return k2(b0(n),"extensions",q)}function oi(n){let t=si(n);if(t.length===0)return!0;if(t.some((a)=>!Li.includes(a)))return!1;let e=k2(n,K),r=Y(e);return r!==void 0&&!r.isSymbolicLink()&&r.isFile()&&ci(e,"utf-8").startsWith(Nn)}function Fe(n){let t=je(n),e=Y(t);if(!e)return;if(!e.isSymbolicLink()&&e.isDirectory()&&oi(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 h0(){let n=v0(ii(import.meta.url));return[k2(n,"..",p0),k2(n,"..","..","..","dist",p0)]}function ze(n=h0()){return n.find((t)=>li(t)&&di(t).isDirectory())}function ui(n=h0()){let t=ze(n);if(!t)throw Error("Packaged OpenClaw plugin directory not found. Reinstall cc-safety-net and try again.");return t}function y0(n=ui()){return[["openclaw","plugins","install",n,"--force"],["openclaw","plugins","enable",q]]}function pi(n){let t=(()=>{try{return JSON.parse(n)}catch{return}})(),e=g(g(t,"plugin"),"status");return typeof e==="string"?e:void 0}function w0(){let n=pi(e2(["openclaw","plugins","inspect",q,"--runtime","--json"],{stdoutOnly:!0}));if(n==="loaded")return;throw Error(`${n===void 0?`The ${q} plugin's load state could not be verified: OpenClaw's runtime inspect report was unreadable.`:`OpenClaw reports the ${q} plugin with status "${n}".`} Run \`openclaw plugins inspect ${q} --runtime\` for details.`)}var nt="openclaw",gn=`run \`openclaw plugins enable ${q}\``;function _2(n,t){let e=$n(n,t),r=Y(e);if(!r)return{error:`${t} is missing from ${e}; run install --openclaw`};if(r.isSymbolicLink()||!r.isFile())return{error:`${e} is a symlink or not a regular file; move or remove it`};try{return{content:m0(e,"utf-8")}}catch(a){return{error:`Failed to read ${e}: ${a instanceof Error?a.message:String(a)}`}}}function g0(n){try{return JSON.parse(M(n))}catch{return}}function vi(n){let t=_2(n,T2);if("error"in t)return t.error;if(g(g0(t.content),"id")===q)return;return`${$n(n,T2)} is not a valid ${q} manifest; run install --openclaw`}function bi(n){let t=_2(n,E2);if("error"in t)return t.error;let e=g(g(g0(t.content),"openclaw"),"extensions");if(Array.isArray(e)&&e.includes(`./${K}`))return;return`${$n(n,E2)} does not point OpenClaw at ${K}; run install --openclaw`}function x0(n){return Array.isArray(n)?n.filter((t)=>typeof t==="string"):[]}function fi(n){let t=f0(n);if(!Y(t))return`${q} is not enabled; ${gn}`;let e=(()=>{try{return JSON.parse(M(m0(t,"utf-8")))}catch{return}})();if(e===void 0)return`Failed to read ${t}; fix it, then ${gn}`;let r=g(e,"plugins");if(g(r,"enabled")===!1)return`plugins.enabled is false in ${t}; no OpenClaw plugin loads`;let a=g(g(g(r,"entries"),q),"enabled");if(x0(g(r,"deny")).includes(q)||a===!1)return`${q} is disabled in ${t}; ${gn}`;let l=x0(g(r,"allow"));if(l.length>0&&!l.includes(q))return`plugins.allow in ${t} does not list ${q}; add it, then ${gn}`;if(l.includes(q)||a===!0)return;return`${q} is not enabled; ${gn}`}function $0(n){return/^\/\/ version:\s*(.+)$/m.exec(n)?.[1]?.trim()}function hi(n,t,e){if(e===void 0)return[];let r=_2(e,K);if("error"in r||$0(r.content)!==t)return[];return[K,T2,E2].flatMap((a)=>{let l=_2(n,a),d=_2(e,a);if("error"in l||"error"in d||l.content===d.content)return[];return[`Modified ${a} occupies ${$n(n,a)}; run install --openclaw to restore it`]})}function D0(n){let t=je(n.homeDir),e=Gn(nt,t);if(e)return e;let r=_2(t,K),l=["error"in r?r.error:r.content.startsWith(Nn)?void 0:`Unmanaged ${K} occupies ${$n(t,K)}; move or remove it`,vi(t),bi(t)].filter((L)=>L!==void 0),d="content"in r?$0(r.content):void 0,s=l.length>0?l:hi(t,d,ze());if(s.length>0)return{platform:nt,status:"n/a",configPath:t,errors:s};let c=d===z()?[]:["Installed OpenClaw plugin is outdated; run install --openclaw to update"],i=fi(n.homeDir);if(i)return{platform:nt,status:"disabled",method:"plugin directory",configPath:t,errors:[i,...c]};return{platform:nt,status:"configured",method:"plugin directory",configPath:t,errors:c.length>0?c:void 0}}import{existsSync as yi,readFileSync as wi}from"node:fs";import{join as k0}from"node:path";function q0(n){let t=[],e=k0(n.homeDir,".config","opencode"),r=["opencode.json","opencode.jsonc"];for(let a of r){let l=k0(e,a);if(yi(l))try{let d=wi(l,"utf-8"),s=M(d);if((JSON.parse(s).plugin??[]).some((u)=>u.includes("cc-safety-net")))return{platform:"opencode",status:"configured",method:"plugin array",configPath:l,errors:t.length>0?t:void 0}}catch(d){t.push(`Failed to parse ${a}: ${d instanceof Error?d.message:String(d)}`)}}return{platform:"opencode",status:"n/a",errors:t.length>0?t:void 0}}import{join as xi}from"node:path";function Be(n){return xi(n,".pi","agent","settings.json")}function Je(n){if(typeof n!=="string")return!1;return n==="npm:cc-safety-net"||n.startsWith("npm:cc-safety-net@")}function j0(n){let t=Be(n.homeDir),e=n2(t);if(e.kind==="unreadable")return{platform:"pi",status:"not-inspected"};if(e.kind==="missing")return{platform:"pi",status:"n/a"};let r=g(e.value,"packages");if(!Array.isArray(r))return{platform:"pi",status:"n/a"};let a=r.find((s)=>Je(typeof s==="string"?s:g(s,"source")));if(a===void 0)return{platform:"pi",status:"n/a"};let l=g(a,"extensions");if(Array.isArray(l)&&l.some((s)=>typeof s==="string"&&s.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 gi={amp:D1,"antigravity-cli":k1,"claude-code":z1,codex:B1,"copilot-cli":W1,cursor:E1,"gemini-cli":_1,"hermes-agent":c0,"kimi-code":L0,openclaw:D0,opencode:q0,pi:j0};function P2(n,t){let e={...t,cwd:n,homeDir:t?.homeDir??mi()};return fa.map((r)=>$i(gi[r](e)))}function $i(n){if(n.status==="not-inspected")return{platform:n.platform,detected:!1,configured:!1,inspectionStatus:"not-inspected"};return{platform:n.platform,detected:n.status!=="n/a",configured:n.status==="configured",inspectionStatus:n.status!=="n/a"?"verified":n.errors&&n.errors.length>0?"failed":"not-applicable",method:n.method,configPath:n.configPath,configPaths:n.configPaths,errors:n.errors}}import{tmpdir as Di}from"node:os";import{join as ki}from"node:path";var qi=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}]),ji=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([])})})}),Fi={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:[]}},sources:{failClosed:[],paranoidRm:[],paranoidInterpreters:[],worktreeMode:[]}};function F0(){let n=ki(Di(),"cc-safety-net-self-test"),t=qi.map((e)=>{let r=Zn(H2("self-test",{command:e.command},{kind:"command",shell:"auto"},{configCwd:n,executionCwd:n},e.command),{guard:{dependencies:{loadPolicySnapshot:()=>ji,getModes:()=>Fi,findPolicyMutation:()=>null}},audit:{agent:"self-test",getSessionId:()=>{return}}}),a=e.expectBlocked?"blocked":"allowed",l=r.decision.kind==="deny"?"blocked":"allowed";return{command:e.command,description:e.description,expected:a,actual:l,passed:a===l,reason:r.decision.kind==="deny"?r.decision.reason:void 0,ruleId:r.decision.kind==="deny"?r.decision.ruleId:void 0}});return{passed:t.filter((e)=>e.passed).length,failed:t.filter((e)=>!e.passed).length,total:t.length,results:t}}function Se(n){let t=j({label:"doctor",booleans:{json:["--json"],skipUpdateCheck:["--skip-update-check"]}},n);if(r2(t.errors))return null;return{json:t.flags.json,skipUpdateCheck:t.flags.skipUpdateCheck}}async function z0(n={}){let t=await Vn(!n.json,()=>{let e=zi(n);return{ready:e,finish:()=>e}},()=>Wn(),{loadingMessage:"Checking system status…"});if(n.json)console.log(JSON.stringify(t,null,2));else Ji(t);return Bi(t.hooks,t.engineSelfTest,{userConfig:t.userConfig,projectConfig:t.projectConfig})?1:0}async function zi(n){let t=n.cwd??process.cwd(),e=await bn(),r=P2(t,{codexPluginListOutput:e.codexPluginListOutput,copilotCliVersion:e.copilotCliVersion}),a=Wa(t),l=Va(),d=H({cwd:t}),s=d.policy,c=d2(s),i=w2(s,c.capabilities),L=Rn(7),u=n.skipUpdateCheck?{currentVersion:z(),latestVersion:null,updateAvailable:!1}:await U2(),p={hooks:r,engineSelfTest:F0(),userConfig:a.userConfig,projectConfig:a.projectConfig,configState:on(d),effectiveRules:a.effectiveRules,shadowedRules:a.shadowedRules,environment:l,effectiveSafety:{selectedPreset:s.safety.level??"standard",level:c.effectiveLevel,capabilities:c.capabilities,ruleOverrides:s.destructiveCommandRuleOverrides,weakenedRuleOverrides:Object.entries(i).filter(([,o])=>o.source==="rule_override"&&o.override==="off"&&o.inheritedEnabled&&o.changesInherited).map(([o])=>o),ruleCounts:{stored:Object.keys(s.destructiveCommandRuleOverrides).length,effective:Object.values(i).filter((o)=>o.changesInherited).length}},posture:e1(a.userConfig.path),activity:L,update:u,system:e};return{...p,findings:Ca(p)}}function Bi(n,t,e){return n.length>0&&n.every((r)=>!r.configured)||n.some((r)=>r.inspectionStatus==="failed")||t.failed>0||e.userConfig.exists&&!e.userConfig.valid||e.projectConfig.exists&&!e.projectConfig.valid}function Ji(n){console.log(),console.log(Ua(n.hooks)),console.log(),console.log(Oa(n.engineSelfTest)),console.log(),console.log(Ta(n)),console.log(),console.log(Ea(n.environment)),console.log(),console.log(_a(n)),console.log(),console.log(Pa(n.findings)),console.log(),console.log(Ia(n.activity)),console.log(),console.log(n1(n.system)),console.log(),console.log(Na(n.update)),console.log(t1(n))}import{existsSync as Si}from"node:fs";var Zi=/^[A-Za-z0-9_@%+=:,./-]+$/,B0="Usage: cc-safety-net explain [--json] [--cwd <path>] <command>";function Ze(n){let t=j({label:"explain",booleans:{json:["--json"]},values:{cwd:["--cwd"]},positionals:"tail"},n);if(r2(t.errors))return console.error(B0),console.error("Pass -- before a command that starts with dashes."),null;if(t.values.cwd!==void 0&&!Si(t.values.cwd))return console.error(`Error: --cwd path does not exist: ${t.values.cwd}`),null;let e=t.positionals.length===1?t.positionals[0]:t.positionals.map((r)=>Zi.test(r)?r:`'${r.replaceAll("'","'\\''")}'`).join(" ");if(!e)return console.error("Error: No command provided"),console.error(B0),null;return{json:t.flags.json,cwd:t.values.cwd,command:e}}function J0(n){if(n)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 S0(n,t){let r=t-18;return[`${n.dtl}${n.dh.repeat(t)}${n.dtr}`,`${n.dv} Command Analysis${" ".repeat(r)}${n.dv}`,`${n.dbl}${n.dh.repeat(t)}${n.dbr}`]}function Qe(n){return JSON.stringify(n)}function Z0(n,t=0){return`[${n.map((r,a)=>Ga(r,a,t)).join(",")}]`}function tt(n,t,e=70){let r=n.split(" "),a=[],l="";for(let d of r)if(l&&l.length+d.length+1>e)a.push(l),l=d;else l=l?`${l} ${d}`:d;if(l)a.push(l);return a.map((d,s)=>s===0?d:`${t}${d}`)}function Q0(n,t,e){let r=[];switch(n.type){case"parse":return null;case"env-strip":{r.push(""),r.push(`STEP ${t} ${e.h} Strip environment variables`);let a=Object.keys(n.envVars);return r.push(` Removed: ${a.map((l)=>`${l}=<redacted>`).join(", ")}`),r.push(` Tokens: ${Qe(n.output)}`),{lines:r,incrementStep:!0}}case"leading-tokens-stripped":return r.push(""),r.push(`STEP ${t} ${e.h} Strip wrappers`),r.push(` Removed: ${n.removed.join(", ")}`),r.push(` Tokens: ${Qe(n.output)}`),{lines:r,incrementStep:!0};case"shell-wrapper":return r.push(""),r.push(`STEP ${t} ${e.h} Detect shell wrapper`),r.push(` Wrapper: ${n.wrapper} -c`),r.push(` Inner: ${n.innerCommand}`),{lines:r,incrementStep:!0};case"interpreter":{if(r.push(""),r.push(`STEP ${t} ${e.h} Detect interpreter`),r.push(` Interpreter: ${n.interpreter}`),r.push(` Code: ${n.codeArg}`),n.paranoidBlocked)r.push(" Result: ✗ BLOCKED (paranoid mode)");return{lines:r,incrementStep:!0}}case"busybox":return r.push(""),r.push(`STEP ${t} ${e.h} Busybox wrapper`),r.push(` Subcommand: ${n.subcommand}`),{lines:r,incrementStep:!0};case"transparent-wrapper":return r.push(""),r.push(`STEP ${t} ${e.h} Transparent wrapper`),r.push(` Wrapper: ${n.wrapper}`),r.push(` Tokens: ${Qe(n.output)}`),{lines:r,incrementStep:!0};case"recurse":return{lines:[],incrementStep:!1};case"rule-check":{r.push(""),r.push(`STEP ${t} ${e.h} Match rules`);let a=`${n.ruleModule}:${n.ruleFunction}()`;if(r.push(` Rule: ${a}`),n.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} ${e.h} Worktree relaxation`),r.push(` Mode: ${D.worktree.name}`),r.push(` Git cwd: ${n.gitCwd}`),r.push(" Result: Allowed local discard in linked worktree"),{lines:r,incrementStep:!0};case"tmpdir-check":return null;case"fallback-scan":{if(n.embeddedCommandFound)return r.push(""),r.push(`STEP ${t} ${e.h} Fallback scan`),r.push(` Found: ${n.embeddedCommandFound}`),{lines:r,incrementStep:!0};return null}case"custom-rules-check":{if(n.rulesChecked){if(r.push(""),r.push(`STEP ${t} ${e.h} Custom rules`),n.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(n.matched)return r.push(""),r.push(`STEP ${t} ${e.h} Dangerous text check`),r.push(` Token: ${n.token}`),r.push(" Result: MATCHED"),{lines:r,incrementStep:!0};return null}case"strict-unparseable":return r.push(""),r.push(`STEP ${t} ${e.h} Strict mode check`),r.push(` Command: ${n.rawCommand}`),r.push(" Result: ✗ UNPARSEABLE"),{lines:r,incrementStep:!0};case"segment-skipped":return null;case"error":return r.push(""),r.push(`ERROR: ${n.message}`),{lines:r,incrementStep:!1};default:return null}}function Xe(n,t){let e=J0(t?.asciiOnly??!1),r=58,a=[],l=1;a.push(...S0(e,58)),a.push("");let d=n.trace.steps.find((o)=>o.type==="error");if(d&&d.type==="error"){a.push("ERROR"),a.push(` ${d.message}`),a.push(""),a.push("RESULT"),a.push(` Status: ${n.result==="blocked"?h.red("BLOCKED"):h.green("ALLOWED")}`),a.push(""),a.push("CONFIG");let o=n.configSource??"none";return a.push(` Path: ${o}`),a.join(`
175
- `)}let s=n.trace.steps.find((o)=>o.type==="parse");if(s&&s.type==="parse"){a.push("INPUT"),a.push(` ${s.input}`),a.push(""),a.push(`STEP ${l} ${e.h} Split shell commands`),l++;for(let o=0;o<s.segments.length;o++){let b=s.segments[o];if(b){let v=Math.random();a.push(` Segment ${o+1}: ${Z0(b,v)}`)}}}let c=n.trace.segments,i=c.length>1;for(let o of c){if(i){a.push("");let w="";if(s&&s.type==="parse"){let ht=s.segments[o.index];if(ht)w=ht.join(" ")}let x=54,y=w,J=` Segment ${o.index+1}: `,z2=" ";if(w){if(J.length+w.length+z2.length>x){let od=x-J.length-z2.length;y=`${w.substring(0,od-1)}…`}}let tn=w?`${J}${y}${z2}`:` Segment ${o.index+1} `,ft=w?`${J}${h.cyan(y)}${z2}`:tn,cr=58-tn.length,ir=Math.floor(cr/2),Ld=cr-ir;a.push(`${e.sh.repeat(ir)}${ft}${e.sh.repeat(Ld)}`)}if(o.steps.find((w)=>w.type==="segment-skipped")){a.push(""),a.push(" (skipped — prior segment blocked)");continue}let v=!1,f=!1;for(let w of o.steps){let x=Q0(w,l,e);if(x){if(f=!0,w.type==="recurse"){a.push("");let y=" RECURSING ",J=58-y.length-4;a.push(` ${e.tl}${e.h}${y}${e.h.repeat(J)}`),a.push(` ${e.v}`),v=!0;continue}for(let y of x.lines)if(v)a.push(` ${e.v} ${y}`);else a.push(y);if(x.incrementStep)l++}}if(v)a.push(` ${e.v}`),a.push(` ${e.bl}${e.h.repeat(56)}`),v=!1;if(!f)a.push(""),a.push(` ${h.green("✓")} Allowed (no matching rules)`)}if(a.push(""),a.push("RESULT"),n.result==="blocked"){if(a.push(` Status: ${h.red("BLOCKED")}`),n.customRule){if(a.push(` Rule: ${n.customRule.id}`),n.customRule.rulebook)a.push(` Rulebook: ${n.customRule.rulebook.name} ${n.customRule.rulebook.version}`);if(n.customRule.source)a.push(` Source: ${n.customRule.source}`);if(n.customRule.override)a.push(` Override: reason ${n.customRule.override.reason}`)}if(n.reason){let o=tt(n.reason," ");a.push(` Reason: ${o[0]}`);for(let b=1;b<o.length;b++)a.push(o[b]??"")}}else a.push(` Status: ${h.green("ALLOWED")}`);a.push(""),a.push("CONFIG");let L=n.configSource??"none",u=n.configValid?"":" (invalid)";a.push(` Path: ${L}${u}`),a.push(` Safety preset: ${n.selectedPreset??"standard"}`),a.push(` Effective capabilities: ${n.effectiveLevel}`);let p=Object.entries(n.destructiveCommandRuleOverrides??{});if(a.push(` Rule customizations: ${p.length}`),n.ruleActivation)a.push(` Rule activation: ${n.ruleActivation.id} — ${n.ruleActivation.enabled?"on":"off"} via ${n.ruleActivation.source}`);return a.join(`
176
- `)}function Ye(n){return JSON.stringify(n,null,2)}var X0="2.0.1",C=" ",q2="cc-safety-net";function Y0(n){return n.argument?`${n.flags} ${n.argument}`:n.flags}function Qi(n){return Math.max(...n.map((t)=>Y0(t).length))}function Xi(n){return Math.max(...n.map((t)=>t.usage.length))}function Yi(n){return Math.max(...n.map((t)=>`${q2} ${t.usage}`.length))}function Ri(n,t){let e=`${q2} ${n.usage}`;return`${C}${e.padEnd(t+2)}${n.description}`}function L2(n,t){return`${C}${n.padEnd(Math.max(40,n.length+2))}${t}`}function et(n,t=console.log){let e=[];if(e.push(`${q2} ${n.name}`),e.push(""),e.push(`${C}${n.description}`),e.push(""),e.push("USAGE:"),e.push(`${C}${q2} ${n.usage}`),e.push(""),n.subcommands&&n.subcommands.length>0){e.push("SUBCOMMANDS:");let r=Xi(n.subcommands);for(let a of n.subcommands)e.push(`${C}${a.usage.padEnd(r+2)}${a.description}`);e.push("")}if(n.options.length>0){e.push("OPTIONS:");let r=Qi(n.options);for(let a of n.options){let l=Y0(a),d=a.default?`${a.description} (default: ${a.default})`:a.description;e.push(`${C}${l.padEnd(r+2)}${d}`)}e.push("")}if(n.examples&&n.examples.length>0){e.push("EXAMPLES:");for(let r of n.examples)e.push(`${C}${r}`)}t(e.join(`
177
- `))}function Re(){let n=Ha(),t=Yi(n),e=[];e.push(`${q2} v${X0}`),e.push(""),e.push("Blocks destructive commands and secret access."),e.push(""),e.push("COMMANDS:");for(let r of n)e.push(Ri(r,t));e.push(""),e.push("GLOBAL OPTIONS:"),e.push(`${C}-h, --help Show help (use with command for command-specific help)`),e.push(`${C}-V, --version Show version`),e.push(""),e.push("HELP:"),e.push(`${C}${q2} help <command> Show help for a specific command`),e.push(`${C}${q2} <command> --help Show help for a specific command`),e.push(""),e.push("ENVIRONMENT VARIABLES:"),e.push(L2(`${D.level.name}=standard|strict|paranoid`,"Set session safety level")),e.push(L2(`${D.worktree.name}=1`,"Allow local git discards in linked worktrees")),e.push(L2(`${D.debug.name}=1`,"Print diagnostic messages to stderr")),e.push(L2(`${D.auditScope.name}=all|blocked`,"Record all command decisions, or denials only")),e.push(L2("CC_SAFETY_NET_HOME","Override rule config home directory")),e.push(""),e.push("LEGACY ENVIRONMENT VARIABLES (STILL SUPPORTED):"),e.push(L2(`${D.strict.name}=1`,"Force safety.overrides.fail_closed on")),e.push(L2(`${D.paranoid.name}=1`,"Force paranoid_rm and paranoid_interpreters on")),e.push(L2(`${D.paranoidRm.name}=1`,"Force safety.overrides.paranoid_rm on")),e.push(L2(`${D.paranoidInterpreters.name}=1`,"Force safety.overrides.paranoid_interpreters on")),e.push(""),e.push("Documentation: https://ccsafetynet.com/docs"),console.log(e.join(`
178
- `))}function R0(){console.log(X0)}function Dn(n,t=console.log){let e=Yn(n);if(!e)return!1;if(e.hidden||e.name.toLowerCase()!==n.toLowerCase())return!1;return et(e,t),!0}import{existsSync as _e,readFileSync as yl}from"node:fs";import{homedir as BL}from"node:os";import{join as Te}from"node:path";import*as v2 from"node:readline";function Ai(n){return n==="install"?"Install":"Uninstall"}function Hi(n){return n==="install"?"Installing":"Uninstalling"}function Mi(n){return n==="install"?"into":"from"}function H0(n){return n?.available===!0}function Wi(n,t){let e=new Set(t);return n.filter((r)=>e.has(r.target)).map((r)=>r.target)}function A0(n,t,e){if(n.length===0||n.every((r)=>!r.available))return t;return Array.from({length:n.length},(r,a)=>a+1).map((r)=>(t+r*e+n.length)%n.length).find((r)=>H0(n[r]))}function Vi(n,t,e){if(e.ctrl&&e.name==="c")return"interrupt";if(e.name==="escape"||t==="q")return"abort";if(n==="install"&&(t==="u"||t==="U"))return"update";if(e.name==="up"||t==="k")return"up";if(e.name==="down"||t==="j")return"down";if(e.name==="space"||t===" ")return"toggle";if(e.name==="return"||e.name==="enter")return"confirm";return null}function Ki(n){return{cursor:n.findIndex((t)=>t.available),selected:[]}}function Ci(n,t,e){if(e==="confirm"||e==="update"||e==="abort"||e==="interrupt")return{state:n,done:e};if(e==="up")return{state:{...n,cursor:A0(t,n.cursor,-1)}};if(e==="down")return{state:{...n,cursor:A0(t,n.cursor,1)}};let r=t[n.cursor];if(!H0(r))return{state:n};let a=n.selected.includes(r.target)?n.selected.filter((l)=>l!==r.target):Wi(t,[...n.selected,r.target]);return{state:{...n,selected:a}}}var Gi="◉",Ui="◯",Oi=">",Ti=" ";function Ei(n,t,e,r={}){let a=r.color!==!1,l=a?h.dim:(c)=>c,d=a?h.green:(c)=>c,s=a?h.bold:(c)=>c;return["",`${Ai(n)} CC Safety Net ${Mi(n)}:`,"",...t.map((c,i)=>{let L=e.selected.includes(c.target),u=i===e.cursor,p=L?Gi:Ui,o=u?Oi:Ti,b=c.available?"":` (${c.unavailableReason??"not installed"})`,v=`${p} ${c.label}${b}`,f=!c.available?l(v):L?d(v):u?s(v):v;return`${o} ${f}`}),"",n==="install"?"Space: select Enter: confirm u: update installed Up/Down: move q/Esc: cancel":t.some((c)=>c.available)?"Space: select Enter: confirm Up/Down: move q/Esc: cancel":`No selectable integrations found for ${n}. q/Esc: close`].join(`
179
- `)}function M0(n=process.stdin,t=process.stdout){return Boolean(n.isTTY&&t.isTTY&&typeof n.setRawMode==="function")}function W0(n,t,e={}){let r=e.input??process.stdin,a=e.output??process.stdout,l=Ki(t);v2.emitKeypressEvents(r);let d=r.isRaw===!0;r.setRawMode(!0),r.resume();let s=0,c=()=>{if(s===0)return;v2.moveCursor(a,0,-s),v2.cursorTo(a,0),v2.clearScreenDown(a)},i=()=>{c();let L=Ei(n,t,l);a.write(`${L}
180
- `),s=L.split(`
181
- `).length};return new Promise((L)=>{let u=()=>{r.off("keypress",o),r.setRawMode(d),r.pause(),c()},p=(b)=>{if(u(),b!=="update"&&b&&b.length>0)a.write(`${Hi(n)} selected integrations...
182
- `);L(b)};function o(b,v){let f=Vi(n,b,v);if(!f)return;let w=Ci(l,t,f);if(l=w.state,w.done==="interrupt"){p(null),(e.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(w.done==="abort"){p(null);return}if(w.done==="update"){p("update");return}if(w.done==="confirm"){if(l.selected.length===0){a.write("\x07"),i();return}p([...l.selected]);return}i()}r.on("keypress",o),i()})}import{existsSync as V0,mkdirSync as _i,readFileSync as Pi}from"node:fs";import{dirname as Ii}from"node:path";var Ae="npx -y cc-safety-net hook --agy-cli",b2="cc-safety-net";function at(){return{PreToolUse:[{hooks:[{type:"command",command:Ae,timeout:30}]}]}}function K0(n){try{let t=JSON.parse(Pi(n,"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 ${n}: ${t.message}`);throw t}}function C0(n){let t=n[b2];if(t===void 0)return n[b2]=at(),n[b2];if(!t||typeof t!=="object"||Array.isArray(t))throw Error(`Antigravity hooks config entry "${b2}" must be an object`);if(!Array.isArray(t.PreToolUse))t.PreToolUse=[];return t}function G0(n){if(!Array.isArray(n.PreToolUse))return!1;return n.PreToolUse.some((t)=>Array.isArray(t.hooks)&&t.hooks.some((e)=>e.command===Ae))}function Ni(n){return Object.values(n).some((t)=>t.enabled!==!1&&G0(t))}function nL(n){if(n[b2]===void 0)return!1;let t=C0(n);if(t.enabled!==!1||!G0(t))return!1;return t.enabled=!0,!0}function tL(n){if(n[b2]===void 0){n[b2]=at();return}let t=C0(n);t.PreToolUse??=[],t.enabled=!0,t.PreToolUse.push(at().PreToolUse?.[0]??{hooks:[]})}function eL(n){let t=!1;for(let e of Object.values(n)){if(!Array.isArray(e.PreToolUse))continue;e.PreToolUse=e.PreToolUse.flatMap((r)=>{if(!Array.isArray(r.hooks))return[r];let a=r.hooks.filter((l)=>l.command!==Ae);if(a.length!==r.hooks.length)t=!0;return a.length===0?[]:[{...r,hooks:a}]})}return t}function rt(n,t){B(n,`${JSON.stringify(t,null,2)}
183
- `)}function U0(n){let t=yn(n);if(_i(Ii(t),{recursive:!0}),!V0(t))return rt(t,{[b2]:at()}),{path:t,alreadyInstalled:!1};let e=K0(t);if(Ni(e))return{path:t,alreadyInstalled:!0};if(nL(e))return rt(t,e),{path:t,alreadyInstalled:!1};return tL(e),rt(t,e),{path:t,alreadyInstalled:!1}}function O0(n){let t=yn(n);if(!V0(t))return{path:t,alreadyInstalled:!1};let e=K0(t);if(!eL(e))return{path:t,alreadyInstalled:!1};return rt(t,e),{path:t,alreadyInstalled:!0}}import{spawn as rL,spawnSync as aL}from"node:child_process";var G=i2.map((n)=>({target:n.id,flag:n.flag,label:n.installLabel,probeCommand:n.probeCommand})),T0=new Map(G.map((n)=>[n.flag,n.target]));function He(n){let t=new Set(n);return G.map((e)=>e.target).filter((e)=>t.has(e))}function E0(n,t){n.forEach(t)}var _0=5000;function lL(n){let t=aL(n[0],n.slice(1),{env:process.env,stdio:"ignore",timeout:_0});return!t.error&&t.status===0}function We(n){return new Promise((t)=>{let e=rL(n[0],n.slice(1),{env:process.env,stdio:"ignore"}),r=!1,a=(d)=>{if(r)return;r=!0,clearTimeout(l),t(d)},l=setTimeout(()=>{e.kill(),a(!1)},_0);e.on("error",()=>a(!1)),e.on("close",(d)=>a(d===0))})}function dL(n=lL,t={}){let e=new Set(t.configuredTargets??[]);if(t.async)return Promise.all(G.map(async(a)=>({target:a.target,flag:a.flag,label:a.label,...Me(t.action,await n(a.probeCommand),e.has(a.target))})));let r=n;return G.map((a)=>({target:a.target,flag:a.flag,label:a.label,...Me(t.action,r(a.probeCommand),e.has(a.target))}))}function P0(n=We,t={}){return dL(n,{...t,async:!0})}function I0(n,t){let e=new Set(t.configuredTargets??[]);return n.map((r)=>({...r,...Me(t.action,r.available,e.has(r.target))}))}function Me(n,t,e){if(n==="uninstall")return e?{available:!0}:{available:!1,unavailableReason:"not installed"};if(n==="install"&&e)return{available:!1,unavailableReason:"already installed"};if(!t)return{available:!1,unavailableReason:"CLI not installed"};return{available:!0}}import{existsSync as N0,readdirSync as sL,rmSync as cL}from"node:fs";import{join as I2}from"node:path";function Ve(n,t=process.platform){let e=I2(process.env.npm_config_cache||(t==="win32"?I2(process.env.LOCALAPPDATA||I2(n,"AppData","Local"),"npm-cache"):I2(n,".npm")),"_npx");if(!N0(e))return;sL(e).filter((r)=>N0(I2(e,r,"node_modules","cc-safety-net"))).forEach((r)=>{cL(I2(e,r),{recursive:!0,force:!0})})}import{existsSync as rl,mkdirSync as LL,readFileSync as al}from"node:fs";import{dirname as oL,join as el}from"node:path";function nl(n){return n!==void 0&&/\s/.test(n)}function iL(n,t,e){let r=t+1,a=!1;while(r<n.length){let l=n[r];if(a){a=!1,r++;continue}if(l==="\\"){a=!0,r++;continue}if(l==='"')return r+1;r++}throw Error(e)}function lt(n,t,e){let r=n[t],a=r==="["?"]":"}",l=0,d=t;while(d<n.length){let s=e.skipComment?.(n,d)??d;if(s!==d){d=s;continue}if(n[d]==='"'){d=iL(n,d,e.stringError);continue}if(n[d]===r)l++;if(n[d]===a){if(l--,l===0)return d}d++}throw Error(e.bracketError)}function tl(n,t){let e=n.lastIndexOf(`
184
- `,t)+1;return/^[ \t]*/.exec(n.slice(e))?.[0]??""}function dt(n,t){let{start:e,end:r,end:a}=t;while(nl(n[a]))a++;if(n[a]===","){if(r=a+1,n[r]===`
185
- `)r++;return`${n.slice(0,e)}${n.slice(r)}`}a=t.start-1;while(nl(n[a]))a--;if(n[a]===","){e=a;let l=n.lastIndexOf(`
186
- `,e-1);if(l!==-1&&/^\s*$/.test(n.slice(l+1,e)))e=l}return`${n.slice(0,e)}${n.slice(r)}`}var kn="npx -y cc-safety-net hook --kimi-code",Ke=`[[hooks]]
172
+ `}function kn(n){return[{name:"__init__.py",content:rL(n)},{name:"plugin.yaml",content:tL(n)}]}import{mkdirSync as eL,readdirSync as aL,readFileSync as lL,rmSync as kr}from"node:fs";import{join as q2}from"node:path";var dL="__pycache__";function qr(n){let t=process.env.HERMES_HOME?.trim();return t?t:q2(n,".hermes")}function jr(n){return q2(qr(n),"plugins",K)}function Fr(n){return n.startsWith(t0)}function zr(n,t){let r=jr(n),e=S(r);if(e&&(e.isSymbolicLink()||!e.isDirectory()))throw Error(`Refusing to ${t} ${r}: not a regular directory. Move or remove it and rerun ${t==="install"?"install":"uninstall"} --hermes-agent.`);return r}function e0(n,t){let r=S(n);if(!r)return;if(r.isSymbolicLink()||!r.isFile())throw Error(`Refusing to ${t} ${n}: not a regular file. Move or remove it.`);let e=lL(n,"utf-8");if(!Fr(e))throw Error(`Refusing to ${t} unmanaged file at ${n}. Move or remove it.`);return e}function a0(n){let t=zr(n,"install"),r=kn(j());if(r.map((a)=>e0(q2(t,a.name),"overwrite")).every((a,l)=>a===r[l]?.content))return{path:t,alreadyInstalled:!0};return eL(t,{recursive:!0}),r.forEach((a)=>{B(q2(t,a.name),a.content)}),{path:t,alreadyInstalled:!1}}function Br(n){let t=zr(n,"remove");if(!S(t))return[];return kn(j()).filter((r)=>e0(q2(t,r.name),"remove")!==void 0)}function l0(n){let t=zr(n,"remove");if(!S(t))return{path:t,alreadyInstalled:!1};let r=Br(n);if(r.forEach((e)=>{kr(q2(t,e.name))}),kr(q2(t,dL),{recursive:!0,force:!0}),aL(t).length===0)kr(t,{recursive:!0});return{path:t,alreadyInstalled:r.length>0}}var rt="hermes-agent",d0=/^([^\s#][^:]*):/,sL=/^\s+([A-Za-z_][\w-]*):/,s0=/^\s+-\s*(.*)$/;function cL(n){return n.trim().replace(/^(["'])(.*)\1$/,"$2")}function LL(n){let t=n.split(/\r?\n/),r=t.findIndex((l)=>d0.exec(l)?.[1]?.trim()==="plugins");if(r===-1)return[];let e=t.slice(r+1),a=e.findIndex((l)=>d0.test(l));return a===-1?e:e.slice(0,a)}function c0(n,t){let r=LL(n),e=r.findIndex((d)=>sL.exec(d)?.[1]===t);if(e===-1)return[];let a=r.slice(e+1),l=a.findIndex((d)=>!s0.test(d));return(l===-1?a:a.slice(0,l)).map((d)=>cL(s0.exec(d)?.[1]??""))}function iL(n){try{return L0(i0(qr(n),"config.yaml"),"utf-8")}catch{return}}function Jr(n){let t=iL(n)??"";return c0(t,"enabled").includes(K)&&!c0(t,"disabled").includes(K)}function p0(n){return/^# version:\s*(.+)$/m.exec(n)?.[1]?.trim()}function pL(n,t){let r=S(n);if(!r)return{error:`${t.name} is missing from ${n}; run install --hermes-agent`};if(r.isSymbolicLink()||!r.isFile())return{error:`${n} is a symlink or not a regular file; move or remove it`};try{let e=L0(n,"utf-8");if(!Fr(e))return{error:`Unmanaged ${t.name} occupies ${n}; move or remove it`};if(p0(e)===j()&&e!==t.content)return{error:`Modified ${t.name} occupies ${n}; run install --hermes-agent to restore it`};return{content:e}}catch(e){return{error:`Failed to read ${n}: ${e instanceof Error?e.message:String(e)}`}}}function u0(n){let t=jr(n.homeDir),r=En(rt,t);if(r)return r;let e=kn(j()).map((s)=>pL(i0(t,s.name),s)),a=e.flatMap((s)=>("error"in s)?[s.error]:[]);if(a.length>0)return{platform:rt,status:"n/a",configPath:t,errors:a};let l=e.some((s)=>("content"in s)&&p0(s.content)!==j()),d=l?["Installed Hermes Agent plugin is outdated; run install --hermes-agent to update"]:[];if(!Jr(n.homeDir))return{platform:rt,status:"disabled",method:"plugin directory",configPath:t,errors:[`${K} is not enabled in Hermes; run \`hermes plugins enable ${K}\``,...d]};return{platform:rt,status:"configured",method:"plugin directory",configPath:t,errors:l?d:void 0}}import{existsSync as uL,readFileSync as oL}from"node:fs";import{join as o0}from"node:path";var vL=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*--kimi-code(\s|["']|$)/;function bL(n){return o0(process.env.KIMI_CODE_HOME||o0(n,".kimi-code"),"config.toml")}function qn(n){let t=bL(n.homeDir);if(!uL(t))return{platform:"kimi-code",status:"n/a",configPath:t};try{if(!vL.test(oL(t,"utf-8")))return{platform:"kimi-code",status:"n/a",configPath:t}}catch(r){return{platform:"kimi-code",status:"n/a",configPath:t,errors:[`Failed to read ${t}: ${r instanceof Error?r.message:String(r)}`]}}return{platform:"kimi-code",status:"configured",method:"hook config",configPath:t}}import{readFileSync as D0}from"node:fs";import{join as Fn}from"node:path";var q="cc-safety-net",M="index.js",P2="openclaw.plugin.json",N2="package.json";var et="// cc-safety-net managed OpenClaw plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --openclaw";import{existsSync as hL,lstatSync as wL,readdirSync as xL,readFileSync as $L}from"node:fs";import{dirname as f0,join as j2}from"node:path";import{fileURLToPath as gL}from"node:url";import{spawn as fL}from"node:child_process";function yL(n){return n.join(" ")}function Zr(n,t,r){return[`Failed to run ${yL(n)}${t===null?"":` (exit ${t})`}.`,r.trim()].filter(Boolean).join(`
173
+ `)}function Qr(n){let t={stdout:"",stderr:""};return n.stdout.setEncoding("utf-8"),n.stderr.setEncoding("utf-8"),n.stdout.on("data",(r)=>{t.stdout+=r}),n.stderr.on("data",(r)=>{t.stderr+=r}),t}function r2(n,t){return new Promise((r,e)=>{let a=f2([...n],process.env),l=fL(a.cmd,a.args,{stdio:["ignore","pipe","pipe"]}),d=Qr(l),s=()=>[d.stdout,d.stderr].filter(Boolean).join(`
174
+ `),c=t?.timeoutMs??120000,L=setTimeout(()=>{l.kill(),e(Error(Zr(n,null,`Timed out after ${c}ms.
175
+ ${s()}`.trim())))},c);l.on("error",(i)=>{clearTimeout(L),e(Error(Zr(n,null,`${i.message}
176
+ ${s()}`.trim())))}),l.on("close",(i)=>{if(clearTimeout(L),i!==0){e(Error(Zr(n,i,s())));return}r(t?.stdoutOnly?d.stdout:s())})})}async function Xr(n){for(let t of n)await r2(t)}async function v0(n){for(let t of n)try{await r2(t)}catch(r){console.warn(r instanceof Error?r.message:String(r))}}var b0=j2("openclaw",q),DL=[M,P2,N2];function y0(n){let t=process.env.OPENCLAW_STATE_DIR?.trim();if(t)return t;let r=process.env.OPENCLAW_CONFIG_PATH?.trim();return r?f0(r):j2(n,".openclaw")}function h0(n){let t=process.env.OPENCLAW_CONFIG_PATH?.trim();return t?t:j2(y0(n),"openclaw.json")}function Yr(n){return j2(y0(n),"extensions",q)}function mL(n){let t=xL(n);if(t.length===0)return!0;if(t.some((a)=>!DL.includes(a)))return!1;let r=j2(n,M),e=S(r);return e!==void 0&&!e.isSymbolicLink()&&e.isFile()&&$L(r,"utf-8").startsWith(et)}function Sr(n){let t=Yr(n),r=S(t);if(!r)return;if(!r.isSymbolicLink()&&r.isDirectory()&&mL(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 w0(){let n=f0(gL(import.meta.url));return[j2(n,"..",b0),j2(n,"..","..","..","dist",b0)]}function Hr(n=w0()){return n.find((t)=>hL(t)&&wL(t).isDirectory())}function kL(n=w0()){let t=Hr(n);if(!t)throw Error("Packaged OpenClaw plugin directory not found. Reinstall cc-safety-net and try again.");return t}function x0(n=kL()){return[["openclaw","plugins","install",n,"--force"],["openclaw","plugins","enable",q]]}function qL(n){let t=(()=>{try{return JSON.parse(n)}catch{return}})(),r=$($(t,"plugin"),"status");return typeof r==="string"?r:void 0}async function $0(){let n=qL(await r2(["openclaw","plugins","inspect",q,"--runtime","--json"],{stdoutOnly:!0}));if(n==="loaded")return;throw Error(`${n===void 0?`The ${q} plugin's load state could not be verified: OpenClaw's runtime inspect report was unreadable.`:`OpenClaw reports the ${q} plugin with status "${n}".`} Run \`openclaw plugins inspect ${q} --runtime\` for details.`)}var at="openclaw",jn=`run \`openclaw plugins enable ${q}\``;function I2(n,t){let r=Fn(n,t),e=S(r);if(!e)return{error:`${t} is missing from ${r}; run install --openclaw`};if(e.isSymbolicLink()||!e.isFile())return{error:`${r} is a symlink or not a regular file; move or remove it`};try{return{content:D0(r,"utf-8")}}catch(a){return{error:`Failed to read ${r}: ${a instanceof Error?a.message:String(a)}`}}}function m0(n){try{return JSON.parse(R(n))}catch{return}}function jL(n){let t=I2(n,P2);if("error"in t)return t.error;if($(m0(t.content),"id")===q)return;return`${Fn(n,P2)} is not a valid ${q} manifest; run install --openclaw`}function FL(n){let t=I2(n,N2);if("error"in t)return t.error;let r=$($(m0(t.content),"openclaw"),"extensions");if(Array.isArray(r)&&r.includes(`./${M}`))return;return`${Fn(n,N2)} does not point OpenClaw at ${M}; run install --openclaw`}function g0(n){return Array.isArray(n)?n.filter((t)=>typeof t==="string"):[]}function zL(n){let t=h0(n);if(!S(t))return`${q} is not enabled; ${jn}`;let r=(()=>{try{return JSON.parse(R(D0(t,"utf-8")))}catch{return}})();if(r===void 0)return`Failed to read ${t}; fix it, then ${jn}`;let e=$(r,"plugins");if($(e,"enabled")===!1)return`plugins.enabled is false in ${t}; no OpenClaw plugin loads`;let a=$($($(e,"entries"),q),"enabled");if(g0($(e,"deny")).includes(q)||a===!1)return`${q} is disabled in ${t}; ${jn}`;let l=g0($(e,"allow"));if(l.length>0&&!l.includes(q))return`plugins.allow in ${t} does not list ${q}; add it, then ${jn}`;if(l.includes(q)||a===!0)return;return`${q} is not enabled; ${jn}`}function k0(n){return/^\/\/ version:\s*(.+)$/m.exec(n)?.[1]?.trim()}function BL(n,t,r){if(r===void 0)return[];let e=I2(r,M);if("error"in e||k0(e.content)!==t)return[];return[M,P2,N2].flatMap((a)=>{let l=I2(n,a),d=I2(r,a);if("error"in l||"error"in d||l.content===d.content)return[];return[`Modified ${a} occupies ${Fn(n,a)}; run install --openclaw to restore it`]})}function q0(n){let t=Yr(n.homeDir),r=En(at,t);if(r)return r;let e=I2(t,M),l=["error"in e?e.error:e.content.startsWith(et)?void 0:`Unmanaged ${M} occupies ${Fn(t,M)}; move or remove it`,jL(t),FL(t)].filter((i)=>i!==void 0),d="content"in e?k0(e.content):void 0,s=l.length>0?l:BL(t,d,Hr());if(s.length>0)return{platform:at,status:"n/a",configPath:t,errors:s};let c=d===j()?[]:["Installed OpenClaw plugin is outdated; run install --openclaw to update"],L=zL(n.homeDir);if(L)return{platform:at,status:"disabled",method:"plugin directory",configPath:t,errors:[L,...c]};return{platform:at,status:"configured",method:"plugin directory",configPath:t,errors:c.length>0?c:void 0}}import{existsSync as JL,readFileSync as ZL}from"node:fs";import{join as j0}from"node:path";function F0(n){let t=[],r=j0(n.homeDir,".config","opencode"),e=["opencode.json","opencode.jsonc"];for(let a of e){let l=j0(r,a);if(JL(l))try{let d=ZL(l,"utf-8"),s=R(d);if((JSON.parse(s).plugin??[]).some((u)=>u.includes("cc-safety-net")))return{platform:"opencode",status:"configured",method:"plugin array",configPath:l,errors:t.length>0?t:void 0}}catch(d){t.push(`Failed to parse ${a}: ${d instanceof Error?d.message:String(d)}`)}}return{platform:"opencode",status:"n/a",errors:t.length>0?t:void 0}}import{join as QL}from"node:path";function Ar(n){return QL(n,".pi","agent","settings.json")}function Wr(n){if(typeof n!=="string")return!1;return n==="npm:cc-safety-net"||n.startsWith("npm:cc-safety-net@")}function z0(n){let t=Ar(n.homeDir),r=n2(t);if(r.kind==="unreadable")return{platform:"pi",status:"not-inspected"};if(r.kind==="missing")return{platform:"pi",status:"n/a"};let e=$(r.value,"packages");if(!Array.isArray(e))return{platform:"pi",status:"n/a"};let a=e.find((s)=>Wr(typeof s==="string"?s:$(s,"source")));if(a===void 0)return{platform:"pi",status:"n/a"};let l=$(a,"extensions");if(Array.isArray(l)&&l.some((s)=>typeof s==="string"&&s.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 YL={amp:Fa,"antigravity-cli":za,"claude-code":Qa,codex:Xa,"copilot-cli":Ca,cursor:Ia,"gemini-cli":n0,"hermes-agent":u0,"kimi-code":qn,openclaw:q0,opencode:F0,pi:z0};function nn(n,t){let r={...t,cwd:n,homeDir:t?.homeDir??XL()};return j1.map((e)=>SL(YL[e](r)))}function SL(n){if(n.status==="not-inspected")return{platform:n.platform,detected:!1,configured:!1,inspectionStatus:"not-inspected"};return{platform:n.platform,detected:n.status!=="n/a",configured:n.status==="configured",inspectionStatus:n.status!=="n/a"?"verified":n.errors&&n.errors.length>0?"failed":"not-applicable",method:n.method,configPath:n.configPath,configPaths:n.configPaths,errors:n.errors}}import{tmpdir as HL}from"node:os";import{join as AL}from"node:path";var WL=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}]),RL=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([])})})}),VL={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:[]}},sources:{failClosed:[],paranoidRm:[],paranoidInterpreters:[],worktreeMode:[]}};function B0(){let n=AL(HL(),"cc-safety-net-self-test"),t=WL.map((r)=>{let e=Wn(K2("self-test",{command:r.command},{kind:"command",shell:"auto"},{configCwd:n,executionCwd:n},r.command),{guard:{dependencies:{loadPolicySnapshot:()=>RL,getModes:()=>VL,findPolicyMutation:()=>null}},audit:{agent:"self-test",getSessionId:()=>{return}}}),a=r.expectBlocked?"blocked":"allowed",l=e.decision.kind==="deny"?"blocked":"allowed";return{command:r.command,description:r.description,expected:a,actual:l,passed:a===l,reason:e.decision.kind==="deny"?e.decision.reason:void 0,ruleId:e.decision.kind==="deny"?e.decision.ruleId:void 0}});return{passed:t.filter((r)=>r.passed).length,failed:t.filter((r)=>!r.passed).length,total:t.length,results:t}}function Rr(n){let t=F({label:"doctor",booleans:{json:["--json"],skipUpdateCheck:["--skip-update-check"]}},n);if(e2(t.errors))return null;return{json:t.flags.json,skipUpdateCheck:t.flags.skipUpdateCheck}}async function J0(n={}){let t=await On(!n.json,()=>{let r=KL(n);return{ready:r,finish:()=>r}},()=>Un(),{loadingMessage:"Checking system status…"});if(n.json)console.log(JSON.stringify(t,null,2));else GL(t);return ML(t.hooks,t.engineSelfTest,{userConfig:t.userConfig,projectConfig:t.projectConfig})?1:0}async function KL(n){let t=n.cwd??process.cwd(),r=await xn(),e=nn(t,{ampPluginListOutput:r.ampPluginListOutput,codexPluginListOutput:r.codexPluginListOutput,copilotCliVersion:r.copilotCliVersion}),a=N1(t),l=I1(),d=W({cwd:t}),s=d.policy,c=d2(s),L=g2(s,c.capabilities),i=Mn(7),u=n.skipUpdateCheck?{currentVersion:j(),latestVersion:null,updateAvailable:!1}:await E2(),v={hooks:e,engineSelfTest:B0(),userConfig:a.userConfig,projectConfig:a.projectConfig,configState:bn(d),effectiveRules:a.effectiveRules,shadowedRules:a.shadowedRules,environment:l,effectiveSafety:{selectedPreset:s.safety.level??"standard",level:c.effectiveLevel,capabilities:c.capabilities,ruleOverrides:s.destructiveCommandRuleOverrides,weakenedRuleOverrides:Object.entries(L).filter(([,p])=>p.source==="rule_override"&&p.override==="off"&&p.inheritedEnabled&&p.changesInherited).map(([p])=>p),ruleCounts:{stored:Object.keys(s.destructiveCommandRuleOverrides).length,effective:Object.values(L).filter((p)=>p.changesInherited).length}},posture:oa(a.userConfig.path),activity:i,update:u,system:r};return{...v,findings:ta(v)}}function ML(n,t,r){return n.length>0&&n.every((e)=>!e.configured)||n.some((e)=>e.inspectionStatus==="failed")||t.failed>0||r.userConfig.exists&&!r.userConfig.valid||r.projectConfig.exists&&!r.projectConfig.valid}function GL(n){console.log(),console.log(ea(n.hooks)),console.log(),console.log(aa(n.engineSelfTest)),console.log(),console.log(la(n)),console.log(),console.log(da(n.environment)),console.log(),console.log(sa(n)),console.log(),console.log(ca(n.findings)),console.log(),console.log(La(n.activity)),console.log(),console.log(pa(n.system)),console.log(),console.log(ia(n.update)),console.log(ua(n))}import{existsSync as CL}from"node:fs";var UL=/^[A-Za-z0-9_@%+=:,./-]+$/,Z0="Usage: cc-safety-net explain [--json] [--cwd <path>] <command>";function Vr(n){let t=F({label:"explain",booleans:{json:["--json"]},values:{cwd:["--cwd"]},positionals:"tail"},n);if(e2(t.errors))return console.error(Z0),console.error("Pass -- before a command that starts with dashes."),null;if(t.values.cwd!==void 0&&!CL(t.values.cwd))return console.error(`Error: --cwd path does not exist: ${t.values.cwd}`),null;let r=t.positionals.length===1?t.positionals[0]:t.positionals.map((e)=>UL.test(e)?e:`'${e.replaceAll("'","'\\''")}'`).join(" ");if(!r)return console.error("Error: No command provided"),console.error(Z0),null;return{json:t.flags.json,cwd:t.values.cwd,command:r}}function Q0(n){if(n)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 X0(n,t){let e=t-18;return[`${n.dtl}${n.dh.repeat(t)}${n.dtr}`,`${n.dv} Command Analysis${" ".repeat(e)}${n.dv}`,`${n.dbl}${n.dh.repeat(t)}${n.dbr}`]}function Kr(n){return JSON.stringify(n)}function Y0(n,t=0){return`[${n.map((e,a)=>ra(e,a,t)).join(",")}]`}function lt(n,t,r=70){let e=n.split(" "),a=[],l="";for(let d of e)if(l&&l.length+d.length+1>r)a.push(l),l=d;else l=l?`${l} ${d}`:d;if(l)a.push(l);return a.map((d,s)=>s===0?d:`${t}${d}`)}function S0(n,t,r){let e=[];switch(n.type){case"parse":return null;case"env-strip":{e.push(""),e.push(`STEP ${t} ${r.h} Strip environment variables`);let a=Object.keys(n.envVars);return e.push(` Removed: ${a.map((l)=>`${l}=<redacted>`).join(", ")}`),e.push(` Tokens: ${Kr(n.output)}`),{lines:e,incrementStep:!0}}case"leading-tokens-stripped":return e.push(""),e.push(`STEP ${t} ${r.h} Strip wrappers`),e.push(` Removed: ${n.removed.join(", ")}`),e.push(` Tokens: ${Kr(n.output)}`),{lines:e,incrementStep:!0};case"shell-wrapper":return e.push(""),e.push(`STEP ${t} ${r.h} Detect shell wrapper`),e.push(` Wrapper: ${n.wrapper} -c`),e.push(` Inner: ${n.innerCommand}`),{lines:e,incrementStep:!0};case"interpreter":{if(e.push(""),e.push(`STEP ${t} ${r.h} Detect interpreter`),e.push(` Interpreter: ${n.interpreter}`),e.push(` Code: ${n.codeArg}`),n.paranoidBlocked)e.push(" Result: ✗ BLOCKED (paranoid mode)");return{lines:e,incrementStep:!0}}case"busybox":return e.push(""),e.push(`STEP ${t} ${r.h} Busybox wrapper`),e.push(` Subcommand: ${n.subcommand}`),{lines:e,incrementStep:!0};case"transparent-wrapper":return e.push(""),e.push(`STEP ${t} ${r.h} Transparent wrapper`),e.push(` Wrapper: ${n.wrapper}`),e.push(` Tokens: ${Kr(n.output)}`),{lines:e,incrementStep:!0};case"recurse":return{lines:[],incrementStep:!1};case"rule-check":{e.push(""),e.push(`STEP ${t} ${r.h} Match rules`);let a=`${n.ruleModule}:${n.ruleFunction}()`;if(e.push(` Rule: ${a}`),n.matched)e.push(" Result: MATCHED");else e.push(" Result: No match");return{lines:e,incrementStep:!0}}case"worktree-relaxation":return e.push(""),e.push(`STEP ${t} ${r.h} Worktree relaxation`),e.push(` Mode: ${m.worktree.name}`),e.push(` Git cwd: ${n.gitCwd}`),e.push(" Result: Allowed local discard in linked worktree"),{lines:e,incrementStep:!0};case"tmpdir-check":return null;case"fallback-scan":{if(n.embeddedCommandFound)return e.push(""),e.push(`STEP ${t} ${r.h} Fallback scan`),e.push(` Found: ${n.embeddedCommandFound}`),{lines:e,incrementStep:!0};return null}case"custom-rules-check":{if(n.rulesChecked){if(e.push(""),e.push(`STEP ${t} ${r.h} Custom rules`),n.matched)e.push(" Result: MATCHED");else e.push(" Result: No match");return{lines:e,incrementStep:!0}}return null}case"cwd-change":return null;case"dangerous-text":{if(n.matched)return e.push(""),e.push(`STEP ${t} ${r.h} Dangerous text check`),e.push(` Token: ${n.token}`),e.push(" Result: MATCHED"),{lines:e,incrementStep:!0};return null}case"strict-unparseable":return e.push(""),e.push(`STEP ${t} ${r.h} Strict mode check`),e.push(` Command: ${n.rawCommand}`),e.push(" Result: ✗ UNPARSEABLE"),{lines:e,incrementStep:!0};case"segment-skipped":return null;case"error":return e.push(""),e.push(`ERROR: ${n.message}`),{lines:e,incrementStep:!1};default:return null}}function Mr(n,t){let r=Q0(t?.asciiOnly??!1),e=58,a=[],l=1;a.push(...X0(r,58)),a.push("");let d=n.trace.steps.find((p)=>p.type==="error");if(d&&d.type==="error"){a.push("ERROR"),a.push(` ${d.message}`),a.push(""),a.push("RESULT"),a.push(` Status: ${n.result==="blocked"?b.red("BLOCKED"):b.green("ALLOWED")}`),a.push(""),a.push("CONFIG");let p=n.configSource??"none";return a.push(` Path: ${p}`),a.join(`
177
+ `)}let s=n.trace.steps.find((p)=>p.type==="parse");if(s&&s.type==="parse"){a.push("INPUT"),a.push(` ${s.input}`),a.push(""),a.push(`STEP ${l} ${r.h} Split shell commands`),l++;for(let p=0;p<s.segments.length;p++){let f=s.segments[p];if(f){let o=Math.random();a.push(` Segment ${p+1}: ${Y0(f,o)}`)}}}let c=n.trace.segments,L=c.length>1;for(let p of c){if(L){a.push("");let x="";if(s&&s.type==="parse"){let mt=s.segments[p.index];if(mt)x=mt.join(" ")}let w=54,h=x,J=` Segment ${p.index+1}: `,Z2=" ";if(x){if(J.length+x.length+Z2.length>w){let Q3=w-J.length-Z2.length;h=`${x.substring(0,Q3-1)}…`}}let an=x?`${J}${h}${Z2}`:` Segment ${p.index+1} `,Dt=x?`${J}${b.cyan(h)}${Z2}`:an,we=58-an.length,xe=Math.floor(we/2),Z3=we-xe;a.push(`${r.sh.repeat(xe)}${Dt}${r.sh.repeat(Z3)}`)}if(p.steps.find((x)=>x.type==="segment-skipped")){a.push(""),a.push(" (skipped — prior segment blocked)");continue}let o=!1,y=!1;for(let x of p.steps){let w=S0(x,l,r);if(w){if(y=!0,x.type==="recurse"){a.push("");let h=" RECURSING ",J=58-h.length-4;a.push(` ${r.tl}${r.h}${h}${r.h.repeat(J)}`),a.push(` ${r.v}`),o=!0;continue}for(let h of w.lines)if(o)a.push(` ${r.v} ${h}`);else a.push(h);if(w.incrementStep)l++}}if(o)a.push(` ${r.v}`),a.push(` ${r.bl}${r.h.repeat(56)}`),o=!1;if(!y)a.push(""),a.push(` ${b.green("✓")} Allowed (no matching rules)`)}if(a.push(""),a.push("RESULT"),n.result==="blocked"){if(a.push(` Status: ${b.red("BLOCKED")}`),n.customRule){if(a.push(` Rule: ${n.customRule.id}`),n.customRule.rulebook)a.push(` Rulebook: ${n.customRule.rulebook.name} ${n.customRule.rulebook.version}`);if(n.customRule.source)a.push(` Source: ${n.customRule.source}`);if(n.customRule.override)a.push(` Override: reason ${n.customRule.override.reason}`)}if(n.reason){let p=lt(n.reason," ");a.push(` Reason: ${p[0]}`);for(let f=1;f<p.length;f++)a.push(p[f]??"")}}else a.push(` Status: ${b.green("ALLOWED")}`);a.push(""),a.push("CONFIG");let i=n.configSource??"none",u=n.configValid?"":" (invalid)";a.push(` Path: ${i}${u}`),a.push(` Safety preset: ${n.selectedPreset??"standard"}`),a.push(` Effective capabilities: ${n.effectiveLevel}`);let v=Object.entries(n.destructiveCommandRuleOverrides??{});if(a.push(` Rule customizations: ${v.length}`),n.ruleActivation)a.push(` Rule activation: ${n.ruleActivation.id} — ${n.ruleActivation.enabled?"on":"off"} via ${n.ruleActivation.source}`);return a.join(`
178
+ `)}function Gr(n){return JSON.stringify(n,null,2)}var H0="2.0.3",G=" ",F2="cc-safety-net";function A0(n){return n.argument?`${n.flags} ${n.argument}`:n.flags}function OL(n){return Math.max(...n.map((t)=>A0(t).length))}function TL(n){return Math.max(...n.map((t)=>t.usage.length))}function EL(n){return Math.max(...n.map((t)=>`${F2} ${t.usage}`.length))}function _L(n,t){let r=`${F2} ${n.usage}`;return`${G}${r.padEnd(t+2)}${n.description}`}function i2(n,t){return`${G}${n.padEnd(Math.max(40,n.length+2))}${t}`}function dt(n,t=console.log){let r=[];if(r.push(`${F2} ${n.name}`),r.push(""),r.push(`${G}${n.description}`),r.push(""),r.push("USAGE:"),r.push(`${G}${F2} ${n.usage}`),r.push(""),n.subcommands&&n.subcommands.length>0){r.push("SUBCOMMANDS:");let e=TL(n.subcommands);for(let a of n.subcommands)r.push(`${G}${a.usage.padEnd(e+2)}${a.description}`);r.push("")}if(n.options.length>0){r.push("OPTIONS:");let e=OL(n.options);for(let a of n.options){let l=A0(a),d=a.default?`${a.description} (default: ${a.default})`:a.description;r.push(`${G}${l.padEnd(e+2)}${d}`)}r.push("")}if(n.examples&&n.examples.length>0){r.push("EXAMPLES:");for(let e of n.examples)r.push(`${G}${e}`)}t(r.join(`
179
+ `))}function Cr(){let n=_1(),t=EL(n),r=[];r.push(`${F2} v${H0}`),r.push(""),r.push("Blocks destructive commands and secret access."),r.push(""),r.push("COMMANDS:");for(let e of n)r.push(_L(e,t));r.push(""),r.push("GLOBAL OPTIONS:"),r.push(`${G}-h, --help Show help (use with command for command-specific help)`),r.push(`${G}-V, --version Show version`),r.push(""),r.push("HELP:"),r.push(`${G}${F2} help <command> Show help for a specific command`),r.push(`${G}${F2} <command> --help Show help for a specific command`),r.push(""),r.push("ENVIRONMENT VARIABLES:"),r.push(i2(`${m.level.name}=standard|strict|paranoid`,"Set session safety level")),r.push(i2(`${m.worktree.name}=1`,"Allow local git discards in linked worktrees")),r.push(i2(`${m.debug.name}=1`,"Print diagnostic messages to stderr")),r.push(i2(`${m.auditScope.name}=all|blocked`,"Record all command decisions, or denials only")),r.push(i2("CC_SAFETY_NET_HOME","Override rule config home directory")),r.push(""),r.push("LEGACY ENVIRONMENT VARIABLES (STILL SUPPORTED):"),r.push(i2(`${m.strict.name}=1`,"Force safety.overrides.fail_closed on")),r.push(i2(`${m.paranoid.name}=1`,"Force paranoid_rm and paranoid_interpreters on")),r.push(i2(`${m.paranoidRm.name}=1`,"Force safety.overrides.paranoid_rm on")),r.push(i2(`${m.paranoidInterpreters.name}=1`,"Force safety.overrides.paranoid_interpreters on")),r.push(""),r.push("Documentation: https://ccsafetynet.com/docs"),console.log(r.join(`
180
+ `))}function W0(){console.log(H0)}function zn(n,t=console.log){let r=Kn(n);if(!r)return!1;if(r.hidden||r.name.toLowerCase()!==n.toLowerCase())return!1;return dt(r,t),!0}import{existsSync as se,readFileSync as Vl}from"node:fs";import{homedir as Ei}from"node:os";import{join as le}from"node:path";import*as y2 from"node:readline";function PL(n){return n==="install"?"Install":"Uninstall"}function NL(n){return n==="install"?"Installing":"Uninstalling"}function IL(n){return n==="install"?"into":"from"}function K0(n){return n?.available===!0}function ni(n,t){let r=new Set(t);return n.filter((e)=>r.has(e.target)).map((e)=>e.target)}function R0(n,t,r){if(n.length===0||n.every((e)=>!e.available))return t;return Array.from({length:n.length},(e,a)=>a+1).map((e)=>(t+e*r+n.length)%n.length).find((e)=>K0(n[e]))}function ti(n,t,r){if(r.ctrl&&r.name==="c")return"interrupt";if(r.name==="escape"||t==="q")return"abort";if(n==="install"&&(t==="u"||t==="U"))return"update";if(r.name==="up"||t==="k")return"up";if(r.name==="down"||t==="j")return"down";if(r.name==="space"||t===" ")return"toggle";if(r.name==="return"||r.name==="enter")return"confirm";return null}function ri(n){return{cursor:n.findIndex((t)=>t.available),selected:[]}}function ei(n,t,r){if(r==="confirm"||r==="update"||r==="abort"||r==="interrupt")return{state:n,done:r};if(r==="up")return{state:{...n,cursor:R0(t,n.cursor,-1)}};if(r==="down")return{state:{...n,cursor:R0(t,n.cursor,1)}};let e=t[n.cursor];if(!K0(e))return{state:n};let a=n.selected.includes(e.target)?n.selected.filter((l)=>l!==e.target):ni(t,[...n.selected,e.target]);return{state:{...n,selected:a}}}var M0="◉",G0="◯",C0=">",U0=" ";function ai(n,t,r,e={}){let a=e.color!==!1,l=a?b.dim:(c)=>c,d=a?b.green:(c)=>c,s=a?b.bold:(c)=>c;return["",`${PL(n)} CC Safety Net ${IL(n)}:`,"",...t.map((c,L)=>{let i=r.selected.includes(c.target),u=L===r.cursor,v=i?M0:G0,p=u?C0:U0,f=c.available?"":` (${c.unavailableReason??"not installed"})`,o=`${v} ${c.label}${f}`,y=!c.available?l(o):i?d(o):u?s(o):o;return`${p} ${y}`}),"",n==="install"?"Space: select Enter: confirm u: update installed Up/Down: move q/Esc: cancel":t.some((c)=>c.available)?"Space: select Enter: confirm Up/Down: move q/Esc: cancel":`No selectable integrations found for ${n}. q/Esc: close`].join(`
181
+ `)}var V0=["global-hook","plugin"];function li(n,t,r={}){let e=r.color!==!1?b.bold:(l)=>l;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((l,d)=>{let s=d===n,c=`${s?M0:G0} ${l}`;return`${s?C0:U0} ${s?e(c):c}`}),"","Enter: confirm Up/Down: move q/Esc: cancel"].join(`
182
+ `)}function O0(n){let{input:t,output:r}=n;y2.emitKeypressEvents(t);let e=t.isRaw===!0;t.setRawMode(!0),t.resume();let a=0,l=()=>{if(a===0)return;y2.moveCursor(r,0,-a),y2.cursorTo(r,0),y2.clearScreenDown(r)},d=()=>{l();let s=n.render();r.write(`${s}
183
+ `),a=s.split(`
184
+ `).length};return new Promise((s)=>{let c=(i)=>{t.off("keypress",L),t.setRawMode(e),t.pause(),l(),s(i)};function L(i,u){n.onKey(i,u,{finish:c,draw:d})}t.on("keypress",L),d()})}function T0(n={}){let t=0;return O0({input:n.input??process.stdin,output:n.output??process.stdout,render:()=>li(t,n.globalHookInstalled===!0),onKey:(r,e,a)=>{if(e.ctrl&&e.name==="c"){a.finish(null),(n.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(e.name==="escape"||r==="q")return a.finish(null);if(e.name==="return"||e.name==="enter")return a.finish(V0[t]);if(e.name==="up"||e.name==="down"||r==="k"||r==="j")t=(t+1)%V0.length,a.draw()}})}function Ur(n=process.stdin,t=process.stdout){return Boolean(n.isTTY&&t.isTTY&&typeof n.setRawMode==="function")}function E0(n,t,r={}){let e=r.output??process.stdout,a=ri(t);return O0({input:r.input??process.stdin,output:e,render:()=>ai(n,t,a),onKey:(l,d,s)=>{let c=ti(n,l,d);if(!c)return;let L=ei(a,t,c);if(a=L.state,L.done==="interrupt"){s.finish(null),(r.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(L.done==="abort")return s.finish(null);if(L.done==="update")return s.finish("update");if(L.done==="confirm"){if(a.selected.length===0){e.write("\x07"),s.draw();return}s.finish([...a.selected]),e.write(`${NL(n)} selected integrations...
185
+ `);return}s.draw()}})}import{existsSync as P0,lstatSync as N0,mkdtempSync as si,readFileSync as Lt,rmSync as I0}from"node:fs";import{tmpdir as ci}from"node:os";import{dirname as Li,join as z2}from"node:path";import{fileURLToPath as ii}from"node:url";var Or="// cc-safety-net managed Amp plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --amp";import{spawn as di}from"node:child_process";var Tr=(n,t)=>{let r=f2([...n],process.env);return new Promise((e)=>{let a=di(r.cmd,r.args,{cwd:t,stdio:["ignore","pipe","pipe"]}),l=Qr(a),d=!1,s=setTimeout(()=>{d=!0,a.kill()},120000);a.on("error",(c)=>{clearTimeout(s),e({status:null,errorCode:c.code,stdout:l.stdout,stderr:[c.message,l.stderr].filter(Boolean).join(`
186
+ `)})}),a.on("close",(c)=>{clearTimeout(s),e({status:d?null:c,errorCode:d?"ETIMEDOUT":void 0,stdout:l.stdout,stderr:l.stderr})})})};var _0=z2("amp","cc-safety-net.ts"),p2="cc-safety-net.ts";function pi(n){return z2(n,".config","amp","plugins",p2)}function ui(){let n=Li(ii(import.meta.url));return[z2(n,"..",_0),z2(n,"..","..","..","dist",_0)]}function oi(n=ui()){let t=n.find((r)=>P0(r)&&N0(r).isFile());if(!t)throw Error("Packaged Amp plugin artifact not found. Reinstall cc-safety-net and try again.");return t}function nl(n){try{return N0(n)}catch{return}}function tl(n){try{return JSON.parse(n)}catch{return}}function rl(n){return n.subarray(0,Buffer.byteLength(Or)).toString("utf-8")===Or}async function Bn(n,t,r){let e=await n(t,r);if(e.status===0)return e;throw Error([`Failed to run ${t.join(" ")}${e.status===null?"":` (exit ${e.status})`}.`,[e.stdout,e.stderr].filter(Boolean).join(`
187
+ `).trim()].filter(Boolean).join(`
188
+ `))}async function el(n){let t=await n(["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.`}
189
+ ${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.
190
+ ${[t.stdout,t.stderr].filter(Boolean).join(`
191
+ `)}`.trim());let r=tl(t.stdout),e=(Array.isArray(r)?r:[]).filter((a)=>$(a,"scope")==="user"&&$(a,"exists")===!0&&$(a,"viewerCanWrite")===!0).map((a)=>$(a,"cloneRef")).find((a)=>typeof a==="string"&&a.length>0);if(!e)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 e}async function al(n,t){let r=si(z2(ci(),"cc-safety-net-amp-"));try{return await Bn(n,["amp","clone","user-plugins",r]),await t(r)}finally{I0(r,{recursive:!0,force:!0})}}function ll(n,t){let r=z2(n,p2),e=nl(r);if(!e)return;if(e.isSymbolicLink()||!e.isFile())throw Error(`Refusing to ${t} ${p2} in your Amp personal plugins repository: not a regular file. Remove it there and rerun install --amp.`);let a=Lt(r);if(rl(a))return a;throw Error(`Refusing to ${t} unmanaged file ${p2} in your Amp personal plugins repository. Remove it there and rerun install --amp.`)}async function dl(n,t,r,e){if(await Bn(n,r,t),(await Bn(n,["git","status","--porcelain"],t)).stdout.trim()==="")return!1;return await Bn(n,["git","-c","commit.gpgsign=false","-c","user.name=cc-safety-net","-c","user.email=cc-safety-net@localhost","commit","-m",e],t),await Bn(n,["git","push","origin","HEAD"],t),!0}function st(n,t){let r=pi(n),e=nl(r);if(!e)return;if(!e.isSymbolicLink()&&e.isFile()&&rl(Lt(r))){I0(r);return}if(t==="keep")return;throw Error(`Local Amp plugin ${r} is not a managed copy and masks the personal plugin. Remove it and rerun install --amp.`)}function vi(){let n=vn();if(!P0(n))return"";let t=tl(Lt(n,"utf-8"));if(!t||typeof t!=="object"||Array.isArray(t))return"";return`;globalThis.__CC_SAFETY_NET_EMBEDDED_POLICY__ = ${JSON.stringify(ct(t))};
192
+ `}async function sl(n,t=oi(),r=Tr){let e=Buffer.concat([Lt(t),Buffer.from(vi(),"utf-8")]),a=await el(r);return al(r,async(l)=>{let d=`${a}/${p2}`;if(ll(l,"overwrite")?.equals(e))return st(n,"fail"),{path:d,alreadyInstalled:!0};B(z2(l,p2),e);let s=await dl(r,l,["git","add",p2],`chore: update cc-safety-net plugin to v${j()}`);return st(n,"fail"),{path:d,alreadyInstalled:!s}})}async function cl(n,t=Tr){let r=await el(t);return al(t,async(e)=>{let a=`${r}/${p2}`;if(!ll(e,"remove"))return st(n,"keep"),{path:a,alreadyInstalled:!1};return await dl(t,e,["git","rm",p2],`chore: remove cc-safety-net plugin v${j()}`),st(n,"keep"),{path:a,alreadyInstalled:!0}})}import{existsSync as Ll,mkdirSync as bi,readFileSync as fi}from"node:fs";import{dirname as yi}from"node:path";var Er="npx -y cc-safety-net hook --agy-cli",h2="cc-safety-net";function pt(){return{PreToolUse:[{hooks:[{type:"command",command:Er,timeout:30}]}]}}function il(n){try{let t=JSON.parse(fi(n,"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 ${n}: ${t.message}`);throw t}}function pl(n){let t=n[h2];if(t===void 0)return n[h2]=pt(),n[h2];if(!t||typeof t!=="object"||Array.isArray(t))throw Error(`Antigravity hooks config entry "${h2}" must be an object`);if(!Array.isArray(t.PreToolUse))t.PreToolUse=[];return t}function ul(n){if(!Array.isArray(n.PreToolUse))return!1;return n.PreToolUse.some((t)=>Array.isArray(t.hooks)&&t.hooks.some((r)=>r.command===Er))}function hi(n){return Object.values(n).some((t)=>t.enabled!==!1&&ul(t))}function wi(n){if(n[h2]===void 0)return!1;let t=pl(n);if(t.enabled!==!1||!ul(t))return!1;return t.enabled=!0,!0}function xi(n){if(n[h2]===void 0){n[h2]=pt();return}let t=pl(n);t.PreToolUse??=[],t.enabled=!0,t.PreToolUse.push(pt().PreToolUse?.[0]??{hooks:[]})}function $i(n){let t=!1;for(let r of Object.values(n)){if(!Array.isArray(r.PreToolUse))continue;r.PreToolUse=r.PreToolUse.flatMap((e)=>{if(!Array.isArray(e.hooks))return[e];let a=e.hooks.filter((l)=>l.command!==Er);if(a.length!==e.hooks.length)t=!0;return a.length===0?[]:[{...e,hooks:a}]})}return t}function it(n,t){B(n,`${JSON.stringify(t,null,2)}
193
+ `)}function ol(n){let t=gn(n);if(bi(yi(t),{recursive:!0}),!Ll(t))return it(t,{[h2]:pt()}),{path:t,alreadyInstalled:!1};let r=il(t);if(hi(r))return{path:t,alreadyInstalled:!0};if(wi(r))return it(t,r),{path:t,alreadyInstalled:!1};return xi(r),it(t,r),{path:t,alreadyInstalled:!1}}function vl(n){let t=gn(n);if(!Ll(t))return{path:t,alreadyInstalled:!1};let r=il(t);if(!$i(r))return{path:t,alreadyInstalled:!1};return it(t,r),{path:t,alreadyInstalled:!0}}import{spawn as gi,spawnSync as Di}from"node:child_process";var C=L2.map((n)=>({target:n.id,flag:n.flag,label:n.installLabel,probeCommand:n.probeCommand})),bl=new Map(C.map((n)=>[n.flag,n.target]));function _r(n){let t=new Set(n);return C.map((r)=>r.target).filter((r)=>t.has(r))}async function fl(n,t){for(let r of n)await t(r)}var yl=5000;function mi(n){let t=f2([...n],process.env),r=Di(t.cmd,t.args,{env:process.env,stdio:"ignore",timeout:yl});return!r.error&&r.status===0}function Nr(n){return new Promise((t)=>{let r=f2([...n],process.env),e=gi(r.cmd,r.args,{env:process.env,stdio:"ignore"}),a=!1,l=(s)=>{if(a)return;a=!0,clearTimeout(d),t(s)},d=setTimeout(()=>{e.kill(),l(!1)},yl);e.on("error",()=>l(!1)),e.on("close",(s)=>l(s===0))})}function ki(n=mi,t={}){let r=new Set(t.configuredTargets??[]);if(t.async)return Promise.all(C.map(async(a)=>({target:a.target,flag:a.flag,label:a.label,...Pr(t.action,await n(a.probeCommand),r.has(a.target))})));let e=n;return C.map((a)=>({target:a.target,flag:a.flag,label:a.label,...Pr(t.action,e(a.probeCommand),r.has(a.target))}))}function hl(n=Nr,t={}){return ki(n,{...t,async:!0})}function wl(n,t){let r=new Set(t.configuredTargets??[]);return n.map((e)=>({...e,...Pr(t.action,e.available,r.has(e.target))}))}function Pr(n,t,r){if(n==="uninstall")return r?{available:!0}:{available:!1,unavailableReason:"not installed"};if(n==="install"&&r)return{available:!1,unavailableReason:"already installed"};if(!t)return{available:!1,unavailableReason:"CLI not installed"};return{available:!0}}import{existsSync as xl,readdirSync as qi,rmSync as ji}from"node:fs";import{join as tn}from"node:path";function Ir(n,t=process.platform){let r=tn(process.env.npm_config_cache||(t==="win32"?tn(process.env.LOCALAPPDATA||tn(n,"AppData","Local"),"npm-cache"):tn(n,".npm")),"_npx");if(!xl(r))return;qi(r).filter((e)=>xl(tn(r,e,"node_modules","cc-safety-net"))).forEach((e)=>{ji(tn(r,e),{recursive:!0,force:!0})})}import{existsSync as ml,mkdirSync as zi,readFileSync as kl}from"node:fs";import{dirname as Bi,join as Dl}from"node:path";function $l(n){return n!==void 0&&/\s/.test(n)}function Fi(n,t,r){let e=t+1,a=!1;while(e<n.length){let l=n[e];if(a){a=!1,e++;continue}if(l==="\\"){a=!0,e++;continue}if(l==='"')return e+1;e++}throw Error(r)}function ut(n,t,r){let e=n[t],a=e==="["?"]":"}",l=0,d=t;while(d<n.length){let s=r.skipComment?.(n,d)??d;if(s!==d){d=s;continue}if(n[d]==='"'){d=Fi(n,d,r.stringError);continue}if(n[d]===e)l++;if(n[d]===a){if(l--,l===0)return d}d++}throw Error(r.bracketError)}function gl(n,t){let r=n.lastIndexOf(`
194
+ `,t)+1;return/^[ \t]*/.exec(n.slice(r))?.[0]??""}function ot(n,t){let{start:r,end:e,end:a}=t;while($l(n[a]))a++;if(n[a]===","){if(e=a+1,n[e]===`
195
+ `)e++;return`${n.slice(0,r)}${n.slice(e)}`}a=t.start-1;while($l(n[a]))a--;if(n[a]===","){r=a;let l=n.lastIndexOf(`
196
+ `,r-1);if(l!==-1&&/^\s*$/.test(n.slice(l+1,r)))r=l}return`${n.slice(0,r)}${n.slice(e)}`}var Jn="npx -y cc-safety-net hook --kimi-code",ne=`[[hooks]]
187
197
  event = "PreToolUse"
188
- command = "${kn}"`,Ce=`{ event = "PreToolUse", command = "${kn}" }`;function ll(n){return el(process.env.KIMI_CODE_HOME??el(n,".kimi-code"),"config.toml")}function uL(n){return n.split(`
189
- `).reduce((e,r)=>{if(/^\s*\[/.test(r))return e.activeTable=!0,e.lines.push(r),e;if(!e.activeTable&&/^\s*hooks\s*=\s*\[\s*]\s*(?:#.*)?$/.test(r))return e;return e.lines.push(r),e},{activeTable:!1,lines:[]}).lines.join(`
190
- `)}function pL(n,t){if(n[t]!=="#")return t;let e=n.indexOf(`
191
- `,t+1);return e===-1?n.length:e+1}function vL(n,t){return lt(n,t,{skipComment:pL,stringError:"Unterminated string in Kimi Code config",bracketError:"Unmatched hooks array in Kimi Code config"})}function dl(n){let t=!1,e=0;while(e<n.length){let r=n.indexOf(`
192
- `,e),a=r===-1?n.length:r,l=n.slice(e,a);if(/^\s*\[/.test(l))t=!0;if(!t){let d=/^(\s*)hooks\s*=\s*\[/.exec(l);if(d){let s=e+d[0].lastIndexOf("[");return{start:s,end:vL(n,s)}}}e=r===-1?n.length:r+1}return}function bL(n,t){let e=n.slice(0,t.end).trimEnd(),r=tl(n,t.end),a=r===""?" ":`${r} `,l=!e.endsWith("[")&&!e.endsWith(",");return`${e}${l?",":""}
193
- ${a}${Ce}${n.slice(t.end)}`}function fL(n){let t=dl(n);if(t&&n.slice(t.start+1,t.end).trim())return bL(n,t);let e=uL(n).trimEnd();if(e==="")return`${Ke}
194
- `;return`${e}
195
-
196
- ${Ke}
197
- `}function hL(n){return n.split(/(?=^\s*\[)/m).filter((e)=>!/^\s*\[\[hooks]]\s*$/m.test(e)||!e.includes(kn)).join("").trimEnd()}function yL(n,t){let e=n.indexOf(Ce,t.start);if(e===-1||e>t.end)return n;return dt(n,{start:e,end:e+Ce.length})}function sl(n){let t=ll(n);if(LL(oL(t),{recursive:!0}),!rl(t))return B(t,`${Ke}
198
- `),{path:t,alreadyInstalled:!1};let e=al(t,"utf-8");if(e.includes(kn))return{path:t,alreadyInstalled:!0};return B(t,fL(e)),{path:t,alreadyInstalled:!1}}function cl(n){let t=ll(n);if(!rl(t))return{path:t,alreadyInstalled:!1};let e=al(t,"utf-8");if(!e.includes(kn))return{path:t,alreadyInstalled:!1};let r=dl(e),a=r?yL(e,r):`${hL(e)}
199
- `;return B(t,a),{path:t,alreadyInstalled:!0}}import{existsSync as il,readFileSync as wL,rmSync as xL}from"node:fs";import{join as Ge}from"node:path";var Ue="cc-safety-net",mL=`${Ue}@latest`,ol=["opencode.json","opencode.jsonc"];function gL(n){return Ge(n,".config","opencode",ol[0])}function $L(n){return ol.map((t)=>Ge(n,".config","opencode",t))}function DL(n){return Ge(n,".cache","opencode","packages",mL)}function Oe(n){xL(DL(n),{recursive:!0,force:!0})}function st(n,t){if(n[t]==="/"&&n[t+1]==="/"){let e=n.indexOf(`
200
- `,t+2);return e===-1?n.length:e+1}if(n[t]==="/"&&n[t+1]==="*"){let e=n.indexOf("*/",t+2);return e===-1?n.length:e+2}return t}function Ll(n,t){let e=t;while(e<n.length){if(/\s/.test(n[e]??"")){e++;continue}let r=st(n,e);if(r===e)return e;e=r}return e}function ul(n,t){let e=t+1,r=!1;while(e<n.length){if(r){r=!1,e++;continue}if(n[e]==="\\"){r=!0,e++;continue}if(n[e]==='"')return e+1;e++}throw Error("Unterminated string in OpenCode config")}function pl(n,t,e){return JSON.parse(n.slice(t,e))}function kL(n,t){return lt(n,t,{skipComment:st,stringError:"Unterminated string in OpenCode config",bracketError:"Unmatched plugin array in OpenCode config"})}function qL(n){let t=0,e=0;while(e<n.length){let r=st(n,e);if(r!==e){e=r;continue}if(n[e]==='"'){let a=ul(n,e);if(t===1&&pl(n,e,a)==="plugin"){let l=Ll(n,a),d=Ll(n,l+1);if(n[l]===":"&&n[d]==="[")return{start:d,end:kL(n,d)}}e=a;continue}if(n[e]==="{"||n[e]==="[")t++;if(n[e]==="}"||n[e]==="]")t--;e++}return}function jL(n,t){let e=[],r=t.start+1;while(r<t.end){let a=st(n,r);if(a!==r){r=a;continue}if(n[r]==='"'){let l=ul(n,r),d=pl(n,r,l);if(typeof d==="string"&&d.includes(Ue))e.push({start:r,end:l});r=l;continue}r++}return e}function vl(n,t){try{return JSON.parse(M(n))}catch(e){if(e instanceof SyntaxError)throw Error(`Failed to parse OpenCode config ${t}: ${e.message}`);throw e}}function FL(n){if(!n||typeof n!=="object"||Array.isArray(n))return!1;let t=n.plugin;if(!Array.isArray(t))return!1;return t.some((e)=>typeof e==="string"&&e.includes(Ue))}function zL(n,t){let e=qL(n);if(!e)throw Error(`Failed to locate OpenCode plugin array in ${t}`);let r=[...jL(n,e)].reverse().reduce(dt,n);return vl(r,t),r}function bl(n){Oe(n);let t=$L(n),e=t.find((a)=>il(a)),r=[];for(let a of t){if(!il(a))continue;try{let l=wL(a,"utf-8");if(!FL(vl(l,a)))continue;return B(a,zL(l,a)),{path:a,alreadyInstalled:!0}}catch(l){r.push(l instanceof Error?l.message:String(l))}}if(r.length>0)throw Error(r.join(`
201
- `));return{path:e??gL(n),alreadyInstalled:!1}}var Ee="safety-net@cc-marketplace",fl=new Set(["claude-code","codex","copilot-cli","gemini-cli","hermes-agent","openclaw","opencode","pi"]);function Pe(n){return/^\s*safety-net@cc-marketplace[^a-z0-9-][^\n]*installed,/m.test(n??"")}function wl(n){return/^\s*cc-safety-net[^a-z0-9-][^\n]*installed,/m.test(n??"")}function JL(n){return/^Marketplace `cc-marketplace`\s*$/m.test(n??"")}var xl={"claude-code":{installCommands:(n)=>{let t=Un(n,"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"]],...Le(n).status==="disabled"?[["claude","plugin","enable","cc-safety-net@cc-marketplace"]]:[]],cleanupCommands:Un(n,Ee)?[["claude","plugin","uninstall",Ee]]:[],update:t}},uninstallCommands:[["claude","plugin","uninstall","cc-safety-net@cc-marketplace"],["claude","plugin","marketplace","remove","cc-marketplace"]]},codex:{installCommands:()=>{let n=e2(["codex","plugin","list"]),t=wl(n);return{commands:[t||JL(n)?["codex","plugin","marketplace","upgrade","cc-marketplace"]:["codex","plugin","marketplace","add","kenryu42/cc-marketplace"],["codex","plugin","add","cc-safety-net@cc-marketplace"]],cleanupCommands:Pe(n)?[["codex","plugin","remove","safety-net@cc-marketplace"]]:[],update:t}},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:()=>{let n=e2(["copilot","plugin","list"]),t=[...Y1(n)?[["copilot","plugin","uninstall","copilot-safety-net"]]:[],...R1(n)?[["copilot","plugin","uninstall",Z1]]:[]];if(Q1(n))return{commands:[["copilot","plugin","marketplace","update","cc-marketplace"],["copilot","plugin","update",t2]],cleanupCommands:t,update:!0};return{commands:[X1(e2(["copilot","plugin","marketplace","list"]))?["copilot","plugin","marketplace","update","cc-marketplace"]:["copilot","plugin","marketplace","add","kenryu42/cc-marketplace"],["copilot","plugin","install",t2]],cleanupCommands:t}},uninstallCommands:[["copilot","plugin","uninstall","cc-safety-net@cc-marketplace"],["copilot","plugin","marketplace","remove","cc-marketplace"]]},"gemini-cli":{installCommands:(n)=>{let t=ye(n);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:Fe,installCommands:()=>({commands:y0()}),uninstallCommands:[["openclaw","plugins","uninstall",q,"--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(`
202
- `)},opencode:{beforeInstall:Oe,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 Ie(){return process.env.HOME??BL()}function ml(n,t=(e)=>e){try{let e=JSON.parse(t(yl(n,"utf-8")));if(!e||typeof e!=="object"||Array.isArray(e))throw Error(`Settings file ${n} must be a JSON object`);return e}catch(e){if(e instanceof SyntaxError)throw Error(`Failed to parse ${n}: ${e.message}`);throw e}}function SL(n){let t=Te(wn(n),"settings.json");if(!_e(t))return;let e=ml(t,M),r=e.enabledPlugins;if(!r||typeof r!=="object"||Array.isArray(r))return;if(r[t2]!==!1)return;let a=yl(t,"utf-8"),l=a.replace(new RegExp(`("${t2}"\\s*:\\s*)false`),"$1true");r[t2]=!0,B(t,l!==a?l:`${JSON.stringify(e,null,2)}
203
- `),console.log(`Enabled ${t2} plugin in ${t}`)}function ZL(n){let t=Be(n);if(!_e(t))return;let e=ml(t);if(!Array.isArray(e.packages))return;let r=e.packages.find((a)=>!!a&&typeof a==="object"&&!Array.isArray(a)&&Je(a.source)&&("extensions"in a));if(!r)return;delete r.extensions,B(t,`${JSON.stringify(e,null,2)}
204
- `),console.log(`Enabled npm:cc-safety-net extensions in ${t}`)}function hl(n,t){let e=j({label:t,booleans:Object.fromEntries(G.map((l)=>[l.target,[l.flag]]))},n),r=e.errors[0];if(r)throw Error(r);let a=G.filter((l)=>e.flags[l.target]).map((l)=>l.target);if(a.length!==1)throw Error(`Choose exactly one ${t} target: ${[...T0.keys()].join(", ")}`);return a[0]}async function gl(n=Ie()){let[t,e]=await Promise.all([Hn(["codex","plugin","list"],30000),Hn(["copilot","--binary-version"])]);return{codexPluginListOutput:t,hooks:P2(process.cwd(),{homeDir:n,codexPluginListOutput:t,copilotCliVersion:e})}}async function QL(n){let t=await gl();return t.hooks.filter((e)=>n==="install"?e.configured:e.detected||e.inspectionStatus==="not-inspected").filter((e)=>e.platform!=="codex"||!Pe(t.codexPluginListOutput)||wl(t.codexPluginListOutput)).map((e)=>e.platform)}function XL(n,t,e){if(t.length>0)return{finish:async()=>[hl(t,n)]};if(!e.selectTargets&&!M0(e.input,e.output))return{finish:async()=>[hl(t,n)]};let r=e.detectConfiguredTargets??(()=>QL(n)),a=Promise.all([P0(e.probeTargets),r()]);return{ready:a,finish:async()=>{let[l,d]=await a,s=I0(l,{action:n,configuredTargets:d}),c=e.selectTargets?await e.selectTargets(n,s):await W0(n,s,{input:e.input,output:e.output});if(c==="update")return c;if(!c||c.length===0)return null;return He(c)}}}function j2(n,t,e=!1){let r=xl[n];r.beforeInstall?.(t);let a=typeof r.installCommands==="function"?r.installCommands(t):{commands:r.installCommands};qe(a.commands),u0(a.cleanupCommands??[]),console.log([`${a.update||e?"Updated":"Installed"} ${m2(n)} integration`,r.postInstallMessage].filter(Boolean).join(`
205
- `))}function N2(n){let t=xl[n];if(!t.uninstallCommands)throw Error(`${m2(n)} uninstall is not supported`);qe(t.uninstallCommands),console.log(`Uninstalled ${m2(n)} integration`)}function YL(n){let t=bl(n);console.log(t.alreadyInstalled?`Uninstalled OpenCode plugin from ${t.path}`:`OpenCode plugin not installed in ${t.path}`)}var RL={"antigravity-cli":{install:U0,uninstall:O0},cursor:{install:O1,uninstall:T1},"kimi-code":{install:sl,uninstall:cl}};function nn(n,t,e,r=!1){if(n==="install")Ve(e);let a=RL[t][n](e),l=m2(t),d=n!=="install"?"Uninstalled":r?"Updated":"Installed";console.log(n==="install"&&a.alreadyInstalled?r?`${l} hook up to date in ${a.path}`:`${l} hook already installed in ${a.path}`:n==="uninstall"&&!a.alreadyInstalled?`${l} hook not installed in ${a.path}`:`${d} ${l} hook ${n==="install"?"in":"from"} ${a.path}`)}var AL={amp:{install:g1,uninstall:$1,restartNote:'Restart Amp or run "plugins: reload" to apply the change.'},"hermes-agent":{install:n0,uninstall:t0,afterInstall:(n)=>{let t=ke(n);return e2(["hermes","plugins","enable",V,"--no-allow-tool-override"]),!t},beforeUninstall:(n)=>{De(n);try{e2(["hermes","plugins","disable",V])}catch(t){console.warn(`${t instanceof Error?t.message:String(t)}
206
- Removing the plugin files anyway; ${V} may still be listed in the Hermes config.`)}},restartNote:"Restart Hermes to apply the change."}};function ct(n,t,e,r=!1){let a=AL[t];if(n==="uninstall")a.beforeUninstall?.(e);let l=n==="install"?a.install(e):a.uninstall(e),d=n==="install"&&a.afterInstall?.(e),s=m2(t),c=!d&&(n==="install"&&l.alreadyInstalled||n==="uninstall"&&!l.alreadyInstalled),L=c?n==="install"?`${s} plugin ${r?"up to date":"already installed"} at ${l.path}`:`${s} plugin not installed at ${l.path}`:`${n!=="install"?"Uninstalled":r?"Updated":"Installed"} ${s} plugin ${n==="install"?"at":"from"} ${l.path}`;console.log([L,c?void 0:a.restartNote].filter(Boolean).join(`
207
- `))}var HL={amp:{install:(n,t)=>ct("install","amp",n,t),uninstall:(n)=>ct("uninstall","amp",n)},"antigravity-cli":{install:(n,t)=>nn("install","antigravity-cli",n,t),uninstall:(n)=>nn("uninstall","antigravity-cli",n)},"claude-code":{install:(n,t)=>j2("claude-code",n,t),uninstall:()=>N2("claude-code")},codex:{install:(n,t)=>j2("codex",n,t),uninstall:()=>N2("codex")},"copilot-cli":{install:(n,t)=>{j2("copilot-cli",n,t),SL(n)},uninstall:()=>N2("copilot-cli")},cursor:{install:(n,t)=>nn("install","cursor",n,t),uninstall:(n)=>nn("uninstall","cursor",n)},"gemini-cli":{install:(n,t)=>j2("gemini-cli",n,t),uninstall:()=>N2("gemini-cli")},"hermes-agent":{install:(n,t)=>{Ve(n),ct("install","hermes-agent",n,t)},uninstall:(n)=>ct("uninstall","hermes-agent",n)},"kimi-code":{install:(n,t)=>nn("install","kimi-code",n,t),uninstall:(n)=>nn("uninstall","kimi-code",n)},openclaw:{install:(n,t)=>{j2("openclaw",n,t),w0()},uninstall:(n)=>{Fe(n),N2("openclaw")}},opencode:{install:(n,t)=>j2("opencode",n,t),uninstall:(n)=>YL(n)},pi:{install:(n,t)=>{j2("pi",n,t),ZL(n)},uninstall:()=>N2("pi")}};function $l(n,t,e,r=!1){HL[t][n](e,r)}function ML(n){let t=j({label:"update"},n).errors[0];if(t)throw Error(t)}async function WL(n){let t=await gl(n),e=Te(wn(n),"installed-plugins");return He([...t.hooks.filter((r)=>r.platform!=="copilot-cli"&&r.detected).map((r)=>r.platform),...[On,S1,J1].flatMap((r)=>_e(Te(e,...r))?["copilot-cli"]:[]),...Un(n,Ee)?["claude-code"]:[],...Pe(t.codexPluginListOutput)?["codex"]:[]])}async function VL(){let n=Ie(),t=await WL(n);if(t.length===0)return console.log("No installed integrations found. Run `cc-safety-net install` to set one up."),0;let e=new Set(t),r=new Map(await Promise.all(G.filter((l)=>e.has(l.target)&&fl.has(l.target)).map(async(l)=>[l.target,await We(l.probeCommand)])));return t.filter((l)=>{if(fl.has(l)&&!r.get(l))return console.log(`${m2(l)} not found; skipped`),!1;try{return $l("install",l,n,!0),!1}catch(d){return console.error(nr(d)),!0}}).length>0?1:0}function Ne(n){return Promise.resolve().then(()=>ML(n)).then(VL).catch((t)=>{return console.error(nr(t)),1})}async function qn(n,t,e={}){try{let r=await Vn(!0,()=>XL(n,t,e),()=>Wn({input:e.input??process.stdin,output:e.output??process.stdout}),{loadingMessage:n==="install"?"Checking available integrations…":"Checking installed integrations…",output:e.output??process.stdout});if(!r)return(e.output??process.stdout).write(`Cancelled: nothing was ${n}ed.
208
- `),0;if(r==="update")return(e.runUpdate??(()=>Ne([])))();let a=Ie();return E0(r,(l)=>$l(n,l,a)),0}catch(r){return console.error(nr(r)),1}}function nr(n){let t=n instanceof Error?n.message:String(n),e=typeof n==="object"&&n!==null&&"code"in n?n.code:null;if(e==="EACCES"||e==="EPERM")return`${t}
209
- Check file permissions for the target config file and parent directory.`;if(e==="ENOENT")return`${t}
210
- Check that the target config path and parent directory exist.`;if(e==="ENOTDIR")return`${t}
211
- Check that every parent path component is a directory.`;return t}import{join as jo}from"node:path";var Dl="# 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 jn(n,t){if(!n.ok){UL(n);return}OL(n),console.log(t),console.log("Rule config synced."),console.log(""),KL(n.entries)}function KL(n){if(n.length===0){console.log("Active rulebooks: (none)");return}console.log(`Active rulebooks (${n.length}):`);for(let t of n)console.log(` - ${t.name} ${t.version} (${CL(t.ruleCount??0)})`),console.log(` Source: ${Yt(t)}`)}function CL(n){return`${n} ${n===1?"rule":"rules"}`}function ql(n,t){F2("Active sources",n.rulebooks,(e)=>[`[${e.source}] ${e.name} ${e.version}`,` Source: ${t[e.source].get(e.spec)??e.spec}`]),F2("Active rules",n.rules,(e)=>[`[${GL(n,e.name)}] ${e.name}`,` Command: ${e.subcommand?`${e.command} ${e.subcommand}`:e.command}`,` Block args: ${e.block_args.join(", ")}`,` Reason: ${e.reason}`]),F2("Disabled rules",kl(n,"off"),(e)=>[e.key]),F2("Reason overrides",kl(n,"reason"),(e)=>[e.key,` Reason: ${e.value.reason}`]),F2("Transparent wrappers",n.transparent_wrappers,(e)=>[e]),F2("Issues",n.errors,(e)=>[e]),F2("Warnings",n.warnings,(e)=>[e])}function F2(n,t,e){if(t.length===0){console.log(`${n}: (none)`);return}console.log(`${n} (${t.length}):`);for(let r of t){let[a,...l]=e(r);console.log(` - ${a}`);for(let d of l)console.log(` ${d}`)}}function GL(n,t){return n.rulebooks.find((e)=>e.rules.includes(t))?.source??"project"}function kl(n,t){return Object.entries({...n.userConfig?.overrides??{},...n.projectConfig?.overrides??{}}).filter((e)=>{if(t==="off")return e[1]==="off";return!!e[1]&&typeof e[1]==="object"}).map(([e,r])=>({key:e,value:r}))}function UL(n){for(let t of n.errors)console.error(t)}function OL(n){if(!n.warnings||n.warnings.length===0)return;for(let t of n.warnings)console.warn(t)}import{dirname as jl,join as it}from"node:path";var TL=".safety-net.json",EL="~/.cc-safety-net/config.json";async function Bl(n){return[await Fl({legacyPath:zl({cwd:n.cwd}),configPath:E(n.cwd),defaultRulebookName:"project-rules",migratedFrom:TL,cleanup:n.cleanup,syncOptions:{cwd:n.cwd}}),await Fl({legacyPath:dn(),configPath:_(),defaultRulebookName:"user-rules",migratedFrom:EL,cleanup:n.cleanup,syncOptions:{cwd:n.cwd,global:!0}})].every((e)=>e)?0:1}async function Fl(n){let t=U(n.syncOptions),e=$(t.filesystemScope,n.legacyPath),r=m(e);if(r===null)return console.log(`No legacy config found at ${n.legacyPath}`),!0;let a=PL(r);if(!a.ok){for(let p of a.errors)console.error(p);return!1}let l=O(t.configTarget);if(l.errors.length>0){for(let p of l.errors)console.error(p);return!1}let d=l.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},s=IL(jl(n.configPath),d.rules,n.defaultRulebookName,n.migratedFrom,t.filesystemScope),c=it(jl(n.configPath),s,"rulebook.json"),i=$(t.filesystemScope,c),L=[tr(t.configTarget),tr(i),tr(t.lockTarget)],u=await _L(n,t.configTarget,i,s,a.config.rules,d.rules.includes(s)?d.rules:[...d.rules,s],d.overrides??{},d.transparent_wrappers??[]);if(!u.ok){to(L);for(let p of u.errors)console.error(p);return!1}if(!n.cleanup)return console.log(`Migrated legacy config at ${n.legacyPath}. Legacy file is no longer used.`),!0;if(!no(t.configTarget,i,s,n.migratedFrom,a.config.rules))return console.error(`Migration cleanup verification failed for ${n.legacyPath}`),!1;return an(e),console.log(`Deleted legacy config at ${n.legacyPath}`),!0}async function _L(n,t,e,r,a,l,d,s){try{return T(t,{version:1,rules:l,overrides:d,transparent_wrappers:s}),T(e,NL(r,n.migratedFrom,a)),await Y2(n.syncOptions)}catch(c){return{ok:!1,errors:[c instanceof Error?c.message:String(c)]}}}function PL(n){try{let t=JSON.parse(n),e=$t(t);if(e.errors.length>0)return{ok:!1,errors:e.errors};return{ok:!0,config:{version:1,rules:t.rules??[]}}}catch{return{ok:!1,errors:["Invalid JSON"]}}}function IL(n,t,e,r,a){let l=t.find((d)=>eo($(a,it(n,d,"rulebook.json")))===r);if(l)return l;if(m($(a,it(n,e,"rulebook.json")))===null)return e;for(let d=2;;d++){let s=`${e}-${d}`;if(m($(a,it(n,s,"rulebook.json")))===null)return s}}function NL(n,t,e){return{rulebook_version:1,name:n,version:"1.0.0",description:"Migrated CC Safety Net rules.",author:"project",migrated_from:t,allowed_commands:[...new Set(e.map((r)=>r.command))],rules:e,tests:e.map((r)=>({command:[r.command,r.subcommand,r.block_args[0]].filter(Boolean).join(" "),expect:"blocked",rule:r.name}))}}function no(n,t,e,r,a){if(!O(n).config?.rules.includes(e))return!1;try{let d=m(t);if(d===null)return!1;let s=JSON.parse(d);return s.migrated_from===r&&JSON.stringify(s.rules)===JSON.stringify(a)}catch{return!1}}function tr(n){return{target:n,content:m(n)}}function to(n){for(let t of n){if(t.content===null){an(t.target);continue}f2(t.target,t.content)}}function eo(n){let t=m(n);if(t===null)return null;try{let e=JSON.parse(t);return typeof e.migrated_from==="string"?e.migrated_from:null}catch{return null}}import{mkdir as ro,readFile as ao,writeFile as lo}from"node:fs/promises";import{dirname as so,join as co}from"node:path";var io=86400000,Lo=604800000;async function Sl(n=Date.now()){if(process.env.CC_SAFETY_NET_NO_UPDATE_CHECK)return null;let t=Ht();if(!t)return null;let e=co(t,".cc-safety-net","update-check.json"),r=await oo(e,n);if(!r.lastCheck||n-r.lastCheck>io){let d=await U2();if(r.lastCheck=n,d.latestVersion)r.latestVersion=d.latestVersion;if(!await Jl(e,r))return null;if(d.error)return null}let a=r.latestVersion,l=z();if(!a||!ae(a,l))return null;if(r.notifiedVersion===a&&r.notifiedAt!==void 0&&n-r.notifiedAt<Lo)return null;if(r.notifiedVersion=a,r.notifiedAt=n,!await Jl(e,r))return null;return`UPDATE_AVAILABLE: cc-safety-net v${a} is available (running v${l}). 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 oo(n,t){let e=await ao(n,"utf8").then((l)=>JSON.parse(l)).catch(()=>{return});if(!e||typeof e!=="object"||Array.isArray(e))return{};let r=e,a=(l)=>typeof l==="number"&&Number.isFinite(l)&&l<=t?l:void 0;return{lastCheck:a(r.lastCheck),latestVersion:typeof r.latestVersion==="string"?r.latestVersion:void 0,notifiedVersion:typeof r.notifiedVersion==="string"?r.notifiedVersion:void 0,notifiedAt:a(r.notifiedAt)}}async function Jl(n,t){return ro(so(n),{recursive:!0,mode:448}).then(()=>lo(n,JSON.stringify(t),{mode:384})).then(()=>!0).catch(()=>!1)}import{dirname as uo,join as po,resolve as er}from"node:path";var Ql="CC Safety Net Config",vo="═".repeat(Ql.length),bo="https://raw.githubusercontent.com/kenryu42/cc-safety-net/main/assets/cc-safety-net.schema.json",fo=new Set(["rule.json","rule.lock","cache"]);function Xl(n={}){try{return ho(n)}catch(t){if(t instanceof S)return console.error(t.message),1;throw t}}function ho(n){let t=n.cwd??process.cwd(),e=n.userConfigPath??_(),r=n.projectConfigPath??E(t),a=n.legacyUserConfigPath??dn(),l=n.legacyProjectConfigPath??kr(t),d=er(t,Xt),s=uo(e),c=P({cwd:t,userConfigPath:e,projectConfigPath:r}),i=P({cwd:t}),L=$(c.userScope,e),u=$(c.projectScope,r),p=n.legacyUserConfigPath?rn(n.legacyUserConfigPath,"user policy"):$(i.userScope,a),o=n.legacyProjectConfigPath?rn(n.legacyProjectConfigPath,"project policy"):$(i.projectScope,l),b=!1,v=!1,f=[],w=[],x=yo($(i.projectScope,d));if(xo(),m(L)!==null){let y=a2(L);if(y.errors.push(...l2(e,R2({userConfigDir:s}),{userConfigDir:s},c.userScope)),f.push({scope:"User",path:e,result:y,schema:"rules",sourceDisplayMap:h2(e,c.userScope),target:L}),y.errors.length>0)b=!0}if(m(p)!==null)if(v=!0,m(L)!==null)w.push(Lt("user","cleanup"));else{let y=Dt(p);if(f.push({scope:"User",path:a,result:y,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:p}),w.push(Lt("user",y.errors.length>0?"fix-or-delete":"migrate")),y.errors.length>0)b=!0}if(m(u)!==null){let y=a2(u);if(y.errors.push(...l2(r,A2(r),{userConfigDir:s},c.projectScope)),f.push({scope:"Project",path:er(r),result:y,schema:"rules",sourceDisplayMap:h2(r,c.projectScope),target:u}),y.errors.length>0)b=!0;if(m(o)!==null)v=!0,w.push(Lt("project","cleanup"))}else if(m(o)!==null){v=!0,b=!0;let y=Dt(o);f.push({scope:"Project",path:er(l),result:y,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:o}),w.push(Lt("project",y.errors.length>0?"fix-or-delete":"migrate"))}if(x?.result.errors.length)b=!0;if(f.length===0&&!x)return console.log(`
212
- No config files found. Using built-in rules only.`),0;for(let y of f)if(y.inactive)go(y.scope,y.path,y.result,y.sourceDisplayMap);else if(y.result.errors.length>0)$o(y.scope,y.path,y.result.errors);else{if(y.schema==="rules"&&qo(y.target))console.log(`
213
- Added $schema to ${y.scope.toLowerCase()} config.`);mo(y.scope,y.path,y.result,y.schema,y.sourceDisplayMap)}for(let y of w)console.error(`
214
- ${h.red(y)}`);if(x)if(x.result.errors.length>0)ko(x.path,x.result.errors);else Do(x.path,x.result);if(b)return console.error(`
215
- Config validation failed.`),1;return console.log(v?`
198
+ command = "${Jn}"`,te=`{ event = "PreToolUse", command = "${Jn}" }`;function ql(n){return Dl(process.env.KIMI_CODE_HOME??Dl(n,".kimi-code"),"config.toml")}function Ji(n){return n.split(`
199
+ `).reduce((r,e)=>{if(/^\s*\[/.test(e))return r.activeTable=!0,r.lines.push(e),r;if(!r.activeTable&&/^\s*hooks\s*=\s*\[\s*]\s*(?:#.*)?$/.test(e))return r;return r.lines.push(e),r},{activeTable:!1,lines:[]}).lines.join(`
200
+ `)}function Zi(n,t){if(n[t]!=="#")return t;let r=n.indexOf(`
201
+ `,t+1);return r===-1?n.length:r+1}function Qi(n,t){return ut(n,t,{skipComment:Zi,stringError:"Unterminated string in Kimi Code config",bracketError:"Unmatched hooks array in Kimi Code config"})}function jl(n){let t=!1,r=0;while(r<n.length){let e=n.indexOf(`
202
+ `,r),a=e===-1?n.length:e,l=n.slice(r,a);if(/^\s*\[/.test(l))t=!0;if(!t){let d=/^(\s*)hooks\s*=\s*\[/.exec(l);if(d){let s=r+d[0].lastIndexOf("[");return{start:s,end:Qi(n,s)}}}r=e===-1?n.length:e+1}return}function Xi(n,t){let r=n.slice(0,t.end).trimEnd(),e=gl(n,t.end),a=e===""?" ":`${e} `,l=!r.endsWith("[")&&!r.endsWith(",");return`${r}${l?",":""}
203
+ ${a}${te}${n.slice(t.end)}`}function Yi(n){let t=jl(n);if(t&&n.slice(t.start+1,t.end).trim())return Xi(n,t);let r=Ji(n).trimEnd();if(r==="")return`${ne}
204
+ `;return`${r}
205
+
206
+ ${ne}
207
+ `}function Si(n){return n.split(/(?=^\s*\[)/m).filter((r)=>!/^\s*\[\[hooks]]\s*$/m.test(r)||!r.includes(Jn)).join("").trimEnd()}function Hi(n,t){let r=n.indexOf(te,t.start);if(r===-1||r>t.end)return n;return ot(n,{start:r,end:r+te.length})}function Fl(n){let t=ql(n);if(zi(Bi(t),{recursive:!0}),!ml(t))return B(t,`${ne}
208
+ `),{path:t,alreadyInstalled:!1};let r=kl(t,"utf-8");if(r.includes(Jn))return{path:t,alreadyInstalled:!0};return B(t,Yi(r)),{path:t,alreadyInstalled:!1}}function zl(n){let t=ql(n);if(!ml(t))return{path:t,alreadyInstalled:!1};let r=kl(t,"utf-8");if(!r.includes(Jn))return{path:t,alreadyInstalled:!1};let e=jl(r),a=e?Hi(r,e):`${Si(r)}
209
+ `;return B(t,a),{path:t,alreadyInstalled:!0}}import{existsSync as Bl,readFileSync as Ai,rmSync as Wi}from"node:fs";import{join as re}from"node:path";var ee="cc-safety-net",Ri=`${ee}@latest`,Zl=["opencode.json","opencode.jsonc"];function Vi(n){return re(n,".config","opencode",Zl[0])}function Ki(n){return Zl.map((t)=>re(n,".config","opencode",t))}function Mi(n){return re(n,".cache","opencode","packages",Ri)}function ae(n){Wi(Mi(n),{recursive:!0,force:!0})}function vt(n,t){if(n[t]==="/"&&n[t+1]==="/"){let r=n.indexOf(`
210
+ `,t+2);return r===-1?n.length:r+1}if(n[t]==="/"&&n[t+1]==="*"){let r=n.indexOf("*/",t+2);return r===-1?n.length:r+2}return t}function Jl(n,t){let r=t;while(r<n.length){if(/\s/.test(n[r]??"")){r++;continue}let e=vt(n,r);if(e===r)return r;r=e}return r}function Ql(n,t){let r=t+1,e=!1;while(r<n.length){if(e){e=!1,r++;continue}if(n[r]==="\\"){e=!0,r++;continue}if(n[r]==='"')return r+1;r++}throw Error("Unterminated string in OpenCode config")}function Xl(n,t,r){return JSON.parse(n.slice(t,r))}function Gi(n,t){return ut(n,t,{skipComment:vt,stringError:"Unterminated string in OpenCode config",bracketError:"Unmatched plugin array in OpenCode config"})}function Ci(n){let t=0,r=0;while(r<n.length){let e=vt(n,r);if(e!==r){r=e;continue}if(n[r]==='"'){let a=Ql(n,r);if(t===1&&Xl(n,r,a)==="plugin"){let l=Jl(n,a),d=Jl(n,l+1);if(n[l]===":"&&n[d]==="[")return{start:d,end:Gi(n,d)}}r=a;continue}if(n[r]==="{"||n[r]==="[")t++;if(n[r]==="}"||n[r]==="]")t--;r++}return}function Ui(n,t){let r=[],e=t.start+1;while(e<t.end){let a=vt(n,e);if(a!==e){e=a;continue}if(n[e]==='"'){let l=Ql(n,e),d=Xl(n,e,l);if(typeof d==="string"&&d.includes(ee))r.push({start:e,end:l});e=l;continue}e++}return r}function Yl(n,t){try{return JSON.parse(R(n))}catch(r){if(r instanceof SyntaxError)throw Error(`Failed to parse OpenCode config ${t}: ${r.message}`);throw r}}function Oi(n){if(!n||typeof n!=="object"||Array.isArray(n))return!1;let t=n.plugin;if(!Array.isArray(t))return!1;return t.some((r)=>typeof r==="string"&&r.includes(ee))}function Ti(n,t){let r=Ci(n);if(!r)throw Error(`Failed to locate OpenCode plugin array in ${t}`);let e=[...Ui(n,r)].reverse().reduce(ot,n);return Yl(e,t),e}function Sl(n){ae(n);let t=Ki(n),r=t.find((a)=>Bl(a)),e=[];for(let a of t){if(!Bl(a))continue;try{let l=Ai(a,"utf-8");if(!Oi(Yl(l,a)))continue;return B(a,Ti(l,a)),{path:a,alreadyInstalled:!0}}catch(l){e.push(l instanceof Error?l.message:String(l))}}if(e.length>0)throw Error(e.join(`
211
+ `));return{path:r??Vi(n),alreadyInstalled:!1}}var de="safety-net@cc-marketplace",Hl=new Set(["claude-code","codex","copilot-cli","gemini-cli","hermes-agent","openclaw","opencode","pi"]);function ce(n){return/^\s*safety-net@cc-marketplace[^a-z0-9-][^\n]*installed,/m.test(n??"")}function Kl(n){return/^\s*cc-safety-net[^a-z0-9-][^\n]*installed,/m.test(n??"")}function _i(n){return/^Marketplace `cc-marketplace`\s*$/m.test(n??"")}var Ml={"claude-code":{installCommands:(n)=>{let t=_n(n,"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"]],...fr(n).status==="disabled"?[["claude","plugin","enable","cc-safety-net@cc-marketplace"]]:[]],cleanupCommands:_n(n,de)?[["claude","plugin","uninstall",de]]:[],update:t}},uninstallCommands:[["claude","plugin","uninstall","cc-safety-net@cc-marketplace"],["claude","plugin","marketplace","remove","cc-marketplace"]]},codex:{installCommands:async()=>{let n=await r2(["codex","plugin","list"]),t=Kl(n);return{commands:[t||_i(n)?["codex","plugin","marketplace","upgrade","cc-marketplace"]:["codex","plugin","marketplace","add","kenryu42/cc-marketplace"],["codex","plugin","add","cc-safety-net@cc-marketplace"]],cleanupCommands:ce(n)?[["codex","plugin","remove","safety-net@cc-marketplace"]]:[],update:t}},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 n=await r2(["copilot","plugin","list"]),t=[...Ra(n)?[["copilot","plugin","uninstall","copilot-safety-net"]]:[],...Va(n)?[["copilot","plugin","uninstall",Ha]]:[]];if(Aa(n))return{commands:[["copilot","plugin","marketplace","update","cc-marketplace"],["copilot","plugin","update",t2]],cleanupCommands:t,update:!0};return{commands:[Wa(await r2(["copilot","plugin","marketplace","list"]))?["copilot","plugin","marketplace","update","cc-marketplace"]:["copilot","plugin","marketplace","add","kenryu42/cc-marketplace"],["copilot","plugin","install",t2]],cleanupCommands:t}},uninstallCommands:[["copilot","plugin","uninstall","cc-safety-net@cc-marketplace"],["copilot","plugin","marketplace","remove","cc-marketplace"]]},"gemini-cli":{installCommands:(n)=>{let t=mr(n);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:Sr,installCommands:()=>({commands:x0()}),uninstallCommands:[["openclaw","plugins","uninstall",q,"--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(`
212
+ `)},opencode:{beforeInstall:ae,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 Le(){return process.env.HOME??Ei()}function Gl(n,t=(r)=>r){try{let r=JSON.parse(t(Vl(n,"utf-8")));if(!r||typeof r!=="object"||Array.isArray(r))throw Error(`Settings file ${n} must be a JSON object`);return r}catch(r){if(r instanceof SyntaxError)throw Error(`Failed to parse ${n}: ${r.message}`);throw r}}function Pi(n){let t=le(Dn(n),"settings.json");if(!se(t))return;let r=Gl(t,R),e=r.enabledPlugins;if(!e||typeof e!=="object"||Array.isArray(e))return;if(e[t2]!==!1)return;let a=Vl(t,"utf-8"),l=a.replace(new RegExp(`("${t2}"\\s*:\\s*)false`),"$1true");return e[t2]=!0,B(t,l!==a?l:`${JSON.stringify(r,null,2)}
213
+ `),`Enabled ${t2} plugin in ${t}`}function Ni(n){let t=Ar(n);if(!se(t))return;let r=Gl(t);if(!Array.isArray(r.packages))return;let e=r.packages.find((a)=>!!a&&typeof a==="object"&&!Array.isArray(a)&&Wr(a.source)&&("extensions"in a));if(!e)return;return delete e.extensions,B(t,`${JSON.stringify(r,null,2)}
214
+ `),`Enabled npm:cc-safety-net extensions in ${t}`}function Al(n,t){let r=F({label:t,booleans:Object.fromEntries(C.map((l)=>[l.target,[l.flag]]))},n),e=r.errors[0];if(e)throw Error(e);let a=C.filter((l)=>r.flags[l.target]).map((l)=>l.target);if(a.length!==1)throw Error(`Choose exactly one ${t} target: ${[...bl.keys()].join(", ")}`);return a[0]}async function Cl(n=Le()){let[t,r,e]=await Promise.all([wn(["amp","plugins","list"],30000),wn(["codex","plugin","list"],30000),wn(["copilot","--binary-version"])]);return{codexPluginListOutput:r,hooks:nn(process.cwd(),{homeDir:n,ampPluginListOutput:t,codexPluginListOutput:r,copilotCliVersion:e})}}async function Ii(n){let t=await Cl();return t.hooks.filter((r)=>n==="install"?r.configured:r.detected||r.inspectionStatus==="not-inspected").filter((r)=>r.platform!=="codex"||!ce(t.codexPluginListOutput)||Kl(t.codexPluginListOutput)).map((r)=>r.platform)}function n5(n,t,r){if(t.length>0)return{finish:async()=>[Al(t,n)]};if(!r.selectTargets&&!Ur(r.input,r.output))return{finish:async()=>[Al(t,n)]};let e=r.detectConfiguredTargets??(()=>Ii(n)),a=Promise.all([hl(r.probeTargets),e()]);return{ready:a,finish:async()=>{let[l,d]=await a,s=wl(l,{action:n,configuredTargets:d}),c=r.selectTargets?await r.selectTargets(n,Rl(n,s)):await E0(n,Rl(n,s),{input:r.input,output:r.output});if(c==="update")return c;if(!c||c.length===0)return null;return _r(c)}}}async function B2(n,t,r=!1){let e=Ml[n];e.beforeInstall?.(t);let a=typeof e.installCommands==="function"?await e.installCommands(t):{commands:e.installCommands};return await Xr(a.commands),await v0(a.cleanupCommands??[]),[`${a.update||r?"Updated":"Installed"} ${b2(n)} integration`,e.postInstallMessage].filter(Boolean).join(`
215
+ `)}async function rn(n){let t=Ml[n];if(!t.uninstallCommands)throw Error(`${b2(n)} uninstall is not supported`);return await Xr(t.uninstallCommands),`Uninstalled ${b2(n)} integration`}function t5(n){let t=Sl(n);return t.alreadyInstalled?`Uninstalled OpenCode plugin from ${t.path}`:`OpenCode plugin not installed in ${t.path}`}var r5={"antigravity-cli":{install:ol,uninstall:vl},cursor:{install:Pa,uninstall:Na},"kimi-code":{install:Fl,uninstall:zl}};function en(n,t,r,e=!1){if(n==="install")Ir(r);let a=r5[t][n](r),l=b2(t),d=n!=="install"?"Uninstalled":e?"Updated":"Installed";return n==="install"&&a.alreadyInstalled?e?`${l} hook up to date in ${a.path}`:`${l} hook already installed in ${a.path}`:n==="uninstall"&&!a.alreadyInstalled?`${l} hook not installed in ${a.path}`:`${d} ${l} hook ${n==="install"?"in":"from"} ${a.path}`}var e5={amp:{install:sl,uninstall:cl,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:a0,uninstall:l0,afterInstall:async(n)=>{let t=Jr(n);return await r2(["hermes","plugins","enable",K,"--no-allow-tool-override"]),!t},beforeUninstall:async(n)=>{Br(n);try{await r2(["hermes","plugins","disable",K])}catch(t){console.warn(`${t instanceof Error?t.message:String(t)}
216
+ Removing the plugin files anyway; ${K} may still be listed in the Hermes config.`)}},restartNote:"Restart Hermes to apply the change."}};async function bt(n,t,r,e=!1){let a=e5[t];if(n==="uninstall")await a.beforeUninstall?.(r);let l=n==="install"?await a.install(r):await a.uninstall(r),d=n==="install"&&await a.afterInstall?.(r),s=b2(t),c=!d&&(n==="install"&&l.alreadyInstalled||n==="uninstall"&&!l.alreadyInstalled);return[c?n==="install"?`${s} plugin ${e?"up to date":"already installed"} at ${l.path}`:`${s} plugin not installed at ${l.path}`:`${n!=="install"?"Uninstalled":e?"Updated":"Installed"} ${s} plugin ${n==="install"?"at":"from"} ${l.path}`,c?void 0:a.restartNote].filter(Boolean).join(`
217
+ `)}var a5={amp:{install:(n,t)=>bt("install","amp",n,t),uninstall:(n)=>bt("uninstall","amp",n)},"antigravity-cli":{install:(n,t)=>en("install","antigravity-cli",n,t),uninstall:(n)=>en("uninstall","antigravity-cli",n)},"claude-code":{install:(n,t)=>B2("claude-code",n,t),uninstall:()=>rn("claude-code")},codex:{install:(n,t)=>B2("codex",n,t),uninstall:()=>rn("codex")},"copilot-cli":{install:async(n,t)=>[await B2("copilot-cli",n,t),Pi(n)].filter(Boolean).join(`
218
+ `),uninstall:()=>rn("copilot-cli")},cursor:{install:(n,t)=>en("install","cursor",n,t),uninstall:(n)=>en("uninstall","cursor",n)},"gemini-cli":{install:(n,t)=>B2("gemini-cli",n,t),uninstall:()=>rn("gemini-cli")},"hermes-agent":{install:(n,t)=>{return Ir(n),bt("install","hermes-agent",n,t)},uninstall:(n)=>bt("uninstall","hermes-agent",n)},"kimi-code":{install:(n,t)=>en("install","kimi-code",n,t),uninstall:(n)=>en("uninstall","kimi-code",n)},openclaw:{install:async(n,t)=>{let r=await B2("openclaw",n,t);return await $0(),r},uninstall:(n)=>{return Sr(n),rn("openclaw")}},opencode:{install:(n,t)=>B2("opencode",n,t),uninstall:(n)=>t5(n)},pi:{install:async(n,t)=>[await B2("pi",n,t),Ni(n)].filter(Boolean).join(`
219
+ `),uninstall:()=>rn("pi")}},Wl=["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(`
220
+ `);function l5(n){if(qn({homeDir:n,cwd:process.cwd()}).status!=="configured")return Wl;return[Wl,"",b.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(`
221
+ `))].join(`
222
+ `)}function Rl(n,t){return t.map((r)=>n==="install"&&r.target==="kimi-code"&&r.unavailableReason==="already installed"?{...r,available:!0,unavailableReason:void 0,label:`${r.label} (global hook installed)`}:r)}function d5(n,t){if(n.selectKimiInstallMethod)return n.selectKimiInstallMethod();if(!Ur(n.input,n.output))return Promise.resolve("global-hook");return T0({input:n.input,output:n.output,globalHookInstalled:qn({homeDir:t,cwd:process.cwd()}).status==="configured"})}async function Ul(n,t,r,e=!1){return a5[t][n](r,e)}function s5(n){let t=F({label:"update"},n).errors[0];if(t)throw Error(t)}async function c5(n){let t=await Cl(n),r=le(Dn(n),"installed-plugins");return _r([...t.hooks.filter((e)=>e.platform!=="copilot-cli"&&e.detected).map((e)=>e.platform),...[Pn,Sa,Ya].flatMap((e)=>se(le(r,...e))?["copilot-cli"]:[]),..._n(n,de)?["claude-code"]:[],...ce(t.codexPluginListOutput)?["codex"]:[]])}async function L5(){let n=Le(),t=await c5(n);if(t.length===0)return console.log("No installed integrations found. Run `cc-safety-net install` to set one up."),0;let r=new Set(t),e=new Map(await Promise.all(C.filter((l)=>r.has(l.target)&&Hl.has(l.target)).map(async(l)=>[l.target,await Nr(l.probeCommand)]))),a=[];for(let l of t){if(Hl.has(l)&&!e.get(l)){console.log(`${b2(l)} not found; skipped`);continue}try{console.log(await Ul("install",l,n,!0))}catch(d){console.error(pe(d)),a.push(l)}}return a.length>0?1:0}function ie(n){return Promise.resolve().then(()=>s5(n)).then(L5).catch((t)=>{return console.error(pe(t)),1})}async function Zn(n,t,r={}){try{let e=await On(!0,()=>n5(n,t,r),()=>Un({input:r.input??process.stdin,output:r.output??process.stdout}),{loadingMessage:n==="install"?"Checking available integrations…":"Checking installed integrations…",output:r.output??process.stdout});if(!e)return(r.output??process.stdout).write(`Cancelled: nothing was ${n}ed.
223
+ `),0;if(e==="update")return(r.runUpdate??(()=>ie([])))();let a=Le(),l=r.output??process.stdout;return await fl(e,async(d)=>{if(d==="kimi-code"&&n==="install"){let c=await d5(r,a);if(c===null){l.write(`Cancelled: Kimi Code integration was not installed.
224
+ `);return}if(c==="plugin"){l.write(`${l5(a)}
225
+ `);return}}let s=await vr(Ul(n,d,a),{loadingMessage:`${n==="install"?"Installing":"Uninstalling"} ${b2(d)} integration…`,output:l});l.write(`${s}
226
+ `)}),0}catch(e){return console.error(pe(e)),1}}function pe(n){let t=n instanceof Error?n.message:String(n),r=typeof n==="object"&&n!==null&&"code"in n?n.code:null;if(r==="EACCES"||r==="EPERM")return`${t}
227
+ Check file permissions for the target config file and parent directory.`;if(r==="ENOENT")return`${t}
228
+ Check that the target config path and parent directory exist.`;if(r==="ENOTDIR")return`${t}
229
+ Check that every parent path component is a directory.`;return t}import{join as O5}from"node:path";var Ol="# 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 Qn(n,t){if(!n.ok){o5(n);return}v5(n),console.log(t),console.log("Rule config synced."),console.log(""),i5(n.entries)}function i5(n){if(n.length===0){console.log("Active rulebooks: (none)");return}console.log(`Active rulebooks (${n.length}):`);for(let t of n)console.log(` - ${t.name} ${t.version} (${p5(t.ruleCount??0)})`),console.log(` Source: ${Mt(t)}`)}function p5(n){return`${n} ${n===1?"rule":"rules"}`}function El(n,t){J2("Active sources",n.rulebooks,(r)=>[`[${r.source}] ${r.name} ${r.version}`,` Source: ${t[r.source].get(r.spec)??r.spec}`]),J2("Active rules",n.rules,(r)=>[`[${u5(n,r.name)}] ${r.name}`,` Command: ${r.subcommand?`${r.command} ${r.subcommand}`:r.command}`,` Block args: ${r.block_args.join(", ")}`,` Reason: ${r.reason}`]),J2("Disabled rules",Tl(n,"off"),(r)=>[r.key]),J2("Reason overrides",Tl(n,"reason"),(r)=>[r.key,` Reason: ${r.value.reason}`]),J2("Transparent wrappers",n.transparent_wrappers,(r)=>[r]),J2("Issues",n.errors,(r)=>[r]),J2("Warnings",n.warnings,(r)=>[r])}function J2(n,t,r){if(t.length===0){console.log(`${n}: (none)`);return}console.log(`${n} (${t.length}):`);for(let e of t){let[a,...l]=r(e);console.log(` - ${a}`);for(let d of l)console.log(` ${d}`)}}function u5(n,t){return n.rulebooks.find((r)=>r.rules.includes(t))?.source??"project"}function Tl(n,t){return Object.entries({...n.userConfig?.overrides??{},...n.projectConfig?.overrides??{}}).filter((r)=>{if(t==="off")return r[1]==="off";return!!r[1]&&typeof r[1]==="object"}).map(([r,e])=>({key:r,value:e}))}function o5(n){for(let t of n.errors)console.error(t)}function v5(n){if(!n.warnings||n.warnings.length===0)return;for(let t of n.warnings)console.warn(t)}import{dirname as _l,join as ft}from"node:path";var b5=".safety-net.json",f5="~/.cc-safety-net/config.json";async function Il(n){return[await Pl({legacyPath:Nl({cwd:n.cwd}),configPath:E(n.cwd),defaultRulebookName:"project-rules",migratedFrom:b5,cleanup:n.cleanup,syncOptions:{cwd:n.cwd}}),await Pl({legacyPath:Ln(),configPath:_(),defaultRulebookName:"user-rules",migratedFrom:f5,cleanup:n.cleanup,syncOptions:{cwd:n.cwd,global:!0}})].every((r)=>r)?0:1}async function Pl(n){let t=U(n.syncOptions),r=D(t.filesystemScope,n.legacyPath),e=g(r);if(e===null)return console.log(`No legacy config found at ${n.legacyPath}`),!0;let a=h5(e);if(!a.ok){for(let v of a.errors)console.error(v);return!1}let l=O(t.configTarget);if(l.errors.length>0){for(let v of l.errors)console.error(v);return!1}let d=l.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},s=w5(_l(n.configPath),d.rules,n.defaultRulebookName,n.migratedFrom,t.filesystemScope),c=ft(_l(n.configPath),s,"rulebook.json"),L=D(t.filesystemScope,c),i=[ue(t.configTarget),ue(L),ue(t.lockTarget)],u=await y5(n,t.configTarget,L,s,a.config.rules,d.rules.includes(s)?d.rules:[...d.rules,s],d.overrides??{},d.transparent_wrappers??[]);if(!u.ok){g5(i);for(let v of u.errors)console.error(v);return!1}if(!n.cleanup)return console.log(`Migrated legacy config at ${n.legacyPath}. Legacy file is no longer used.`),!0;if(!$5(t.configTarget,L,s,n.migratedFrom,a.config.rules))return console.error(`Migration cleanup verification failed for ${n.legacyPath}`),!1;return sn(r),console.log(`Deleted legacy config at ${n.legacyPath}`),!0}async function y5(n,t,r,e,a,l,d,s){try{return T(t,{version:1,rules:l,overrides:d,transparent_wrappers:s}),T(r,x5(e,n.migratedFrom,a)),await W2(n.syncOptions)}catch(c){return{ok:!1,errors:[c instanceof Error?c.message:String(c)]}}}function h5(n){try{let t=JSON.parse(n),r=Bt(t);if(r.errors.length>0)return{ok:!1,errors:r.errors};return{ok:!0,config:{version:1,rules:t.rules??[]}}}catch{return{ok:!1,errors:["Invalid JSON"]}}}function w5(n,t,r,e,a){let l=t.find((d)=>D5(D(a,ft(n,d,"rulebook.json")))===e);if(l)return l;if(g(D(a,ft(n,r,"rulebook.json")))===null)return r;for(let d=2;;d++){let s=`${r}-${d}`;if(g(D(a,ft(n,s,"rulebook.json")))===null)return s}}function x5(n,t,r){return{rulebook_version:1,name:n,version:"1.0.0",description:"Migrated CC Safety Net rules.",author:"project",migrated_from:t,allowed_commands:[...new Set(r.map((e)=>e.command))],rules:r,tests:r.map((e)=>({command:[e.command,e.subcommand,e.block_args[0]].filter(Boolean).join(" "),expect:"blocked",rule:e.name}))}}function $5(n,t,r,e,a){if(!O(n).config?.rules.includes(r))return!1;try{let d=g(t);if(d===null)return!1;let s=JSON.parse(d);return s.migrated_from===e&&JSON.stringify(s.rules)===JSON.stringify(a)}catch{return!1}}function ue(n){return{target:n,content:g(n)}}function g5(n){for(let t of n){if(t.content===null){sn(t.target);continue}w2(t.target,t.content)}}function D5(n){let t=g(n);if(t===null)return null;try{let r=JSON.parse(t);return typeof r.migrated_from==="string"?r.migrated_from:null}catch{return null}}import{mkdir as m5,readFile as k5,writeFile as q5}from"node:fs/promises";import{dirname as j5,join as F5}from"node:path";var z5=86400000,B5=604800000;async function t3(n=Date.now()){if(process.env.CC_SAFETY_NET_NO_UPDATE_CHECK)return null;let t=Ut();if(!t)return null;let r=F5(t,".cc-safety-net","update-check.json"),e=await J5(r,n);if(!e.lastCheck||n-e.lastCheck>z5){let d=await E2();if(e.lastCheck=n,d.latestVersion)e.latestVersion=d.latestVersion;if(!await n3(r,e))return null;if(d.error)return null}let a=e.latestVersion,l=j();if(!a||!ir(a,l))return null;if(e.notifiedVersion===a&&e.notifiedAt!==void 0&&n-e.notifiedAt<B5)return null;if(e.notifiedVersion=a,e.notifiedAt=n,!await n3(r,e))return null;return`UPDATE_AVAILABLE: cc-safety-net v${a} is available (running v${l}). 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 J5(n,t){let r=await k5(n,"utf8").then((l)=>JSON.parse(l)).catch(()=>{return});if(!r||typeof r!=="object"||Array.isArray(r))return{};let e=r,a=(l)=>typeof l==="number"&&Number.isFinite(l)&&l<=t?l:void 0;return{lastCheck:a(e.lastCheck),latestVersion:typeof e.latestVersion==="string"?e.latestVersion:void 0,notifiedVersion:typeof e.notifiedVersion==="string"?e.notifiedVersion:void 0,notifiedAt:a(e.notifiedAt)}}async function n3(n,t){return m5(j5(n),{recursive:!0,mode:448}).then(()=>q5(n,JSON.stringify(t),{mode:384})).then(()=>!0).catch(()=>!1)}import{dirname as Z5,join as Q5,resolve as oe}from"node:path";var e3="CC Safety Net Config",X5="═".repeat(e3.length),Y5="https://raw.githubusercontent.com/kenryu42/cc-safety-net/main/assets/cc-safety-net.schema.json",S5=new Set(["rule.json","rule.lock","cache"]);function a3(n={}){try{return H5(n)}catch(t){if(t instanceof Z)return console.error(t.message),1;throw t}}function H5(n){let t=n.cwd??process.cwd(),r=n.userConfigPath??_(),e=n.projectConfigPath??E(t),a=n.legacyUserConfigPath??Ln(),l=n.legacyProjectConfigPath??Se(t),d=oe(t,Kt),s=Z5(r),c=P({cwd:t,userConfigPath:r,projectConfigPath:e}),L=P({cwd:t}),i=D(c.userScope,r),u=D(c.projectScope,e),v=n.legacyUserConfigPath?dn(n.legacyUserConfigPath,"user policy"):D(L.userScope,a),p=n.legacyProjectConfigPath?dn(n.legacyProjectConfigPath,"project policy"):D(L.projectScope,l),f=!1,o=!1,y=[],x=[],w=A5(D(L.projectScope,d));if(R5(),g(i)!==null){let h=a2(i);if(h.errors.push(...l2(r,R2({userConfigDir:s}),{userConfigDir:s},c.userScope)),y.push({scope:"User",path:r,result:h,schema:"rules",sourceDisplayMap:x2(r,c.userScope),target:i}),h.errors.length>0)f=!0}if(g(v)!==null)if(o=!0,g(i)!==null)x.push(yt("user","cleanup"));else{let h=Jt(v);if(y.push({scope:"User",path:a,result:h,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:v}),x.push(yt("user",h.errors.length>0?"fix-or-delete":"migrate")),h.errors.length>0)f=!0}if(g(u)!==null){let h=a2(u);if(h.errors.push(...l2(e,V2(e),{userConfigDir:s},c.projectScope)),y.push({scope:"Project",path:oe(e),result:h,schema:"rules",sourceDisplayMap:x2(e,c.projectScope),target:u}),h.errors.length>0)f=!0;if(g(p)!==null)o=!0,x.push(yt("project","cleanup"))}else if(g(p)!==null){o=!0,f=!0;let h=Jt(p);y.push({scope:"Project",path:oe(l),result:h,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:p}),x.push(yt("project",h.errors.length>0?"fix-or-delete":"migrate"))}if(w?.result.errors.length)f=!0;if(y.length===0&&!w)return console.log(`
230
+ No config files found. Using built-in rules only.`),0;for(let h of y)if(h.inactive)K5(h.scope,h.path,h.result,h.sourceDisplayMap);else if(h.result.errors.length>0)M5(h.scope,h.path,h.result.errors);else{if(h.schema==="rules"&&U5(h.target))console.log(`
231
+ Added $schema to ${h.scope.toLowerCase()} config.`);V5(h.scope,h.path,h.result,h.schema,h.sourceDisplayMap)}for(let h of x)console.error(`
232
+ ${b.red(h)}`);if(w)if(w.result.errors.length>0)C5(w.path,w.result.errors);else G5(w.path,w.result);if(f)return console.error(`
233
+ Config validation failed.`),1;return console.log(o?`
216
234
  Configs valid with warnings.`:`
217
- All configs valid.`),0}function Lt(n,t){let e=`legacy ${n} config`;if(t==="cleanup")return`Warning: Legacy ${n} 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 ${n} config is ignored by CC Safety Net. Run \`npx -y cc-safety-net rule migrate\`.`;return`Warning: Legacy ${n} config is no longer supported. Fix or delete the ${e}, then run \`npx -y cc-safety-net rule migrate\`.`}function yo(n){if(X2(n)===null)return null;let t=wo(n);if(t.ruleNames.size===0&&t.errors.length===0)return null;return{path:n.path,result:t}}function wo(n){let t=[],e=new Set,r=(X2(n)??[]).filter((a)=>!fo.has(a.name)).sort((a,l)=>a.name.localeCompare(l.name));if(r.length===0)return{errors:t,ruleNames:e};for(let a of r){if(!ln.test(a.name)){t.push(`rulebook directory names must match ${ln}: ${a.name}`);continue}if(a.kind!=="directory"){t.push(`${a.name} must be a rulebook directory`);continue}let l=$(n.scope,po(n.path,a.name,"rulebook.json")),d=m(l);if(d===null){t.push(`${a.name}/rulebook.json is required`);continue}try{let s;try{s=JSON.parse(d)}catch{t.push(`${a.name}/rulebook.json: invalid JSON`);continue}let c=Zl(s);if(c.name!==a.name){t.push(`rulebook name "${c.name}" must match folder "${a.name}"`);continue}e.add(a.name)}catch(s){t.push(s instanceof Error?`${a.name}/rulebook.json: ${s.message}`:`${a.name}/rulebook.json: ${String(s)}`)}}return{errors:t,ruleNames:e}}function xo(){console.log(Ql),console.log(vo)}function mo(n,t,e,r,a){if(console.log(`
218
- ✓ ${n} config: ${t}`),console.log(` Schema: ${r==="rules"?"rulebook sources":"legacy inline rules"}`),e.ruleNames.size>0){console.log(` ${r==="rules"?"Sources":"Rules"}:`);let l=1;for(let d of e.ruleNames)console.log(` ${l}. ${a.get(d)??d}`),l++}else console.log(` ${r==="rules"?"Sources":"Rules"}: (none)`)}function go(n,t,e,r){if(console.error(`
219
- ✗ Legacy ${n.toLowerCase()} config: ${t}`),console.error(" Schema: legacy inline rules"),console.error(" Status: ignored by CC Safety Net"),e.errors.length>0){console.error(" Errors:");let a=1;for(let l of e.errors)for(let d of l.split("; "))console.error(` ${a}. ${d}`),a++;return}if(e.ruleNames.size>0){console.error(" Rules:");let a=1;for(let l of e.ruleNames)console.error(` ${a}. ${r.get(l)??l}`),a++;return}console.error(" Rules: (none)")}function $o(n,t,e){Yl(`${n} config`,t,e)}function Do(n,t){console.log(`
220
- ✓ GitHub source rules: ${n}`),console.log(" Rulebooks:");let e=1;for(let r of t.ruleNames)console.log(` ${e}. ${r}`),e++}function ko(n,t){Yl("GitHub source rules",n,t)}function Yl(n,t,e){console.error(`
221
- ✗ ${n}: ${t}`),console.error(" Errors:");let r=1;for(let a of e)for(let l of a.split("; "))console.error(` ${r}. ${l}`),r++}function qo(n){try{let t=m(n);if(t===null)return!1;let e=JSON.parse(t);if(e.$schema)return!1;return f2(n,JSON.stringify({$schema:bo,...e},null,2)),!0}catch(t){if(t instanceof S)throw t;return!1}}var Rl=new Set(["init","add","remove","update","sync","list","wrapper","migrate","doc","verify"]),Fo=new Set(["add","remove","list"]);async function Hl(n){try{return await zo(n)}catch(t){if(t instanceof S)return console.error(t.message),1;throw t}}async function zo(n){let t=Jo(n),e=t.help?Bo(t.positionals):null;if(e)return et(e),0;if(t.errors.length>0){for(let d of t.errors)console.error(d);return 1}let r=t.positionals[0];if(!r)return et(G2,console.error),1;let a=t.positionals[1],l={global:t.global,check:t.check};if(r==="init"){let d=U(l),s=d.configDir;Qo(d.configTarget),Al($(d.filesystemScope,Jn({...l,cacheConfigDir:s})));let c=jo(s,"example-rules","rulebook.json"),i=$(d.filesystemScope,c);if(t.example&&m(i)===null)At(i,"example-rules");let L=await Y2(l);return jn(L,"Rule config initialized."),L.ok?0:1}if(r==="add"){if(!a)return console.error("rule add requires a source"),1;let d=await St(a,l);return jn(d,`Added rulebook source: ${a}`),d.ok?0:1}if(r==="remove"){if(!a)return console.error("rule remove requires a source"),1;let d=await Qt(a,{...l,deleteSource:t.deleteSource});return jn(d,`Removed rulebook source: ${a}`),d.ok?0:1}if(r==="update"||r==="sync"){let d=await Y2({...l,only:r==="update"?a:void 0});return jn(d,t.check?"Rule config checked.":"Rule config synced."),d.ok?0:1}if(r==="list"){let d=u2(),s=P({});return ql(d,{user:h2(d.userConfigPath,s.userScope),project:h2(d.projectConfigPath,s.projectScope)}),d.errors.length>0?1:0}if(r==="wrapper")return Xo(t);if(r==="migrate")return Bl({cleanup:t.cleanup,cwd:process.cwd()});if(r==="doc"){console.log(Dl);let d=await Sl();if(d)console.error(d);return 0}if(r==="verify")return Xl();return 1}function Bo(n){if(n.length===0)return G2;let t=G2.subcommands.filter((r)=>r.usage.split(" ")[0]===n[0]);if(t.length===0)return null;if(n.length===1&&t.length>1)return{name:`rule ${n[0]}`,description:`Subcommands of rule ${n[0]}`,usage:`rule ${n[0]} <subcommand>`,subcommands:t,options:[]};let e=n.length===1?t[0]:t.find((r)=>r.usage.split(" ")[1]===n[1]);if(!e)return null;return{name:`rule ${n[0]}`,description:e.description,usage:`rule ${e.usage}`,options:[]}}function Jo(n){let t=j({label:"rule",booleans:{global:["-g","--global"],check:["--check"],cleanup:["--cleanup"],deleteSource:["--delete-source"],example:["--example"]},positionals:"list"},n),e={...t.flags,help:t.help,positionals:t.positionals,errors:t.errors};return So(e),e}function So(n){let[t]=n.positionals;if(t&&!Rl.has(t))n.errors.push(`Unknown rule subcommand: ${t}`);if(n.deleteSource&&t!=="remove")if(t&&Rl.has(t))n.errors.push(`Unknown option for rule ${t}: --delete-source`);else n.errors.push("--delete-source is only valid with 'rule remove'");if(n.cleanup&&t!=="migrate")n.errors.push(ot(t,"--cleanup"));if(n.example&&t!=="init")n.errors.push(ot(t,"--example"));if(t==="migrate"){if(n.global)n.errors.push(ot(t,"--global"));if(n.check)n.errors.push(ot(t,"--check"));if(n.positionals.length>1)n.errors.push(`Unexpected rule migrate argument: ${n.positionals[1]}`)}else if(t==="wrapper")Zo(n);else if(n.positionals.length>2)n.errors.push(`Unexpected rule argument: ${n.positionals[2]}`);if(t==="list"&&n.global)n.errors.push("Unknown option for rule list: --global")}function ot(n,t){return n?`Unknown option for rule ${n}: ${t}`:`Unknown option for rule: ${t}`}function Zo(n){let t=n.positionals[1],e=n.positionals[2];if(!t){n.errors.push("rule wrapper requires add, remove, or list");return}if(!Fo.has(t)){n.errors.push(`Unknown rule wrapper action: ${t}`);return}if(t==="list"){if(e)n.errors.push(`Unexpected rule wrapper argument: ${e}`);return}if(!e){n.errors.push(`rule wrapper ${t} requires a command`);return}if(n.positionals.length>3)n.errors.push(`Unexpected rule wrapper argument: ${n.positionals[3]}`)}function Qo(n){if(m(n)===null){Rt(n);return}let t=O(n);if(!t.config)return;T(n,{version:1,rules:t.config.rules,overrides:t.config.overrides??{},transparent_wrappers:t.config.transparent_wrappers??[]})}async function Xo(n){let t=n.positionals[1],e=n.positionals[2],r=U({global:n.global}).configTarget;if(t==="list"){let s=O(r);if(s.errors.length>0){for(let c of s.errors)console.error(c);return 1}return Yo(s.config?.transparent_wrappers??[]),0}if(!e||!Mt.test(e))return console.error("transparent wrapper must match command pattern"),1;if(Wt(e))return console.error(`reserved command "${e}" cannot be a wrapper`),1;let a=O(r);if(a.errors.length>0){for(let s of a.errors)console.error(s);return 1}let l=a.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},d=t==="add"?[...new Set([...l.transparent_wrappers??[],e])]:(l.transparent_wrappers??[]).filter((s)=>s!==e);return T(r,{version:1,rules:l.rules,overrides:l.overrides??{},transparent_wrappers:d}),console.log(t==="add"?`Added transparent wrapper: ${e}`:`Removed transparent wrapper: ${e}`),0}function Yo(n){if(n.length===0){console.log("Transparent wrappers: (none)");return}console.log(`Transparent wrappers (${n.length}):`);for(let t of n)console.log(` - ${t}`)}import{homedir as Ml}from"node:os";import{existsSync as Ro,readFileSync as Ao}from"node:fs";import{homedir as Ho}from"node:os";import{join as Mo}from"node:path";async function Wo(){if(process.stdin.isTTY)return null;return(await Et(process.stdin).catch(()=>null))?.trim()||null}function Vo(){if(process.env.CLAUDE_SETTINGS_PATH)return process.env.CLAUDE_SETTINGS_PATH;return Mo(Ho(),".claude","settings.json")}function rr(){let n=Vo();if(!Ro(n))return!1;try{let t=Ao(n,"utf-8"),e=JSON.parse(t);if(!e.enabledPlugins)return!1;let r="cc-safety-net@cc-marketplace";if(!(r in e.enabledPlugins))return!1;return e.enabledPlugins[r]===!0}catch(t){if(Ln(D.debug))console.error(`CC Safety Net debug: failed to read Claude settings: ${n}: ${t instanceof Error?t.message:String(t)}`);return!1}}async function ar(){let n=rr(),t;if(!n)t="\uD83D\uDEE1️ CC Safety Net ❌";else{let r=H({cwd:process.cwd()}),a=r.policy,l=d2(a),d=Object.values(w2(a,l.capabilities)).some((c)=>c.changesInherited);t=`\uD83D\uDEE1️ CC Safety Net ${{standard:"✅",strict:"\uD83D\uDD12",paranoid:"\uD83D\uDC41️",custom:"\uD83D\uDD27"}[d?"custom":l.effectiveLevel]}${l.worktreeMode?"\uD83C\uDF33":""}${r.state==="degraded"?"⚠️":""}`}let e=await Wo();if(e&&!e.startsWith("{"))console.log(`${e} | ${t}`);else console.log(t)}function Wl(){let n=H({cwd:process.cwd()}),t=n.policy,e=d2(t),r=!!process.env.NO_COLOR||!process.stdout.isTTY,a=Math.min(process.stdout.columns||80,100),l=r?"ok":"✔",d=r?"OFF":"✘",s=(o,b)=>{let v=` ${o.padEnd(13)}${b}`;return(v.length>a?`${v.slice(0,a-1)}…`:v).replaceAll(d,h.red(d))},c=Object.values(w2(t,e.capabilities)).some((o)=>o.changesInherited),i=Ut(),L={ready:h.green,degraded:h.yellow}[n.state],u=[...rr()?[]:["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."],...n.diagnostics],p=r?"-":"·";console.log([`${r?"":"\uD83D\uDEE1️ "}CC Safety Net — ${L(n.state)}`,"",s("Protection",`destructive ${t.destructiveCommandProtectionEnabled?l:d} secrets ${t.secretProtection.enabled?l:d}`),s("Level",c?`${e.effectiveLevel} (customised)`:e.effectiveLevel),s("Rules",t.rules.length===0?"none active":`${t.rules.length} active`),s("Policy",i.startsWith(Ml())?`~${i.slice(Ml().length)}`:i),...e.worktreeMode?[s("Worktree","relaxations active")]:[],"",...u.length===0?[" Everything configured is active."]:[" Not active",...u.flatMap((o)=>tt(o," ",a-6).map((b,v)=>v===0?` ${p} ${b}`:b)),""," Full report: cc-safety-net doctor"]].join(`
222
- `))}import{spawn as sd}from"node:child_process";import{randomBytes as No}from"node:crypto";import{createServer as n5}from"node:http";import{Writable as t5}from"node:stream";import{homedir as Ko}from"node:os";var ut=500;function Co(n){let t=n.filter((a)=>a.decision!=="allow"),e=n.filter((a)=>a.decision==="allow"),r=Math.min(t.length,Math.max(ut-e.length,Math.ceil(ut/2)));return[...t.slice(0,r),...e.slice(0,ut-r)]}function Vl(n,t=s2()){if(t)y2(t);let e=(v)=>new Date(v.getFullYear(),v.getMonth(),v.getDate()).getTime(),r=e(new Date),a=new Date(r);a.setDate(a.getDate()-(n-1));let l=a.getTime(),d=[],s={count:0};for(let v of t?o2(t,s):[])for(let f of en(v,s)){if(!f||typeof f.ts!=="string"||typeof f.command!=="string")continue;let w=new Date(f.ts).getTime();if(!Number.isFinite(w))continue;if(w>=l)d.push(f)}d.sort((v,f)=>new Date(f.ts).getTime()-new Date(v.ts).getTime());let c=Array.from({length:n},()=>0),i=Array.from({length:n},()=>0),L={},u={},p={},o=0,b=0;for(let v of d){let f=v.agent||"unknown";L[f]=(L[f]??0)+1;let w=Math.round((r-e(new Date(v.ts)))/86400000),x=n-1-w,y=w>=0&&w<n;if(y)i[x]=(i[x]??0)+1;if(v.decision!=="allow"){if(o++,v.ruleId)u[v.ruleId]=(u[v.ruleId]??0)+1;let J=B2(v.segment||v.command);if(J)p[J]=(p[J]??0)+1;if(v.failureStage)b++;if(y)c[x]=(c[x]??0)+1}}return{days:n,logsDir:t,homeDir:Ko(),totalInWindow:d.length,truncated:d.length>ut,unreadable:s.count,counts:{blocked:o,allowed:d.length-o,agents:L,blockedByDay:c,analyzedByDay:i,rules:u,commands:p,errors:b},entries:Co(d).sort((v,f)=>new Date(f.ts).getTime()-new Date(v.ts).getTime())}}import{spawn as Go}from"node:child_process";import{existsSync as Kl,statSync as Uo}from"node:fs";import{delimiter as Oo,join as To}from"node:path";var Eo=120000,pt="Choose the project folder",_o=`try
223
- return POSIX path of (choose folder with prompt "${pt}")
235
+ All configs valid.`),0}function yt(n,t){let r=`legacy ${n} config`;if(t==="cleanup")return`Warning: Legacy ${n} 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 ${n} config is ignored by CC Safety Net. Run \`npx -y cc-safety-net rule migrate\`.`;return`Warning: Legacy ${n} config is no longer supported. Fix or delete the ${r}, then run \`npx -y cc-safety-net rule migrate\`.`}function A5(n){if(A2(n)===null)return null;let t=W5(n);if(t.ruleNames.size===0&&t.errors.length===0)return null;return{path:n.path,result:t}}function W5(n){let t=[],r=new Set,e=(A2(n)??[]).filter((a)=>!S5.has(a.name)).sort((a,l)=>a.name.localeCompare(l.name));if(e.length===0)return{errors:t,ruleNames:r};for(let a of e){if(!cn.test(a.name)){t.push(`rulebook directory names must match ${cn}: ${a.name}`);continue}if(a.kind!=="directory"){t.push(`${a.name} must be a rulebook directory`);continue}let l=D(n.scope,Q5(n.path,a.name,"rulebook.json")),d=g(l);if(d===null){t.push(`${a.name}/rulebook.json is required`);continue}try{let s;try{s=JSON.parse(d)}catch{t.push(`${a.name}/rulebook.json: invalid JSON`);continue}let c=r3(s);if(c.name!==a.name){t.push(`rulebook name "${c.name}" must match folder "${a.name}"`);continue}r.add(a.name)}catch(s){t.push(s instanceof Error?`${a.name}/rulebook.json: ${s.message}`:`${a.name}/rulebook.json: ${String(s)}`)}}return{errors:t,ruleNames:r}}function R5(){console.log(e3),console.log(X5)}function V5(n,t,r,e,a){if(console.log(`
236
+ ✓ ${n} config: ${t}`),console.log(` Schema: ${e==="rules"?"rulebook sources":"legacy inline rules"}`),r.ruleNames.size>0){console.log(` ${e==="rules"?"Sources":"Rules"}:`);let l=1;for(let d of r.ruleNames)console.log(` ${l}. ${a.get(d)??d}`),l++}else console.log(` ${e==="rules"?"Sources":"Rules"}: (none)`)}function K5(n,t,r,e){if(console.error(`
237
+ ✗ Legacy ${n.toLowerCase()} config: ${t}`),console.error(" Schema: legacy inline rules"),console.error(" Status: ignored by CC Safety Net"),r.errors.length>0){console.error(" Errors:");let a=1;for(let l of r.errors)for(let d of l.split("; "))console.error(` ${a}. ${d}`),a++;return}if(r.ruleNames.size>0){console.error(" Rules:");let a=1;for(let l of r.ruleNames)console.error(` ${a}. ${e.get(l)??l}`),a++;return}console.error(" Rules: (none)")}function M5(n,t,r){l3(`${n} config`,t,r)}function G5(n,t){console.log(`
238
+ ✓ GitHub source rules: ${n}`),console.log(" Rulebooks:");let r=1;for(let e of t.ruleNames)console.log(` ${r}. ${e}`),r++}function C5(n,t){l3("GitHub source rules",n,t)}function l3(n,t,r){console.error(`
239
+ ✗ ${n}: ${t}`),console.error(" Errors:");let e=1;for(let a of r)for(let l of a.split("; "))console.error(` ${e}. ${l}`),e++}function U5(n){try{let t=g(n);if(t===null)return!1;let r=JSON.parse(t);if(r.$schema)return!1;return w2(n,JSON.stringify({$schema:Y5,...r},null,2)),!0}catch(t){if(t instanceof Z)throw t;return!1}}var d3=new Set(["init","add","remove","update","sync","list","wrapper","migrate","doc","verify"]),T5=new Set(["add","remove","list"]);async function c3(n){try{return await E5(n)}catch(t){if(t instanceof Z)return console.error(t.message),1;throw t}}async function E5(n){let t=P5(n),r=t.help?_5(t.positionals):null;if(r)return dt(r),0;if(t.errors.length>0){for(let d of t.errors)console.error(d);return 1}let e=t.positionals[0];if(!e)return dt(T2,console.error),1;let a=t.positionals[1],l={global:t.global,check:t.check};if(e==="init"){let d=U(l),s=d.configDir;n8(d.configTarget),s3(D(d.filesystemScope,Hn({...l,cacheConfigDir:s})));let c=O5(s,"example-rules","rulebook.json"),L=D(d.filesystemScope,c);if(t.example&&g(L)===null)Ct(L,"example-rules");let i=await W2(l);return Qn(i,"Rule config initialized."),i.ok?0:1}if(e==="add"){if(!a)return console.error("rule add requires a source"),1;let d=await Wt(a,l);return Qn(d,`Added rulebook source: ${a}`),d.ok?0:1}if(e==="remove"){if(!a)return console.error("rule remove requires a source"),1;let d=await Vt(a,{...l,deleteSource:t.deleteSource});return Qn(d,`Removed rulebook source: ${a}`),d.ok?0:1}if(e==="update"||e==="sync"){let d=await W2({...l,only:e==="update"?a:void 0});return Qn(d,t.check?"Rule config checked.":"Rule config synced."),d.ok?0:1}if(e==="list"){let d=o2(),s=P({});return El(d,{user:x2(d.userConfigPath,s.userScope),project:x2(d.projectConfigPath,s.projectScope)}),d.errors.length>0?1:0}if(e==="wrapper")return t8(t);if(e==="migrate")return Il({cleanup:t.cleanup,cwd:process.cwd()});if(e==="doc"){console.log(Ol);let d=await t3();if(d)console.error(d);return 0}if(e==="verify")return a3();return 1}function _5(n){if(n.length===0)return T2;let t=T2.subcommands.filter((e)=>e.usage.split(" ")[0]===n[0]);if(t.length===0)return null;if(n.length===1&&t.length>1)return{name:`rule ${n[0]}`,description:`Subcommands of rule ${n[0]}`,usage:`rule ${n[0]} <subcommand>`,subcommands:t,options:[]};let r=n.length===1?t[0]:t.find((e)=>e.usage.split(" ")[1]===n[1]);if(!r)return null;return{name:`rule ${n[0]}`,description:r.description,usage:`rule ${r.usage}`,options:[]}}function P5(n){let t=F({label:"rule",booleans:{global:["-g","--global"],check:["--check"],cleanup:["--cleanup"],deleteSource:["--delete-source"],example:["--example"]},positionals:"list"},n),r={...t.flags,help:t.help,positionals:t.positionals,errors:t.errors};return N5(r),r}function N5(n){let[t]=n.positionals;if(t&&!d3.has(t))n.errors.push(`Unknown rule subcommand: ${t}`);if(n.deleteSource&&t!=="remove")if(t&&d3.has(t))n.errors.push(`Unknown option for rule ${t}: --delete-source`);else n.errors.push("--delete-source is only valid with 'rule remove'");if(n.cleanup&&t!=="migrate")n.errors.push(ht(t,"--cleanup"));if(n.example&&t!=="init")n.errors.push(ht(t,"--example"));if(t==="migrate"){if(n.global)n.errors.push(ht(t,"--global"));if(n.check)n.errors.push(ht(t,"--check"));if(n.positionals.length>1)n.errors.push(`Unexpected rule migrate argument: ${n.positionals[1]}`)}else if(t==="wrapper")I5(n);else if(n.positionals.length>2)n.errors.push(`Unexpected rule argument: ${n.positionals[2]}`);if(t==="list"&&n.global)n.errors.push("Unknown option for rule list: --global")}function ht(n,t){return n?`Unknown option for rule ${n}: ${t}`:`Unknown option for rule: ${t}`}function I5(n){let t=n.positionals[1],r=n.positionals[2];if(!t){n.errors.push("rule wrapper requires add, remove, or list");return}if(!T5.has(t)){n.errors.push(`Unknown rule wrapper action: ${t}`);return}if(t==="list"){if(r)n.errors.push(`Unexpected rule wrapper argument: ${r}`);return}if(!r){n.errors.push(`rule wrapper ${t} requires a command`);return}if(n.positionals.length>3)n.errors.push(`Unexpected rule wrapper argument: ${n.positionals[3]}`)}function n8(n){if(g(n)===null){Gt(n);return}let t=O(n);if(!t.config)return;T(n,{version:1,rules:t.config.rules,overrides:t.config.overrides??{},transparent_wrappers:t.config.transparent_wrappers??[]})}async function t8(n){let t=n.positionals[1],r=n.positionals[2],e=U({global:n.global}).configTarget;if(t==="list"){let s=O(e);if(s.errors.length>0){for(let c of s.errors)console.error(c);return 1}return r8(s.config?.transparent_wrappers??[]),0}if(!r||!Ot.test(r))return console.error("transparent wrapper must match command pattern"),1;if(Tt(r))return console.error(`reserved command "${r}" cannot be a wrapper`),1;let a=O(e);if(a.errors.length>0){for(let s of a.errors)console.error(s);return 1}let l=a.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},d=t==="add"?[...new Set([...l.transparent_wrappers??[],r])]:(l.transparent_wrappers??[]).filter((s)=>s!==r);return T(e,{version:1,rules:l.rules,overrides:l.overrides??{},transparent_wrappers:d}),console.log(t==="add"?`Added transparent wrapper: ${r}`:`Removed transparent wrapper: ${r}`),0}function r8(n){if(n.length===0){console.log("Transparent wrappers: (none)");return}console.log(`Transparent wrappers (${n.length}):`);for(let t of n)console.log(` - ${t}`)}import{homedir as L3}from"node:os";import{existsSync as e8,readFileSync as a8}from"node:fs";import{homedir as l8}from"node:os";import{join as d8}from"node:path";async function s8(){if(process.stdin.isTTY)return null;return(await tr(process.stdin).catch(()=>null))?.trim()||null}function c8(){if(process.env.CLAUDE_SETTINGS_PATH)return process.env.CLAUDE_SETTINGS_PATH;return d8(l8(),".claude","settings.json")}function ve(){let n=c8();if(!e8(n))return!1;try{let t=a8(n,"utf-8"),r=JSON.parse(t);if(!r.enabledPlugins)return!1;let e="cc-safety-net@cc-marketplace";if(!(e in r.enabledPlugins))return!1;return r.enabledPlugins[e]===!0}catch(t){if(on(m.debug))console.error(`CC Safety Net debug: failed to read Claude settings: ${n}: ${t instanceof Error?t.message:String(t)}`);return!1}}async function be(){let n=ve(),t;if(!n)t="\uD83D\uDEE1️ CC Safety Net ❌";else{let e=W({cwd:process.cwd()}),a=e.policy,l=d2(a),d=Object.values(g2(a,l.capabilities)).some((c)=>c.changesInherited);t=`\uD83D\uDEE1️ CC Safety Net ${{standard:"✅",strict:"\uD83D\uDD12",paranoid:"\uD83D\uDC41️",custom:"\uD83D\uDD27"}[d?"custom":l.effectiveLevel]}${l.worktreeMode?"\uD83C\uDF33":""}${e.state==="degraded"?"⚠️":""}`}let r=await s8();if(r&&!r.startsWith("{"))console.log(`${r} | ${t}`);else console.log(t)}function i3(){let n=W({cwd:process.cwd()}),t=n.policy,r=d2(t),e=!!process.env.NO_COLOR||!process.stdout.isTTY,a=Math.min(process.stdout.columns||80,100),l=e?"ok":"✔",d=e?"OFF":"✘",s=(p,f)=>{let o=` ${p.padEnd(13)}${f}`;return(o.length>a?`${o.slice(0,a-1)}…`:o).replaceAll(d,b.red(d))},c=Object.values(g2(t,r.capabilities)).some((p)=>p.changesInherited),L=vn(),i={ready:b.green,degraded:b.yellow}[n.state],u=[...ve()?[]:["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."],...n.diagnostics],v=e?"-":"·";console.log([`${e?"":"\uD83D\uDEE1️ "}CC Safety Net — ${i(n.state)}`,"",s("Protection",`destructive ${t.destructiveCommandProtectionEnabled?l:d} secrets ${t.secretProtection.enabled?l:d}`),s("Level",c?`${r.effectiveLevel} (customised)`:r.effectiveLevel),s("Rules",t.rules.length===0?"none active":`${t.rules.length} active`),s("Policy",L.startsWith(L3())?`~${L.slice(L3().length)}`:L),...r.worktreeMode?[s("Worktree","relaxations active")]:[],"",...u.length===0?[" Everything configured is active."]:[" Not active",...u.flatMap((p)=>lt(p," ",a-6).map((f,o)=>o===0?` ${v} ${f}`:f)),""," Full report: cc-safety-net doctor"]].join(`
240
+ `))}import{spawn as z3}from"node:child_process";import{randomBytes as w8}from"node:crypto";import{createServer as x8}from"node:http";import{Writable as $8}from"node:stream";import{homedir as L8}from"node:os";var wt=500;function i8(n){let t=n.filter((a)=>a.decision!=="allow"),r=n.filter((a)=>a.decision==="allow"),e=Math.min(t.length,Math.max(wt-r.length,Math.ceil(wt/2)));return[...t.slice(0,e),...r.slice(0,wt-e)]}function p3(n,t=s2()){if(t)$2(t);let r=(o)=>new Date(o.getFullYear(),o.getMonth(),o.getDate()).getTime(),e=r(new Date),a=new Date(e);a.setDate(a.getDate()-(n-1));let l=a.getTime(),d=[],s={count:0};for(let o of t?u2(t,s):[])for(let y of ln(o,s)){if(!y||typeof y.ts!=="string"||typeof y.command!=="string")continue;let x=new Date(y.ts).getTime();if(!Number.isFinite(x))continue;if(x>=l)d.push(y)}d.sort((o,y)=>new Date(y.ts).getTime()-new Date(o.ts).getTime());let c=Array.from({length:n},()=>0),L=Array.from({length:n},()=>0),i={},u={},v={},p=0,f=0;for(let o of d){let y=o.agent||"unknown";i[y]=(i[y]??0)+1;let x=Math.round((e-r(new Date(o.ts)))/86400000),w=n-1-x,h=x>=0&&x<n;if(h)L[w]=(L[w]??0)+1;if(o.decision!=="allow"){if(p++,o.ruleId)u[o.ruleId]=(u[o.ruleId]??0)+1;let J=Q2(o.segment||o.command);if(J)v[J]=(v[J]??0)+1;if(o.failureStage)f++;if(h)c[w]=(c[w]??0)+1}}return{days:n,logsDir:t,homeDir:L8(),totalInWindow:d.length,truncated:d.length>wt,unreadable:s.count,counts:{blocked:p,allowed:d.length-p,agents:i,blockedByDay:c,analyzedByDay:L,rules:u,commands:v,errors:f},entries:i8(d).sort((o,y)=>new Date(y.ts).getTime()-new Date(o.ts).getTime())}}import{spawn as p8}from"node:child_process";import{existsSync as u3,statSync as u8}from"node:fs";import{delimiter as o8,join as v8}from"node:path";var b8=120000,xt="Choose the project folder",f8=`try
241
+ return POSIX path of (choose folder with prompt "${xt}")
224
242
  on error number -128
225
243
  return ""
226
- end try`,Po=`Add-Type -AssemblyName System.Windows.Forms
244
+ end try`,y8=`Add-Type -AssemblyName System.Windows.Forms
227
245
  $dialog = New-Object System.Windows.Forms.FolderBrowserDialog
228
- $dialog.Description = '${pt}'
229
- if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { [Console]::Out.Write($dialog.SelectedPath) }`,Cl=[{binary:"zenity",args:["--file-selection","--directory",`--title=${pt}`]},{binary:"kdialog",args:["--getexistingdirectory",".","--title",pt]}],Gl=(n,t)=>(t.PATH??"").split(Oo).some((e)=>e.length>0&&Kl(To(e,n)));function Ul(n,t){if(n==="darwin"||n==="win32")return!0;if(n!=="linux")return!1;if(!t.DISPLAY&&!t.WAYLAND_DISPLAY)return!1;return Cl.some((e)=>Gl(e.binary,t))}function Io(n,t){if(n==="darwin")return{cmd:"osascript",args:["-e",_o]};if(n==="win32")return{cmd:"powershell.exe",args:["-NoProfile","-STA","-Command",Po]};let e=Cl.find((r)=>Gl(r.binary,t));return e?{cmd:e.binary,args:e.args}:null}function Ol(n=process.platform,t=process.env){let e=Io(n,t);if(!e)return Promise.resolve({error:"No folder dialog is available on this system"});return new Promise((r)=>{let a=Go(e.cmd,e.args,{env:t,stdio:["ignore","pipe","pipe"]}),l="",d=!1,s=(i)=>{if(d)return;d=!0,clearTimeout(c),r(i)},c=setTimeout(()=>{a.kill(),s({error:"The folder dialog timed out"})},Eo);a.stdout.on("data",(i)=>{l+=i.toString()}),a.on("error",()=>s({error:`Could not open the folder dialog (${e.cmd})`})),a.on("close",()=>{let i=l.trim().replace(/\/+$/,"");if(!i)return s({cancelled:!0});if(!Kl(i)||!Uo(i).isDirectory())return s({error:"That selection is not a folder on disk"});s({path:i})})})}var Tl=`<!doctype html>
246
+ $dialog.Description = '${xt}'
247
+ if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { [Console]::Out.Write($dialog.SelectedPath) }`,o3=[{binary:"zenity",args:["--file-selection","--directory",`--title=${xt}`]},{binary:"kdialog",args:["--getexistingdirectory",".","--title",xt]}],v3=(n,t)=>(t.PATH??"").split(o8).some((r)=>r.length>0&&u3(v8(r,n)));function b3(n,t){if(n==="darwin"||n==="win32")return!0;if(n!=="linux")return!1;if(!t.DISPLAY&&!t.WAYLAND_DISPLAY)return!1;return o3.some((r)=>v3(r.binary,t))}function h8(n,t){if(n==="darwin")return{cmd:"osascript",args:["-e",f8]};if(n==="win32")return{cmd:"powershell.exe",args:["-NoProfile","-STA","-Command",y8]};let r=o3.find((e)=>v3(e.binary,t));return r?{cmd:r.binary,args:r.args}:null}function f3(n=process.platform,t=process.env){let r=h8(n,t);if(!r)return Promise.resolve({error:"No folder dialog is available on this system"});return new Promise((e)=>{let a=p8(r.cmd,r.args,{env:t,stdio:["ignore","pipe","pipe"]}),l="",d=!1,s=(L)=>{if(d)return;d=!0,clearTimeout(c),e(L)},c=setTimeout(()=>{a.kill(),s({error:"The folder dialog timed out"})},b8);a.stdout.on("data",(L)=>{l+=L.toString()}),a.on("error",()=>s({error:`Could not open the folder dialog (${r.cmd})`})),a.on("close",()=>{let L=l.trim().replace(/\/+$/,"");if(!L)return s({cancelled:!0});if(!u3(L)||!u8(L).isDirectory())return s({error:"That selection is not a folder on disk"});s({path:L})})})}var y3=`<!doctype html>
230
248
  <html lang="en">
231
249
  <head>
232
250
  <meta charset="utf-8">
@@ -5323,5 +5341,5 @@ load().then((loaded) => {
5323
5341
  </script>
5324
5342
  </body>
5325
5343
  </html>
5326
- `;var El='<script id="ccsn-data" type="application/json">';function _l(n){return Tl.replace(El,()=>El+JSON.stringify({token:n}).replaceAll("<","\\u003c"))}var bt="kenryu42/cc-safety-net",e5=`https://github.com/${bt}`,sr=1e4,r5=7;async function cd(n,t={}){let e=j({label:"gui",booleans:{noOpen:["--no-open"]}},n),r=t.log??console.log,a=t.error??console.error;if(e.errors.length>0){for(let d of e.errors)a(d);return a("Usage: cc-safety-net gui [--no-open]"),1}let l=await a5(t);if(r(`CC Safety Net policy GUI: ${l.url}`),!e.flags.noOpen)try{await(t.openBrowser??u5)(l.url)}catch(d){a(`Failed to open browser: ${d instanceof Error?d.message:String(d)}`),a(`Open this URL manually: ${l.url}`)}if(t.keepAlive===!1)return await l.close(),0;return await o5(l),0}async function a5(n={}){let t=n.token??No(24).toString("base64url"),e=n5((l,d)=>{l5(l,d,t,n)});await new Promise((l,d)=>{e.once("error",d),e.listen(0,"127.0.0.1",()=>{e.off("error",d),l()})});let a=`http://127.0.0.1:${e.address().port}`;return{origin:a,token:t,url:`${a}/?token=${encodeURIComponent(t)}`,close:()=>L5(e)}}async function l5(n,t,e,r){let a=new URL(n.url??"/","http://127.0.0.1");if(n.method==="GET"&&a.pathname==="/favicon.ico"){t.writeHead(204,{"cache-control":"no-store"}),t.end();return}if(!c5(n,a,e)){k(t,403,{error:"Forbidden"});return}if(n.method==="GET"&&a.pathname==="/"){i5(t,_l(e));return}if(n.method==="GET"&&a.pathname==="/api/policy"){let l=nd(r);k(t,200,{...l,configState:on(H(r)),destructiveCommandRules:sn,secretPatterns:Il,version:z(),preview:l.errors.length>0?null:ed(l.policy)});return}if(n.method==="POST"&&a.pathname==="/api/policy/preview"){let l=await vt(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=td(l.value);k(t,d.errors.length>0?400:200,d);return}if(n.method==="POST"&&a.pathname==="/api/policy/explain"){let l=await vt(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=l.value;if(d===null||typeof d.command!=="string"){k(t,400,{errors:["command must be a string"]});return}let s=Gt(d.policy);if(s.length>0){k(t,400,{errors:s});return}k(t,200,d5(d.command,d.policy,r));return}if(n.method==="POST"&&a.pathname==="/api/policy"){let l=await vt(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=lr(l.value,r);k(t,d.errors.length>0?400:200,d);return}if(n.method==="POST"&&a.pathname==="/api/reset"){k(t,200,lr(Nl,r));return}if(n.method==="POST"&&a.pathname==="/api/repair"){k(t,200,rd(r));return}if(n.method==="GET"&&a.pathname==="/api/activity"){let l=W2(r),d=s5(a.searchParams.get("days"),l);if(d===null){k(t,400,{error:`days must be an integer between 1 and ${l}`});return}k(t,200,Vl(d,r.activityLogsDir));return}if(n.method==="POST"&&a.pathname==="/api/rules/choose-directory"){k(t,200,await Ol());return}if(n.method==="GET"&&a.pathname==="/api/rules"){let l=u2(r),d=new Map(l.rules.map((s)=>[s.name,s]));k(t,200,{projectPath:r.cwd??process.cwd(),canPickDirectory:Ul(process.platform,process.env),rulebooks:l.rulebooks.map((s)=>({source:s.source,spec:s.spec,name:s.name,version:s.version,rules:s.rules.flatMap((c)=>{let i=d.get(c);if(!i)return[];return[{name:i.name,command:i.command,subcommand:i.subcommand,block_args:i.block_args,reason:i.reason}]})})),errors:l.errors,warnings:l.warnings});return}if(n.method==="GET"&&a.pathname==="/api/star/context"){k(t,200,await(r.fetchStarContext??(()=>y5({logsDir:r.activityLogsDir})))());return}if(n.method==="POST"&&a.pathname==="/api/star"){let l=await(r.starRepo??p5)();k(t,200,l.ok?{ok:!0}:{ok:!1,fallbackUrl:e5});return}if(n.method==="GET"&&a.pathname==="/api/integrations"){k(t,200,await(r.fetchIntegrations??b5)());return}if(n.method==="GET"&&a.pathname==="/api/health"){k(t,200,await(r.fetchHealth??f5)());return}if(n.method==="POST"&&(a.pathname==="/api/install"||a.pathname==="/api/uninstall")){let l=await vt(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=l.value?.target;if(typeof d!=="string"||!G.some((c)=>c.target===d)){k(t,400,{error:"unknown target"});return}let s=a.pathname==="/api/install"?"install":"uninstall";k(t,200,await(r.runIntegration??h5)(s,d));return}k(t,404,{error:"Not found"})}function d5(n,t,e){let r=ad(t),a=H(e),l=cn({rules:a.policy.rules,transparentWrappers:a.policy.transparentWrappers,safety:dd(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}});return M2(n,{policySnapshot:l,cwd:e.cwd,userConfigDir:e.userConfigDir})}function s5(n,t){if(n===null)return Math.min(r5,t);let e=Number(n);if(!Number.isInteger(e)||e<1||e>t)return null;return e}function c5(n,t,e){if(t.searchParams.get("token")!==e)return!1;if(n.method!=="POST")return!0;return n.headers["x-cc-safety-net-token"]===e}async function vt(n){let t=[];for await(let e of n)t.push(e);try{return{ok:!0,value:JSON.parse(Buffer.concat(t).toString("utf-8")||"{}")}}catch(e){return{ok:!1,error:`Invalid JSON: ${e instanceof Error?e.message:String(e)}`}}}function i5(n,t){n.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),n.end(t)}function k(n,t,e){n.writeHead(t,{"content-type":"application/json; charset=utf-8","cache-control":"no-store"}),n.end(JSON.stringify(e))}function L5(n){return new Promise((t,e)=>{n.close((r)=>r?e(r):t())})}function o5(n){return new Promise((t)=>{let e=()=>{process.off("SIGINT",r),process.off("SIGTERM",r)},r=()=>{e(),n.close().then(t)};process.once("SIGINT",r),process.once("SIGTERM",r)})}function u5(n){let t=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",e=process.platform==="win32"?["/c","start","",n]:[n];return new Promise((r,a)=>{let l=sd(t,e,{detached:!0,stdio:"ignore"}),d=(c)=>{l.off("spawn",s),a(c)},s=()=>{l.off("error",d),l.unref(),r()};l.once("error",d),l.once("spawn",s)})}async function p5(n="gh",t=sr){return{ok:await dr(n,["api","-X","PUT",`/user/starred/${bt}`],t)===0}}var v5={amp:"ampVersion","antigravity-cli":"antigravityCliVersion","claude-code":"claudeCodeVersion",codex:"codexCliVersion","copilot-cli":"copilotCliVersion",cursor:"cursorVersion","gemini-cli":"geminiCliVersion","hermes-agent":"hermesAgentVersion","kimi-code":"kimiCodeVersion",openclaw:"openClawVersion",opencode:"openCodeVersion",pi:"piCliVersion"};async function b5(n={}){let t=await bn(n.fetcher),e=id(t,n.homeDir);return{targets:i2.map((r)=>{let a=e.find((l)=>l.platform===r.id);return{target:r.id,label:p2(r.id),version:t[v5[r.id]],status:a?.configured?"active":a?.detected?"disabled":a?.inspectionStatus==="not-inspected"?"not-inspected":"not-installed"}}),system:{version:t.version,nodeVersion:t.nodeVersion,platform:t.platform}}}function id(n,t){return P2(process.cwd(),{homeDir:t,codexPluginListOutput:n.codexPluginListOutput,copilotCliVersion:n.copilotCliVersion})}async function f5(n={}){let[t,e]=await Promise.all([bn(n.fetcher),(n.checkUpdates??U2)()]);return{hooks:id(t,n.homeDir).filter((r)=>r.detected).map((r)=>({platform:r.platform,label:p2(r.platform),configured:r.configured})),update:{currentVersion:e.currentVersion,latestVersion:e.latestVersion??null,updateAvailable:e.updateAvailable}}}var Pl=Promise.resolve();function h5(n,t,e={}){let r=async()=>{let l=[],d=console.log,s=console.error;console.log=(...c)=>l.push(c.map(String).join(" ")),console.error=console.log;try{return{ok:await qn(n,[],{selectTargets:async()=>[t],output:new t5({write(i,L,u){u()}}),...e})===0,output:l.join(`
5327
- `)}}finally{console.log=d,console.error=s}},a=Pl.then(r);return Pl=a.then(()=>{return},()=>{return}),a}async function y5(n={}){let[t,e,r]=await Promise.all([w5(n.command),x5(n.fetchRepo),Promise.resolve(Rn(W2(),n.logsDir).totalBlocked)]);return{starred:t,starCount:e,blockedTotal:r}}async function w5(n="gh",t=sr){if(await dr(n,["auth","status"],t)!==0)return null;let e=await dr(n,["api",`/user/starred/${bt}`],t);if(e===0)return!0;if(e===null)return null;return!1}function dr(n,t,e){return new Promise((r)=>{let a=sd(n,t,{stdio:"ignore",windowsHide:!0}),l=!1,d,s=(c)=>{if(l)return;if(l=!0,d)clearTimeout(d);r(c)};a.once("error",()=>s(null)),a.once("close",s),d=setTimeout(()=>{a.kill(),s(null)},e)})}async function x5(n=fetch){try{let t=await n(`https://api.github.com/repos/${bt}`,{headers:{accept:"application/vnd.github+json"},signal:AbortSignal.timeout(sr)});if(!t.ok)return null;let e=await t.json();return typeof e.stargazers_count==="number"?e.stargazers_count:null}catch{return null}}function m5(n){if(n[0]!=="help")return!1;let t=n[1];if(!t)Re(),process.exit(0);if(Dn(t))process.exit(0);console.error(`Unknown command: ${t}`),console.error("Run 'cc-safety-net --help' for available commands."),process.exit(1)}var g5={hook:async(n)=>{let t=za(n);if(t){await t.run();return}console.error("hook requires exactly one integration flag. Try: cc-safety-net hook --kimi-code"),Dn("hook",console.error),process.exit(1)},install:async(n)=>{process.exit(await qn("install",n))},update:async(n)=>{process.exit(await Ne(n))},uninstall:async(n)=>{process.exit(await qn("uninstall",n))},rule:async(n)=>{process.exit(await Hl(n))},status:async(n)=>{if(r2(j({label:"status"},n).errors))process.exit(1);Wl()},statusline:async(n)=>{let t=j({label:"statusline",booleans:{claudeCode:["-cc","--claude-code"]}},n);if(t.errors.length===0&&t.flags.claudeCode){await ar();return}if(r2(t.errors),!t.flags.claudeCode)console.error("statusline requires --claude-code (-cc)");Dn("statusline",console.error),process.exit(1)},doctor:async(n)=>{let t=Se(n);if(!t)process.exit(1);let e=await z0({json:t.json,skipUpdateCheck:t.skipUpdateCheck});process.exit(e)},logs:async(n)=>{process.exit(await Ir(n))},gui:async(n)=>{process.exit(await cd(n))},explain:async(n)=>{let t=Ze(n);if(!t)process.exit(1);let e=M2(t.command,{cwd:t.cwd}),r=!!process.env.NO_COLOR||!process.stdout.isTTY;if(t.json)console.log(Ye(e));else console.log(Xe(e,{asciiOnly:r}));process.exit(0)}};async function $5(){let n=process.argv.slice(2),t=j({label:"cc-safety-net",booleans:{version:["-V","--version"]},positionals:"list"},n);if(m5(n))return;let e=n[0],r=e?Yn(e):void 0;if(t.help&&r&&r.name!=="rule")Dn(r.name),process.exit(0);if(!e||t.help&&!r)Re(),process.exit(0);if(t.flags.version)R0(),process.exit(0);if(r){await g5[r.name](n.slice(1));return}let a=Ba(e);if(a){await a.run();return}if(e==="--statusline"){await ar();return}console.error(e.startsWith("-")?`Unknown option: ${e}`:`Unknown command: ${e}`),console.error("Run 'cc-safety-net --help' for usage."),process.exit(1)}$5().catch((n)=>{console.error("CC Safety Net error:",n),process.exit(1)});
5344
+ `;var h3='<script id="ccsn-data" type="application/json">';function w3(n){return y3.replace(h3,()=>h3+JSON.stringify({token:n}).replaceAll("<","\\u003c"))}var gt="kenryu42/cc-safety-net",g8=`https://github.com/${gt}`,he=1e4,D8=7;async function B3(n,t={}){let r=F({label:"gui",booleans:{noOpen:["--no-open"]}},n),e=t.log??console.log,a=t.error??console.error;if(r.errors.length>0){for(let d of r.errors)a(d);return a("Usage: cc-safety-net gui [--no-open]"),1}let l=await m8(t);if(e(`CC Safety Net policy GUI: ${l.url}`),!r.flags.noOpen)try{await(t.openBrowser??Z8)(l.url)}catch(d){a(`Failed to open browser: ${d instanceof Error?d.message:String(d)}`),a(`Open this URL manually: ${l.url}`)}if(t.keepAlive===!1)return await l.close(),0;return await J8(l),0}async function m8(n={}){let t=n.token??w8(24).toString("base64url"),r=x8((l,d)=>{k8(l,d,t,n)});await new Promise((l,d)=>{r.once("error",d),r.listen(0,"127.0.0.1",()=>{r.off("error",d),l()})});let a=`http://127.0.0.1:${r.address().port}`;return{origin:a,token:t,url:`${a}/?token=${encodeURIComponent(t)}`,close:()=>B8(r)}}async function k8(n,t,r,e){let a=new URL(n.url??"/","http://127.0.0.1");if(n.method==="GET"&&a.pathname==="/favicon.ico"){t.writeHead(204,{"cache-control":"no-store"}),t.end();return}if(!F8(n,a,r)){k(t,403,{error:"Forbidden"});return}if(n.method==="GET"&&a.pathname==="/"){z8(t,w3(r));return}if(n.method==="GET"&&a.pathname==="/api/policy"){let l=D3(e);k(t,200,{...l,configState:bn(W(e)),destructiveCommandRules:pn,secretPatterns:$3,version:j(),preview:l.errors.length>0?null:k3(l.policy)});return}if(n.method==="POST"&&a.pathname==="/api/policy/preview"){let l=await $t(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=m3(l.value);k(t,d.errors.length>0?400:200,d);return}if(n.method==="POST"&&a.pathname==="/api/policy/explain"){let l=await $t(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=l.value;if(d===null||typeof d.command!=="string"){k(t,400,{errors:["command must be a string"]});return}let s=Nt(d.policy);if(s.length>0){k(t,400,{errors:s});return}k(t,200,q8(d.command,d.policy,e));return}if(n.method==="POST"&&a.pathname==="/api/policy"){let l=await $t(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=fe(l.value,e);k(t,d.errors.length>0?400:200,d);return}if(n.method==="POST"&&a.pathname==="/api/reset"){k(t,200,fe(g3,e));return}if(n.method==="POST"&&a.pathname==="/api/repair"){k(t,200,q3(e));return}if(n.method==="GET"&&a.pathname==="/api/activity"){let l=G2(e),d=j8(a.searchParams.get("days"),l);if(d===null){k(t,400,{error:`days must be an integer between 1 and ${l}`});return}k(t,200,p3(d,e.activityLogsDir));return}if(n.method==="POST"&&a.pathname==="/api/rules/choose-directory"){k(t,200,await f3());return}if(n.method==="GET"&&a.pathname==="/api/rules"){let l=o2(e),d=new Map(l.rules.map((s)=>[s.name,s]));k(t,200,{projectPath:e.cwd??process.cwd(),canPickDirectory:b3(process.platform,process.env),rulebooks:l.rulebooks.map((s)=>({source:s.source,spec:s.spec,name:s.name,version:s.version,rules:s.rules.flatMap((c)=>{let L=d.get(c);if(!L)return[];return[{name:L.name,command:L.command,subcommand:L.subcommand,block_args:L.block_args,reason:L.reason}]})})),errors:l.errors,warnings:l.warnings});return}if(n.method==="GET"&&a.pathname==="/api/star/context"){k(t,200,await(e.fetchStarContext??(()=>A8({logsDir:e.activityLogsDir})))());return}if(n.method==="POST"&&a.pathname==="/api/star"){let l=await(e.starRepo??Q8)();k(t,200,l.ok?{ok:!0}:{ok:!1,fallbackUrl:g8});return}if(n.method==="GET"&&a.pathname==="/api/integrations"){k(t,200,await(e.fetchIntegrations??Y8)());return}if(n.method==="GET"&&a.pathname==="/api/health"){k(t,200,await(e.fetchHealth??S8)());return}if(n.method==="POST"&&(a.pathname==="/api/install"||a.pathname==="/api/uninstall")){let l=await $t(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=l.value?.target;if(typeof d!=="string"||!C.some((c)=>c.target===d)){k(t,400,{error:"unknown target"});return}let s=a.pathname==="/api/install"?"install":"uninstall";k(t,200,await(e.runIntegration??H8)(s,d));return}k(t,404,{error:"Not found"})}function q8(n,t,r){let e=ct(t),a=W(r),l=un({rules:a.policy.rules,transparentWrappers:a.policy.transparentWrappers,safety:F3(e.safety),worktreeMode:e.workflow.worktree_mode,destructiveCommandProtectionEnabled:e.destructive_command_protection.enabled,destructiveCommandRuleOverrides:e.destructive_command_protection.overrides,destructiveCommandAllowPaths:e.destructive_command_protection.allow_paths,secretProtection:{enabled:e.secret_protection.enabled,disabledRules:[...j3(e.secret_protection.overrides)],denyPaths:e.secret_protection.deny_paths}});return M2(n,{policySnapshot:l,cwd:r.cwd,userConfigDir:r.userConfigDir})}function j8(n,t){if(n===null)return Math.min(D8,t);let r=Number(n);if(!Number.isInteger(r)||r<1||r>t)return null;return r}function F8(n,t,r){if(t.searchParams.get("token")!==r)return!1;if(n.method!=="POST")return!0;return n.headers["x-cc-safety-net-token"]===r}async function $t(n){let t=[];for await(let r of n)t.push(r);try{return{ok:!0,value:JSON.parse(Buffer.concat(t).toString("utf-8")||"{}")}}catch(r){return{ok:!1,error:`Invalid JSON: ${r instanceof Error?r.message:String(r)}`}}}function z8(n,t){n.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),n.end(t)}function k(n,t,r){n.writeHead(t,{"content-type":"application/json; charset=utf-8","cache-control":"no-store"}),n.end(JSON.stringify(r))}function B8(n){return new Promise((t,r)=>{n.close((e)=>e?r(e):t())})}function J8(n){return new Promise((t)=>{let r=()=>{process.off("SIGINT",e),process.off("SIGTERM",e)},e=()=>{r(),n.close().then(t)};process.once("SIGINT",e),process.once("SIGTERM",e)})}function Z8(n){let t=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",r=process.platform==="win32"?["/c","start","",n]:[n];return new Promise((e,a)=>{let l=z3(t,r,{detached:!0,stdio:"ignore"}),d=(c)=>{l.off("spawn",s),a(c)},s=()=>{l.off("error",d),l.unref(),e()};l.once("error",d),l.once("spawn",s)})}async function Q8(n="gh",t=he){return{ok:await ye(n,["api","-X","PUT",`/user/starred/${gt}`],t)===0}}var X8={amp:"ampVersion","antigravity-cli":"antigravityCliVersion","claude-code":"claudeCodeVersion",codex:"codexCliVersion","copilot-cli":"copilotCliVersion",cursor:"cursorVersion","gemini-cli":"geminiCliVersion","hermes-agent":"hermesAgentVersion","kimi-code":"kimiCodeVersion",openclaw:"openClawVersion",opencode:"openCodeVersion",pi:"piCliVersion"};async function Y8(n={}){let t=await xn(n.fetcher),r=J3(t,n.homeDir);return{targets:L2.map((e)=>{let a=r.find((l)=>l.platform===e.id);return{target:e.id,label:v2(e.id),version:t[X8[e.id]],status:a?.configured?"active":a?.detected?"disabled":a?.inspectionStatus==="not-inspected"?"not-inspected":"not-installed"}}),system:{version:t.version,nodeVersion:t.nodeVersion,platform:t.platform}}}function J3(n,t){return nn(process.cwd(),{homeDir:t,ampPluginListOutput:n.ampPluginListOutput,codexPluginListOutput:n.codexPluginListOutput,copilotCliVersion:n.copilotCliVersion})}async function S8(n={}){let[t,r]=await Promise.all([xn(n.fetcher),(n.checkUpdates??E2)()]);return{hooks:J3(t,n.homeDir).filter((e)=>e.detected).map((e)=>({platform:e.platform,label:v2(e.platform),configured:e.configured})),update:{currentVersion:r.currentVersion,latestVersion:r.latestVersion??null,updateAvailable:r.updateAvailable}}}var x3=Promise.resolve();function H8(n,t,r={}){let e=async()=>{let l=[],d=console.log,s=console.error;console.log=(...c)=>l.push(c.map(String).join(" ")),console.error=console.log;try{return{ok:await Zn(n,[],{selectTargets:async()=>[t],output:new $8({write(L,i,u){u()}}),...r})===0,output:l.join(`
5345
+ `)}}finally{console.log=d,console.error=s}},a=x3.then(e);return x3=a.then(()=>{return},()=>{return}),a}async function A8(n={}){let[t,r,e]=await Promise.all([W8(n.command),R8(n.fetchRepo),Promise.resolve(Mn(G2(),n.logsDir).totalBlocked)]);return{starred:t,starCount:r,blockedTotal:e}}async function W8(n="gh",t=he){if(await ye(n,["auth","status"],t)!==0)return null;let r=await ye(n,["api",`/user/starred/${gt}`],t);if(r===0)return!0;if(r===null)return null;return!1}function ye(n,t,r){return new Promise((e)=>{let a=z3(n,t,{stdio:"ignore",windowsHide:!0}),l=!1,d,s=(c)=>{if(l)return;if(l=!0,d)clearTimeout(d);e(c)};a.once("error",()=>s(null)),a.once("close",s),d=setTimeout(()=>{a.kill(),s(null)},r)})}async function R8(n=fetch){try{let t=await n(`https://api.github.com/repos/${gt}`,{headers:{accept:"application/vnd.github+json"},signal:AbortSignal.timeout(he)});if(!t.ok)return null;let r=await t.json();return typeof r.stargazers_count==="number"?r.stargazers_count:null}catch{return null}}function V8(n){if(n[0]!=="help")return!1;let t=n[1];if(!t)Cr(),process.exit(0);if(zn(t))process.exit(0);console.error(`Unknown command: ${t}`),console.error("Run 'cc-safety-net --help' for available commands."),process.exit(1)}var K8={hook:async(n)=>{let t=R1(n);if(t){await t.run();return}console.error("hook requires exactly one integration flag. Try: cc-safety-net hook --kimi-code"),zn("hook",console.error),process.exit(1)},install:async(n)=>{process.exit(await Zn("install",n))},update:async(n)=>{process.exit(await ie(n))},uninstall:async(n)=>{process.exit(await Zn("uninstall",n))},rule:async(n)=>{process.exit(await c3(n))},status:async(n)=>{if(e2(F({label:"status"},n).errors))process.exit(1);i3()},statusline:async(n)=>{let t=F({label:"statusline",booleans:{claudeCode:["-cc","--claude-code"]}},n);if(t.errors.length===0&&t.flags.claudeCode){await be();return}if(e2(t.errors),!t.flags.claudeCode)console.error("statusline requires --claude-code (-cc)");zn("statusline",console.error),process.exit(1)},doctor:async(n)=>{let t=Rr(n);if(!t)process.exit(1);let r=await J0({json:t.json,skipUpdateCheck:t.skipUpdateCheck});process.exit(r)},logs:async(n)=>{process.exit(await L1(n))},gui:async(n)=>{process.exit(await B3(n))},explain:async(n)=>{let t=Vr(n);if(!t)process.exit(1);let r=M2(t.command,{cwd:t.cwd}),e=!!process.env.NO_COLOR||!process.stdout.isTTY;if(t.json)console.log(Gr(r));else console.log(Mr(r,{asciiOnly:e}));process.exit(0)}};async function M8(){let n=process.argv.slice(2),t=F({label:"cc-safety-net",booleans:{version:["-V","--version"]},positionals:"list"},n);if(V8(n))return;let r=n[0],e=r?Kn(r):void 0;if(t.help&&e&&e.name!=="rule")zn(e.name),process.exit(0);if(!r||t.help&&!e)Cr(),process.exit(0);if(t.flags.version)W0(),process.exit(0);if(e){await K8[e.name](n.slice(1));return}let a=V1(r);if(a){await a.run();return}if(r==="--statusline"){await be();return}console.error(r.startsWith("-")?`Unknown option: ${r}`:`Unknown command: ${r}`),console.error("Run 'cc-safety-net --help' for usage."),process.exit(1)}M8().catch((n)=>{console.error("CC Safety Net error:",n),process.exit(1)});