cc-safety-net 2.0.11 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,42 +1,42 @@
1
1
  #!/usr/bin/env node
2
- import{$ as yr,$a as er,A as ht,Aa as qo,B as pc,Ba as Vo,C as ee,Ca as gr,D as J,Da as zo,E as ir,Ea as Ko,F as Jn,Fa as Y,G as qt,Ga as Qn,H as Yn,Ha as sr,I as Ze,Ia as ar,J as Ce,Ja as Z,K as lr,Ka as Nc,L as ue,La as bt,M as Ai,Ma as Fc,N as hr,Na as Eo,O as Vt,Oa as Hc,P as Ei,Pa as Mc,Q as Pi,Qa as jc,R as Se,Ra as xn,S as Kt,Sa as Uc,T as kt,Ta as Gc,U as xt,Ua as gi,V as li,Va as hi,W as yt,Wa as yi,X as De,Xa as Li,Y as cr,Ya as hc,Z as pe,Za as ri,_ as Ti,_a as oi,aa as Oi,ab as ii,b as Oo,ba as $i,bb as si,c as $o,ca as dr,cb as Le,d as G,da as ci,db as xe,e as No,ea as jo,eb as ce,f as Vn,fa as di,fb as ai,g as N,ga as ui,gb as B,h as C,ha as pi,hb as wt,i as ft,ia as ur,ib as Lt,j as w,ja as Uo,jb as _i,k as ke,ka as S,kb as Ae,l as Zo,la as pr,lb as fe,m as Ve,ma as Ii,mb as Gi,n as mt,na as de,nb as zt,o as wc,oa as vt,p as Wn,pa as fr,q as Xo,qa as mr,r as gt,ra as fi,s as Qo,sa as mi,t as or,ta as Go,u as ei,ua as Je,v as ti,va as Zn,w as X,wa as Xn,x as Q,xa as ni,y as Ke,ya as Be,z as We,za as $c}from"../chunks/index-9dxxkq16.js";var Wc=["-h","--help"];function T(e,t){let n=Object.entries(e.booleans??{}),r=Object.entries(e.values??{}),o=Object.fromEntries(n.map(([d])=>[d,!1])),i={},s=[],a=[],l=!1,c=-1;for(let[d,p]of t.entries()){if(d<=c)continue;if(p==="--"){s.push(...t.slice(d+1));break}if(Wc.includes(p)){l=!0;continue}let g=n.find(([,m])=>m.includes(p));if(g){o[g[0]]=!0;continue}let u=r.find(([,m])=>m.includes(p));if(u){let m=t[d+1];if(m===void 0||m.startsWith("-")){a.push(`${p} requires a value`);continue}i[u[0]]=m,c=d+1;continue}if(p.startsWith("-")){a.push(`Unknown option for ${e.label}: ${p}`);continue}if(e.positionals==="tail"){s.push(...t.slice(d));break}s.push(p)}if(e.positionals!=="list"&&e.positionals!=="tail")a.push(...s.map((d)=>`Unexpected argument for ${e.label}: ${d}`));return{flags:o,values:i,positionals:s,help:l,errors:a}}function ae(e){for(let t of e)console.error(t);return e.length>0}import{readdirSync as $d,statSync as bi,unlinkSync as Nd}from"node:fs";import{basename as wi,dirname as Fd,join as Hd,resolve as Md}from"node:path";function I(e){return Array.from(e,(t)=>{let n=t.charCodeAt(0);if(n<=31||n>=127&&n<=159)return`\\x${n.toString(16).padStart(2,"0")}`;return t}).join("")}var Un=(e)=>{let t=Date.now()-new Date(e).getTime();if(!Number.isFinite(t))return"";let n=Math.floor(t/60000),r=Math.floor(n/60),o=Math.floor(r/24);if(o>0)return`${o}d ago`;if(r>0)return`${r}h ago`;if(n>0)return`${n}m ago`;return"just now"},je=(e)=>{let t=(e??"").trim().split(/\s+/).filter((o)=>o&&!/^[A-Za-z_][A-Za-z0-9_]*=/.test(o)),n=t[0]?.split("/").pop();if(!n)return null;let r=t[1];return r&&/^[a-z][a-z0-9-]*$/.test(r)?`${n} ${r}`:n};import{existsSync as Jc,readdirSync as Yc,readFileSync as Zc}from"node:fs";import{join as Xc}from"node:path";function ye(e,t){try{return Yc(e,{withFileTypes:!0,encoding:"utf8"}).flatMap((n)=>{let r=Xc(e,n.name);if(n.isDirectory())return ye(r,t);if(n.name.endsWith(".jsonl"))return[r];return[]})}catch{if(t&&Jc(e))t.count++;return[]}}function Gn(e){let t=(o)=>`${o.sessionId}
3
- ${je(o.segment||o.command)}`,n=e.filter((o)=>o.decision!=="allow"),r=n.filter((o)=>o.sessionId).reduce((o,i)=>o.set(t(i),(o.get(t(i))??0)+1),new Map);return new Set(n.filter((o)=>o.failureStage||(r.get(t(o))??0)>=2))}var Qc=["segment","reason","sessionId","decision","agent","ruleId","failureStage"];function ed(e){if(!e||typeof e!=="object"||Array.isArray(e))return!1;let t=e;if(typeof t.ts!=="string"||typeof t.command!=="string")return!1;return Qc.every((n)=>t[n]===void 0||typeof t[n]==="string")}function we(e,t){try{return Zc(e,"utf-8").split(`
4
- `).filter(Boolean).flatMap((n)=>{try{let r=JSON.parse(n);if(!ed(r)){if(t)t.count++;return[]}return[r]}catch{if(t)t.count++;return[]}})}catch{if(t)t.count++;return[]}}import{resolve as Rd}from"node:path";var td=["AKIA","ASIA","ghp_","gho_","ghu_","ghs_","ghr_","github_pat_","glpat-","xox","npm_","pypi-","rk_","sk-","sk_","gsk_","xai-","pplx-","bastn_","tgp_v1_","flp_","wfr_","fw_","fwp_","tp-","psk-"];function Fo(e){let t=0,n={allocateSegment(){return t++},getNextSegmentIndex(){return t},recordGlobal(r){e.record({kind:"step",scope:"global",step:r})},recordSegment(r,o=n.currentSegmentIndex){if(o===void 0)return;e.record({kind:"step",scope:"segment",segmentIndex:o,step:r})}};return n}function Ho(e={}){let t=[],n=e.maxEvents??512,r={maxTextLength:e.maxTextLength??2048,maxListLength:e.maxListLength??128,maxObjectProperties:e.maxObjectProperties??e.maxListLength??128,maxDepth:e.maxDepth??16},o=0,i,s=new Set;return{record(a){if(i)return;try{if(!a||t.length>=n){o++;return}t.push(qn(nd(a,r,s)))}catch{o++}},finish(a){if(i)return i;try{i=qn({events:Object.freeze(t),droppedEvents:o,terminal:rd(a,r,s)})}catch{o++,i=Object.freeze({events:Object.freeze(t),droppedEvents:o,terminal:Object.freeze({result:"blocked",reason:"trace unavailable".slice(0,r.maxTextLength),segment:"trace unavailable".slice(0,r.maxTextLength)})})}return i}}}function nd(e,t,n){if(e.kind!=="step")throw TypeError("invalid trace event");let{scope:r,step:o}=e;Ut(o,n,t);let i=Ue(o,t,n);if(r==="global")return{kind:"step",scope:"global",step:i};if(r!=="segment")throw TypeError("invalid trace event scope");return{kind:"step",scope:"segment",segmentIndex:e.segmentIndex,step:i}}function rd(e,t,n){let r=e.result;if(r==="allowed")return Object.freeze({result:"allowed"});if(r!=="blocked")throw TypeError("invalid trace terminal");let o=e.ruleId;return Object.freeze({result:"blocked",reason:Ue(e.reason,t,n),segment:Ue(e.segment,t,n),...o?{ruleId:Ue(o,t,n)}:{}})}function Ut(e,t,n,r=0,o=new WeakSet){if(typeof e==="string"){let a=e.slice(0,n.maxTextLength);if(!Vn(a))return;for(let l of No(a))for(let c of l.match(/[^\s"'()$]+/g)??[])t.add(Mo(c));return}if(!e||typeof e!=="object"||r>=n.maxDepth||o.has(e))return;if(o.add(e),Array.isArray(e)){let a=Math.min(e.length,n.maxListLength);for(let l=0;l<a;l++)Ut(e[l],t,n,r+1,o);return}let i=0,s=new Set;for(let a in e){if(!Object.hasOwn(e,a))continue;if(i>=n.maxObjectProperties)break;i++,Ut(a,t,n);let l=Bn(a,n,t);if(s.has(l))continue;s.add(l),Ut(e[a],t,n,r+1,o)}}function Ue(e,t,n,r=0,o=new WeakSet){if(typeof e==="string")return Bn(e,t,n);if(!e||typeof e!=="object")return e;if(r>=t.maxDepth)return;if(o.has(e))return;if(o.add(e),Array.isArray(e)){let a=[],l=Math.min(e.length,t.maxListLength);for(let c=0;c<l;c++)a.push(Ue(e[c],t,n,r+1,o));return a}let i={},s=0;for(let a in e){if(!Object.hasOwn(e,a))continue;if(s>=t.maxObjectProperties)break;s++;let l=Bn(a,t,n);if(Object.hasOwn(i,l))continue;Object.defineProperty(i,l,{value:Ue(e[a],t,n,r+1,o),enumerable:!0,configurable:!0,writable:!0})}return i}function Bn(e,t,n){let r=e.slice(0,t.maxTextLength),o=Vn(r)?$o(r):r,i=n.size>0?id(o,n):o;return(od(i)?Oo(i):i).slice(0,t.maxTextLength)}function od(e){return e.includes("PRIVATE KEY")||e.includes("://")||e.includes("eyJ")||e.includes(":")&&/(?:authorization|cookie|x-api-key|api-key|(?:^|\s)(?:-u|--user)(?:\s|=))/i.test(e)||e.length>=14&&td.some((t)=>e.includes(t))||e.length>=49&&/\b[a-f0-9]{32}\.[A-Za-z0-9]{16}\b/.test(e)}function id(e,t){return e.replace(/[^\s"'()$]+/g,(n)=>t.has(Mo(n))?"<redacted>":n)}function Mo(e){let t=2166136261,n=2166136261;for(let r=0;r<e.length;r++)t=Math.imul(t^e.charCodeAt(r),16777619),n=Math.imul(n^e.charCodeAt(e.length-r-1),16777619);return`${t>>>0}:${n>>>0}:${e.length}`}function qn(e){if(e&&typeof e==="object"&&!Object.isFrozen(e)){for(let t of Object.values(e))qn(t);Object.freeze(e)}return e}function Bo(e,t,n){let r=n??jo(),o=r.getCommandProgram(e,t.shell??"auto"),i=Ho(),s=Fo(i),a=o.dialect==="powershell"?r.getCommandProgram(e,"posix"):o,l=Uo(a);s.recordGlobal({type:"parse",input:e,segments:l.map((p)=>[...p])});let c=Go(e,{...t,analyzePartialProgram:!0,trace:s},o,r),d=s.getNextSegmentIndex();if(c&&d>0&&d<l.length)s.recordSegment({type:"segment-skipped",index:d,reason:"prior-segment-blocked"},d);return Object.freeze({decision:c,trace:i.finish(c?{result:"blocked",reason:c.reason,segment:c.evidence.find((p)=>p.kind==="command")?.segment??e,...c.ruleId?{ruleId:c.ruleId}:{}}:{result:"allowed"}),program:o})}import{resolve as sd}from"node:path";function zn(e){let t=qo().safeParse(e);return{errors:t.success?[]:zo(t.error.issues),ruleNames:new Set(Vo(e).map((n)=>n.toLowerCase()))}}function Kn(e){let t=Wo(e);if(!t.ok)return t.result;return zn(t.parsed)}function Wo(e){let t=[],n=new Set;try{let r=typeof e==="string"?ft(e):e,o=w(r);if(o===null)return t.push(`File not found: ${r.path}`),{ok:!1,result:{errors:t,ruleNames:n}};if(!o.trim())return t.push("Config file is empty"),{ok:!1,result:{errors:t,ruleNames:n}};return{ok:!0,parsed:JSON.parse(o)}}catch(r){if(r instanceof N)return t.push(r.message),{ok:!1,result:{errors:t,ruleNames:n}};let o=r instanceof Error?r.message:String(r);return t.push(r instanceof SyntaxError?"Invalid JSON":o),{ok:!1,result:{errors:t,ruleNames:n}}}}function Jo(e){return sd(e??process.cwd(),".safety-net.json")}function le(e){let t=Wo(e);if(!t.ok)return t.result;let n=Ko(t.parsed);return{errors:n.errors,ruleNames:n.sources}}import{isAbsolute as ad,join as Gt,relative as ld,resolve as Yo,sep as cd}from"node:path";async function ze(e={}){let t=nr(e);return dd(t,await Bt(t,Be()))}function dd(e,t){if(!t.ok)return t;let n=J(e),r=[...new Set(ce(n.configPath,n.lockPath,e,n.filesystemScope))];if(r.length===0)return t;return{ok:!1,errors:r,warnings:t.warnings,entries:t.entries}}async function Bt(e,t,n,r={}){let o=null,i=!1;try{let s=J(e),a=Qn(s.configTarget);if(!a.ok)return a.result;let l=a.config;if(e.check)return hd(l,s,e);o={target:s.lockTarget,content:w(s.lockTarget)};let c=er(s.lockTarget);if(c.errors.some((L)=>L.startsWith("Unable to access ")))return{ok:!1,errors:c.errors,warnings:[],entries:[]};if(e.only&&c.errors.length>0)return{ok:!1,errors:c.errors,warnings:[],entries:[]};let d=c.errors.length>0?null:c.lock,p=e.only?ri(l,d,e.only):{ok:!0,specs:l.rules};if(!p.ok)return p.result;if(e.only&&!d&&p.specs.length<l.rules.length)return{ok:!1,errors:[`No lockfile available for partial update; run ${ti}`],warnings:[],entries:[]};let g=(await pd(p.specs,(L)=>ii(L,s.configDir,e,d,s.filesystemScope,t),t)).map((L)=>yd(L,d,n));for(let L of g)bd(L.content,L.entry,s.configDir,e,s.filesystemScope);let u=e.only?Ld(l,d,g):g.map((L)=>L.entry);i=!0,Z(s.lockTarget,{version:1,rulebooks:u},void 0,r._testAfterPolicyRename);let m=new Map(g.map((L)=>[L.entry.spec,L.rulebook.rules.length])),f=wd(u,s.configDir,e,s.filesystemScope,r);return{ok:!0,errors:[],warnings:f,entries:u.map((L)=>vd(L,m))}}catch(s){if(i&&o)try{Ge(o.target,o.content)}catch(a){return qe(a)}return qe(s)}}async function tr(e,t={}){return ud(e,nr(t),Be())}async function ud(e,t,n,r={}){let o=null,i=!1;try{let s=J(t),a=w(s.configTarget);o={target:s.configTarget,content:a};let l=Qn(s.configTarget);if(!l.ok)return l.result;let c=l.config,d=ei(e)?await si(e,n):[{spec:e}],p=d.map((m)=>m.spec),g=[...new Set([...c.rules,...p])];if(g.length>Zn)return fd();if(g.length!==c.rules.length)i=!0,Z(s.configTarget,{version:1,rules:g,overrides:c.overrides??{},transparent_wrappers:c.transparent_wrappers??[]},void 0,r._testAfterPolicyRename);let u=await Bt(t,n,new Map(d.filter((m)=>!!m.display_ref).map((m)=>[m.spec,m.display_ref])),r);if(!u.ok)Ge(s.configTarget,a);return u}catch(s){if(i&&o)try{Ge(o.target,o.content)}catch(a){return qe(a)}return qe(s)}}async function pd(e,t,n=Be()){if(e.length>Zn)throw Error(Xn);let r=Array(e.length),o=0,i,s=Array.from({length:Math.min(e.length,ni.concurrency)},async()=>{while(!i){let a=o;if(a>=e.length)return;o++;try{r[a]=await t(e[a],a,n.controller.signal)}catch(l){if(!i)i={value:l},o=e.length,n.controller.abort(l);return}}});if(await Promise.all(s),i)throw i.value;return r}function fd(){return{ok:!1,errors:[Xn],warnings:[],entries:[]}}function nr(e){return{cwd:e.cwd,cacheConfigDir:e.cacheConfigDir,userConfigDir:e.userConfigDir,userConfigPath:e.userConfigPath,projectConfigPath:e.projectConfigPath,global:e.global,check:e.check,only:e.only,refresh:e.refresh}}function md(e){return{...nr(e),deleteSource:e.deleteSource}}async function rr(e,t={}){try{return await gd(e,md(t),{})}catch(n){return qe(n)}}async function gd(e,t,n){let r=J(t),o=Y(r.configTarget);if(o.errors.length>0)return{ok:!1,errors:o.errors,warnings:[],entries:[]};if(!o.config)return{ok:!1,errors:[`No config found at ${r.configPath}`],warnings:[],entries:[]};let i=er(r.lockTarget);if(i.errors.length>0)return{ok:!1,errors:i.errors,warnings:[],entries:[]};let s=oi(o.config.rules,i.lock,e);if(!s.ok)return s.result;let a=t.deleteSource?kd(r.configDir,s.specs,i.lock,r.filesystemScope):{ok:!0,dirs:[]};if(!a.ok)return a.result;let l=w(r.configTarget);if(l===null)return qe(Error("Rules config is unavailable."));try{Z(r.configTarget,{version:1,rules:o.config.rules.filter((p)=>!s.specs.includes(p)),overrides:o.config.overrides??{},transparent_wrappers:o.config.transparent_wrappers??[]},void 0,n._testAfterPolicyRename)}catch(p){throw Ge(r.configTarget,l),p}let c=await Bt(t,Be(),void 0,n);if(!c.ok)return Ge(r.configTarget,l),c;let d=Cd(a.dirs,n,r.filesystemScope);if(!d.ok){Ge(r.configTarget,l);let p=await Bt(t,Be(),void 0,n);if(!p.ok)return{ok:!1,errors:[...d.result.errors,...p.errors],warnings:p.warnings,entries:p.entries};return d.result}return c}async function hd(e,t,n){let r=ai(e,t.lockPath,t.configDir,n,n.global?"user":"project",t.filesystemScope);return{ok:r.errors.length===0&&r.warnings.length===0,errors:[...r.errors,...r.warnings],warnings:[],entries:r.entries}}function yd(e,t,n){let r=t?.rulebooks.find((i)=>i.spec===e.entry.spec&&i.kind==="github"),o=n?.get(e.entry.spec)??(r?.kind==="github"?r.display_ref:void 0);if(!o||e.entry.kind!=="github")return e;return{...e,entry:{...e.entry,display_ref:o}}}function Ld(e,t,n){let r=new Set(e.rules),o=new Set(t?.rulebooks.map((s)=>s.spec)??[]),i=new Map(n.map((s)=>[s.entry.spec,s.entry]));return[...(t?.rulebooks.filter((s)=>r.has(s.spec))??[]).map((s)=>i.get(s.spec)??s),...n.filter((s)=>!o.has(s.entry.spec)).map((s)=>s.entry)]}function vd(e,t){return{...e,ruleCount:t.get(e.spec)}}function bd(e,t,n,r,o){let i=Jn(t,Yn(n,r));ke(C(o,i),e)}function wd(e,t,n,r,o){let i=Yn(t,n),s=qt(i),a=C(r,s),l=Ve(a);if(!l)return[];let c=e.map((p)=>C(r,Jn(p,i))),d=l.filter((p)=>p.kind==="directory").map((p)=>({directory:C(r,Gt(s,p.name)),identity:C(r,Gt(s,p.name,Qo))})).filter((p)=>!c.some((g)=>Zo(p.identity,g))).map((p)=>p.directory);for(let p of d)Xo(p);return d.flatMap((p)=>{try{return Sd(p,o),[]}catch{return["Unable to prune rules policy cache safely."]}})}function kd(e,t,n,r){let o=new Map(n?.rulebooks.map((c)=>[c.spec,c])??[]),i=t.flatMap((c)=>{let d=o.get(c);if(!d)return gt.test(c)?[]:["--delete-source can only delete local rulebook sources"];return d.kind==="local-directory"?[]:["--delete-source can only delete local rulebook sources"]}),s=t.map((c)=>{let d=o.get(c);return Gt(e,d?.kind==="local-directory"?d.path:c)}),a=i.length>0?[]:s.flatMap((c)=>xd(e,c,r)),l=[...i,...a];return l.length>0?{ok:!1,result:{ok:!1,errors:l,warnings:[],entries:[]}}:{ok:!0,dirs:s}}function xd(e,t,n){let r=Yo(e),o=Yo(t),i=ld(r,o);if(i===""||i===".."||i.startsWith(`..${cd}`)||ad(i))return[`Refusing to delete local rulebook source outside ${e}: ${t}`];let s=C(n,o),a=Ve(s);if(!a)return[`Local rulebook source directory not found: ${t}`];let l=a.find((c)=>c.name==="rulebook.json");if(!l)return[`Local rulebook source directory is missing rulebook.json: ${t}`];if(l.kind!=="file")throw new N(n.label);if(w(C(n,Gt(o,"rulebook.json"))),a.length>1)return[`Local rulebook source directory contains extra files: ${t}. delete manually if you really want to remove the directory.`];return[]}function Cd(e,t,n){let r=e.flatMap((o)=>{try{return Dd(C(n,o),t),[]}catch(i){return[`Failed to delete local rulebook source ${o}: ${i instanceof Error?i.message:String(i)}`]}});return r.length>0?{ok:!1,result:{ok:!1,errors:r,warnings:[],entries:[]}}:{ok:!0}}function Sd(e,t){if(t._testPruneRulebookCacheDir){t._testPruneRulebookCacheDir(e.path);return}Wn(e)}function Dd(e,t){if(t._testDeleteLocalSourceDir){t._testDeleteLocalSourceDir(e.path);return}Wn(e)}function Ge(e,t){if(t===null){mt(e);return}ke(e,t)}function qe(e){return{ok:!1,errors:[e instanceof Error?e.message:String(e)],warnings:[],entries:[]}}function Ye(e,t){let n=Ed(t),r=fi(n),o={effectiveLevel:r.effectiveLevel,selectedPreset:n.policySnapshot.policy.safety.level??"standard",effectiveCapabilities:r.effectiveCapabilities,destructiveCommandRuleOverrides:n.policySnapshot.policy.destructiveCommandRuleOverrides},{configSource:i,configValid:s}=Ad({cwd:t?.cwd,userConfigDir:t?.userConfigDir});if(!e||!e.trim())return{trace:{steps:[{type:"error",message:"No command provided"}],segments:[]},result:"allowed",configSource:i,configValid:s,...o};let a=Pd(e,n);if(a)return{trace:{steps:[],segments:[{index:0,steps:[{type:"rule-check",rule:a.rule,matched:!0,reason:a.reason}]}]},result:"blocked",reason:G(a.reason),segment:G(a.target),...a.ruleId?{ruleId:G(a.ruleId)}:{},configSource:i,configValid:s,...o};let l=Bo(e,n),c=l.decision,d=c?.ruleId??Td(e,n),p=yt.find((u)=>u.id===d&&u.activationCapability),g=p?r.policy.effectiveDestructiveCommandRules[p.id]:void 0;return{trace:_d(l.trace),result:c?"blocked":"allowed",reason:c?G(c.reason):void 0,segment:c?G(c.evidence.find((u)=>u.kind==="command")?.segment??e):void 0,ruleId:c?.ruleId?G(c.ruleId):void 0,customRule:Id(Od(c?.ruleId,n.policySnapshot)),configSource:i,configValid:s,...o,...p&&g?{ruleActivation:{id:p.id,...g}}:{}}}function Ad(e){let t=X(e?.cwd),n=e?.userConfigPath??Q(e),r=ee({cwd:e?.cwd,userConfigDir:e?.userConfigDir,userConfigPath:e?.userConfigPath});try{if(w(r.projectConfigTarget)!==null){if(le(r.projectConfigTarget).errors.length===0)return{configSource:t,configValid:!0};return{configSource:t,configValid:!1}}}catch(o){if(o instanceof N)return{configSource:t,configValid:!1};throw o}try{if(w(r.userConfigTarget)!==null){let o=le(r.userConfigTarget);return{configSource:n,configValid:o.errors.length===0}}return{configSource:null,configValid:!0}}catch(o){if(o instanceof N)return{configSource:n,configValid:!1};throw o}}function Ed(e){let t=Rd(e?.cwd??process.cwd()),n=e?.policySnapshot??B({cwd:t,userConfigDir:e?.userConfigDir}),r=de(n.policy);return{cwd:t,effectiveCwd:t,policySnapshot:n,environment:li(),protectedGitMetadata:pi([t]),effectiveCapabilities:r.capabilities,strict:e?.strict??r.strict,paranoidRm:r.paranoidRm,paranoidInterpreters:r.paranoidInterpreters,worktreeMode:r.worktreeMode}}function Pd(e,t){let n=t.cwd??process.cwd(),r=ci(Je("",{command:e},{kind:"command",shell:"posix"},{executionCwd:n,configCwd:n},e)),o=hi(r);if(o)return{reason:gi,target:o.target,ruleId:"policy-protection",rule:"policy-protection:findPolicyConfigMutationTargetInSemanticFacts"};let i=ui(r,t.protectedGitMetadata);if(i)return{reason:di,target:i.target,ruleId:"git-metadata-protection",rule:"git-metadata-protection:findGitMetadataMutationTargetInSemanticFacts"};let s=t.policySnapshot.policy,a=s.secretProtection.enabled===!1?null:Li(r,s.secretProtection,{strict:t.strict});if(a)return{reason:yi,target:a.target,ruleId:a.ruleId,rule:"secret-protection:findSensitiveTargetInSemanticFacts"};return null}function Td(e,t){let n=t.policySnapshot.policy,r=Lt({...n,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:{...n.destructiveCommandRuleOverrides,...Object.fromEntries(yt.flatMap((o)=>o.activationCapability?[[o.id,"on"]]:[]))}},t.policySnapshot.state==="degraded"?{diagnostics:t.policySnapshot.diagnostics,reason:t.policySnapshot.reason}:void 0);return mi(e,{...t,policySnapshot:r,strict:!0,paranoidRm:!0,paranoidInterpreters:!0})?.ruleId}function Id(e){if(!e)return;return{id:G(e.id),...e.rulebook?{rulebook:{name:G(e.rulebook.name),version:G(e.rulebook.version)}}:{},...e.source?{source:G(e.source)}:{},...e.override?{override:{type:"reason",reason:G(e.override.reason)}}:{}}}function _d(e){let t=e.events.flatMap((r)=>r.kind==="step"&&r.scope==="global"?[r.step]:[]),n=new Map;for(let r of e.events){if(r.kind!=="step"||r.scope!=="segment")continue;let o=n.get(r.segmentIndex)??{index:r.segmentIndex,steps:[]};o.steps.push(r.step),n.set(r.segmentIndex,o)}return{steps:t,segments:[...n.values()]}}function Od(e,t){let n=e?.replace(/^custom\./,"");if(!n||!t.policy.rules.some((r)=>r.name===n))return;return t.ruleMetadata[n]??Object.freeze({id:n})}function jd(e){let t=Ze(),n=T({label:"logs",booleans:{all:["--all"],suspect:["--suspect"],json:["--json"],pruneLegacy:["--prune-legacy"],dryRun:["--dry-run"]},values:{id:["--id"],limit:["--limit"],since:["--since"],agent:["--agent"],rule:["--rule"],session:["--session"],project:["--project"]}},e);if(ae(n.errors))return null;if(n.values.id!==void 0&&!/^[a-f0-9]{16}$/.test(n.values.id))return console.error("--id must be 16 hexadecimal characters"),null;let r=n.values.limit===void 0?20:vi(n.values.limit);if(r===null)return console.error("--limit must be a positive number"),null;let o=n.values.since===void 0?Math.min(30,t):vi(n.values.since);if(o===null||o>t)return console.error(`--since must be a positive number of days no greater than ${t}`),null;let i={limit:r,limitExplicit:n.values.limit!==void 0,since:o,sinceExplicit:n.values.since!==void 0,all:n.flags.all,json:n.flags.json,suspect:n.flags.suspect,pruneLegacy:n.flags.pruneLegacy,dryRun:n.flags.dryRun,id:n.values.id,agent:n.values.agent,rule:n.values.rule,session:n.values.session,project:n.values.project===void 0?void 0:Md(n.values.project)};if(i.id&&(i.agent!==void 0||i.rule!==void 0||i.session!==void 0||i.project!==void 0||i.suspect||i.sinceExplicit||i.limitExplicit))return console.error("--id cannot be combined with --agent, --rule, --session, --project, --suspect, --since, or --limit"),null;if(i.pruneLegacy&&(i.id!==void 0||i.agent!==void 0||i.rule!==void 0||i.session!==void 0||i.project!==void 0||i.suspect||i.all||i.sinceExplicit||i.limitExplicit))return console.error("--prune-legacy cannot be combined with --id, --agent, --rule, --session, --project, --suspect, --all, --since, or --limit"),null;if(i.dryRun&&!i.pruneLegacy)return console.error("--dry-run requires --prune-legacy"),null;return i}async function ki(e,t={}){let n=jd(e);if(!n)return 1;let r=t.logsDir??ue();if(n.pruneLegacy)return Ud(r,n.json,n.dryRun);if(!r)return console.log(n.json?"[]":n.id?`No retained audit log entry found for id ${I(n.id)}.`:"No audit log entries found."),0;Ce(r);let o={count:0},i=ye(r,o).flatMap((d)=>we(d,o).map((p)=>({entry:p,file:d})));if(o.count>0)console.error(`warning: ${o.count} audit log ${o.count===1?"source":"sources"} could not be read; these results are incomplete`);if(n.id)return Vd(i,n,t.timeZone);let s=Date.now()-n.since*24*60*60*1000,a=i.filter((d)=>zd(d,n,r,s)),l=n.suspect?Gn(a.map((d)=>d.entry)):null,c=(l?a.filter((d)=>l.has(d.entry)):a).sort((d,p)=>Date.parse(p.entry.ts)-Date.parse(d.entry.ts)).slice(0,n.limit);if(n.json)return console.log(JSON.stringify(c.map((d)=>d.entry),null,2)),0;if(c.length===0)return console.log("No audit log entries found."),0;for(let d of c)console.log(Jd(d.entry,t.timeZone));return 0}function Ud(e,t,n){let r=e?Bd(e).map((a)=>Hd(e,a)):[];if(n)return Gd(r,t);let o=[],i=0,s=0;for(let a of r){let l=bi(a,{throwIfNoEntry:!1})?.size??0,c=qd(a);if(c){o.push(`${wi(a)}: ${c}`);continue}i++,s+=l}if(t)return console.log(JSON.stringify({removedFiles:i,removedBytes:s,failedFiles:o.length})),o.length===0?0:1;console.log(i===0&&o.length===0?"No legacy audit log files found.":`Removed ${i} legacy audit log ${i===1?"file":"files"} (${xi(s)}).`);for(let a of o)console.error(`Could not remove ${I(a)}`);if(console.log("Nested v2 audit logs were not changed."),i>0)console.log("This deletion cannot be undone.");return o.length===0?0:1}function Gd(e,t){let n=e.reduce((r,o)=>r+(bi(o,{throwIfNoEntry:!1})?.size??0),0);if(t)return console.log(JSON.stringify({dryRun:!0,files:e.length,bytes:n})),0;if(console.log(e.length===0?"No legacy audit log files found.":`Would remove ${e.length} legacy audit log ${e.length===1?"file":"files"} (${xi(n)}).`),console.log("Nested v2 audit logs are not included."),e.length>0)console.log("Run the same command without --dry-run to delete them.");return 0}function Bd(e){try{return $d(e,{withFileTypes:!0}).filter((t)=>t.isFile()&&t.name.endsWith(".jsonl")).map((t)=>t.name)}catch{return[]}}function qd(e){try{return Nd(e),null}catch(t){return t instanceof Error?t.message:String(t)}}function xi(e){let t=["B","KiB","MiB","GiB"],n=Math.min(Math.floor(Math.log2(Math.max(e,1))/10),t.length-1);return`${Math.round(e/1024**n*10)/10} ${t[n]}`}function Vd(e,t,n){let r=e.filter((i)=>i.entry.id===t.id);if(r.length>1)return console.error(`Multiple audit log entries found for id ${I(t.id??"")}.`),1;if(t.json)return console.log(JSON.stringify(r.map((i)=>i.entry),null,2)),0;let o=r[0];if(!o)return console.log(`No retained audit log entry found for id ${I(t.id??"")}.`),0;return console.log(Yd(o.entry,n)),0}function zd(e,t,n,r){if(!t.all&&e.entry.decision==="allow")return!1;if(Date.parse(e.entry.ts)<r)return!1;if(t.agent!==void 0&&e.entry.agent!==t.agent)return!1;if(t.rule!==void 0&&e.entry.ruleId!==t.rule)return!1;if(t.session!==void 0&&!Kd(e,n,t.session))return!1;if(t.project!==void 0&&!Wd(e.entry.cwd,t.project))return!1;return!0}function Kd(e,t,n){if(e.entry.sessionId===n)return!0;return Fd(e.file)===t&&wi(e.file,".jsonl")===n}function Wd(e,t){if(!e)return!1;return e===t||e.startsWith(`${t}/`)}function Jd(e,t){let n=I(e.id??"-"),r=I(e.decision??"deny"),o=e.cwd?` [${I(e.cwd)}]`:"",i=e.segment||e.command,s=i===e.command?"":"↳ ",a=i.length>50?`${i.slice(0,50)}…`:i;return`${n.padEnd(16)} ${I(Ci(e.ts,t))} ${r.padEnd(5)} ${I(e.agent??"-").padEnd(15)} ${I(e.ruleId??"-").padEnd(20)} ${s}${I(a)}${o}`}function Yd(e,t){let n=(o)=>I(o===void 0||o===null||o===""?"-":o),r=e.shape?`${e.agent??"-"} (shape: ${e.shape})`:e.agent??"-";return[`id: ${n(e.id)}`,`ts: ${n(Ci(e.ts,t))}`,`decision: ${n(e.decision)}`,`agent: ${n(r)}`,`level: ${n(e.level)}`,`tool: ${n(e.toolName)}`,`rule: ${n(e.ruleId)}`,`intent: ${n(e.intent)}`,`stage: ${n(e.failureStage)}`,`error: ${n(e.errorCode)}`,`session: ${n(e.sessionId)}`,`cwd: ${n(e.cwd)}`,`version: ${n(e.v)}`,`truncated: ${n(e.truncated===!0?"yes":void 0)}`,`reason: ${n(e.reason)}`,`command: ${n(e.command)}`,`segment: ${n(e.segment)}`].join(`
5
- `)}function Ci(e,t){let n=new Date(e);if(Number.isNaN(n.getTime()))return e;return new Intl.DateTimeFormat("sv-SE",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hourCycle:"h23",timeZone:t}).format(n)}function vi(e){let t=Number(e);return Number.isFinite(t)&&t>0?t:null}var Si={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 Di={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 Ri={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 Ni,join as au,relative as lu}from"node:path";var Zd=8388608;function Xd(e,t){console.log(JSON.stringify(e(Ei(t))))}async function Qd(e){let t;try{t=(await Lr(process.stdin)).trim()}catch{e({reason:"Failed to parse hook input JSON."});return}if(!t){e({reason:"Missing hook input JSON."});return}return vr(t,e,"Failed to parse hook input JSON.")}async function Lr(e){let t=[],n=0;for await(let r of e){let o=typeof r==="string"?Buffer.from(r,"utf-8"):Buffer.from(r.buffer,r.byteOffset,r.byteLength);if(n+=o.byteLength,n>Zd)throw eu(e),Error("hook input byte limit exceeded");t.push(o)}return Buffer.concat(t,n).toString("utf-8")}function eu(e){let t=e.destroy??e.cancel;if(!t)return;try{Promise.resolve(t.call(e)).catch(()=>{})}catch{}}function vr(e,t,n){try{return JSON.parse(e)}catch{t({reason:n});return}}function M(e,t){let n=t.get(e);return n?{kind:"command",shell:n}:{kind:Ti(e)}}function te(e,t,n,r){let o=e===void 0?process.cwd():e,i=typeof o==="string"&&o.trim()!==""?fe([o]):void 0;if(i)return{configCwd:i,executionCwd:i};return O(r,t,n,ou(o)),null}function O(e,t,n,r){let o;try{o=yr(t)}catch(i){if(!(i instanceof pe))throw i}e(Vt({command:o,segment:r,toolName:n}))}async function tu(e){let t=await Qd(e.outputDeny);if(t===void 0)return;if(!t||typeof t!=="object"||Array.isArray(t)){O(e.outputDeny);return}if(!e.isSupported(t))return;let n=e.getAgent?.(t)??e.agent,r=e.agent===n?void 0:e.agent,o=su(t),i=(u,m)=>{Ai(u,()=>e.getSessionId(t),{agent:n,shape:r,toolName:m,cwd:o}),e.outputDeny(u)},s=e.getToolName(t);if(typeof s!=="string"||s.trim()===""){O((u)=>i(u),iu(t));return}let a=s,l=(u)=>i(u,a),c;try{c=e.getToolInput(t,a,l)}catch(u){if(!(u instanceof pe))throw u;O(l,void 0,a);return}if(!c.ok)return;let d=e.getContext(t,c.input,a,l);if(!d)return;let p;try{p=yr(c.input)}catch(u){if(!(u instanceof pe))throw u;O(l,void 0,a);return}let g=Je(a,c.input,c.route,d,p??null);try{let u=zt(g,{guard:{auditAllowed:Ii(),dependencies:e.guardDependencies},audit:{agent:n,shape:r,getSessionId:()=>e.getSessionId(t)}}),m=hr(u,{includeEvidence:!0,toolName:u.stage==="command-analysis"?void 0:a});if(m){e.outputDeny(m);return}e.outputAllow?.()}catch(u){if(!(u instanceof _i))throw u;nu(u);let m=hr(u.evaluation,{includeEvidence:!0,toolName:u.evaluation.stage==="command-analysis"?void 0:a});if(m)e.outputDeny(m);return}}function nu(e){if(!vt(S.debug))return;console.error(`CC Safety Net debug: ${ru(e.stage)}: ${Pi(e.cause)}`)}function ru(e){if(e==="policy-protection")return"hook policy protection failed";if(e==="config-load")return"hook config loading failed";if(e==="secret-protection")return"hook secret protection failed";return"hook analysis failed"}function ou(e){return typeof e==="string"?e:void 0}function iu(e){if(!e||typeof e!=="object"||Array.isArray(e))return;if(Object.hasOwn(e,"tool_input"))return e.tool_input;let t=e.toolCall;if(t&&typeof t==="object"&&!Array.isArray(t))return t.args;return}function su(e){if(!e||typeof e!=="object"||Array.isArray(e))return null;let t=e.cwd;if(typeof t==="string")return t;let n=e.toolCall;if(!n||typeof n!=="object"||Array.isArray(n))return null;let r=n.args;if(!r||typeof r!=="object"||Array.isArray(r))return null;let o=r.Cwd;return typeof o==="string"?o:null}async function j(e){let t=(o)=>Xd(e.createDenyOutput,o),n=e.createAllowOutput;await tu({...e,outputDeny:t,outputAllow:n?()=>console.log(JSON.stringify(n())):void 0})}function Ct(e){return au(e,".gemini","config","hooks.json")}var cu=new Map([["run_command","auto"]]),du=new Set(["absolutepath","directorypath","file_path","filepath","path","searchdirectory","searchpath","target_file","targetfile"]);function Fi(e){return M(e,cu)}async function Hi(){await j({agent:"antigravity-cli",createDenyOutput:(e)=>({decision:"deny",reason:e}),isSupported:()=>!0,getToolName:(e)=>e.toolCall?.name,getToolInput:(e,t)=>({ok:!0,input:gu(e.toolCall?.args,t),route:Fi(t)}),getContext:uu,getSessionId:(e)=>e.conversationId})}function uu(e,t,n,r){let i=mu(e).flatMap((c)=>{let d=fe([c]);return d?[d]:[]});if(!i[0])return Re(r,t,n),null;if(n!=="run_command"){let c;try{c=pu(t,n,i)}catch(d){if(d instanceof pe)return Re(r,void 0,n),null;if(!(d instanceof Se))throw d;return Re(r,t,n),null}if(!c)return Re(r,t,n),null;return{configCwd:c,executionCwd:c}}let s=e.toolCall?.args;if(!s||!Object.hasOwn(s,"Cwd"))return{configCwd:i[0],executionCwd:i[0]};let a=s.Cwd;if(typeof a!=="string"||a.trim()==="")return Re(r,t,n),null;let l=Ae(a,i);if(l){let c=Mi(l,i);if(!c)return Re(r,t,n,a),null;return{configCwd:c,executionCwd:l}}return Re(r,t,n,a),null}function pu(e,t,n){let r=Fi(t),o=[...Oi(e,du),...r.kind==="patch"?$i(e):[]].filter(Ni),i=Kt(),s=new Set(o.flatMap((a)=>{let l=Mi(kt(a,xt,i),n);return l?[l]:[]}));if(s.size>1)return null;return[...s][0]??n[0]??null}function Mi(e,t){return t.filter((n)=>fu(e,n)).reduce((n,r)=>r.length>n.length?r:n,"")||null}function fu(e,t){let n=lu(t,e);return n===""||!n.startsWith("..")&&!Ni(n)}function Re(e,t,n,r){let o=t&&typeof t==="object"?t.command:void 0;e(Vt({command:typeof o==="string"?o:void 0,segment:r,toolName:n}))}function mu(e){if(e.workspacePaths===void 0)return[process.cwd()];let t=Array.isArray(e.workspacePaths)?e.workspacePaths.filter((n)=>typeof n==="string"&&n.trim()!==""):[];return fe(t)?t:[]}function gu(e,t){if(!e)return;if(t!=="run_command")return e;return{...e,command:typeof e.CommandLine==="string"&&e.CommandLine!==""?e.CommandLine:void 0}}var St=[{id:"antigravity-cli",displayName:"Antigravity CLI",doctorOrder:3,runtime:{order:1,flags:["-ac","--agy-cli"],description:"Run as Antigravity CLI PreToolUse hook",legacyTopLevelFlags:[]},install:{order:2,flag:"--agy-cli",artifactKind:"hook config",probeCommand:["agy","--version"]}},{id:"claude-code",displayName:"Claude Code",doctorOrder:1,runtime:{order:2,displayName:"Coding CLI",flags:["-cc","--coding-cli"],legacyFlags:["--claude-code"],description:"Run as Coding CLI PreToolUse hook",legacyTopLevelFlags:["-cc","--claude-code"]},install:{order:3,flag:"--claude-code",artifactKind:"plugin",probeCommand:["claude","--version"]}},{id:"codex",displayName:"Codex",doctorOrder:4,install:{order:4,flag:"--codex",artifactKind:"plugin",probeCommand:["codex","--version"]}},{id:"copilot-cli",displayName:"GitHub Copilot CLI",doctorOrder:7,runtime:{order:5,flags:["-cp","--copilot-cli"],description:"Run as GitHub Copilot CLI PreToolUse hook",legacyTopLevelFlags:["-cp","--copilot-cli"]},install:{order:7,flag:"--copilot-cli",artifactKind:"plugin",probeCommand:["copilot","--binary-version"]}},{id:"gemini-cli",displayName:"Gemini CLI",doctorOrder:6,runtime:{order:4,flags:["-gc","--gemini-cli"],description:"Run as Gemini CLI BeforeTool hook",legacyTopLevelFlags:["-gc","--gemini-cli"]},install:{order:6,flag:"--gemini-cli",artifactKind:"extension",probeCommand:["gemini","--version"]}},{id:"hermes-agent",displayName:"Hermes Agent",doctorOrder:8,runtime:{order:6,flags:["-ha","--hermes-agent"],description:"Run as Hermes Agent pre_tool_call hook",legacyTopLevelFlags:[]},install:{order:8,flag:"--hermes-agent",artifactKind:"plugin",probeCommand:["hermes","--version"]}},{id:"kimi-code",displayName:"Kimi Code",doctorOrder:9,runtime:{order:7,flags:["-kc","--kimi-code"],description:"Run as Kimi Code PreToolUse hook",legacyTopLevelFlags:[]},install:{order:9,flag:"--kimi-code",artifactKind:"hook config",probeCommand:["kimi","--version"]}},{id:"openclaw",displayName:"OpenClaw",doctorOrder:10,install:{order:10,flag:"--openclaw",artifactKind:"plugin",probeCommand:["openclaw","--version"]}},{id:"opencode",displayName:"OpenCode",doctorOrder:11,install:{order:11,flag:"--opencode",artifactKind:"plugin",probeCommand:["opencode","--version"]}},{id:"pi",displayName:"Pi",doctorOrder:12,install:{order:12,flag:"--pi",artifactKind:"package",probeCommand:["pi","--version"]}},{id:"cursor",displayName:"Cursor",doctorOrder:5,runtime:{order:3,flags:["-cu","--cursor"],description:"Run as Cursor preToolUse hook",legacyTopLevelFlags:[]},install:{order:5,flag:"--cursor",artifactKind:"hook config",probeCommand:["cursor","--version"]}},{id:"amp",displayName:"Amp Code",doctorOrder:2,install:{order:1,flag:"--amp",artifactKind:"plugin",probeCommand:["amp","--version"]}}],Wt=St.slice().sort((e,t)=>e.doctorOrder-t.doctorOrder).map((e)=>e.id),ji=St.filter((e)=>("runtime"in e)).slice().sort((e,t)=>e.runtime.order-t.runtime.order).map((e)=>({id:e.id,displayName:"displayName"in e.runtime?e.runtime.displayName:e.displayName,flags:e.runtime.flags,legacyFlags:"legacyFlags"in e.runtime?e.runtime.legacyFlags:[],description:e.runtime.description,legacyTopLevelFlags:e.runtime.legacyTopLevelFlags})),V=St.slice().sort((e,t)=>e.install.order-t.install.order).map((e)=>({id:e.id,...e.install})).map(({order:e,...t})=>t),Z0=Object.fromEntries(St.map((e)=>[e.id,e.displayName]));function R(e){return St.find((t)=>t.id===e)?.displayName??e}import{homedir as hu}from"node:os";import{isAbsolute as Ui,join as br}from"node:path";function Bi(e){if(e!==void 0&&e!==null&&typeof e!=="string")return"unknown";if(typeof e==="string"&&!Ui(e))return"unknown";try{let t=Kt(),n=typeof e==="string"&&e?kt(e,xt,t):void 0,r=process.env.HOME||hu(),o=[["codex",process.env.CODEX_HOME||br(r,".codex")],["copilot-cli",process.env.COPILOT_HOME||br(r,".copilot")],["claude-code",process.env.CLAUDE_CONFIG_DIR||br(r,".claude")]],i=n?o.flatMap(([s,a])=>{if(!Ui(a))return[];return Gi(n,kt(a,xt,t))?[s]:[]}):[];if(i.length===1)return i[0]??"unknown";if(i.length>1)return"unknown"}catch(t){if(t instanceof Se)return"unknown";return"unknown"}if(process.env.CLAUDECODE==="1"||Boolean(process.env.CLAUDE_CODE_ENTRYPOINT))return"claude-code";return"unknown"}var wr="PreToolUse",qi="BeforeTool",Vi="pre_tool_call",kr="PreToolUse";var yu=new Map([["Bash","posix"],["PowerShell","powershell"]]);function Lu(e){return M(e,yu)}async function zi(){await j({agent:"claude-code",getAgent:(e)=>Bi(e.transcript_path),createDenyOutput:(e)=>({hookSpecificOutput:{hookEventName:wr,permissionDecision:"deny",permissionDecisionReason:e}}),isSupported:(e)=>e.hook_event_name===wr,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:Lu(t)}),getContext:(e,t,n,r)=>te(e.cwd,t,n,r),getSessionId:(e)=>e.session_id})}var vu=new Map([["bash","auto"],["Bash","auto"],["powershell","powershell"],["PowerShell","powershell"]]);function bu(e){return M(e,vu)}async function Ki(){await j({agent:"copilot-cli",createDenyOutput:(e)=>({permissionDecision:"deny",permissionDecisionReason:e}),isSupported:()=>!0,getToolName:(e)=>e.toolName,getToolInput:(e,t,n)=>{if(typeof e.toolArgs!=="string")return n({reason:"Failed to parse toolArgs JSON."}),{ok:!1};let r=vr(e.toolArgs,n,"Failed to parse toolArgs JSON.");if(r===void 0)return{ok:!1};return{ok:!0,input:r,route:bu(t)}},getContext:(e,t,n,r)=>te(e.cwd,t,n,r),getSessionId:(e)=>typeof e.sessionId==="string"&&e.sessionId.trim()?e.sessionId:void 0})}var wu=new Map([["Shell","auto"]]);function ku(e){return M(e,wu)}async function Wi(){await j({agent:"cursor",createDenyOutput:(e)=>({permission:"deny",user_message:e,agent_message:e}),createAllowOutput:()=>({permission:"allow"}),isSupported:()=>!0,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:ku(t)}),getContext:xu,getSessionId:(e)=>e.conversation_id})}function xu(e,t,n,r){let o=Cu(e);if(!o[0])return O(r,t,n),null;let i=Ae(Du(e.cwd),o);if(!i)return O(r,t,n,typeof e.cwd==="string"?e.cwd:void 0),null;if(t===null||typeof t!=="object"||Array.isArray(t))return{configCwd:i,executionCwd:i};if(!Object.hasOwn(t,"working_directory"))return{configCwd:i,executionCwd:i};let s=t.working_directory;if(typeof s!=="string"||s.trim()==="")return O(r,t,n),null;let a=Ae(s,o);if(!a)return O(r,t,n,s),null;return{configCwd:i,executionCwd:a}}function Cu(e){return Su(e).flatMap((t)=>{let n=fe([t]);return n?[n]:[]})}function Su(e){if(e.workspace_roots===void 0)return typeof e.cwd==="string"&&e.cwd.trim()!==""?[e.cwd]:[];if(!Array.isArray(e.workspace_roots))return[];return e.workspace_roots.filter((t)=>typeof t==="string"&&t.trim()!=="")}function Du(e){return typeof e==="string"&&e.trim()!==""?e:"."}var Ru=new Map([["run_shell_command","auto"]]);function Au(e){return M(e,Ru)}async function Ji(){await j({agent:"gemini-cli",createDenyOutput:(e)=>({decision:"deny",reason:e,systemMessage:e}),isSupported:(e)=>e.hook_event_name===qi,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:Au(t)}),getContext:(e,t,n,r)=>te(e.cwd,t,n,r),getSessionId:(e)=>e.session_id})}import{resolve as Eu}from"node:path";var Pu=new Map([["terminal","posix"]]);async function Yi(){await j({agent:"hermes-agent",createDenyOutput:(e)=>({action:"block",message:e}),isSupported:(e)=>e.hook_event_name===Vi,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:M(t,Pu)}),getContext:Tu,getSessionId:(e)=>e.session_id})}function Tu(e,t,n,r){let o=te(e.cwd,t,n,r);if(!o)return null;if(!t||typeof t!=="object"||Array.isArray(t))return o;if(!Object.hasOwn(t,"workdir"))return o;let i=t.workdir;if(typeof i!=="string"||i.trim()==="")return O(r,t,n),null;let s=fe([Eu(o.configCwd,i)]);if(!s)return O(r,t,n,i),null;return{...o,executionCwd:s}}var Zi=new Map([["Bash","posix"]]);function Iu(e){return M(e,Zi)}async function Xi(){await j({agent:"kimi-code",createDenyOutput:(e)=>({hookSpecificOutput:{hookEventName:kr,permissionDecision:"deny",permissionDecisionReason:e}}),isSupported:(e)=>e.hook_event_name===kr,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:Iu(t)}),getContext:(e,t,n,r)=>{let o=te(e.cwd,t,n,r);if(!o)return null;let i=e.tool_input;if(!Zi.has(n)||!i||!Object.hasOwn(i,"cwd"))return o;let s=i.cwd;if(typeof s!=="string"||s.trim()==="")return O(r,t,n),null;let a=Ae(s,[o.configCwd]);if(!a)return O(r,t,n,s),null;return{configCwd:o.configCwd,executionCwd:a}},getSessionId:(e)=>e.session_id})}var _u={"antigravity-cli":Hi,"claude-code":zi,"copilot-cli":Ki,cursor:Wi,"gemini-cli":Ji,"hermes-agent":Yi,"kimi-code":Xi},Xe=ji.map((e)=>({...e,run:_u[e.id]}));function Qi(e){let t=T({label:"hook",booleans:Object.fromEntries(Xe.map((r)=>[r.id,[...r.flags,...r.legacyFlags]]))},e);if(t.errors.length>0)return;let n=Xe.filter((r)=>t.flags[r.id]);return n.length===1?n[0]:void 0}function es(e){return Xe.find((t)=>t.legacyTopLevelFlags.some((n)=>n===e))}var Ou=Xe.map((e)=>({flags:e.flags.join(", "),description:e.description})),$u=Xe.flatMap((e)=>e.flags.map((t)=>`cc-safety-net hook ${t}`)),ts={name:"hook",description:"Run as an agent CLI hook (reads JSON from stdin)",usage:"hook INTEGRATION_FLAG",options:[...Ou,{flags:"-h, --help",description:"Show this help"}],examples:$u};var ns={name:"install",description:"Install CC Safety Net into a coding agent CLI",usage:"install [TARGET_FLAG]",options:[...V.map((e)=>({flags:e.flag,description:`Install ${R(e.id)} ${e.artifactKind}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net install",...V.map((e)=>`cc-safety-net install ${e.flag}`)]},rs={name:"uninstall",description:"Uninstall CC Safety Net from a coding agent CLI",usage:"uninstall [TARGET_FLAG]",options:[...V.map((e)=>({flags:e.flag,description:`Uninstall ${R(e.id)} ${e.artifactKind}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net uninstall",...V.map((e)=>`cc-safety-net uninstall ${e.flag}`)]},os={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 is={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 Qe={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 ss={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 as={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 Jt=[ss,Si,is,Di,Qe,ns,os,rs,ts,Ri,as];function Nu(e){return e.aliases??[]}function Yt(e){let t=e.toLowerCase();return Jt.find((n)=>n.name.toLowerCase()===t||Nu(n).some((r)=>r.toLowerCase()===t))}import{basename as Fu}from"node:path";function Zt(e=7,t=ue()){let n=Date.now()-e*24*60*60*1000,r=[],o=new Set,i=0,s,a,l,c;if(t)Ce(t);let d={count:0},p=t?ye(t,d):[];for(let u of p)for(let m of we(u,d)){if(m.decision==="allow")continue;let f=new Date(m.ts).getTime();if(f>=n){if(i++,o.add(m.sessionId??Fu(u,".jsonl")),a===void 0||f<=a)s=m.ts,a=f;if(c===void 0||f>c)l=m.ts,c=f;Hu(r,m,f)}}let g=r.map((u)=>({timestamp:u.ts,command:u.command,reason:u.reason,relativeTime:Un(new Date(u.ts))}));return{totalBlocked:i,sessionCount:o.size,recentEntries:g,oldestEntry:s,newestEntry:l,unreadable:d.count}}function Hu(e,t,n){let r=e.findIndex((o)=>n>new Date(o.ts).getTime());if(r===-1){if(e.length<3)e.push(t);return}if(e.splice(r,0,t),e.length>3)e.pop()}import{dirname as Mu}from"node:path";function ls(e,t,n,r,o){let i;try{if(w(r)===null)return{path:e,exists:!1,valid:!1,ruleCount:0};i=le(r),i.errors.push(...ce(e,t,{userConfigDir:n},o))}catch(s){if(!(s instanceof N))throw s;i={errors:[s.message],ruleNames:new Set}}return{path:e,exists:!0,valid:i.errors.length===0,ruleCount:i.ruleNames.size,...i.errors.length>0?{errors:i.errors}:{}}}function ju(e,t){return{source:t,name:e.name,command:e.command,subcommand:e.subcommand,blockArgs:[...e.block_args],reason:e.reason}}function cs(e,t){let n=t?.userConfigPath??Q(),r=t?.projectConfigPath??X(e),o=Mu(n),i=Le({cwd:e,userConfigPath:n,projectConfigPath:r,userConfigDir:o}),s=ee({cwd:e,userConfigPath:n,projectConfigPath:r,userConfigDir:o}),a=new Map(i.rulebooks.flatMap((l)=>l.rules.map((c)=>[c,l.source])));return{userConfig:ls(n,Ke({userConfigPath:n}),o,s.userConfigTarget,s.userScope),projectConfig:ls(r,We(r),o,s.projectConfigTarget,s.projectScope),effectiveRules:i.rules.map((l)=>ju(l,a.get(l.name)??"project")),shadowedRules:[]}}var Uu=[{flag:S.level,description:"Safety level preset: standard, strict, or paranoid",defaultBehavior:"standard"},{flag:S.strict,description:"Legacy; equivalent to safety.overrides.fail_closed",defaultBehavior:"permissive"},{flag:S.paranoid,description:"Legacy; equivalent to safety.overrides.paranoid_rm and paranoid_interpreters",defaultBehavior:"off"},{flag:S.paranoidRm,description:"Legacy; equivalent to safety.overrides.paranoid_rm",defaultBehavior:"off"},{flag:S.paranoidInterpreters,description:"Legacy; equivalent to safety.overrides.paranoid_interpreters",defaultBehavior:"off"},{flag:S.worktree,description:"Allow local git discards in linked worktrees",defaultBehavior:"off"},{flag:S.debug,description:"Print diagnostic messages to stderr",defaultBehavior:"off"},{flag:S.auditScope,description:"Command decisions recorded: all, or blocked (privacy-minimizing, denials only)",defaultBehavior:"all"}];function ds(){return[...Uu.map((e)=>({name:e.flag.name,value:fr(e.flag),isSet:mr(e.flag),legacyName:e.flag.legacyName,legacyValue:e.flag.legacyName?process.env[e.flag.legacyName]:void 0,legacyIsSet:e.flag.legacyName?process.env[e.flag.legacyName]!==void 0:void 0,description:e.description,defaultBehavior:e.defaultBehavior})),{name:"CC_SAFETY_NET_HOME",value:process.env.CC_SAFETY_NET_HOME,isSet:process.env.CC_SAFETY_NET_HOME!==void 0,description:"Override user-scope config/cache directory",defaultBehavior:"~/.cc-safety-net"}]}var us={error:0,warning:1,info:2},Gu=["policy","config","audit"];function Bu(e){return e.map((t)=>{if(t==="ownership")return"is not owned by the current user";if(t==="permissions")return"has unsafe permissions";if(t==="symlink")return"is a symbolic link";return"is not a directory"}).join(" and ")}var qu=[{derive:(e)=>e.hooks.length>0&&e.hooks.every((t)=>!t.configured)?[{checkId:"integration.none-configured",severity:"error",title:"No integration configured",detail:"CC Safety Net is not connected to any supported coding-agent integration.",fixHint:"Run `cc-safety-net install` and configure at least one integration."}]:[]},{derive:(e)=>e.hooks.filter((t)=>t.inspectionStatus==="failed").map((t)=>{let n=R(t.platform);return{checkId:"integration.inspection-failed",severity:"error",title:`${n} inspection failed`,detail:`Doctor could not verify the ${n} integration configuration.`,fixHint:`Correct the reported ${n} configuration error, then run \`cc-safety-net doctor\` again.`,integration:t.platform}})},{derive:(e)=>e.userConfig.exists&&!e.userConfig.valid?[{checkId:"config.user-invalid",severity:"error",title:"User configuration is invalid",detail:"Doctor could not load a valid user rules configuration.",fixHint:"Run `cc-safety-net rule verify`, correct the reported error, then rerun doctor.",path:e.userConfig.path}]:[]},{derive:(e)=>e.projectConfig.exists&&!e.projectConfig.valid?[{checkId:"config.project-invalid",severity:"error",title:"Project configuration is invalid",detail:"Doctor could not load a valid project rules configuration.",fixHint:"Run `cc-safety-net rule verify`, correct the reported error, then rerun doctor.",path:e.projectConfig.path}]:[]},{derive:(e)=>e.configState.state==="degraded"?[{checkId:"config.runtime-degraded",severity:"warning",title:"Runtime is enforcing a fallback configuration",detail:`The rejected candidate configuration is not active: ${e.configState.reason}`,fixHint:"Correct the named source, run `cc-safety-net rule sync` for a rule source, then rerun doctor."}]:[]},{derive:(e)=>{let t=e.environment.find((n)=>n.name==="CC_SAFETY_NET_AUDIT_SCOPE");return pr(t?.value)==="invalid"?[{checkId:"environment.audit-scope-invalid",severity:"warning",title:"Audit scope value is invalid",detail:"CC_SAFETY_NET_AUDIT_SCOPE is not `all` or `blocked`, so allowed command decisions are not recorded.",fixHint:"Set CC_SAFETY_NET_AUDIT_SCOPE to `all` or `blocked`, then restart the integration."}]:[]}},...Gu.map((e)=>({derive:(t)=>t.posture.directories.filter((n)=>n.kind===e&&n.status==="unsafe").map((n)=>({checkId:`posture.${e}-directory-unsafe`,severity:"error",title:`${e[0]?.toUpperCase()}${e.slice(1)} directory is unsafe`,detail:`The ${e} directory ${Bu(n.issues)}.`,fixHint:"Ensure this is a real directory owned by the current user with no group or other write access, then rerun doctor.",...n.path?{path:n.path}:{}}))})),{derive:(e)=>{let t=[...e.effectiveSafety.weakenedRuleOverrides].sort();return t.length>0?[{checkId:"posture.rule-overrides-weaken-preset",severity:"warning",title:"Rule overrides weaken the selected preset",detail:`Explicit overrides disable rules the resolved preset would enable: ${t.join(", ")}.`,fixHint:`Remove these \`off\` overrides or set them to \`on\`: ${t.join(", ")}.`}]:[]}}];function ps(e){return qu.flatMap((t,n)=>t.derive(e).map((r,o)=>({finding:r,catalogOrder:n,occurrence:o}))).sort((t,n)=>us[t.finding.severity]-us[n.finding.severity]||t.catalogOrder-n.catalogOrder||t.occurrence-n.occurrence).map((t)=>t.finding)}function ne(){return Boolean(process.stdout.isTTY&&!process.env.NO_COLOR)}var Vu=(e)=>ne()?`\x1B[32m${e}\x1B[0m`:e,zu=(e)=>ne()?`\x1B[33m${e}\x1B[0m`:e,Ku=(e)=>ne()?`\x1B[34m${e}\x1B[0m`:e,Wu=(e)=>ne()?`\x1B[35m${e}\x1B[0m`:e,Ju=(e)=>ne()?`\x1B[36m${e}\x1B[0m`:e,Yu=(e)=>ne()?`\x1B[31m${e}\x1B[0m`:e,Zu=(e)=>ne()?`\x1B[2m${e}\x1B[0m`:e,Xu=(e)=>ne()?`\x1B[1m${e}\x1B[0m`:e,h={green:Vu,yellow:zu,blue:Ku,magenta:Wu,cyan:Ju,red:Yu,dim:Zu,bold:Xu},Qu="\x1B[0m",ep=[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 tp(e){let t=e;return()=>(t=(t*1664525+1013904223)%4294967296,t/4294967296)}function np(e){let t=[...ep],n=tp(e);for(let r=t.length-1;r>0;r--){let o=Math.floor(n()*(r+1)),i=t[r];t[r]=t[o],t[o]=i}return t}function rp(e,t=0){if(!ne())return"";let n=np(t);return`\x1B[38;5;${n[e%n.length]}m`}function fs(e,t,n=0){if(!ne())return`"${e}"`;return`${rp(t,n)}"${e}"${Qu}`}var op=new RegExp("\x1B\\[[0-9;]*m","g"),xr=(e)=>e.replace(op,"").length;function Ee(e){let t=(e.headers??e.rows[0]??[]).map((s,a)=>{let l=Math.max(...e.rows.map((c)=>xr(c[a]??"")));return Math.max(xr(s),l)}),n=(s,a)=>s+" ".repeat(Math.max(0,a-xr(s))),r=(s,a)=>a[0]+t.map((l)=>s.repeat(l+2)).join(a[1])+a[2],o=(s)=>`│ ${s.map((a,l)=>n(a,t[l]??0)).join(" │ ")} │`,i=e.headers?[` ${o(e.headers)}`,` ${r("─",["├","┼","┤"])}`]:[];return[` ${r("─",["┌","┬","┐"])}`,...i,...e.rows.map((s)=>` ${o(s)}`),` ${r("─",["└","┴","┘"])}`].join(`
6
- `)}function ms(e){let t=[];t.push("Hook Integration"),t.push(ip(e));let n=[],r=[];for(let o of e){let i=R(o.platform);if(o.errors&&o.errors.length>0)for(let s of o.errors)if(o.configured)n.push({platform:i,message:s});else r.push({platform:i,message:s})}for(let o of n)t.push(` Warning (${o.platform}): ${o.message}`);for(let o of r)t.push(h.red(` Error (${o.platform}): ${o.message}`));return t.join(`
7
- `)}function ip(e){let t=["Platform","Discovery","Configuration","Inspection"],n=e.map((r)=>{let o=R(r.platform);if(r.inspectionStatus==="not-inspected"){let l=h.dim("Not inspected");return[o,l,l,l]}let i=r.detected?h.green("Detected"):r.inspectionStatus==="failed"?h.red("Unknown"):h.dim("Not detected"),s=r.configured?h.green("Configured"):r.detected?h.yellow("Not configured"):r.inspectionStatus==="failed"?h.red("Unknown"):h.dim("Not applicable"),a=r.inspectionStatus==="verified"?h.green("Verified"):r.inspectionStatus==="failed"?h.red("Failed"):h.dim("Not applicable");return[o,i,s,a]});return Ee({headers:t,rows:n})}function gs(e){let n=["Guard Engine Verification",` Synthetic self-test: ${e.failed>0?h.red(`${e.passed}/${e.total} FAIL`):h.green(`${e.passed}/${e.total} passed`)}`],r=e.results.filter((o)=>!o.passed);if(r.length>0){n.push(""),n.push(h.red(" Failures:"));for(let o of r)n.push(h.red(` • ${o.description}`)),n.push(h.red(` expected ${o.expected}, got ${o.actual}`))}return n.join(`
8
- `)}function sp(e){if(e.length===0)return" (no custom rules)";let t=["Source","Name","Command","Block Args"],n=e.map((r)=>[r.source,r.name,r.subcommand?`${r.command} ${r.subcommand}`:r.command,r.blockArgs.join(", ")]);return Ee({headers:t,rows:n})}function hs(e){let t=[];if(t.push("Configuration"),t.push(ap(e.userConfig,e.projectConfig)),t.push(""),e.effectiveRules.length>0)t.push(` Effective rules (${e.effectiveRules.length} total):`),t.push(sp(e.effectiveRules));else t.push(" Effective rules: (none - using built-in rules only)");for(let n of e.shadowedRules)t.push(""),t.push(` Note: Project rule "${n.name}" shadows user rule with same name`);return t.join(`
9
- `)}function ap(e,t){let n=["Scope","Status"],r=(i)=>{if(!i.exists)return h.dim("N/A");if(!i.valid)return h.red(`Invalid (${i.errors?.[0]??"unknown error"})`);return h.green("Configured")},o=[["User",r(e)],["Project",r(t)]];return Ee({headers:n,rows:o})}function ys(e){let t=[];return t.push("Environment"),t.push(lp(e)),t.join(`
10
- `)}function Ls(e){let t=["Effective Safety",` Selected preset: ${e.effectiveSafety.selectedPreset}`,` Effective: ${e.effectiveSafety.level}`],n=[["fail_closed","fail_closed"],["paranoid_rm","paranoid_rm"],["paranoid_interpreters","paranoid_interpreters"]];for(let[r,o]of n){let i=e.effectiveSafety.capabilities[r],s=i.enabled?h.green("ON"):h.dim("OFF"),a=i.sources.length>0?` (${i.sources.join(", ")})`:"";t.push(` ${o}: ${s} via ${i.source}${a}`)}t.push(` Stored rule customizations: ${e.effectiveSafety.ruleCounts.stored}`),t.push(` Effective rule customizations: ${e.effectiveSafety.ruleCounts.effective}`);for(let[r,o]of Object.entries(e.effectiveSafety.ruleOverrides))t.push(` ${r}: ${o}`);return t.join(`
11
- `)}function vs(e){let t=["Findings"];if(e.length===0)return t.push(" No findings from inspected doctor facts."),t.join(`
2
+ import{b as Oo,c as $o,d as G,e as No,f as Vn,g as Xe,h as Se,i as lr,j as ue,k as Pi,l as hr,m as Vt,n as Ti,o as Ii,p as zt}from"../chunks/index-znwvxg7d.js";import{$a as Gc,A as xc,Aa as fr,B as Xo,Ba as mr,C as Qo,Ca as gi,D as ei,Da as hi,E as ht,Ea as Go,F as Wn,Fa as Ye,G as or,Ga as Zn,H as ti,Ha as Xn,Ia as ri,J as ni,Ja as qe,K as X,Ka as Fc,La as qo,M as Q,Ma as Vo,N as We,Na as gr,O as Je,Oa as zo,P as yt,Pa as Ko,Q as mc,Qa as Y,R as ee,Ra as Qn,S as J,Sa as sr,T as ir,Ta as ar,U as Jn,Ua as Z,V as qt,Va as Hc,W as Yn,Wa as wt,Xa as Mc,Y as Ee,Ya as Eo,Z as fe,Za as jc,_ as qi,_a as Uc,aa as De,ab as xn,ba as Kt,bb as Bc,ca as xt,cb as qc,da as Ct,db as yi,ea as di,eb as Li,fa as Lt,fb as vi,ga as Re,gb as bi,ha as cr,hb as Lc,ia as pe,ib as oi,ja as _i,jb as ii,ka as yr,kb as er,la as Ni,lb as si,ma as Fi,mb as ai,na as dr,nb as Le,oa as ui,ob as Ce,pa as jo,pb as ce,qa as pi,qb as li,ra as fi,rb as B,s as N,sa as mi,sb as kt,t as k,ta as ur,tb as vt,u as mt,ua as Uo,ub as $i,v as w,va as S,w as ke,wa as pr,x as Zo,xa as Oi,y as xe,ya as de,z as ze,za as bt}from"../chunks/index-4g6x1r63.js";var Yc=["-h","--help"];function T(e,t){let n=Object.entries(e.booleans??{}),r=Object.entries(e.values??{}),o=Object.fromEntries(n.map(([d])=>[d,!1])),i={},s=[],a=[],l=!1,c=-1;for(let[d,p]of t.entries()){if(d<=c)continue;if(p==="--"){s.push(...t.slice(d+1));break}if(Yc.includes(p)){l=!0;continue}let g=n.find(([,m])=>m.includes(p));if(g){o[g[0]]=!0;continue}let u=r.find(([,m])=>m.includes(p));if(u){let m=t[d+1];if(m===void 0||m.startsWith("-")){a.push(`${p} requires a value`);continue}i[u[0]]=m,c=d+1;continue}if(p.startsWith("-")){a.push(`Unknown option for ${e.label}: ${p}`);continue}if(e.positionals==="tail"){s.push(...t.slice(d));break}s.push(p)}if(e.positionals!=="list"&&e.positionals!=="tail")a.push(...s.map((d)=>`Unexpected argument for ${e.label}: ${d}`));return{flags:o,values:i,positionals:s,help:l,errors:a}}function ae(e){for(let t of e)console.error(t);return e.length>0}import{readdirSync as Nd,statSync as ki,unlinkSync as Fd}from"node:fs";import{basename as xi,dirname as Hd,join as Md,resolve as jd}from"node:path";function I(e){return Array.from(e,(t)=>{let n=t.charCodeAt(0);if(n<=31||n>=127&&n<=159)return`\\x${n.toString(16).padStart(2,"0")}`;return t}).join("")}var Un=(e)=>{let t=Date.now()-new Date(e).getTime();if(!Number.isFinite(t))return"";let n=Math.floor(t/60000),r=Math.floor(n/60),o=Math.floor(r/24);if(o>0)return`${o}d ago`;if(r>0)return`${r}h ago`;if(n>0)return`${n}m ago`;return"just now"},Ue=(e)=>{let t=(e??"").trim().split(/\s+/).filter((o)=>o&&!/^[A-Za-z_][A-Za-z0-9_]*=/.test(o)),n=t[0]?.split("/").pop();if(!n)return null;let r=t[1];return r&&/^[a-z][a-z0-9-]*$/.test(r)?`${n} ${r}`:n};import{existsSync as Zc,readdirSync as Xc,readFileSync as Qc}from"node:fs";import{join as ed}from"node:path";function ye(e,t){try{return Xc(e,{withFileTypes:!0,encoding:"utf8"}).flatMap((n)=>{let r=ed(e,n.name);if(n.isDirectory())return ye(r,t);if(n.name.endsWith(".jsonl"))return[r];return[]})}catch{if(t&&Zc(e))t.count++;return[]}}function Gn(e){let t=(o)=>`${o.sessionId}
3
+ ${Ue(o.segment||o.command)}`,n=e.filter((o)=>o.decision!=="allow"),r=n.filter((o)=>o.sessionId).reduce((o,i)=>o.set(t(i),(o.get(t(i))??0)+1),new Map);return new Set(n.filter((o)=>o.failureStage||(r.get(t(o))??0)>=2))}var td=["segment","reason","sessionId","decision","agent","ruleId","failureStage"];function nd(e){if(!e||typeof e!=="object"||Array.isArray(e))return!1;let t=e;if(typeof t.ts!=="string"||typeof t.command!=="string")return!1;return td.every((n)=>t[n]===void 0||typeof t[n]==="string")}function we(e,t){try{return Qc(e,"utf-8").split(`
4
+ `).filter(Boolean).flatMap((n)=>{try{let r=JSON.parse(n);if(!nd(r)){if(t)t.count++;return[]}return[r]}catch{if(t)t.count++;return[]}})}catch{if(t)t.count++;return[]}}import{resolve as Ad}from"node:path";var rd=["AKIA","ASIA","ghp_","gho_","ghu_","ghs_","ghr_","github_pat_","glpat-","xox","npm_","pypi-","rk_","sk-","sk_","gsk_","xai-","pplx-","bastn_","tgp_v1_","flp_","wfr_","fw_","fwp_","tp-","psk-"];function Fo(e){let t=0,n={allocateSegment(){return t++},getNextSegmentIndex(){return t},recordGlobal(r){e.record({kind:"step",scope:"global",step:r})},recordSegment(r,o=n.currentSegmentIndex){if(o===void 0)return;e.record({kind:"step",scope:"segment",segmentIndex:o,step:r})}};return n}function Ho(e={}){let t=[],n=e.maxEvents??512,r={maxTextLength:e.maxTextLength??2048,maxListLength:e.maxListLength??128,maxObjectProperties:e.maxObjectProperties??e.maxListLength??128,maxDepth:e.maxDepth??16},o=0,i,s=new Set;return{record(a){if(i)return;try{if(!a||t.length>=n){o++;return}t.push(qn(od(a,r,s)))}catch{o++}},finish(a){if(i)return i;try{i=qn({events:Object.freeze(t),droppedEvents:o,terminal:id(a,r,s)})}catch{o++,i=Object.freeze({events:Object.freeze(t),droppedEvents:o,terminal:Object.freeze({result:"blocked",reason:"trace unavailable".slice(0,r.maxTextLength),segment:"trace unavailable".slice(0,r.maxTextLength)})})}return i}}}function od(e,t,n){if(e.kind!=="step")throw TypeError("invalid trace event");let{scope:r,step:o}=e;Gt(o,n,t);let i=Ge(o,t,n);if(r==="global")return{kind:"step",scope:"global",step:i};if(r!=="segment")throw TypeError("invalid trace event scope");return{kind:"step",scope:"segment",segmentIndex:e.segmentIndex,step:i}}function id(e,t,n){let r=e.result;if(r==="allowed")return Object.freeze({result:"allowed"});if(r!=="blocked")throw TypeError("invalid trace terminal");let o=e.ruleId;return Object.freeze({result:"blocked",reason:Ge(e.reason,t,n),segment:Ge(e.segment,t,n),...o?{ruleId:Ge(o,t,n)}:{}})}function Gt(e,t,n,r=0,o=new WeakSet){if(typeof e==="string"){let a=e.slice(0,n.maxTextLength);if(!Vn(a))return;for(let l of No(a))for(let c of l.match(/[^\s"'()$]+/g)??[])t.add(Mo(c));return}if(!e||typeof e!=="object"||r>=n.maxDepth||o.has(e))return;if(o.add(e),Array.isArray(e)){let a=Math.min(e.length,n.maxListLength);for(let l=0;l<a;l++)Gt(e[l],t,n,r+1,o);return}let i=0,s=new Set;for(let a in e){if(!Object.hasOwn(e,a))continue;if(i>=n.maxObjectProperties)break;i++,Gt(a,t,n);let l=Bn(a,n,t);if(s.has(l))continue;s.add(l),Gt(e[a],t,n,r+1,o)}}function Ge(e,t,n,r=0,o=new WeakSet){if(typeof e==="string")return Bn(e,t,n);if(!e||typeof e!=="object")return e;if(r>=t.maxDepth)return;if(o.has(e))return;if(o.add(e),Array.isArray(e)){let a=[],l=Math.min(e.length,t.maxListLength);for(let c=0;c<l;c++)a.push(Ge(e[c],t,n,r+1,o));return a}let i={},s=0;for(let a in e){if(!Object.hasOwn(e,a))continue;if(s>=t.maxObjectProperties)break;s++;let l=Bn(a,t,n);if(Object.hasOwn(i,l))continue;Object.defineProperty(i,l,{value:Ge(e[a],t,n,r+1,o),enumerable:!0,configurable:!0,writable:!0})}return i}function Bn(e,t,n){let r=e.slice(0,t.maxTextLength),o=Vn(r)?$o(r):r,i=n.size>0?ad(o,n):o;return(sd(i)?Oo(i):i).slice(0,t.maxTextLength)}function sd(e){return e.includes("PRIVATE KEY")||e.includes("://")||e.includes("eyJ")||e.includes(":")&&/(?:authorization|cookie|x-api-key|api-key|(?:^|\s)(?:-u|--user)(?:\s|=))/i.test(e)||e.length>=14&&rd.some((t)=>e.includes(t))||e.length>=49&&/\b[a-f0-9]{32}\.[A-Za-z0-9]{16}\b/.test(e)}function ad(e,t){return e.replace(/[^\s"'()$]+/g,(n)=>t.has(Mo(n))?"<redacted>":n)}function Mo(e){let t=2166136261,n=2166136261;for(let r=0;r<e.length;r++)t=Math.imul(t^e.charCodeAt(r),16777619),n=Math.imul(n^e.charCodeAt(e.length-r-1),16777619);return`${t>>>0}:${n>>>0}:${e.length}`}function qn(e){if(e&&typeof e==="object"&&!Object.isFrozen(e)){for(let t of Object.values(e))qn(t);Object.freeze(e)}return e}function Bo(e,t,n){let r=n??jo(),o=r.getCommandProgram(e,t.shell??"auto"),i=Ho(),s=Fo(i),a=o.dialect==="powershell"?r.getCommandProgram(e,"posix"):o,l=Uo(a);s.recordGlobal({type:"parse",input:e,segments:l.map((p)=>[...p])});let c=Go(e,{...t,analyzePartialProgram:!0,trace:s},o,r),d=s.getNextSegmentIndex();if(c&&d>0&&d<l.length)s.recordSegment({type:"segment-skipped",index:d,reason:"prior-segment-blocked"},d);return Object.freeze({decision:c,trace:i.finish(c?{result:"blocked",reason:c.reason,segment:c.evidence.find((p)=>p.kind==="command")?.segment??e,...c.ruleId?{ruleId:c.ruleId}:{}}:{result:"allowed"}),program:o})}import{resolve as ld}from"node:path";function zn(e){let t=qo().safeParse(e);return{errors:t.success?[]:zo(t.error.issues),ruleNames:new Set(Vo(e).map((n)=>n.toLowerCase()))}}function Kn(e){let t=Wo(e);if(!t.ok)return t.result;return zn(t.parsed)}function Wo(e){let t=[],n=new Set;try{let r=typeof e==="string"?mt(e):e,o=w(r);if(o===null)return t.push(`File not found: ${r.path}`),{ok:!1,result:{errors:t,ruleNames:n}};if(!o.trim())return t.push("Config file is empty"),{ok:!1,result:{errors:t,ruleNames:n}};return{ok:!0,parsed:JSON.parse(o)}}catch(r){if(r instanceof N)return t.push(r.message),{ok:!1,result:{errors:t,ruleNames:n}};let o=r instanceof Error?r.message:String(r);return t.push(r instanceof SyntaxError?"Invalid JSON":o),{ok:!1,result:{errors:t,ruleNames:n}}}}function Jo(e){return ld(e??process.cwd(),".safety-net.json")}function le(e){let t=Wo(e);if(!t.ok)return t.result;let n=Ko(t.parsed);return{errors:n.errors,ruleNames:n.sources}}import{isAbsolute as cd,join as gt,relative as dd,resolve as Yo,sep as ud}from"node:path";async function Ke(e={}){let t=nr(e);return pd(t,await Bt(t,qe()))}function pd(e,t){if(!t.ok)return t;let n=J(e),r=[...new Set(ce(n.configPath,n.lockPath,e,n.filesystemScope))];if(r.length===0)return t;return{ok:!1,errors:r,warnings:t.warnings,entries:t.entries}}async function Bt(e,t,n,r={}){let o=null,i=!1;try{let s=J(e),a=Qn(s.configTarget);if(!a.ok)return a.result;let l=a.config;if(e.check)return Ld(l,s,e);o={target:s.lockTarget,content:w(s.lockTarget)};let c=er(s.lockTarget);if(c.errors.some((L)=>L.startsWith("Unable to access ")))return{ok:!1,errors:c.errors,warnings:[],entries:[]};if(e.only&&c.errors.length>0)return{ok:!1,errors:c.errors,warnings:[],entries:[]};let d=c.errors.length>0?null:c.lock,p=e.only?oi(l,d,e.only):{ok:!0,specs:l.rules};if(!p.ok)return p.result;if(e.only&&!d&&p.specs.length<l.rules.length)return{ok:!1,errors:[`No lockfile available for partial update; run ${ni}`],warnings:[],entries:[]};let g=(await md(p.specs,(L)=>si(L,s.configDir,e,d,s.filesystemScope,t),t)).map((L)=>vd(L,d,n));for(let L of g)kd(L.content,L.entry,s.configDir,e,s.filesystemScope);let u=e.only?bd(l,d,g):g.map((L)=>L.entry);i=!0,Z(s.lockTarget,{version:1,rulebooks:u},void 0,r._testAfterPolicyRename);let m=new Map(g.map((L)=>[L.entry.spec,L.rulebook.rules.length])),f=xd(u,s.configDir,e,s.filesystemScope,r);return{ok:!0,errors:[],warnings:f,entries:u.map((L)=>wd(L,m))}}catch(s){if(i&&o)try{Be(o.target,o.content)}catch(a){return Ve(a)}return Ve(s)}}async function tr(e,t={}){return fd(e,nr(t),qe())}async function fd(e,t,n,r={}){let o=null,i=!1;try{let s=J(t),a=w(s.configTarget);o={target:s.configTarget,content:a};let l=Qn(s.configTarget);if(!l.ok)return l.result;let c=l.config,d=ti(e)?await ai(e,n):[{spec:e}],p=d.map((m)=>m.spec),g=[...new Set([...c.rules,...p])];if(g.length>Zn)return gd();if(g.length!==c.rules.length)i=!0,Z(s.configTarget,{version:1,rules:g,overrides:c.overrides??{},transparent_wrappers:c.transparent_wrappers??[]},void 0,r._testAfterPolicyRename);let u=await Bt(t,n,new Map(d.filter((m)=>!!m.display_ref).map((m)=>[m.spec,m.display_ref])),r);if(!u.ok)Be(s.configTarget,a);return u}catch(s){if(i&&o)try{Be(o.target,o.content)}catch(a){return Ve(a)}return Ve(s)}}async function md(e,t,n=qe()){if(e.length>Zn)throw Error(Xn);let r=Array(e.length),o=0,i,s=Array.from({length:Math.min(e.length,ri.concurrency)},async()=>{while(!i){let a=o;if(a>=e.length)return;o++;try{r[a]=await t(e[a],a,n.controller.signal)}catch(l){if(!i)i={value:l},o=e.length,n.controller.abort(l);return}}});if(await Promise.all(s),i)throw i.value;return r}function gd(){return{ok:!1,errors:[Xn],warnings:[],entries:[]}}function nr(e){return{cwd:e.cwd,cacheConfigDir:e.cacheConfigDir,userConfigDir:e.userConfigDir,userConfigPath:e.userConfigPath,projectConfigPath:e.projectConfigPath,global:e.global,check:e.check,only:e.only,refresh:e.refresh}}function hd(e){return{...nr(e),deleteSource:e.deleteSource}}async function rr(e,t={}){try{return await yd(e,hd(t),{})}catch(n){return Ve(n)}}async function yd(e,t,n){let r=J(t),o=Y(r.configTarget);if(o.errors.length>0)return{ok:!1,errors:o.errors,warnings:[],entries:[]};if(!o.config)return{ok:!1,errors:[`No config found at ${r.configPath}`],warnings:[],entries:[]};let i=er(r.lockTarget);if(i.errors.length>0)return{ok:!1,errors:i.errors,warnings:[],entries:[]};let s=ii(o.config.rules,i.lock,e);if(!s.ok)return s.result;let a=t.deleteSource?Cd(r.configDir,s.specs,i.lock,r.filesystemScope):{ok:!0,dirs:[]};if(!a.ok)return a.result;let l=w(r.configTarget);if(l===null)return Ve(Error("Rules config is unavailable."));try{Z(r.configTarget,{version:1,rules:o.config.rules.filter((p)=>!s.specs.includes(p)),overrides:o.config.overrides??{},transparent_wrappers:o.config.transparent_wrappers??[]},void 0,n._testAfterPolicyRename)}catch(p){throw Be(r.configTarget,l),p}let c=await Bt(t,qe(),void 0,n);if(!c.ok)return Be(r.configTarget,l),c;let d=Sd(r.configDir,a.dirs,n,r.filesystemScope);if(!d.ok){Be(r.configTarget,l);let p=await Bt(t,qe(),void 0,n);if(!p.ok)return{ok:!1,errors:[...d.result.errors,...p.errors],warnings:p.warnings,entries:p.entries};return d.result}return c}async function Ld(e,t,n){let r=li(e,t.lockPath,t.configDir,n,n.global?"user":"project",t.filesystemScope);return{ok:r.errors.length===0&&r.warnings.length===0,errors:[...r.errors,...r.warnings],warnings:[],entries:r.entries}}function vd(e,t,n){let r=t?.rulebooks.find((i)=>i.spec===e.entry.spec&&i.kind==="github"),o=n?.get(e.entry.spec)??(r?.kind==="github"?r.display_ref:void 0);if(!o||e.entry.kind!=="github")return e;return{...e,entry:{...e.entry,display_ref:o}}}function bd(e,t,n){let r=new Set(e.rules),o=new Set(t?.rulebooks.map((s)=>s.spec)??[]),i=new Map(n.map((s)=>[s.entry.spec,s.entry]));return[...(t?.rulebooks.filter((s)=>r.has(s.spec))??[]).map((s)=>i.get(s.spec)??s),...n.filter((s)=>!o.has(s.entry.spec)).map((s)=>s.entry)]}function wd(e,t){return{...e,ruleCount:t.get(e.spec)}}function kd(e,t,n,r,o){let i=Jn(t,Yn(n,r));ke(k(o,i),e)}function xd(e,t,n,r,o){let i=Yn(t,n),s=qt(i),a=k(r,s),l=xe(a);if(!l)return[];let c=e.map((p)=>k(r,Jn(p,i))),d=l.filter((p)=>p.kind==="directory").map((p)=>({directory:k(r,gt(s,p.name)),identity:k(r,gt(s,p.name,Wn))})).filter((p)=>!c.some((g)=>Zo(p.identity,g))).map((p)=>p.directory);for(let p of d)ei(p);return d.flatMap((p)=>{try{return Dd(p,o),[]}catch{return["Unable to prune rules policy cache safely."]}})}function Cd(e,t,n,r){let o=new Map(n?.rulebooks.map((c)=>[c.spec,c])??[]),i=t.flatMap((c)=>{let d=o.get(c);if(!d)return ht.test(c)?[]:["--delete-source can only delete local rulebook sources"];return d.kind==="local-directory"?[]:["--delete-source can only delete local rulebook sources"]}),s=t.map((c)=>{let d=o.get(c);return gt(e,d?.kind==="local-directory"?d.path:c)}),a=i.length>0?[]:s.flatMap((c)=>ci(e,c,r)),l=[...i,...a];return l.length>0?{ok:!1,result:{ok:!1,errors:l,warnings:[],entries:[]}}:{ok:!0,dirs:s}}function ci(e,t,n){let r=Yo(e),o=Yo(t),i=dd(r,o);if(i===""||i===".."||i.startsWith(`..${ud}`)||cd(i))return[`Refusing to delete local rulebook source outside ${e}: ${t}`];let s=k(n,o),a=xe(s);if(!a)return[`Local rulebook source directory not found: ${t}`];let l=a.find((c)=>c.name==="rulebook.json");if(!l)return[`Local rulebook source directory is missing rulebook.json: ${t}`];if(l.kind!=="file")throw new N(n.label);if(w(k(n,gt(o,"rulebook.json"))),a.length>1)return[`Local rulebook source directory contains extra files: ${t}. delete manually if you really want to remove the directory.`];return[]}function Sd(e,t,n,r){let o=t.flatMap((i)=>{try{if(!xe(k(r,i)))return[];let s=ci(e,i,r);if(s.length>0)return s;return Rd(i,n,r),[]}catch(s){return[`Failed to delete local rulebook source ${i}: ${s instanceof Error?s.message:String(s)}`]}});return o.length>0?{ok:!1,result:{ok:!1,errors:o,warnings:[],entries:[]}}:{ok:!0}}function Dd(e,t){if(t._testPruneRulebookCacheDir){t._testPruneRulebookCacheDir(e.path);return}Xo(e)}function Rd(e,t,n){if(t._testDeleteLocalSourceDir){t._testDeleteLocalSourceDir(e);return}ze(k(n,gt(e,Wn))),Qo(k(n,e))}function Be(e,t){if(t===null){ze(e);return}ke(e,t)}function Ve(e){return{ok:!1,errors:[e instanceof Error?e.message:String(e)],warnings:[],entries:[]}}function Ze(e,t){let n=Pd(t),r=gi(n),o={effectiveLevel:r.effectiveLevel,selectedPreset:n.policySnapshot.policy.safety.level??"standard",effectiveCapabilities:r.effectiveCapabilities,destructiveCommandRuleOverrides:n.policySnapshot.policy.destructiveCommandRuleOverrides},{configSource:i,configValid:s}=Ed({cwd:t?.cwd,userConfigDir:t?.userConfigDir});if(!e||!e.trim())return{trace:{steps:[{type:"error",message:"No command provided"}],segments:[]},result:"allowed",configSource:i,configValid:s,...o};let a=Td(e,n);if(a)return{trace:{steps:[],segments:[{index:0,steps:[{type:"rule-check",rule:a.rule,matched:!0,reason:a.reason}]}]},result:"blocked",reason:G(a.reason),segment:G(a.target),...a.ruleId?{ruleId:G(a.ruleId)}:{},configSource:i,configValid:s,...o};let l=Bo(e,n),c=l.decision,d=c?.ruleId??Id(e,n),p=Lt.find((u)=>u.id===d&&u.activationCapability),g=p?r.policy.effectiveDestructiveCommandRules[p.id]:void 0;return{trace:Od(l.trace),result:c?"blocked":"allowed",reason:c?G(c.reason):void 0,segment:c?G(c.evidence.find((u)=>u.kind==="command")?.segment??e):void 0,ruleId:c?.ruleId?G(c.ruleId):void 0,customRule:_d($d(c?.ruleId,n.policySnapshot)),configSource:i,configValid:s,...o,...p&&g?{ruleActivation:{id:p.id,...g}}:{}}}function Ed(e){let t=X(e?.cwd),n=e?.userConfigPath??Q(e),r=ee({cwd:e?.cwd,userConfigDir:e?.userConfigDir,userConfigPath:e?.userConfigPath});try{if(w(r.projectConfigTarget)!==null){if(le(r.projectConfigTarget).errors.length===0)return{configSource:t,configValid:!0};return{configSource:t,configValid:!1}}}catch(o){if(o instanceof N)return{configSource:t,configValid:!1};throw o}try{if(w(r.userConfigTarget)!==null){let o=le(r.userConfigTarget);return{configSource:n,configValid:o.errors.length===0}}return{configSource:null,configValid:!0}}catch(o){if(o instanceof N)return{configSource:n,configValid:!1};throw o}}function Pd(e){let t=Ad(e?.cwd??process.cwd()),n=e?.policySnapshot??B({cwd:t,userConfigDir:e?.userConfigDir}),r=de(n.policy);return{cwd:t,effectiveCwd:t,policySnapshot:n,environment:di(),protectedGitMetadata:mi([t]),effectiveCapabilities:r.capabilities,strict:e?.strict??r.strict,paranoidRm:r.paranoidRm,paranoidInterpreters:r.paranoidInterpreters,worktreeMode:r.worktreeMode}}function Td(e,t){let n=t.cwd??process.cwd(),r=ui(Ye("",{command:e},{kind:"command",shell:"posix"},{executionCwd:n,configCwd:n},e)),o=Li(r);if(o)return{reason:yi,target:o.target,ruleId:"policy-protection",rule:"policy-protection:findPolicyConfigMutationTargetInSemanticFacts"};let i=fi(r,t.protectedGitMetadata);if(i)return{reason:pi,target:i.target,ruleId:"git-metadata-protection",rule:"git-metadata-protection:findGitMetadataMutationTargetInSemanticFacts"};let s=t.policySnapshot.policy,a=s.secretProtection.enabled===!1?null:bi(r,s.secretProtection,{strict:t.strict});if(a)return{reason:vi,target:a.target,ruleId:a.ruleId,rule:"secret-protection:findSensitiveTargetInSemanticFacts"};return null}function Id(e,t){let n=t.policySnapshot.policy,r=vt({...n,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:{...n.destructiveCommandRuleOverrides,...Object.fromEntries(Lt.flatMap((o)=>o.activationCapability?[[o.id,"on"]]:[]))}},t.policySnapshot.state==="degraded"?{diagnostics:t.policySnapshot.diagnostics,reason:t.policySnapshot.reason}:void 0);return hi(e,{...t,policySnapshot:r,strict:!0,paranoidRm:!0,paranoidInterpreters:!0})?.ruleId}function _d(e){if(!e)return;return{id:G(e.id),...e.rulebook?{rulebook:{name:G(e.rulebook.name),version:G(e.rulebook.version)}}:{},...e.source?{source:G(e.source)}:{},...e.override?{override:{type:"reason",reason:G(e.override.reason)}}:{}}}function Od(e){let t=e.events.flatMap((r)=>r.kind==="step"&&r.scope==="global"?[r.step]:[]),n=new Map;for(let r of e.events){if(r.kind!=="step"||r.scope!=="segment")continue;let o=n.get(r.segmentIndex)??{index:r.segmentIndex,steps:[]};o.steps.push(r.step),n.set(r.segmentIndex,o)}return{steps:t,segments:[...n.values()]}}function $d(e,t){let n=e?.replace(/^custom\./,"");if(!n||!t.policy.rules.some((r)=>r.name===n))return;return t.ruleMetadata[n]??Object.freeze({id:n})}function Ud(e){let t=Xe(),n=T({label:"logs",booleans:{all:["--all"],suspect:["--suspect"],json:["--json"],pruneLegacy:["--prune-legacy"],dryRun:["--dry-run"]},values:{id:["--id"],limit:["--limit"],since:["--since"],agent:["--agent"],rule:["--rule"],session:["--session"],project:["--project"]}},e);if(ae(n.errors))return null;if(n.values.id!==void 0&&!/^[a-f0-9]{16}$/.test(n.values.id))return console.error("--id must be 16 hexadecimal characters"),null;let r=n.values.limit===void 0?20:wi(n.values.limit);if(r===null)return console.error("--limit must be a positive number"),null;let o=n.values.since===void 0?Math.min(30,t):wi(n.values.since);if(o===null||o>t)return console.error(`--since must be a positive number of days no greater than ${t}`),null;let i={limit:r,limitExplicit:n.values.limit!==void 0,since:o,sinceExplicit:n.values.since!==void 0,all:n.flags.all,json:n.flags.json,suspect:n.flags.suspect,pruneLegacy:n.flags.pruneLegacy,dryRun:n.flags.dryRun,id:n.values.id,agent:n.values.agent,rule:n.values.rule,session:n.values.session,project:n.values.project===void 0?void 0:jd(n.values.project)};if(i.id&&(i.agent!==void 0||i.rule!==void 0||i.session!==void 0||i.project!==void 0||i.suspect||i.sinceExplicit||i.limitExplicit))return console.error("--id cannot be combined with --agent, --rule, --session, --project, --suspect, --since, or --limit"),null;if(i.pruneLegacy&&(i.id!==void 0||i.agent!==void 0||i.rule!==void 0||i.session!==void 0||i.project!==void 0||i.suspect||i.all||i.sinceExplicit||i.limitExplicit))return console.error("--prune-legacy cannot be combined with --id, --agent, --rule, --session, --project, --suspect, --all, --since, or --limit"),null;if(i.dryRun&&!i.pruneLegacy)return console.error("--dry-run requires --prune-legacy"),null;return i}async function Ci(e,t={}){let n=Ud(e);if(!n)return 1;let r=t.logsDir??ue();if(n.pruneLegacy)return Gd(r,n.json,n.dryRun);if(!r)return console.log(n.json?"[]":n.id?`No retained audit log entry found for id ${I(n.id)}.`:"No audit log entries found."),0;Se(r);let o={count:0},i=ye(r,o).flatMap((d)=>we(d,o).map((p)=>({entry:p,file:d})));if(o.count>0)console.error(`warning: ${o.count} audit log ${o.count===1?"source":"sources"} could not be read; these results are incomplete`);if(n.id)return zd(i,n,t.timeZone);let s=Date.now()-n.since*24*60*60*1000,a=i.filter((d)=>Kd(d,n,r,s)),l=n.suspect?Gn(a.map((d)=>d.entry)):null,c=(l?a.filter((d)=>l.has(d.entry)):a).sort((d,p)=>Date.parse(p.entry.ts)-Date.parse(d.entry.ts)).slice(0,n.limit);if(n.json)return console.log(JSON.stringify(c.map((d)=>d.entry),null,2)),0;if(c.length===0)return console.log("No audit log entries found."),0;for(let d of c)console.log(Yd(d.entry,t.timeZone));return 0}function Gd(e,t,n){let r=e?qd(e).map((a)=>Md(e,a)):[];if(n)return Bd(r,t);let o=[],i=0,s=0;for(let a of r){let l=ki(a,{throwIfNoEntry:!1})?.size??0,c=Vd(a);if(c){o.push(`${xi(a)}: ${c}`);continue}i++,s+=l}if(t)return console.log(JSON.stringify({removedFiles:i,removedBytes:s,failedFiles:o.length})),o.length===0?0:1;console.log(i===0&&o.length===0?"No legacy audit log files found.":`Removed ${i} legacy audit log ${i===1?"file":"files"} (${Si(s)}).`);for(let a of o)console.error(`Could not remove ${I(a)}`);if(console.log("Nested v2 audit logs were not changed."),i>0)console.log("This deletion cannot be undone.");return o.length===0?0:1}function Bd(e,t){let n=e.reduce((r,o)=>r+(ki(o,{throwIfNoEntry:!1})?.size??0),0);if(t)return console.log(JSON.stringify({dryRun:!0,files:e.length,bytes:n})),0;if(console.log(e.length===0?"No legacy audit log files found.":`Would remove ${e.length} legacy audit log ${e.length===1?"file":"files"} (${Si(n)}).`),console.log("Nested v2 audit logs are not included."),e.length>0)console.log("Run the same command without --dry-run to delete them.");return 0}function qd(e){try{return Nd(e,{withFileTypes:!0}).filter((t)=>t.isFile()&&t.name.endsWith(".jsonl")).map((t)=>t.name)}catch{return[]}}function Vd(e){try{return Fd(e),null}catch(t){return t instanceof Error?t.message:String(t)}}function Si(e){let t=["B","KiB","MiB","GiB"],n=Math.min(Math.floor(Math.log2(Math.max(e,1))/10),t.length-1);return`${Math.round(e/1024**n*10)/10} ${t[n]}`}function zd(e,t,n){let r=e.filter((i)=>i.entry.id===t.id);if(r.length>1)return console.error(`Multiple audit log entries found for id ${I(t.id??"")}.`),1;if(t.json)return console.log(JSON.stringify(r.map((i)=>i.entry),null,2)),0;let o=r[0];if(!o)return console.log(`No retained audit log entry found for id ${I(t.id??"")}.`),0;return console.log(Zd(o.entry,n)),0}function Kd(e,t,n,r){if(!t.all&&e.entry.decision==="allow")return!1;if(Date.parse(e.entry.ts)<r)return!1;if(t.agent!==void 0&&e.entry.agent!==t.agent)return!1;if(t.rule!==void 0&&e.entry.ruleId!==t.rule)return!1;if(t.session!==void 0&&!Wd(e,n,t.session))return!1;if(t.project!==void 0&&!Jd(e.entry.cwd,t.project))return!1;return!0}function Wd(e,t,n){if(e.entry.sessionId===n)return!0;return Hd(e.file)===t&&xi(e.file,".jsonl")===n}function Jd(e,t){if(!e)return!1;return e===t||e.startsWith(`${t}/`)}function Yd(e,t){let n=I(e.id??"-"),r=I(e.decision??"deny"),o=e.cwd?` [${I(e.cwd)}]`:"",i=e.segment||e.command,s=i===e.command?"":"↳ ",a=i.length>50?`${i.slice(0,50)}…`:i;return`${n.padEnd(16)} ${I(Di(e.ts,t))} ${r.padEnd(5)} ${I(e.agent??"-").padEnd(15)} ${I(e.ruleId??"-").padEnd(20)} ${s}${I(a)}${o}`}function Zd(e,t){let n=(o)=>I(o===void 0||o===null||o===""?"-":o),r=e.shape?`${e.agent??"-"} (shape: ${e.shape})`:e.agent??"-";return[`id: ${n(e.id)}`,`ts: ${n(Di(e.ts,t))}`,`decision: ${n(e.decision)}`,`agent: ${n(r)}`,`level: ${n(e.level)}`,`tool: ${n(e.toolName)}`,`rule: ${n(e.ruleId)}`,`intent: ${n(e.intent)}`,`stage: ${n(e.failureStage)}`,`error: ${n(e.errorCode)}`,`session: ${n(e.sessionId)}`,`cwd: ${n(e.cwd)}`,`version: ${n(e.v)}`,`truncated: ${n(e.truncated===!0?"yes":void 0)}`,`reason: ${n(e.reason)}`,`command: ${n(e.command)}`,`segment: ${n(e.segment)}`].join(`
5
+ `)}function Di(e,t){let n=new Date(e);if(Number.isNaN(n.getTime()))return e;return new Intl.DateTimeFormat("sv-SE",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hourCycle:"h23",timeZone:t}).format(n)}function wi(e){let t=Number(e);return Number.isFinite(t)&&t>0?t:null}var Ri={name:"doctor",aliases:["--doctor"],description:"Run diagnostic checks to verify installation and configuration",usage:"doctor [options]",options:[{flags:"--json",description:"Output diagnostics as JSON"},{flags:"--skip-update-check",description:"Skip npm registry version check"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net doctor","cc-safety-net doctor --json","cc-safety-net doctor --skip-update-check"]};var Ai={name:"explain",description:"Show step-by-step analysis trace of how a command would be analyzed",usage:"explain [options] <command>",argument:"<command>",options:[{flags:"--json",description:"Output analysis as JSON"},{flags:"--cwd",argument:"<path>",description:"Use custom working directory"},{flags:"-h, --help",description:"Show this help"}],examples:['cc-safety-net explain "git reset --hard"','cc-safety-net explain --json "rm -rf /"','cc-safety-net explain --cwd /tmp "git status"']};var Ei={name:"gui",description:"Open the local policy editor GUI",usage:"gui [options]",options:[{flags:"--no-open",description:"Print the URL without opening a browser"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net gui","cc-safety-net gui --no-open"]};import{isAbsolute as Hi,join as lu,relative as cu}from"node:path";var Xd=8388608;function Qd(e,t){console.log(JSON.stringify(e(Ti(t))))}async function eu(e){let t;try{t=(await Lr(process.stdin)).trim()}catch{e({reason:"Failed to parse hook input JSON."});return}if(!t){e({reason:"Missing hook input JSON."});return}return vr(t,e,"Failed to parse hook input JSON.")}async function Lr(e){let t=[],n=0;for await(let r of e){let o=typeof r==="string"?Buffer.from(r,"utf-8"):Buffer.from(r.buffer,r.byteOffset,r.byteLength);if(n+=o.byteLength,n>Xd)throw tu(e),Error("hook input byte limit exceeded");t.push(o)}return Buffer.concat(t,n).toString("utf-8")}function tu(e){let t=e.destroy??e.cancel;if(!t)return;try{Promise.resolve(t.call(e)).catch(()=>{})}catch{}}function vr(e,t,n){try{return JSON.parse(e)}catch{t({reason:n});return}}function M(e,t){let n=t.get(e);return n?{kind:"command",shell:n}:{kind:_i(e)}}function te(e,t,n,r){let o=e===void 0?process.cwd():e,i=typeof o==="string"&&o.trim()!==""?fe([o]):void 0;if(i)return{configCwd:i,executionCwd:i};return O(r,t,n,iu(o)),null}function O(e,t,n,r){let o;try{o=yr(t)}catch(i){if(!(i instanceof pe))throw i}e(Vt({command:o,segment:r,toolName:n}))}async function nu(e){let t=await eu(e.outputDeny);if(t===void 0)return;if(!t||typeof t!=="object"||Array.isArray(t)){O(e.outputDeny);return}if(!e.isSupported(t))return;let n=e.getAgent?.(t)??e.agent,r=e.agent===n?void 0:e.agent,o=au(t),i=(u,m)=>{Pi(u,()=>e.getSessionId(t),{agent:n,shape:r,toolName:m,cwd:o}),e.outputDeny(u)},s=e.getToolName(t);if(typeof s!=="string"||s.trim()===""){O((u)=>i(u),su(t));return}let a=s,l=(u)=>i(u,a),c;try{c=e.getToolInput(t,a,l)}catch(u){if(!(u instanceof pe))throw u;O(l,void 0,a);return}if(!c.ok)return;let d=e.getContext(t,c.input,a,l);if(!d)return;let p;try{p=yr(c.input)}catch(u){if(!(u instanceof pe))throw u;O(l,void 0,a);return}let g=Ye(a,c.input,c.route,d,p??null);try{let u=zt(g,{guard:{auditAllowed:Oi(),dependencies:e.guardDependencies},audit:{agent:n,shape:r,getSessionId:()=>e.getSessionId(t)}}),m=hr(u,{includeEvidence:!0,toolName:u.stage==="command-analysis"?void 0:a});if(m){e.outputDeny(m);return}e.outputAllow?.()}catch(u){if(!(u instanceof $i))throw u;ru(u);let m=hr(u.evaluation,{includeEvidence:!0,toolName:u.evaluation.stage==="command-analysis"?void 0:a});if(m)e.outputDeny(m);return}}function ru(e){if(!bt(S.debug))return;console.error(`CC Safety Net debug: ${ou(e.stage)}: ${Ii(e.cause)}`)}function ou(e){if(e==="policy-protection")return"hook policy protection failed";if(e==="config-load")return"hook config loading failed";if(e==="secret-protection")return"hook secret protection failed";return"hook analysis failed"}function iu(e){return typeof e==="string"?e:void 0}function su(e){if(!e||typeof e!=="object"||Array.isArray(e))return;if(Object.hasOwn(e,"tool_input"))return e.tool_input;let t=e.toolCall;if(t&&typeof t==="object"&&!Array.isArray(t))return t.args;return}function au(e){if(!e||typeof e!=="object"||Array.isArray(e))return null;let t=e.cwd;if(typeof t==="string")return t;let n=e.toolCall;if(!n||typeof n!=="object"||Array.isArray(n))return null;let r=n.args;if(!r||typeof r!=="object"||Array.isArray(r))return null;let o=r.Cwd;return typeof o==="string"?o:null}async function j(e){let t=(o)=>Qd(e.createDenyOutput,o),n=e.createAllowOutput;await nu({...e,outputDeny:t,outputAllow:n?()=>console.log(JSON.stringify(n())):void 0})}function St(e){return lu(e,".gemini","config","hooks.json")}var du=new Map([["run_command","auto"]]),uu=new Set(["absolutepath","directorypath","file_path","filepath","path","searchdirectory","searchpath","target_file","targetfile"]);function Mi(e){return M(e,du)}async function ji(){await j({agent:"antigravity-cli",createDenyOutput:(e)=>({decision:"deny",reason:e}),isSupported:()=>!0,getToolName:(e)=>e.toolCall?.name,getToolInput:(e,t)=>({ok:!0,input:hu(e.toolCall?.args,t),route:Mi(t)}),getContext:pu,getSessionId:(e)=>e.conversationId})}function pu(e,t,n,r){let i=gu(e).flatMap((c)=>{let d=fe([c]);return d?[d]:[]});if(!i[0])return Ae(r,t,n),null;if(n!=="run_command"){let c;try{c=fu(t,n,i)}catch(d){if(d instanceof pe)return Ae(r,void 0,n),null;if(!(d instanceof De))throw d;return Ae(r,t,n),null}if(!c)return Ae(r,t,n),null;return{configCwd:c,executionCwd:c}}let s=e.toolCall?.args;if(!s||!Object.hasOwn(s,"Cwd"))return{configCwd:i[0],executionCwd:i[0]};let a=s.Cwd;if(typeof a!=="string"||a.trim()==="")return Ae(r,t,n),null;let l=Ee(a,i);if(l){let c=Ui(l,i);if(!c)return Ae(r,t,n,a),null;return{configCwd:c,executionCwd:l}}return Ae(r,t,n,a),null}function fu(e,t,n){let r=Mi(t),o=[...Ni(e,uu),...r.kind==="patch"?Fi(e):[]].filter(Hi),i=Kt(),s=new Set(o.flatMap((a)=>{let l=Ui(xt(a,Ct,i),n);return l?[l]:[]}));if(s.size>1)return null;return[...s][0]??n[0]??null}function Ui(e,t){return t.filter((n)=>mu(e,n)).reduce((n,r)=>r.length>n.length?r:n,"")||null}function mu(e,t){let n=cu(t,e);return n===""||!n.startsWith("..")&&!Hi(n)}function Ae(e,t,n,r){let o=t&&typeof t==="object"?t.command:void 0;e(Vt({command:typeof o==="string"?o:void 0,segment:r,toolName:n}))}function gu(e){if(e.workspacePaths===void 0)return[process.cwd()];let t=Array.isArray(e.workspacePaths)?e.workspacePaths.filter((n)=>typeof n==="string"&&n.trim()!==""):[];return fe(t)?t:[]}function hu(e,t){if(!e)return;if(t!=="run_command")return e;return{...e,command:typeof e.CommandLine==="string"&&e.CommandLine!==""?e.CommandLine:void 0}}var Dt=[{id:"antigravity-cli",displayName:"Antigravity CLI",doctorOrder:3,runtime:{order:1,flags:["-ac","--agy-cli"],description:"Run as Antigravity CLI PreToolUse hook",legacyTopLevelFlags:[]},install:{order:2,flag:"--agy-cli",artifactKind:"hook config",probeCommand:["agy","--version"]}},{id:"claude-code",displayName:"Claude Code",doctorOrder:1,runtime:{order:2,displayName:"Coding CLI",flags:["-cc","--coding-cli"],legacyFlags:["--claude-code"],description:"Run as Coding CLI PreToolUse hook",legacyTopLevelFlags:["-cc","--claude-code"]},install:{order:3,flag:"--claude-code",artifactKind:"plugin",probeCommand:["claude","--version"]}},{id:"codex",displayName:"Codex",doctorOrder:4,install:{order:4,flag:"--codex",artifactKind:"plugin",probeCommand:["codex","--version"]}},{id:"copilot-cli",displayName:"GitHub Copilot CLI",doctorOrder:7,runtime:{order:5,flags:["-cp","--copilot-cli"],description:"Run as GitHub Copilot CLI PreToolUse hook",legacyTopLevelFlags:["-cp","--copilot-cli"]},install:{order:7,flag:"--copilot-cli",artifactKind:"plugin",probeCommand:["copilot","--binary-version"]}},{id:"gemini-cli",displayName:"Gemini CLI",doctorOrder:6,runtime:{order:4,flags:["-gc","--gemini-cli"],description:"Run as Gemini CLI BeforeTool hook",legacyTopLevelFlags:["-gc","--gemini-cli"]},install:{order:6,flag:"--gemini-cli",artifactKind:"extension",probeCommand:["gemini","--version"]}},{id:"hermes-agent",displayName:"Hermes Agent",doctorOrder:8,runtime:{order:6,flags:["-ha","--hermes-agent"],description:"Run as Hermes Agent pre_tool_call hook",legacyTopLevelFlags:[]},install:{order:8,flag:"--hermes-agent",artifactKind:"plugin",probeCommand:["hermes","--version"]}},{id:"kimi-code",displayName:"Kimi Code",doctorOrder:9,runtime:{order:7,flags:["-kc","--kimi-code"],description:"Run as Kimi Code PreToolUse hook",legacyTopLevelFlags:[]},install:{order:9,flag:"--kimi-code",artifactKind:"hook config",probeCommand:["kimi","--version"]}},{id:"openclaw",displayName:"OpenClaw",doctorOrder:10,install:{order:10,flag:"--openclaw",artifactKind:"plugin",probeCommand:["openclaw","--version"]}},{id:"opencode",displayName:"OpenCode",doctorOrder:11,install:{order:11,flag:"--opencode",artifactKind:"plugin",probeCommand:["opencode","--version"]}},{id:"pi",displayName:"Pi",doctorOrder:12,install:{order:12,flag:"--pi",artifactKind:"package",probeCommand:["pi","--version"]}},{id:"cursor",displayName:"Cursor",doctorOrder:5,runtime:{order:3,flags:["-cu","--cursor"],description:"Run as Cursor preToolUse hook",legacyTopLevelFlags:[]},install:{order:5,flag:"--cursor",artifactKind:"hook config",probeCommand:["cursor","--version"]}},{id:"amp",displayName:"Amp Code",doctorOrder:2,install:{order:1,flag:"--amp",artifactKind:"plugin",probeCommand:["amp","--version"]}}],Wt=Dt.slice().sort((e,t)=>e.doctorOrder-t.doctorOrder).map((e)=>e.id),Gi=Dt.filter((e)=>("runtime"in e)).slice().sort((e,t)=>e.runtime.order-t.runtime.order).map((e)=>({id:e.id,displayName:"displayName"in e.runtime?e.runtime.displayName:e.displayName,flags:e.runtime.flags,legacyFlags:"legacyFlags"in e.runtime?e.runtime.legacyFlags:[],description:e.runtime.description,legacyTopLevelFlags:e.runtime.legacyTopLevelFlags})),V=Dt.slice().sort((e,t)=>e.install.order-t.install.order).map((e)=>({id:e.id,...e.install})).map(({order:e,...t})=>t),X0=Object.fromEntries(Dt.map((e)=>[e.id,e.displayName]));function R(e){return Dt.find((t)=>t.id===e)?.displayName??e}import{homedir as yu}from"node:os";import{isAbsolute as Bi,join as br}from"node:path";function Vi(e){if(e!==void 0&&e!==null&&typeof e!=="string")return"unknown";if(typeof e==="string"&&!Bi(e))return"unknown";try{let t=Kt(),n=typeof e==="string"&&e?xt(e,Ct,t):void 0,r=process.env.HOME||yu(),o=[["codex",process.env.CODEX_HOME||br(r,".codex")],["copilot-cli",process.env.COPILOT_HOME||br(r,".copilot")],["claude-code",process.env.CLAUDE_CONFIG_DIR||br(r,".claude")]],i=n?o.flatMap(([s,a])=>{if(!Bi(a))return[];return qi(n,xt(a,Ct,t))?[s]:[]}):[];if(i.length===1)return i[0]??"unknown";if(i.length>1)return"unknown"}catch(t){if(t instanceof De)return"unknown";return"unknown"}if(process.env.CLAUDECODE==="1"||Boolean(process.env.CLAUDE_CODE_ENTRYPOINT))return"claude-code";return"unknown"}var wr="PreToolUse",zi="BeforeTool",Ki="pre_tool_call",kr="PreToolUse";var Lu=new Map([["Bash","posix"],["PowerShell","powershell"]]);function vu(e){return M(e,Lu)}async function Wi(){await j({agent:"claude-code",getAgent:(e)=>Vi(e.transcript_path),createDenyOutput:(e)=>({hookSpecificOutput:{hookEventName:wr,permissionDecision:"deny",permissionDecisionReason:e}}),isSupported:(e)=>e.hook_event_name===wr,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:vu(t)}),getContext:(e,t,n,r)=>te(e.cwd,t,n,r),getSessionId:(e)=>e.session_id})}var bu=new Map([["bash","auto"],["Bash","auto"],["powershell","powershell"],["PowerShell","powershell"]]);function wu(e){return M(e,bu)}async function Ji(){await j({agent:"copilot-cli",createDenyOutput:(e)=>({permissionDecision:"deny",permissionDecisionReason:e}),isSupported:()=>!0,getToolName:(e)=>e.toolName,getToolInput:(e,t,n)=>{if(typeof e.toolArgs!=="string")return n({reason:"Failed to parse toolArgs JSON."}),{ok:!1};let r=vr(e.toolArgs,n,"Failed to parse toolArgs JSON.");if(r===void 0)return{ok:!1};return{ok:!0,input:r,route:wu(t)}},getContext:(e,t,n,r)=>te(e.cwd,t,n,r),getSessionId:(e)=>typeof e.sessionId==="string"&&e.sessionId.trim()?e.sessionId:void 0})}var ku=new Map([["Shell","auto"]]);function xu(e){return M(e,ku)}async function Yi(){await j({agent:"cursor",createDenyOutput:(e)=>({permission:"deny",user_message:e,agent_message:e}),createAllowOutput:()=>({permission:"allow"}),isSupported:()=>!0,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:xu(t)}),getContext:Cu,getSessionId:(e)=>e.conversation_id})}function Cu(e,t,n,r){let o=Su(e);if(!o[0])return O(r,t,n),null;let i=Ee(Ru(e.cwd),o);if(!i)return O(r,t,n,typeof e.cwd==="string"?e.cwd:void 0),null;if(t===null||typeof t!=="object"||Array.isArray(t))return{configCwd:i,executionCwd:i};if(!Object.hasOwn(t,"working_directory"))return{configCwd:i,executionCwd:i};let s=t.working_directory;if(typeof s!=="string"||s.trim()==="")return O(r,t,n),null;let a=Ee(s,o);if(!a)return O(r,t,n,s),null;return{configCwd:i,executionCwd:a}}function Su(e){return Du(e).flatMap((t)=>{let n=fe([t]);return n?[n]:[]})}function Du(e){if(e.workspace_roots===void 0)return typeof e.cwd==="string"&&e.cwd.trim()!==""?[e.cwd]:[];if(!Array.isArray(e.workspace_roots))return[];return e.workspace_roots.filter((t)=>typeof t==="string"&&t.trim()!=="")}function Ru(e){return typeof e==="string"&&e.trim()!==""?e:"."}var Au=new Map([["run_shell_command","auto"]]);function Eu(e){return M(e,Au)}async function Zi(){await j({agent:"gemini-cli",createDenyOutput:(e)=>({decision:"deny",reason:e,systemMessage:e}),isSupported:(e)=>e.hook_event_name===zi,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:Eu(t)}),getContext:(e,t,n,r)=>te(e.cwd,t,n,r),getSessionId:(e)=>e.session_id})}import{resolve as Pu}from"node:path";var Tu=new Map([["terminal","posix"]]);async function Xi(){await j({agent:"hermes-agent",createDenyOutput:(e)=>({action:"block",message:e}),isSupported:(e)=>e.hook_event_name===Ki,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:M(t,Tu)}),getContext:Iu,getSessionId:(e)=>e.session_id})}function Iu(e,t,n,r){let o=te(e.cwd,t,n,r);if(!o)return null;if(!t||typeof t!=="object"||Array.isArray(t))return o;if(!Object.hasOwn(t,"workdir"))return o;let i=t.workdir;if(typeof i!=="string"||i.trim()==="")return O(r,t,n),null;let s=fe([Pu(o.configCwd,i)]);if(!s)return O(r,t,n,i),null;return{...o,executionCwd:s}}var Qi=new Map([["Bash","posix"]]);function _u(e){return M(e,Qi)}async function es(){await j({agent:"kimi-code",createDenyOutput:(e)=>({hookSpecificOutput:{hookEventName:kr,permissionDecision:"deny",permissionDecisionReason:e}}),isSupported:(e)=>e.hook_event_name===kr,getToolName:(e)=>e.tool_name,getToolInput:(e,t)=>({ok:!0,input:e.tool_input,route:_u(t)}),getContext:(e,t,n,r)=>{let o=te(e.cwd,t,n,r);if(!o)return null;let i=e.tool_input;if(!Qi.has(n)||!i||!Object.hasOwn(i,"cwd"))return o;let s=i.cwd;if(typeof s!=="string"||s.trim()==="")return O(r,t,n),null;let a=Ee(s,[o.configCwd]);if(!a)return O(r,t,n,s),null;return{configCwd:o.configCwd,executionCwd:a}},getSessionId:(e)=>e.session_id})}var Ou={"antigravity-cli":ji,"claude-code":Wi,"copilot-cli":Ji,cursor:Yi,"gemini-cli":Zi,"hermes-agent":Xi,"kimi-code":es},Qe=Gi.map((e)=>({...e,run:Ou[e.id]}));function ts(e){let t=T({label:"hook",booleans:Object.fromEntries(Qe.map((r)=>[r.id,[...r.flags,...r.legacyFlags]]))},e);if(t.errors.length>0)return;let n=Qe.filter((r)=>t.flags[r.id]);return n.length===1?n[0]:void 0}function ns(e){return Qe.find((t)=>t.legacyTopLevelFlags.some((n)=>n===e))}var $u=Qe.map((e)=>({flags:e.flags.join(", "),description:e.description})),Nu=Qe.flatMap((e)=>e.flags.map((t)=>`cc-safety-net hook ${t}`)),rs={name:"hook",description:"Run as an agent CLI hook (reads JSON from stdin)",usage:"hook INTEGRATION_FLAG",options:[...$u,{flags:"-h, --help",description:"Show this help"}],examples:Nu};var os={name:"install",description:"Install CC Safety Net into a coding agent CLI",usage:"install [TARGET_FLAG]",options:[...V.map((e)=>({flags:e.flag,description:`Install ${R(e.id)} ${e.artifactKind}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net install",...V.map((e)=>`cc-safety-net install ${e.flag}`)]},is={name:"uninstall",description:"Uninstall CC Safety Net from a coding agent CLI",usage:"uninstall [TARGET_FLAG]",options:[...V.map((e)=>({flags:e.flag,description:`Uninstall ${R(e.id)} ${e.artifactKind}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net uninstall",...V.map((e)=>`cc-safety-net uninstall ${e.flag}`)]},ss={name:"update",description:"Update every installed CC Safety Net integration to the latest version",usage:"update",options:[{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net update"]};var as={name:"logs",description:"Browse audit log entries recorded by hooks",usage:"logs [options]",options:[{flags:"--id",argument:"<id>",description:"Show one entry from retained history by its 16-character id (not guaranteed once it is older than the configured retention)"},{flags:"--limit",argument:"<n>",description:"Maximum entries to print",default:"20"},{flags:"--since",argument:"<days>",description:"Only include entries newer than this many days (max: the configured audit retention, 1-365)",default:"30"},{flags:"--agent",argument:"<name>",description:"Filter by agent name"},{flags:"--rule",argument:"<ruleId>",description:"Filter by rule id"},{flags:"--session",argument:"<id>",description:"Filter by session id"},{flags:"--project",argument:"<path>",description:"Filter by project path"},{flags:"--suspect",description:"Only denials that look like false positives"},{flags:"--all",description:"Include allow entries"},{flags:"--prune-legacy",description:"Permanently delete all legacy root-level logs; nested logs are untouched"},{flags:"--dry-run",description:"With --prune-legacy, report what would be deleted and delete nothing"},{flags:"--json",description:"Output entries as JSON"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net logs --id 3fa9c2d1a70e8b42","cc-safety-net logs --agent claude-code","cc-safety-net logs --project . --since 7","cc-safety-net logs --suspect --since 7","cc-safety-net logs --json","cc-safety-net logs --prune-legacy --dry-run","cc-safety-net logs --prune-legacy"]};var et={name:"rule",description:"Manage CC Safety Net rule config and rulebook sources",usage:"rule <subcommand>",subcommands:[{usage:"init [--example]",description:"Create inert rule config"},{usage:"add <source>",description:"Add a rulebook source and sync"},{usage:"remove <source>",description:"Remove a rulebook source and sync"},{usage:"update [source]",description:"Refresh rulebook lock/cache state"},{usage:"sync",description:"Sync configured rulebooks"},{usage:"list",description:"List active rulebooks"},{usage:"wrapper add <command>",description:"Trust a transparent command wrapper"},{usage:"wrapper remove <command>",description:"Remove a transparent command wrapper"},{usage:"wrapper list",description:"List transparent command wrappers"},{usage:"migrate [--cleanup]",description:"Migrate legacy inline rules"},{usage:"doc",description:"Print the rulebook authoring guide"},{usage:"verify",description:"Validate rule config files"}],options:[{flags:"-g, --global",description:"Use user-scope rule config"},{flags:"--check",description:"Check without changing lock/cache state"},{flags:"--cleanup",description:"Delete legacy files after rule migrate verifies them"},{flags:"--delete-source",description:"Delete clean local source directory on remove"},{flags:"--example",description:"Create an inactive example rulebook with rule init"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net rule init","cc-safety-net rule init --example","cc-safety-net rule wrapper add rtk","cc-safety-net rule add project-rules","cc-safety-net rule sync","cc-safety-net rule migrate --cleanup","cc-safety-net rule verify"]};var ls={name:"status",description:"Show what the runtime is enforcing right now",usage:"status",options:[{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net status"]};var cs={name:"statusline",description:"Print status line with mode indicators for shell integration",usage:"statusline --claude-code",options:[{flags:"-cc, --claude-code",description:"Print status line for Claude Code"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net statusline -cc","cc-safety-net statusline --claude-code"]};var Jt=[ls,Ri,as,Ai,et,os,ss,is,rs,Ei,cs];function Fu(e){return e.aliases??[]}function Yt(e){let t=e.toLowerCase();return Jt.find((n)=>n.name.toLowerCase()===t||Fu(n).some((r)=>r.toLowerCase()===t))}import{basename as Hu}from"node:path";function Zt(e=7,t=ue()){let n=Date.now()-e*24*60*60*1000,r=[],o=new Set,i=0,s,a,l,c;if(t)Se(t);let d={count:0},p=t?ye(t,d):[];for(let u of p)for(let m of we(u,d)){if(m.decision==="allow")continue;let f=new Date(m.ts).getTime();if(f>=n){if(i++,o.add(m.sessionId??Hu(u,".jsonl")),a===void 0||f<=a)s=m.ts,a=f;if(c===void 0||f>c)l=m.ts,c=f;Mu(r,m,f)}}let g=r.map((u)=>({timestamp:u.ts,command:u.command,reason:u.reason,relativeTime:Un(new Date(u.ts))}));return{totalBlocked:i,sessionCount:o.size,recentEntries:g,oldestEntry:s,newestEntry:l,unreadable:d.count}}function Mu(e,t,n){let r=e.findIndex((o)=>n>new Date(o.ts).getTime());if(r===-1){if(e.length<3)e.push(t);return}if(e.splice(r,0,t),e.length>3)e.pop()}import{dirname as ju}from"node:path";function ds(e,t,n,r,o){let i;try{if(w(r)===null)return{path:e,exists:!1,valid:!1,ruleCount:0};i=le(r),i.errors.push(...ce(e,t,{userConfigDir:n},o))}catch(s){if(!(s instanceof N))throw s;i={errors:[s.message],ruleNames:new Set}}return{path:e,exists:!0,valid:i.errors.length===0,ruleCount:i.ruleNames.size,...i.errors.length>0?{errors:i.errors}:{}}}function Uu(e,t){return{source:t,name:e.name,command:e.command,subcommand:e.subcommand,blockArgs:[...e.block_args],reason:e.reason}}function us(e,t){let n=t?.userConfigPath??Q(),r=t?.projectConfigPath??X(e),o=ju(n),i=Le({cwd:e,userConfigPath:n,projectConfigPath:r,userConfigDir:o}),s=ee({cwd:e,userConfigPath:n,projectConfigPath:r,userConfigDir:o}),a=new Map(i.rulebooks.flatMap((l)=>l.rules.map((c)=>[c,l.source])));return{userConfig:ds(n,We({userConfigPath:n}),o,s.userConfigTarget,s.userScope),projectConfig:ds(r,Je(r),o,s.projectConfigTarget,s.projectScope),effectiveRules:i.rules.map((l)=>Uu(l,a.get(l.name)??"project")),shadowedRules:[]}}var Gu=[{flag:S.level,description:"Safety level preset: standard, strict, or paranoid",defaultBehavior:"standard"},{flag:S.strict,description:"Legacy; equivalent to safety.overrides.fail_closed",defaultBehavior:"permissive"},{flag:S.paranoid,description:"Legacy; equivalent to safety.overrides.paranoid_rm and paranoid_interpreters",defaultBehavior:"off"},{flag:S.paranoidRm,description:"Legacy; equivalent to safety.overrides.paranoid_rm",defaultBehavior:"off"},{flag:S.paranoidInterpreters,description:"Legacy; equivalent to safety.overrides.paranoid_interpreters",defaultBehavior:"off"},{flag:S.worktree,description:"Allow local git discards in linked worktrees",defaultBehavior:"off"},{flag:S.debug,description:"Print diagnostic messages to stderr",defaultBehavior:"off"},{flag:S.auditScope,description:"Command decisions recorded: all, or blocked (privacy-minimizing, denials only)",defaultBehavior:"all"}];function ps(){return[...Gu.map((e)=>({name:e.flag.name,value:fr(e.flag),isSet:mr(e.flag),legacyName:e.flag.legacyName,legacyValue:e.flag.legacyName?process.env[e.flag.legacyName]:void 0,legacyIsSet:e.flag.legacyName?process.env[e.flag.legacyName]!==void 0:void 0,description:e.description,defaultBehavior:e.defaultBehavior})),{name:"CC_SAFETY_NET_HOME",value:process.env.CC_SAFETY_NET_HOME,isSet:process.env.CC_SAFETY_NET_HOME!==void 0,description:"Override user-scope config/cache directory",defaultBehavior:"~/.cc-safety-net"}]}var fs={error:0,warning:1,info:2},Bu=["policy","config","audit"];function qu(e){return e.map((t)=>{if(t==="ownership")return"is not owned by the current user";if(t==="permissions")return"has unsafe permissions";if(t==="symlink")return"is a symbolic link";return"is not a directory"}).join(" and ")}var Vu=[{derive:(e)=>e.hooks.length>0&&e.hooks.every((t)=>!t.configured)?[{checkId:"integration.none-configured",severity:"error",title:"No integration configured",detail:"CC Safety Net is not connected to any supported coding-agent integration.",fixHint:"Run `cc-safety-net install` and configure at least one integration."}]:[]},{derive:(e)=>e.hooks.filter((t)=>t.inspectionStatus==="failed").map((t)=>{let n=R(t.platform);return{checkId:"integration.inspection-failed",severity:"error",title:`${n} inspection failed`,detail:`Doctor could not verify the ${n} integration configuration.`,fixHint:`Correct the reported ${n} configuration error, then run \`cc-safety-net doctor\` again.`,integration:t.platform}})},{derive:(e)=>e.userConfig.exists&&!e.userConfig.valid?[{checkId:"config.user-invalid",severity:"error",title:"User configuration is invalid",detail:"Doctor could not load a valid user rules configuration.",fixHint:"Run `cc-safety-net rule verify`, correct the reported error, then rerun doctor.",path:e.userConfig.path}]:[]},{derive:(e)=>e.projectConfig.exists&&!e.projectConfig.valid?[{checkId:"config.project-invalid",severity:"error",title:"Project configuration is invalid",detail:"Doctor could not load a valid project rules configuration.",fixHint:"Run `cc-safety-net rule verify`, correct the reported error, then rerun doctor.",path:e.projectConfig.path}]:[]},{derive:(e)=>e.configState.state==="degraded"?[{checkId:"config.runtime-degraded",severity:"warning",title:"Runtime is enforcing a fallback configuration",detail:`The rejected candidate configuration is not active: ${e.configState.reason}`,fixHint:"Correct the named source, run `cc-safety-net rule sync` for a rule source, then rerun doctor."}]:[]},{derive:(e)=>{let t=e.environment.find((n)=>n.name==="CC_SAFETY_NET_AUDIT_SCOPE");return pr(t?.value)==="invalid"?[{checkId:"environment.audit-scope-invalid",severity:"warning",title:"Audit scope value is invalid",detail:"CC_SAFETY_NET_AUDIT_SCOPE is not `all` or `blocked`, so allowed command decisions are not recorded.",fixHint:"Set CC_SAFETY_NET_AUDIT_SCOPE to `all` or `blocked`, then restart the integration."}]:[]}},...Bu.map((e)=>({derive:(t)=>t.posture.directories.filter((n)=>n.kind===e&&n.status==="unsafe").map((n)=>({checkId:`posture.${e}-directory-unsafe`,severity:"error",title:`${e[0]?.toUpperCase()}${e.slice(1)} directory is unsafe`,detail:`The ${e} directory ${qu(n.issues)}.`,fixHint:"Ensure this is a real directory owned by the current user with no group or other write access, then rerun doctor.",...n.path?{path:n.path}:{}}))})),{derive:(e)=>{let t=[...e.effectiveSafety.weakenedRuleOverrides].sort();return t.length>0?[{checkId:"posture.rule-overrides-weaken-preset",severity:"warning",title:"Rule overrides weaken the selected preset",detail:`Explicit overrides disable rules the resolved preset would enable: ${t.join(", ")}.`,fixHint:`Remove these \`off\` overrides or set them to \`on\`: ${t.join(", ")}.`}]:[]}}];function ms(e){return Vu.flatMap((t,n)=>t.derive(e).map((r,o)=>({finding:r,catalogOrder:n,occurrence:o}))).sort((t,n)=>fs[t.finding.severity]-fs[n.finding.severity]||t.catalogOrder-n.catalogOrder||t.occurrence-n.occurrence).map((t)=>t.finding)}function ne(){return Boolean(process.stdout.isTTY&&!process.env.NO_COLOR)}var zu=(e)=>ne()?`\x1B[32m${e}\x1B[0m`:e,Ku=(e)=>ne()?`\x1B[33m${e}\x1B[0m`:e,Wu=(e)=>ne()?`\x1B[34m${e}\x1B[0m`:e,Ju=(e)=>ne()?`\x1B[35m${e}\x1B[0m`:e,Yu=(e)=>ne()?`\x1B[36m${e}\x1B[0m`:e,Zu=(e)=>ne()?`\x1B[31m${e}\x1B[0m`:e,Xu=(e)=>ne()?`\x1B[2m${e}\x1B[0m`:e,Qu=(e)=>ne()?`\x1B[1m${e}\x1B[0m`:e,h={green:zu,yellow:Ku,blue:Wu,magenta:Ju,cyan:Yu,red:Zu,dim:Xu,bold:Qu},ep="\x1B[0m",tp=[39,82,198,226,208,51,196,46,201,214,93,154,220,27,49,190,200,33,129,227,45,160,63,118,123,202];function np(e){let t=e;return()=>(t=(t*1664525+1013904223)%4294967296,t/4294967296)}function rp(e){let t=[...tp],n=np(e);for(let r=t.length-1;r>0;r--){let o=Math.floor(n()*(r+1)),i=t[r];t[r]=t[o],t[o]=i}return t}function op(e,t=0){if(!ne())return"";let n=rp(t);return`\x1B[38;5;${n[e%n.length]}m`}function gs(e,t,n=0){if(!ne())return`"${e}"`;return`${op(t,n)}"${e}"${ep}`}var ip=new RegExp("\x1B\\[[0-9;]*m","g"),xr=(e)=>e.replace(ip,"").length;function Pe(e){let t=(e.headers??e.rows[0]??[]).map((s,a)=>{let l=Math.max(...e.rows.map((c)=>xr(c[a]??"")));return Math.max(xr(s),l)}),n=(s,a)=>s+" ".repeat(Math.max(0,a-xr(s))),r=(s,a)=>a[0]+t.map((l)=>s.repeat(l+2)).join(a[1])+a[2],o=(s)=>`│ ${s.map((a,l)=>n(a,t[l]??0)).join(" │ ")} │`,i=e.headers?[` ${o(e.headers)}`,` ${r("─",["├","┼","┤"])}`]:[];return[` ${r("─",["┌","┬","┐"])}`,...i,...e.rows.map((s)=>` ${o(s)}`),` ${r("─",["└","┴","┘"])}`].join(`
6
+ `)}function hs(e){let t=[];t.push("Hook Integration"),t.push(sp(e));let n=[],r=[];for(let o of e){let i=R(o.platform);if(o.errors&&o.errors.length>0)for(let s of o.errors)if(o.configured)n.push({platform:i,message:s});else r.push({platform:i,message:s})}for(let o of n)t.push(` Warning (${o.platform}): ${o.message}`);for(let o of r)t.push(h.red(` Error (${o.platform}): ${o.message}`));return t.join(`
7
+ `)}function sp(e){let t=["Platform","Discovery","Configuration","Inspection"],n=e.map((r)=>{let o=R(r.platform);if(r.inspectionStatus==="not-inspected"){let l=h.dim("Not inspected");return[o,l,l,l]}let i=r.detected?h.green("Detected"):r.inspectionStatus==="failed"?h.red("Unknown"):h.dim("Not detected"),s=r.configured?h.green("Configured"):r.detected?h.yellow("Not configured"):r.inspectionStatus==="failed"?h.red("Unknown"):h.dim("Not applicable"),a=r.inspectionStatus==="verified"?h.green("Verified"):r.inspectionStatus==="failed"?h.red("Failed"):h.dim("Not applicable");return[o,i,s,a]});return Pe({headers:t,rows:n})}function ys(e){let n=["Guard Engine Verification",` Synthetic self-test: ${e.failed>0?h.red(`${e.passed}/${e.total} FAIL`):h.green(`${e.passed}/${e.total} passed`)}`],r=e.results.filter((o)=>!o.passed);if(r.length>0){n.push(""),n.push(h.red(" Failures:"));for(let o of r)n.push(h.red(` • ${o.description}`)),n.push(h.red(` expected ${o.expected}, got ${o.actual}`))}return n.join(`
8
+ `)}function ap(e){if(e.length===0)return" (no custom rules)";let t=["Source","Name","Command","Block Args"],n=e.map((r)=>[r.source,r.name,r.subcommand?`${r.command} ${r.subcommand}`:r.command,r.blockArgs.join(", ")]);return Pe({headers:t,rows:n})}function Ls(e){let t=[];if(t.push("Configuration"),t.push(lp(e.userConfig,e.projectConfig)),t.push(""),e.effectiveRules.length>0)t.push(` Effective rules (${e.effectiveRules.length} total):`),t.push(ap(e.effectiveRules));else t.push(" Effective rules: (none - using built-in rules only)");for(let n of e.shadowedRules)t.push(""),t.push(` Note: Project rule "${n.name}" shadows user rule with same name`);return t.join(`
9
+ `)}function lp(e,t){let n=["Scope","Status"],r=(i)=>{if(!i.exists)return h.dim("N/A");if(!i.valid)return h.red(`Invalid (${i.errors?.[0]??"unknown error"})`);return h.green("Configured")},o=[["User",r(e)],["Project",r(t)]];return Pe({headers:n,rows:o})}function vs(e){let t=[];return t.push("Environment"),t.push(cp(e)),t.join(`
10
+ `)}function bs(e){let t=["Effective Safety",` Selected preset: ${e.effectiveSafety.selectedPreset}`,` Effective: ${e.effectiveSafety.level}`],n=[["fail_closed","fail_closed"],["paranoid_rm","paranoid_rm"],["paranoid_interpreters","paranoid_interpreters"]];for(let[r,o]of n){let i=e.effectiveSafety.capabilities[r],s=i.enabled?h.green("ON"):h.dim("OFF"),a=i.sources.length>0?` (${i.sources.join(", ")})`:"";t.push(` ${o}: ${s} via ${i.source}${a}`)}t.push(` Stored rule customizations: ${e.effectiveSafety.ruleCounts.stored}`),t.push(` Effective rule customizations: ${e.effectiveSafety.ruleCounts.effective}`);for(let[r,o]of Object.entries(e.effectiveSafety.ruleOverrides))t.push(` ${r}: ${o}`);return t.join(`
11
+ `)}function ws(e){let t=["Findings"];if(e.length===0)return t.push(" No findings from inspected doctor facts."),t.join(`
12
12
  `);for(let n of e){let r=`[${n.severity.toUpperCase()}] ${n.checkId}: ${I(n.title)}`,o=n.severity==="error"?h.red:n.severity==="warning"?h.yellow:h.blue;if(t.push(` ${o(r)}`),t.push(` ${I(n.detail)}`),n.path)t.push(` Path: ${I(n.path)}`);if(n.fixHint)t.push(` Fix: ${I(n.fixHint)}`)}return t.join(`
13
- `)}function lp(e){let t=["Variable","Status","Legacy"],n=e.map((r)=>{let o=r.isSet?h.green("✓"):h.dim("✗"),i=r.legacyName&&r.legacyIsSet?`${r.legacyName} ${h.green("✓")}`:r.legacyName??"";return[r.name,o,i]});return Ee({headers:t,rows:n})}function bs(e){let t=[];if(e.totalBlocked===0)t.push("Recent Activity"),t.push(" No blocked commands in the last 7 days"),t.push(" Tip: This is normal for new installations");else t.push(`Recent Activity · last 7 days (${e.totalBlocked} blocked / ${e.sessionCount} sessions)`),t.push(cp(e.recentEntries));if(e.unreadable>0)t.push(` Warning: ${e.unreadable} audit log ${e.unreadable===1?"source":"sources"} could not be read; this summary is incomplete`);return t.join(`
14
- `)}function cp(e){let t=["Time","Command"],n=e.map((r)=>{let o=I(r.command.replace(/\r\n|\r|\n/g," ↵ ").replace(/\t/g," ")),i=o.length>40?`${o.slice(0,37)}...`:o;return[r.relativeTime,i]});return Ee({headers:t,rows:n})}function ws(e){let t=[];if(t.push("Update Check"),e.latestVersion===null&&!e.error)return t.push(Xt([["Status",h.dim("Skipped")],["Installed",e.currentVersion]])),t.join(`
13
+ `)}function cp(e){let t=["Variable","Status","Legacy"],n=e.map((r)=>{let o=r.isSet?h.green("✓"):h.dim("✗"),i=r.legacyName&&r.legacyIsSet?`${r.legacyName} ${h.green("✓")}`:r.legacyName??"";return[r.name,o,i]});return Pe({headers:t,rows:n})}function ks(e){let t=[];if(e.totalBlocked===0)t.push("Recent Activity"),t.push(" No blocked commands in the last 7 days"),t.push(" Tip: This is normal for new installations");else t.push(`Recent Activity · last 7 days (${e.totalBlocked} blocked / ${e.sessionCount} sessions)`),t.push(dp(e.recentEntries));if(e.unreadable>0)t.push(` Warning: ${e.unreadable} audit log ${e.unreadable===1?"source":"sources"} could not be read; this summary is incomplete`);return t.join(`
14
+ `)}function dp(e){let t=["Time","Command"],n=e.map((r)=>{let o=I(r.command.replace(/\r\n|\r|\n/g," ↵ ").replace(/\t/g," ")),i=o.length>40?`${o.slice(0,37)}...`:o;return[r.relativeTime,i]});return Pe({headers:t,rows:n})}function xs(e){let t=[];if(t.push("Update Check"),e.latestVersion===null&&!e.error)return t.push(Xt([["Status",h.dim("Skipped")],["Installed",e.currentVersion]])),t.join(`
15
15
  `);if(e.error)return t.push(Xt([["Status",`${h.yellow("⚠")} Error`],["Installed",e.currentVersion],["Error",h.dim(e.error)]])),t.join(`
16
16
  `);if(e.updateAvailable)return t.push(Xt([["Status",`${h.yellow("⚠")} Update Available`],["Current",e.currentVersion],["Latest",h.green(e.latestVersion??"")]])),t.push(""),t.push(" Run: bunx cc-safety-net@latest doctor"),t.push(" Or: npx cc-safety-net@latest doctor"),t.join(`
17
17
  `);return t.push(Xt([["Status",`${h.green("✓")} Up to date`],["Version",e.currentVersion]])),t.join(`
18
- `)}function Xt(e){return Ee({rows:e})}function ks(e){let t=[];return t.push("System Info"),t.push(dp(e)),t.join(`
19
- `)}function dp(e){let t=["Component","Version"],n=(i)=>{if(i===null)return h.dim("not found");return i},o=[{label:"cc-safety-net",value:e.version},...Wt.map((i)=>({label:R(i),value:e.versions[i]??null})),{label:"Node.js",value:e.nodeVersion},{label:"npm",value:e.npmVersion},{label:"Bun",value:e.bunVersion},{label:"Platform",value:e.platform}].map((i)=>[i.label,n(i.value)]);return Ee({headers:t,rows:o})}function xs(e){if(e.findings.length===0)return h.green(`
18
+ `)}function Xt(e){return Pe({rows:e})}function Cs(e){let t=[];return t.push("System Info"),t.push(up(e)),t.join(`
19
+ `)}function up(e){let t=["Component","Version"],n=(i)=>{if(i===null)return h.dim("not found");return i},o=[{label:"cc-safety-net",value:e.version},...Wt.map((i)=>({label:R(i),value:e.versions[i]??null})),{label:"Node.js",value:e.nodeVersion},{label:"npm",value:e.npmVersion},{label:"Bun",value:e.bunVersion},{label:"Platform",value:e.platform}].map((i)=>[i.label,n(i.value)]);return Pe({headers:t,rows:o})}function Ss(e){if(e.findings.length===0)return h.green(`
20
20
  No findings from inspected doctor facts.`);let t={error:e.findings.filter((i)=>i.severity==="error").length,warning:e.findings.filter((i)=>i.severity==="warning").length,info:e.findings.filter((i)=>i.severity==="info").length},n=["error","warning","info"].filter((i)=>t[i]>0).map((i)=>`${t[i]} ${i}`),r=e.findings.length===1?"finding":"findings",o=`
21
- ${e.findings.length} ${r}: ${n.join(", ")}.`;if(t.error>0)return h.red(o);if(t.warning>0)return h.yellow(o);return h.blue(o)}import{lstatSync as up}from"node:fs";import{dirname as Cr}from"node:path";function Sr(e,t){try{let n=up(t);if(n.isSymbolicLink())return{kind:e,path:t,status:"unsafe",issues:["symlink"]};if(!n.isDirectory())return{kind:e,path:t,status:"unsafe",issues:["not-directory"]};if(process.platform==="win32"||typeof process.getuid!=="function")return{kind:e,path:t,status:"unknown",issues:[]};let r=[...n.uid!==process.getuid()?["ownership"]:[],...(n.mode&18)!==0?["permissions"]:[]];return{kind:e,path:t,status:r.length>0?"unsafe":"safe",issues:r}}catch(n){if(typeof n==="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return{kind:e,path:t,status:"not-applicable",issues:[]};return{kind:e,path:t,status:"unknown",issues:[]}}}function Cs(e){let t=ue();return{directories:[Sr("policy",Cr(Cr(e))),Sr("config",Cr(e)),...t?[Sr("audit",t)]:[{kind:"audit",status:"unknown",issues:[]}]]}}import{spawn as pp}from"node:child_process";import{existsSync as Ss}from"node:fs";import{delimiter as fp,extname as mp,join as gp}from"node:path";import{stripVTControlCharacters as Ds}from"node:util";var As="2.0.11",hp=5000,yp="_CC_SAFETY_NET_TEST_SPAWN_PLATFORM";function P(){return As}function Dr(e,t){let n=e[t];if(n)return n;let r=Object.keys(e).find((o)=>o.toLowerCase()===t.toLowerCase()&&!!e[o]);return r?e[r]:n}function Lp(e){return(Dr(e,"PATHEXT")||".COM;.EXE;.BAT;.CMD").split(";").filter((t)=>t.length>0)}function vp(e,t){let n=mp(e)?[e]:[...Lp(t).map((r)=>`${e}${r}`),e];if(e.includes("/")||e.includes("\\"))return n.find((r)=>Ss(r))??e;return(Dr(t,"PATH")??"").split(fp).flatMap((r)=>n.map((o)=>gp(r,o))).find((r)=>Ss(r))??e}function Rs(e){if(!/[\s"&|<>^]/.test(e))return e;return`"${e.replace(/"/g,'""')}"`}function Pe(e,t){let[n,...r]=e,o=t[yp]==="win32"?"win32":process.platform;if(!n||o!=="win32")return{cmd:n??"",args:r};let i=vp(n,t);if(!/\.(?:bat|cmd)$/i.test(i))return{cmd:i,args:r};return{cmd:Dr(t,"COMSPEC")??"cmd.exe",args:["/d","/c",["call",Rs(i),...r.map(Rs)].join(" ")]}}var et=async(e,t=hp)=>{let n=await bp(e,{timeoutMs:t});if(n.code!==0)return null;return Ds(n.stdout).trim()||Ds(n.stderr).trim()||null};function bp(e,t){let[n,...r]=e;if(!n)return Promise.resolve({code:null,stdout:"",stderr:""});return new Promise((o)=>{try{let i=Pe([n,...r],process.env),s=pp(i.cmd,i.args,{stdio:["ignore","pipe","pipe"]}),a=!1,l="",c="";s.stdout.on("data",(g)=>{l+=g.toString()}),s.stderr.on("data",(g)=>{c+=g.toString()});let d=(g)=>{if(a)return;a=!0,clearTimeout(p),o(g)},p=setTimeout(()=>{s.kill(),d({code:null,stdout:l,stderr:c})},t.timeoutMs);s.on("close",(g)=>{d({code:g,stdout:l,stderr:c})}),s.on("error",()=>{d({code:null,stdout:l,stderr:c})})}catch{o({code:null,stdout:"",stderr:""})}})}function Qt(e){if(!e)return null;let t=/Claude Code\s+(\d+\.\d+\.\d+)/i.exec(e);if(t)return t[1]??null;let n=/v?(\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)/i.exec(e);if(n)return n[1]??null;return e.split(`
22
- `)[0]?.trim()||null}async function Dt(e=et){let[t,n,r,o,i,s]=await Promise.all([Promise.all(V.map(async(a)=>[a.id,Qt(await e([...a.probeCommand]))])),e(["codex","plugin","list"],30000),e(["amp","plugins","list"],30000),e(["node","--version"]),e(["npm","--version"]),e(["bun","--version"])]);return{version:As,versions:Object.fromEntries(t),codexPluginListOutput:n,ampPluginListOutput:r,nodeVersion:Qt(o),npmVersion:Qt(i),bunVersion:Qt(s),platform:`${process.platform} ${process.arch}`}}function Rr(e,t){if(t==="dev")return!1;let n=e.split(".").map(Number),r=t.split(".").map(Number),[o=0,i=0,s=0]=n,[a=0,l=0,c=0]=r;if(o!==a)return o>a;if(i!==l)return i>l;return s>c}async function tt(){let e=P(),t=new AbortController,n=setTimeout(()=>t.abort(),3000);try{let r=await fetch("https://registry.npmjs.org/cc-safety-net/latest",{signal:t.signal});if(!r.ok)return{currentVersion:e,latestVersion:null,updateAvailable:!1,error:`npm registry returned ${r.status}`};let o=await r.json(),i=Rr(o.version,e);return{currentVersion:e,latestVersion:o.version,updateAvailable:i}}catch(r){return{currentVersion:e,latestVersion:null,updateAvailable:!1,error:r instanceof Error?r.message:"Network error"}}finally{clearTimeout(n)}}import*as Ns from"node:readline";var Is=(e)=>`\x1B[${e}B`,wp=(e)=>`\x1B[${e}A`;var Es=["░","▒","▓","╱","╲","┃","━","┏","┓","┗","┛","╋"];function kp(e){return new Promise((t)=>setTimeout(t,e))}function xp(e,t,n){if(!n)return t(e);if(n.aborted)return Promise.resolve();return new Promise((r,o)=>{let i=()=>n.removeEventListener("abort",s),s=()=>{i(),r()};n.addEventListener("abort",s,{once:!0}),t(e).then(()=>{i(),r()},(a)=>{i(),o(a)})})}function Rt(e,t){return e&&e>0?e:t}function en(e){return Math.max(0,Math.min(1,e))}function nt(e){return Math.max(0,Math.min(255,Math.round(e)))}function Ar(e){return e<=0.0031308?12.92*e:1.055*e**0.4166666666666667-0.055}function Cp(e,t,n){let r=n*Math.PI/180,o=t*Math.cos(r),i=t*Math.sin(r),s=(e+0.3963377774*o+0.2158037573*i)**3,a=(e-0.1055613458*o-0.0638541728*i)**3,l=(e-0.0894841775*o-1.291485548*i)**3;return{blue:nt(Ar(en(-0.0041960863*s-0.7034186147*a+1.707614701*l))*255),green:nt(Ar(en(-1.2684380046*s+2.6097574011*a-0.3413193965*l))*255),red:nt(Ar(en(4.0767416621*s-3.3077115913*a+0.2309699292*l))*255)}}function Er(e,t){let n=(t*e*180/Math.PI%360+360)%360;return Cp(0.72,0.15,n)}function _s(e,t=0.1){let n=Er(t,e);return`\x1B[38;2;${n.red};${n.green};${n.blue}m`}function Sp(e,t){return{blue:nt(e.blue+(255-e.blue)*t),green:nt(e.green+(255-e.green)*t),red:nt(e.red+(255-e.red)*t)}}function Os(e,t,n){let r=Math.imul(e+2654435769,2246822507)^Math.imul(t+3266489909,668265263)^Math.imul(n+374761393,2654435761),o=r^r>>>15,i=Math.imul(o,739982445),s=i^i>>>12,a=Math.imul(s,695872825);return((a^a>>>15)>>>0)/4294967296}function Dp(e,t,n){let r=Math.floor(Os(e,t,n)*Es.length);return Es[r]??"░"}function Ps(e){let t=en(e);return t*t*t*(t*(t*6-15)+10)}function Rp(e){if(e.length===0)return"";let t=[],n=!1,r="";for(let o of e){let i=`${o.red};${o.green};${o.blue}`;if(o.bold!==n)t.push(o.bold?"\x1B[1m":"\x1B[22m"),n=o.bold;if(i!==r)t.push(`\x1B[38;2;${i}m`),r=i;t.push(o.character)}return`${t.join("")}\x1B[22m\x1B[39m`}function Ap(e,t,n,r,o){return e.map((i,s)=>({...Er(n,r+t+s/o),bold:!1,character:i}))}function Ep(e,t,n,r,o,i,s,a){let l=Math.max(1,r*0.75),c=Math.min(1,n/l),d=o*Ps(c),p=Math.max(0,(n-l)/Math.max(1,r-l)),g=(1-Ps(n/r))*a*2,u=0.35*Math.max(0,1-p*2),m=c>=1,f=Math.min(e.length,Math.ceil(d+2+1));return e.slice(0,f).map((L,v)=>{let k=Er(i,s+t+v/a+g),y=v+Os(t,v,7919)*2-1;if(y>d+2)return{...k,bold:!1,character:" "};let x=d-y,H=0.8*Math.exp(-(x*x)/12.5),he=Math.min(0.9,H+u),Mn=!m&&y>d-4;return{...Sp(k,he),bold:he>0.3,character:Mn?Dp(t,v,n):L}})}function Ts(e){return`\x1B[?2026h${e.map((t,n)=>`\x1B8${n>0?Is(n):""}${Rp(t)}`).join("")}\x1B[?2026l`}async function Pr(e,t={}){if(!e)return;let n=t.output??process.stdout,r=t.sleep??kp,o=Rt(t.frequency,0.1),i=t.seed??0,s=Rt(t.speed,40),a=Rt(t.spread,3),l=Rt(t.frameRate,60),c=Math.max(1,Math.floor(Rt(t.duration,12))),d=e.split(`
21
+ ${e.findings.length} ${r}: ${n.join(", ")}.`;if(t.error>0)return h.red(o);if(t.warning>0)return h.yellow(o);return h.blue(o)}import{lstatSync as pp}from"node:fs";import{dirname as Cr}from"node:path";function Sr(e,t){try{let n=pp(t);if(n.isSymbolicLink())return{kind:e,path:t,status:"unsafe",issues:["symlink"]};if(!n.isDirectory())return{kind:e,path:t,status:"unsafe",issues:["not-directory"]};if(process.platform==="win32"||typeof process.getuid!=="function")return{kind:e,path:t,status:"unknown",issues:[]};let r=[...n.uid!==process.getuid()?["ownership"]:[],...(n.mode&18)!==0?["permissions"]:[]];return{kind:e,path:t,status:r.length>0?"unsafe":"safe",issues:r}}catch(n){if(typeof n==="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return{kind:e,path:t,status:"not-applicable",issues:[]};return{kind:e,path:t,status:"unknown",issues:[]}}}function Ds(e){let t=ue();return{directories:[Sr("policy",Cr(Cr(e))),Sr("config",Cr(e)),...t?[Sr("audit",t)]:[{kind:"audit",status:"unknown",issues:[]}]]}}import{spawn as fp}from"node:child_process";import{existsSync as Rs}from"node:fs";import{delimiter as mp,extname as gp,join as hp}from"node:path";import{stripVTControlCharacters as As}from"node:util";var Ps="2.1.0",yp=5000,Lp="_CC_SAFETY_NET_TEST_SPAWN_PLATFORM";function P(){return Ps}function Dr(e,t){let n=e[t];if(n)return n;let r=Object.keys(e).find((o)=>o.toLowerCase()===t.toLowerCase()&&!!e[o]);return r?e[r]:n}function vp(e){return(Dr(e,"PATHEXT")||".COM;.EXE;.BAT;.CMD").split(";").filter((t)=>t.length>0)}function bp(e,t){let n=gp(e)?[e]:[...vp(t).map((r)=>`${e}${r}`),e];if(e.includes("/")||e.includes("\\"))return n.find((r)=>Rs(r))??e;return(Dr(t,"PATH")??"").split(mp).flatMap((r)=>n.map((o)=>hp(r,o))).find((r)=>Rs(r))??e}function Es(e){if(!/[\s"&|<>^]/.test(e))return e;return`"${e.replace(/"/g,'""')}"`}function Te(e,t){let[n,...r]=e,o=t[Lp]==="win32"?"win32":process.platform;if(!n||o!=="win32")return{cmd:n??"",args:r};let i=bp(n,t);if(!/\.(?:bat|cmd)$/i.test(i))return{cmd:i,args:r};return{cmd:Dr(t,"COMSPEC")??"cmd.exe",args:["/d","/c",["call",Es(i),...r.map(Es)].join(" ")]}}var tt=async(e,t=yp)=>{let n=await wp(e,{timeoutMs:t});if(n.code!==0)return null;return As(n.stdout).trim()||As(n.stderr).trim()||null};function wp(e,t){let[n,...r]=e;if(!n)return Promise.resolve({code:null,stdout:"",stderr:""});return new Promise((o)=>{try{let i=Te([n,...r],process.env),s=fp(i.cmd,i.args,{stdio:["ignore","pipe","pipe"]}),a=!1,l="",c="";s.stdout.on("data",(g)=>{l+=g.toString()}),s.stderr.on("data",(g)=>{c+=g.toString()});let d=(g)=>{if(a)return;a=!0,clearTimeout(p),o(g)},p=setTimeout(()=>{s.kill(),d({code:null,stdout:l,stderr:c})},t.timeoutMs);s.on("close",(g)=>{d({code:g,stdout:l,stderr:c})}),s.on("error",()=>{d({code:null,stdout:l,stderr:c})})}catch{o({code:null,stdout:"",stderr:""})}})}function Qt(e){if(!e)return null;let t=/Claude Code\s+(\d+\.\d+\.\d+)/i.exec(e);if(t)return t[1]??null;let n=/v?(\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)/i.exec(e);if(n)return n[1]??null;return e.split(`
22
+ `)[0]?.trim()||null}async function Rt(e=tt){let[t,n,r,o,i,s]=await Promise.all([Promise.all(V.map(async(a)=>[a.id,Qt(await e([...a.probeCommand]))])),e(["codex","plugin","list"],30000),e(["amp","plugins","list"],30000),e(["node","--version"]),e(["npm","--version"]),e(["bun","--version"])]);return{version:Ps,versions:Object.fromEntries(t),codexPluginListOutput:n,ampPluginListOutput:r,nodeVersion:Qt(o),npmVersion:Qt(i),bunVersion:Qt(s),platform:`${process.platform} ${process.arch}`}}function Rr(e,t){if(t==="dev")return!1;let n=e.split(".").map(Number),r=t.split(".").map(Number),[o=0,i=0,s=0]=n,[a=0,l=0,c=0]=r;if(o!==a)return o>a;if(i!==l)return i>l;return s>c}async function nt(){let e=P(),t=new AbortController,n=setTimeout(()=>t.abort(),3000);try{let r=await fetch("https://registry.npmjs.org/cc-safety-net/latest",{signal:t.signal});if(!r.ok)return{currentVersion:e,latestVersion:null,updateAvailable:!1,error:`npm registry returned ${r.status}`};let o=await r.json(),i=Rr(o.version,e);return{currentVersion:e,latestVersion:o.version,updateAvailable:i}}catch(r){return{currentVersion:e,latestVersion:null,updateAvailable:!1,error:r instanceof Error?r.message:"Network error"}}finally{clearTimeout(n)}}import*as Hs from"node:readline";var Os=(e)=>`\x1B[${e}B`,kp=(e)=>`\x1B[${e}A`;var Ts=["░","▒","▓","╱","╲","┃","━","┏","┓","┗","┛","╋"];function xp(e){return new Promise((t)=>setTimeout(t,e))}function Cp(e,t,n){if(!n)return t(e);if(n.aborted)return Promise.resolve();return new Promise((r,o)=>{let i=()=>n.removeEventListener("abort",s),s=()=>{i(),r()};n.addEventListener("abort",s,{once:!0}),t(e).then(()=>{i(),r()},(a)=>{i(),o(a)})})}function At(e,t){return e&&e>0?e:t}function en(e){return Math.max(0,Math.min(1,e))}function rt(e){return Math.max(0,Math.min(255,Math.round(e)))}function Ar(e){return e<=0.0031308?12.92*e:1.055*e**0.4166666666666667-0.055}function Sp(e,t,n){let r=n*Math.PI/180,o=t*Math.cos(r),i=t*Math.sin(r),s=(e+0.3963377774*o+0.2158037573*i)**3,a=(e-0.1055613458*o-0.0638541728*i)**3,l=(e-0.0894841775*o-1.291485548*i)**3;return{blue:rt(Ar(en(-0.0041960863*s-0.7034186147*a+1.707614701*l))*255),green:rt(Ar(en(-1.2684380046*s+2.6097574011*a-0.3413193965*l))*255),red:rt(Ar(en(4.0767416621*s-3.3077115913*a+0.2309699292*l))*255)}}function Er(e,t){let n=(t*e*180/Math.PI%360+360)%360;return Sp(0.72,0.15,n)}function $s(e,t=0.1){let n=Er(t,e);return`\x1B[38;2;${n.red};${n.green};${n.blue}m`}function Dp(e,t){return{blue:rt(e.blue+(255-e.blue)*t),green:rt(e.green+(255-e.green)*t),red:rt(e.red+(255-e.red)*t)}}function Ns(e,t,n){let r=Math.imul(e+2654435769,2246822507)^Math.imul(t+3266489909,668265263)^Math.imul(n+374761393,2654435761),o=r^r>>>15,i=Math.imul(o,739982445),s=i^i>>>12,a=Math.imul(s,695872825);return((a^a>>>15)>>>0)/4294967296}function Rp(e,t,n){let r=Math.floor(Ns(e,t,n)*Ts.length);return Ts[r]??"░"}function Is(e){let t=en(e);return t*t*t*(t*(t*6-15)+10)}function Ap(e){if(e.length===0)return"";let t=[],n=!1,r="";for(let o of e){let i=`${o.red};${o.green};${o.blue}`;if(o.bold!==n)t.push(o.bold?"\x1B[1m":"\x1B[22m"),n=o.bold;if(i!==r)t.push(`\x1B[38;2;${i}m`),r=i;t.push(o.character)}return`${t.join("")}\x1B[22m\x1B[39m`}function Ep(e,t,n,r,o){return e.map((i,s)=>({...Er(n,r+t+s/o),bold:!1,character:i}))}function Pp(e,t,n,r,o,i,s,a){let l=Math.max(1,r*0.75),c=Math.min(1,n/l),d=o*Is(c),p=Math.max(0,(n-l)/Math.max(1,r-l)),g=(1-Is(n/r))*a*2,u=0.35*Math.max(0,1-p*2),m=c>=1,f=Math.min(e.length,Math.ceil(d+2+1));return e.slice(0,f).map((L,v)=>{let x=Er(i,s+t+v/a+g),y=v+Ns(t,v,7919)*2-1;if(y>d+2)return{...x,bold:!1,character:" "};let C=d-y,H=0.8*Math.exp(-(C*C)/12.5),he=Math.min(0.9,H+u),Mn=!m&&y>d-4;return{...Dp(x,he),bold:he>0.3,character:Mn?Rp(t,v,n):L}})}function _s(e){return`\x1B[?2026h${e.map((t,n)=>`\x1B8${n>0?Os(n):""}${Ap(t)}`).join("")}\x1B[?2026l`}async function Pr(e,t={}){if(!e)return;let n=t.output??process.stdout,r=t.sleep??xp,o=At(t.frequency,0.1),i=t.seed??0,s=At(t.speed,40),a=At(t.spread,3),l=At(t.frameRate,60),c=Math.max(1,Math.floor(At(t.duration,12))),d=e.split(`
23
23
  `).map((f)=>Array.from(f)),p=Math.max(...d.map((f)=>f.length)),g=1000*c*d.filter((f)=>f.length>0).length/s,u=p>0?Math.max(1,Math.ceil(g/(1000/l))):0,m=u>0?g/u:0;n.write(`\x1B[?25l${d.length>1?`${`
24
- `.repeat(d.length-1)}${wp(d.length-1)}`:""}\x1B7`);try{for(let f=1;f<=u;f+=1){if(t.signal?.aborted)break;n.write(Ts(d.map((L,v)=>Ep(L,v,f,u,p,o,i,a)))),await xp(m,r,t.signal)}}finally{if(n.write(Ts(d.map((f,L)=>Ap(f,L,o,i,a)))),n.write("\x1B8"),d.length>1)n.write(Is(d.length-1));n.write(`
25
- \x1B[0m\x1B[?25h`)}}var $s=["┏━┛┏━┛ ┏━┛┏━┃┏━┛┏━┛━┏┛┃ ┃ ┏━ ┏━┛━┏┛","┃ ┃ ━━┃┏━┃┏━┛┏━┛ ┃ ━┏┛ ┃ ┃┏━┛ ┃ ","━━┛━━┛ ━━┛┛ ┛┛ ━━┛ ┛ ┛ ┛ ┛━━┛ ┛ "].join(`
26
- `);function Pp(e){return Boolean(e.isTTY)}async function At(e={}){let t=e.output??process.stdout;if(!Pp(t))return;let n=e.input??process.stdin,r={duration:e.duration,frequency:e.frequency,output:t,seed:e.seed??Math.random()*8192,sleep:e.sleep,speed:e.speed,spread:e.spread};if(!n.isTTY||typeof n.setRawMode!=="function"){await Pr($s,r);return}let o=new AbortController,i=n.readableFlowing===!0,s=n.isRaw===!0,a=!1,l=(c,d)=>{if(d.ctrl&&d.name==="c")a=!0;if(a||d.name==="return"||d.name==="enter")o.abort()};Ns.emitKeypressEvents(n),n.on("keypress",l),n.setRawMode(!0),n.resume();try{await Pr($s,{...r,signal:o.signal})}finally{if(n.off("keypress",l),n.setRawMode(s),!i)n.pause()}if(!a)return;if(e.onInterrupt){e.onInterrupt();return}process.kill(process.pid,"SIGINT")}var Fs="\r\x1B[2K",Tp="\x1B[?25l",Ip="\x1B[39m",_p="\x1B[?25h",Op=100,$p=0.55,Np=80,Hs=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function Fp(e){return new Promise((t)=>setTimeout(t,e))}async function tn(e,t={}){let n=t.output??process.stdout;if(!n.isTTY)return e;let r=t.sleep??Fp,o=!1,i=e.then((a)=>(o=!0,a),(a)=>{throw o=!0,a});if(await Promise.race([i.then(()=>!0),r(Op).then(()=>!1)]))return i;n.write(Tp);try{for(let a=0;!o;a+=1)n.write(`${Fs}${_s(a*$p)}${Hs[a%Hs.length]}${Ip} ${t.loadingMessage??"Loading…"}`),await Promise.race([i,r(Np)]);return await i}finally{n.write(`${Fs}${_p}`)}}async function Et(e,t,n,r={}){let o=t();if(e)await n();if(e&&o.ready)await tn(o.ready,r);return o.finish()}import{homedir as sf}from"node:os";import{stripVTControlCharacters as Hp}from"node:util";var nn="amp plugins list",Mp=/^\s*[✓✗]\s+cc-safety-net(?:\.ts)?\s+\(User Plugins\)\s+(\S+)\s*$/;function Ms(e){if(!e.ampPluginListOutput)return{platform:"amp",status:"n/a"};let t=Hp(e.ampPluginListOutput).split(`
27
- `).map((n)=>Mp.exec(n)?.[1]).find((n)=>n!==void 0);if(!t)return{platform:"amp",status:"n/a"};if(t!=="active")return{platform:"amp",status:"disabled",method:nn,configPath:nn,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:nn,configPath:nn}}import{existsSync as jp,readFileSync as Up}from"node:fs";var Gp=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*(?:--agy-cli|-ac)(\s|["']|$)/;function Bp(e){if(!e||typeof e!=="object"||Array.isArray(e))return[];return Object.values(e).flatMap((t)=>{if(!t||typeof t!=="object"||Array.isArray(t))return[];let n=t,r=n.PreToolUse;if(!Array.isArray(r))return[];return r.flatMap((o)=>{if(!o||typeof o!=="object"||Array.isArray(o))return[];let i=o.hooks;if(!Array.isArray(i))return[];return i.flatMap((s)=>{if(!s||typeof s!=="object"||Array.isArray(s))return[];let a=s.command;if(typeof a!=="string"||!Gp.test(a))return[];return[{command:a,enabled:n.enabled!==!1}]})})})}function js(e){let t=Ct(e.homeDir);if(!jp(t))return{platform:"antigravity-cli",status:"n/a",configPath:t};let n;try{n=Bp(JSON.parse(Up(t,"utf-8")))}catch(r){return{platform:"antigravity-cli",status:"n/a",configPath:t,errors:[`Failed to parse Antigravity hooks config ${t}: ${r instanceof Error?r.message:String(r)}`]}}if(n.some((r)=>r.enabled))return{platform:"antigravity-cli",status:"configured",method:"hook config",configPath:t};if(n.length>0)return{platform:"antigravity-cli",status:"disabled",method:"hook config",configPath:t};return{platform:"antigravity-cli",status:"n/a",configPath:t}}import{join as Us}from"node:path";import{existsSync as qp,lstatSync as Vp,readFileSync as zp}from"node:fs";function re(e,t=(n)=>n){if(!qp(e))return{kind:"missing"};try{return{kind:"ok",value:JSON.parse(t(zp(e,"utf-8")))}}catch{return{kind:"unreadable"}}}function E(e){try{return Vp(e)}catch{return}}function rn(e,t){let n=E(t);if(!n)return{platform:e,status:"n/a",configPath:t};if(!n.isSymbolicLink()&&n.isDirectory())return;return{platform:e,status:"n/a",configPath:t,errors:[`${t} is a symlink or not a directory; move or remove it before installing`]}}function b(e,t){return typeof e==="object"&&e!==null?e[t]:void 0}var Tr="cc-safety-net@cc-marketplace";function Gs(e){return Us(e,".claude","plugins","installed_plugins.json")}function Bs(e,t){let n=b(b(e,"plugins"),t);return Array.isArray(n)&&n.length>0}function on(e,t){let n=re(Gs(e));return n.kind==="ok"&&Bs(n.value,t)}function Ir(e){let t=Gs(e),n=re(t);if(n.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(n.kind==="missing")return{platform:"claude-code",status:"n/a"};if(!Bs(n.value,Tr))return{platform:"claude-code",status:"n/a"};let r=Us(e,".claude","settings.json"),o=re(r);if(o.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(!(o.kind==="ok"&&b(b(o.value,"enabledPlugins"),Tr)===!0))return{platform:"claude-code",status:"disabled",method:"plugin config",configPath:r,errors:[`${Tr} is installed but not enabled in Claude Code`]};return{platform:"claude-code",status:"configured",method:"plugin config",configPath:t}}function qs(e){return Ir(e.homeDir)}function Vs(e){if(!e.codexPluginListOutput)return{platform:"codex",status:"n/a"};let t=e.codexPluginListOutput.split(`
28
- `).find((n)=>n.includes("https://github.com/kenryu42/cc-safety-net.git"));if(!t)return{platform:"codex",status:"n/a"};if(!t.includes("installed,"))return{platform:"codex",status:"n/a"};if(!t.includes("installed, enabled"))return{platform:"codex",status:"disabled",method:"codex plugin list",configPath:"codex plugin list",errors:["Codex plugin line for https://github.com/kenryu42/cc-safety-net.git must contain installed, enabled."]};return{platform:"codex",status:"configured",method:"codex plugin list",configPath:"codex plugin list"}}import{existsSync as cn,readdirSync as Kp,readFileSync as Wp}from"node:fs";import{join as F}from"node:path";var oe="cc-safety-net@cc-marketplace",sn=["cc-marketplace","cc-safety-net"],zs=["_direct","copilot-safety-net"],Ks=["cc-marketplace","safety-net"],Ws="safety-net@cc-marketplace";function an(e,t){let n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(^|[^a-z0-9-])${n}([^a-z0-9-]|$)`,"m").test(e??"")}function Js(e){return an(e,"cc-safety-net@cc-marketplace")}function Ys(e){return an(e,"cc-marketplace")}function Zs(e){return an(e,"copilot-safety-net")}function Xs(e){return an(e,"safety-net@cc-marketplace")}function q(e){let t="",n=0,r=!1,o=!1,i=-1;while(n<e.length){let s=e[n],a=e[n+1];if(o){t+=s,o=!1,n++;continue}if(s==='"'&&!r){r=!0,i=-1,t+=s,n++;continue}if(s==='"'&&r){r=!1,t+=s,n++;continue}if(s==="\\"&&r){o=!0,t+=s,n++;continue}if(r){t+=s,n++;continue}if(s==="/"&&a==="/"){while(n<e.length&&e[n]!==`
29
- `)n++;continue}if(s==="/"&&a==="*"){n+=2;while(n<e.length-1){if(e[n]==="*"&&e[n+1]==="/"){n+=2;break}n++}continue}if(s===","){i=t.length,t+=s,n++;continue}if(s==="}"||s==="]"){if(i!==-1){let l=t.slice(i+1);if(/^\s*$/.test(l))t=t.slice(0,i)+l}i=-1,t+=s,n++;continue}if(!/\s/.test(s))i=-1;t+=s,n++}return t}function _r(e){if(!e?.includes("cc-safety-net"))return!1;return/(^|\s)hook\s+(?:[^\s]+\s+)*(--copilot-cli|-cp)(\s|$)/.test(e)}function ea(e,t){if(!e)return null;let n=e.match(/(\d+)\.(\d+)\.(\d+)/);if(!n)return null;let r=[Number(n[1]),Number(n[2]),Number(n[3])];for(let o=0;o<t.length;o++){let i=r[o]??0,s=t[o]??0;if(i!==s)return i>s}return!0}function Jp(e){return ea(e,[0,0,422])}function Yp(e){return ea(e,[1,0,8])}function Pt(e){return process.env.COPILOT_HOME||F(e,".copilot")}function Or(e){return(e.hooks?.preToolUse??[]).some((n)=>{if(n.type!=="command")return!1;return _r(n.command)||_r(n.bash)||_r(n.powershell)})}function ln(e){return e===void 0||typeof e==="string"}function Zp(e){if(!e||typeof e!=="object"||Array.isArray(e))return!1;let t=e;if(t.disableAllHooks!==void 0&&typeof t.disableAllHooks!=="boolean")return!1;if(t.hooks===void 0)return!0;if(!t.hooks||typeof t.hooks!=="object"||Array.isArray(t.hooks))return!1;let n=t.hooks.preToolUse;if(n===void 0)return!0;return Array.isArray(n)&&n.every((r)=>r!==null&&typeof r==="object"&&!Array.isArray(r)&&ln(r.type)&&ln(r.command)&&ln(r.bash)&&ln(r.powershell))}function $r(e,t){try{let n=JSON.parse(q(Wp(e,"utf-8")));if(!Zp(n)){t?.push(`Invalid hook config ${e}: hooks.preToolUse must be an array of hook objects`);return}return n}catch(n){t?.push(`Failed to parse ${e}: ${n instanceof Error?n.message:String(n)}`);return}}function ta(e,t){try{return Kp(e).filter((n)=>n.endsWith(".json")).sort((n,r)=>n.localeCompare(r))}catch(n){return t?.push(`Failed to read ${e}: ${n instanceof Error?n.message:String(n)}`),[]}}function Xp(e,t){if(!cn(e))return[];let n=[];for(let r of ta(e,t)){let o=F(e,r),i=$r(o,t);if(i&&Or(i))n.push(o)}return n}function rt(e,t){if(!cn(e))return;let n=$r(e,t);if(!n)return;return{path:e,config:n}}function Qs(e,t,n,r){if(t){e.push(`GitHub Copilot CLI ${t} does not support ${n}; requires ${r}+`);return}e.push(`GitHub Copilot CLI version unavailable; skipping ${n} because it requires ${r}+`)}function Qp(e){for(let t of e){if(t?.config.disableAllHooks===!0)return t.path;if(t?.config.disableAllHooks===!1)return}return}function e2(e,t,n,r){let o=Pt(e),i=F(t,".github","hooks"),s=F(o,"hooks"),a=F(t,".github","copilot"),l=F(t,".claude"),c=Yp(n),d=c===!0?r:void 0,p=[rt(F(a,"settings.local.json"),d),rt(F(a,"settings.json"),d),rt(F(l,"settings.local.json"),d),rt(F(l,"settings.json"),d)],g=[rt(F(o,"settings.json"),d),rt(F(o,"config.json"),d)];if(c!==!1){let x=Qp([...p,...g]);if(x){if(c===null)r.push(`GitHub Copilot CLI version unavailable; treating disableAllHooks in ${x} as active`);return{activeConfigPaths:[],disabledBy:x}}}let u=Xp(i,r),m=Jp(n),f=m===!0?r:void 0,L=cn(s)?ta(s,f):[],v=[];for(let x of L){let H=F(s,x),he=$r(H,f);if(he&&Or(he))v.push(H)}if(m!==!0&&v.length>0)Qs(r,n,`user hook files in ${s}`,"0.0.422"),v.length=0;let k=[];for(let x of[...p,...g]){if(!x)continue;if(!Or(x.config))continue;if(c===!0){k.push(x);continue}Qs(r,n,"inline hook definitions in Copilot config files","1.0.8");break}let y=(x)=>x.filter((H)=>!!H&&k.includes(H)).map((H)=>H.path);return{activeConfigPaths:[...y(p),...u,...y(g),...v]}}function na(e){let t=[],n=e2(e.homeDir,e.cwd,e.copilotCliVersion,t);if(n.disabledBy)return{platform:"copilot-cli",status:"disabled",method:"hook config",configPath:n.disabledBy,configPaths:[n.disabledBy],errors:t.length>0?t:void 0};let r=Pt(e.homeDir),o=F(r,"installed-plugins",...sn),i=cn(o),s=F(r,"settings.json"),a=re(s,q);if(i&&a.kind==="unreadable")return{platform:"copilot-cli",status:"not-inspected"};if(i&&a.kind==="ok"&&b(b(a.value,"enabledPlugins"),oe)===!1)return{platform:"copilot-cli",status:"disabled",method:"plugin config",configPath:s,errors:[`${oe} is installed but not enabled in Copilot CLI`]};if(i||n.activeConfigPaths.length>0){let l=i,c=n.activeConfigPaths[0];return{platform:"copilot-cli",status:"configured",method:l?"plugin config":"hook config",configPath:c??(l?o:void 0),configPaths:n.activeConfigPaths.length>0?n.activeConfigPaths:void 0,errors:t.length>0?t:void 0}}return{platform:"copilot-cli",status:"n/a",errors:t.length>0?t:void 0}}import{existsSync as d2,readFileSync as u2}from"node:fs";import{existsSync as ra,mkdirSync as r2,readFileSync as o2}from"node:fs";import{dirname as i2,join as s2}from"node:path";import{renameSync as t2,writeFileSync as n2}from"node:fs";function _(e,t){let n=`${e}.${process.pid}.tmp`;n2(n,t),t2(n,e)}var Tt="npx -y cc-safety-net hook --cursor",oa=30;function un(e){return s2(e,".cursor","hooks.json")}function Te(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Nr(){return{command:Tt,timeout:oa,failClosed:!0}}function dn(e){return Te(e)&&e.command===Tt}function a2(e){return Object.keys(e).length===3&&e.command===Tt&&e.timeout===oa&&e.failClosed===!0}function l2(e){try{return JSON.parse(o2(e,"utf-8"))}catch(t){if(t instanceof SyntaxError)throw Error(`Failed to parse Cursor hooks config ${e}: ${t.message}`);throw t}}function ia(e){let t=l2(e);if(!Te(t))throw Error(`Cursor hooks config ${e} must be a JSON object`);if(t.version!==1)throw Error(`Cursor hooks config ${e} must set "version": 1`);if(t.hooks!==void 0&&!Te(t.hooks))throw Error(`Cursor hooks config ${e} "hooks" must be an object`);let n=Te(t.hooks)?t.hooks.preToolUse:void 0;if(n!==void 0&&!Array.isArray(n))throw Error(`Cursor hooks config ${e} "hooks.preToolUse" must be an array`);return t}function sa(e){let t=Te(e.hooks)?e.hooks.preToolUse:void 0;return Array.isArray(t)?t:[]}function c2(e){if(!e.some(dn))return[...e,Nr()];return e.reduce((t,n)=>{if(!dn(n))return t.result.push(n),t;if(!t.inserted)t.result.push(Nr()),t.inserted=!0;return t},{result:[],inserted:!1}).result}function aa(e,t,n){let r=Te(t.hooks)?t.hooks:{},o={...t,hooks:{...r,preToolUse:n}};_(e,`${JSON.stringify(o,null,2)}
30
- `)}function la(e){let t=un(e);if(!ra(t))return r2(i2(t),{recursive:!0}),_(t,`${JSON.stringify({version:1,hooks:{preToolUse:[Nr()]}},null,2)}
31
- `),{path:t,alreadyInstalled:!1};let n=ia(t),r=sa(n),o=r.filter(dn);if(Te(n.hooks)&&Array.isArray(n.hooks.preToolUse)&&o.length===1&&o[0]!==void 0&&a2(o[0]))return{path:t,alreadyInstalled:!0};return aa(t,n,c2(r)),{path:t,alreadyInstalled:!1}}function ca(e){let t=un(e);if(!ra(t))return{path:t,alreadyInstalled:!1};let n=ia(t),r=sa(n),o=r.filter((i)=>!dn(i));if(o.length===r.length)return{path:t,alreadyInstalled:!1};return aa(t,n,o),{path:t,alreadyInstalled:!0}}function p2(e){if(!e||typeof e!=="object"||Array.isArray(e))return[];let t=e.hooks;if(!t||typeof t!=="object"||Array.isArray(t))return[];let n=t.preToolUse;if(!Array.isArray(n))return[];return n.filter((r)=>!!r&&typeof r==="object"&&!Array.isArray(r)&&r.command===Tt)}function f2(e){let t=[];if(e.length>1)t.push("Multiple managed cc-safety-net hooks found; reinstall to collapse duplicates");let n=e[0];if(n&&n.failClosed!==!0)t.push('Managed hook is missing "failClosed": true; reinstall to repair');if(n&&n.timeout!==30)t.push('Managed hook "timeout" is not 30; reinstall to repair');return t}function da(e){let t=un(e.homeDir);if(!d2(t))return{platform:"cursor",status:"n/a",configPath:t};let n;try{n=JSON.parse(u2(t,"utf-8"))}catch(i){return{platform:"cursor",status:"n/a",configPath:t,errors:[`Failed to parse Cursor hooks config ${t}: ${i instanceof Error?i.message:String(i)}`]}}let r=p2(n);if(r.length===0)return{platform:"cursor",status:"n/a",configPath:t};let o=f2(r);return{platform:"cursor",status:"configured",method:"hook config",configPath:t,errors:o.length>0?o:void 0}}import{existsSync as m2}from"node:fs";import{join as Fr}from"node:path";var Hr="gemini-safety-net";function Mr(e){let t=Fr(e,".gemini","extensions"),n=Fr(t,Hr);if(!m2(n))return{platform:"gemini-cli",status:"n/a"};let r=Fr(t,"extension-enablement.json"),o=re(r);if(o.kind==="unreadable")return{platform:"gemini-cli",status:"not-inspected"};let i=o.kind==="ok"?b(b(o.value,Hr),"overrides"):void 0;if(Array.isArray(i)&&i.some((a)=>typeof a==="string"&&a.startsWith("!")))return{platform:"gemini-cli",status:"disabled",method:"extension config",configPath:r,errors:[`${Hr} is disabled in Gemini CLI`]};return{platform:"gemini-cli",status:"configured",method:"extension config",configPath:n}}function ua(e){return Mr(e.homeDir)}import{readFileSync as ba}from"node:fs";import{join as wa}from"node:path";var z="cc-safety-net",pa="# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent";function fa(e){return`# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent
24
+ `.repeat(d.length-1)}${kp(d.length-1)}`:""}\x1B7`);try{for(let f=1;f<=u;f+=1){if(t.signal?.aborted)break;n.write(_s(d.map((L,v)=>Pp(L,v,f,u,p,o,i,a)))),await Cp(m,r,t.signal)}}finally{if(n.write(_s(d.map((f,L)=>Ep(f,L,o,i,a)))),n.write("\x1B8"),d.length>1)n.write(Os(d.length-1));n.write(`
25
+ \x1B[0m\x1B[?25h`)}}var Fs=["┏━┛┏━┛ ┏━┛┏━┃┏━┛┏━┛━┏┛┃ ┃ ┏━ ┏━┛━┏┛","┃ ┃ ━━┃┏━┃┏━┛┏━┛ ┃ ━┏┛ ┃ ┃┏━┛ ┃ ","━━┛━━┛ ━━┛┛ ┛┛ ━━┛ ┛ ┛ ┛ ┛━━┛ ┛ "].join(`
26
+ `);function Tp(e){return Boolean(e.isTTY)}async function Et(e={}){let t=e.output??process.stdout;if(!Tp(t))return;let n=e.input??process.stdin,r={duration:e.duration,frequency:e.frequency,output:t,seed:e.seed??Math.random()*8192,sleep:e.sleep,speed:e.speed,spread:e.spread};if(!n.isTTY||typeof n.setRawMode!=="function"){await Pr(Fs,r);return}let o=new AbortController,i=n.readableFlowing===!0,s=n.isRaw===!0,a=!1,l=(c,d)=>{if(d.ctrl&&d.name==="c")a=!0;if(a||d.name==="return"||d.name==="enter")o.abort()};Hs.emitKeypressEvents(n),n.on("keypress",l),n.setRawMode(!0),n.resume();try{await Pr(Fs,{...r,signal:o.signal})}finally{if(n.off("keypress",l),n.setRawMode(s),!i)n.pause()}if(!a)return;if(e.onInterrupt){e.onInterrupt();return}process.kill(process.pid,"SIGINT")}var Ms="\r\x1B[2K",Ip="\x1B[?25l",_p="\x1B[39m",Op="\x1B[?25h",$p=100,Np=0.55,Fp=80,js=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function Hp(e){return new Promise((t)=>setTimeout(t,e))}async function tn(e,t={}){let n=t.output??process.stdout;if(!n.isTTY)return e;let r=t.sleep??Hp,o=!1,i=e.then((a)=>(o=!0,a),(a)=>{throw o=!0,a});if(await Promise.race([i.then(()=>!0),r($p).then(()=>!1)]))return i;n.write(Ip);try{for(let a=0;!o;a+=1)n.write(`${Ms}${$s(a*Np)}${js[a%js.length]}${_p} ${t.loadingMessage??"Loading…"}`),await Promise.race([i,r(Fp)]);return await i}finally{n.write(`${Ms}${Op}`)}}async function Pt(e,t,n,r={}){let o=t();if(e)await n();if(e&&o.ready)await tn(o.ready,r);return o.finish()}import{homedir as af}from"node:os";import{stripVTControlCharacters as Mp}from"node:util";var nn="amp plugins list",jp=/^\s*[✓✗]\s+cc-safety-net(?:\.ts)?\s+\(User Plugins\)\s+(\S+)\s*$/;function Us(e){if(!e.ampPluginListOutput)return{platform:"amp",status:"n/a"};let t=Mp(e.ampPluginListOutput).split(`
27
+ `).map((n)=>jp.exec(n)?.[1]).find((n)=>n!==void 0);if(!t)return{platform:"amp",status:"n/a"};if(t!=="active")return{platform:"amp",status:"disabled",method:nn,configPath:nn,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:nn,configPath:nn}}import{existsSync as Up,readFileSync as Gp}from"node:fs";var Bp=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*(?:--agy-cli|-ac)(\s|["']|$)/;function qp(e){if(!e||typeof e!=="object"||Array.isArray(e))return[];return Object.values(e).flatMap((t)=>{if(!t||typeof t!=="object"||Array.isArray(t))return[];let n=t,r=n.PreToolUse;if(!Array.isArray(r))return[];return r.flatMap((o)=>{if(!o||typeof o!=="object"||Array.isArray(o))return[];let i=o.hooks;if(!Array.isArray(i))return[];return i.flatMap((s)=>{if(!s||typeof s!=="object"||Array.isArray(s))return[];let a=s.command;if(typeof a!=="string"||!Bp.test(a))return[];return[{command:a,enabled:n.enabled!==!1}]})})})}function Gs(e){let t=St(e.homeDir);if(!Up(t))return{platform:"antigravity-cli",status:"n/a",configPath:t};let n;try{n=qp(JSON.parse(Gp(t,"utf-8")))}catch(r){return{platform:"antigravity-cli",status:"n/a",configPath:t,errors:[`Failed to parse Antigravity hooks config ${t}: ${r instanceof Error?r.message:String(r)}`]}}if(n.some((r)=>r.enabled))return{platform:"antigravity-cli",status:"configured",method:"hook config",configPath:t};if(n.length>0)return{platform:"antigravity-cli",status:"disabled",method:"hook config",configPath:t};return{platform:"antigravity-cli",status:"n/a",configPath:t}}import{join as Bs}from"node:path";import{existsSync as Vp,lstatSync as zp,readFileSync as Kp}from"node:fs";function re(e,t=(n)=>n){if(!Vp(e))return{kind:"missing"};try{return{kind:"ok",value:JSON.parse(t(Kp(e,"utf-8")))}}catch{return{kind:"unreadable"}}}function E(e){try{return zp(e)}catch{return}}function rn(e,t){let n=E(t);if(!n)return{platform:e,status:"n/a",configPath:t};if(!n.isSymbolicLink()&&n.isDirectory())return;return{platform:e,status:"n/a",configPath:t,errors:[`${t} is a symlink or not a directory; move or remove it before installing`]}}function b(e,t){return typeof e==="object"&&e!==null?e[t]:void 0}var Tr="cc-safety-net@cc-marketplace";function qs(e){return Bs(e,".claude","plugins","installed_plugins.json")}function Vs(e,t){let n=b(b(e,"plugins"),t);return Array.isArray(n)&&n.length>0}function on(e,t){let n=re(qs(e));return n.kind==="ok"&&Vs(n.value,t)}function Ir(e){let t=qs(e),n=re(t);if(n.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(n.kind==="missing")return{platform:"claude-code",status:"n/a"};if(!Vs(n.value,Tr))return{platform:"claude-code",status:"n/a"};let r=Bs(e,".claude","settings.json"),o=re(r);if(o.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(!(o.kind==="ok"&&b(b(o.value,"enabledPlugins"),Tr)===!0))return{platform:"claude-code",status:"disabled",method:"plugin config",configPath:r,errors:[`${Tr} is installed but not enabled in Claude Code`]};return{platform:"claude-code",status:"configured",method:"plugin config",configPath:t}}function zs(e){return Ir(e.homeDir)}function Ks(e){if(!e.codexPluginListOutput)return{platform:"codex",status:"n/a"};let t=e.codexPluginListOutput.split(`
28
+ `).find((n)=>n.includes("https://github.com/kenryu42/cc-safety-net.git"));if(!t)return{platform:"codex",status:"n/a"};if(!t.includes("installed,"))return{platform:"codex",status:"n/a"};if(!t.includes("installed, enabled"))return{platform:"codex",status:"disabled",method:"codex plugin list",configPath:"codex plugin list",errors:["Codex plugin line for https://github.com/kenryu42/cc-safety-net.git must contain installed, enabled."]};return{platform:"codex",status:"configured",method:"codex plugin list",configPath:"codex plugin list"}}import{existsSync as cn,readdirSync as Wp,readFileSync as Jp}from"node:fs";import{join as F}from"node:path";var oe="cc-safety-net@cc-marketplace",sn=["cc-marketplace","cc-safety-net"],Ws=["_direct","copilot-safety-net"],Js=["cc-marketplace","safety-net"],Ys="safety-net@cc-marketplace";function an(e,t){let n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(^|[^a-z0-9-])${n}([^a-z0-9-]|$)`,"m").test(e??"")}function Zs(e){return an(e,"cc-safety-net@cc-marketplace")}function Xs(e){return an(e,"cc-marketplace")}function Qs(e){return an(e,"copilot-safety-net")}function ea(e){return an(e,"safety-net@cc-marketplace")}function q(e){let t="",n=0,r=!1,o=!1,i=-1;while(n<e.length){let s=e[n],a=e[n+1];if(o){t+=s,o=!1,n++;continue}if(s==='"'&&!r){r=!0,i=-1,t+=s,n++;continue}if(s==='"'&&r){r=!1,t+=s,n++;continue}if(s==="\\"&&r){o=!0,t+=s,n++;continue}if(r){t+=s,n++;continue}if(s==="/"&&a==="/"){while(n<e.length&&e[n]!==`
29
+ `)n++;continue}if(s==="/"&&a==="*"){n+=2;while(n<e.length-1){if(e[n]==="*"&&e[n+1]==="/"){n+=2;break}n++}continue}if(s===","){i=t.length,t+=s,n++;continue}if(s==="}"||s==="]"){if(i!==-1){let l=t.slice(i+1);if(/^\s*$/.test(l))t=t.slice(0,i)+l}i=-1,t+=s,n++;continue}if(!/\s/.test(s))i=-1;t+=s,n++}return t}function _r(e){if(!e?.includes("cc-safety-net"))return!1;return/(^|\s)hook\s+(?:[^\s]+\s+)*(--copilot-cli|-cp)(\s|$)/.test(e)}function na(e,t){if(!e)return null;let n=e.match(/(\d+)\.(\d+)\.(\d+)/);if(!n)return null;let r=[Number(n[1]),Number(n[2]),Number(n[3])];for(let o=0;o<t.length;o++){let i=r[o]??0,s=t[o]??0;if(i!==s)return i>s}return!0}function Yp(e){return na(e,[0,0,422])}function Zp(e){return na(e,[1,0,8])}function Tt(e){return process.env.COPILOT_HOME||F(e,".copilot")}function Or(e){return(e.hooks?.preToolUse??[]).some((n)=>{if(n.type!=="command")return!1;return _r(n.command)||_r(n.bash)||_r(n.powershell)})}function ln(e){return e===void 0||typeof e==="string"}function Xp(e){if(!e||typeof e!=="object"||Array.isArray(e))return!1;let t=e;if(t.disableAllHooks!==void 0&&typeof t.disableAllHooks!=="boolean")return!1;if(t.hooks===void 0)return!0;if(!t.hooks||typeof t.hooks!=="object"||Array.isArray(t.hooks))return!1;let n=t.hooks.preToolUse;if(n===void 0)return!0;return Array.isArray(n)&&n.every((r)=>r!==null&&typeof r==="object"&&!Array.isArray(r)&&ln(r.type)&&ln(r.command)&&ln(r.bash)&&ln(r.powershell))}function $r(e,t){try{let n=JSON.parse(q(Jp(e,"utf-8")));if(!Xp(n)){t?.push(`Invalid hook config ${e}: hooks.preToolUse must be an array of hook objects`);return}return n}catch(n){t?.push(`Failed to parse ${e}: ${n instanceof Error?n.message:String(n)}`);return}}function ra(e,t){try{return Wp(e).filter((n)=>n.endsWith(".json")).sort((n,r)=>n.localeCompare(r))}catch(n){return t?.push(`Failed to read ${e}: ${n instanceof Error?n.message:String(n)}`),[]}}function Qp(e,t){if(!cn(e))return[];let n=[];for(let r of ra(e,t)){let o=F(e,r),i=$r(o,t);if(i&&Or(i))n.push(o)}return n}function ot(e,t){if(!cn(e))return;let n=$r(e,t);if(!n)return;return{path:e,config:n}}function ta(e,t,n,r){if(t){e.push(`GitHub Copilot CLI ${t} does not support ${n}; requires ${r}+`);return}e.push(`GitHub Copilot CLI version unavailable; skipping ${n} because it requires ${r}+`)}function e2(e){for(let t of e){if(t?.config.disableAllHooks===!0)return t.path;if(t?.config.disableAllHooks===!1)return}return}function t2(e,t,n,r){let o=Tt(e),i=F(t,".github","hooks"),s=F(o,"hooks"),a=F(t,".github","copilot"),l=F(t,".claude"),c=Zp(n),d=c===!0?r:void 0,p=[ot(F(a,"settings.local.json"),d),ot(F(a,"settings.json"),d),ot(F(l,"settings.local.json"),d),ot(F(l,"settings.json"),d)],g=[ot(F(o,"settings.json"),d),ot(F(o,"config.json"),d)];if(c!==!1){let C=e2([...p,...g]);if(C){if(c===null)r.push(`GitHub Copilot CLI version unavailable; treating disableAllHooks in ${C} as active`);return{activeConfigPaths:[],disabledBy:C}}}let u=Qp(i,r),m=Yp(n),f=m===!0?r:void 0,L=cn(s)?ra(s,f):[],v=[];for(let C of L){let H=F(s,C),he=$r(H,f);if(he&&Or(he))v.push(H)}if(m!==!0&&v.length>0)ta(r,n,`user hook files in ${s}`,"0.0.422"),v.length=0;let x=[];for(let C of[...p,...g]){if(!C)continue;if(!Or(C.config))continue;if(c===!0){x.push(C);continue}ta(r,n,"inline hook definitions in Copilot config files","1.0.8");break}let y=(C)=>C.filter((H)=>!!H&&x.includes(H)).map((H)=>H.path);return{activeConfigPaths:[...y(p),...u,...y(g),...v]}}function oa(e){let t=[],n=t2(e.homeDir,e.cwd,e.copilotCliVersion,t);if(n.disabledBy)return{platform:"copilot-cli",status:"disabled",method:"hook config",configPath:n.disabledBy,configPaths:[n.disabledBy],errors:t.length>0?t:void 0};let r=Tt(e.homeDir),o=F(r,"installed-plugins",...sn),i=cn(o),s=F(r,"settings.json"),a=re(s,q);if(i&&a.kind==="unreadable")return{platform:"copilot-cli",status:"not-inspected"};if(i&&a.kind==="ok"&&b(b(a.value,"enabledPlugins"),oe)===!1)return{platform:"copilot-cli",status:"disabled",method:"plugin config",configPath:s,errors:[`${oe} is installed but not enabled in Copilot CLI`]};if(i||n.activeConfigPaths.length>0){let l=i,c=n.activeConfigPaths[0];return{platform:"copilot-cli",status:"configured",method:l?"plugin config":"hook config",configPath:c??(l?o:void 0),configPaths:n.activeConfigPaths.length>0?n.activeConfigPaths:void 0,errors:t.length>0?t:void 0}}return{platform:"copilot-cli",status:"n/a",errors:t.length>0?t:void 0}}import{existsSync as u2,readFileSync as p2}from"node:fs";import{existsSync as ia,mkdirSync as o2,readFileSync as i2}from"node:fs";import{dirname as s2,join as a2}from"node:path";import{renameSync as n2,writeFileSync as r2}from"node:fs";function _(e,t){let n=`${e}.${process.pid}.tmp`;r2(n,t),n2(n,e)}var It="npx -y cc-safety-net hook --cursor",sa=30;function un(e){return a2(e,".cursor","hooks.json")}function Ie(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Nr(){return{command:It,timeout:sa,failClosed:!0}}function dn(e){return Ie(e)&&e.command===It}function l2(e){return Object.keys(e).length===3&&e.command===It&&e.timeout===sa&&e.failClosed===!0}function c2(e){try{return JSON.parse(i2(e,"utf-8"))}catch(t){if(t instanceof SyntaxError)throw Error(`Failed to parse Cursor hooks config ${e}: ${t.message}`);throw t}}function aa(e){let t=c2(e);if(!Ie(t))throw Error(`Cursor hooks config ${e} must be a JSON object`);if(t.version!==1)throw Error(`Cursor hooks config ${e} must set "version": 1`);if(t.hooks!==void 0&&!Ie(t.hooks))throw Error(`Cursor hooks config ${e} "hooks" must be an object`);let n=Ie(t.hooks)?t.hooks.preToolUse:void 0;if(n!==void 0&&!Array.isArray(n))throw Error(`Cursor hooks config ${e} "hooks.preToolUse" must be an array`);return t}function la(e){let t=Ie(e.hooks)?e.hooks.preToolUse:void 0;return Array.isArray(t)?t:[]}function d2(e){if(!e.some(dn))return[...e,Nr()];return e.reduce((t,n)=>{if(!dn(n))return t.result.push(n),t;if(!t.inserted)t.result.push(Nr()),t.inserted=!0;return t},{result:[],inserted:!1}).result}function ca(e,t,n){let r=Ie(t.hooks)?t.hooks:{},o={...t,hooks:{...r,preToolUse:n}};_(e,`${JSON.stringify(o,null,2)}
30
+ `)}function da(e){let t=un(e);if(!ia(t))return o2(s2(t),{recursive:!0}),_(t,`${JSON.stringify({version:1,hooks:{preToolUse:[Nr()]}},null,2)}
31
+ `),{path:t,alreadyInstalled:!1};let n=aa(t),r=la(n),o=r.filter(dn);if(Ie(n.hooks)&&Array.isArray(n.hooks.preToolUse)&&o.length===1&&o[0]!==void 0&&l2(o[0]))return{path:t,alreadyInstalled:!0};return ca(t,n,d2(r)),{path:t,alreadyInstalled:!1}}function ua(e){let t=un(e);if(!ia(t))return{path:t,alreadyInstalled:!1};let n=aa(t),r=la(n),o=r.filter((i)=>!dn(i));if(o.length===r.length)return{path:t,alreadyInstalled:!1};return ca(t,n,o),{path:t,alreadyInstalled:!0}}function f2(e){if(!e||typeof e!=="object"||Array.isArray(e))return[];let t=e.hooks;if(!t||typeof t!=="object"||Array.isArray(t))return[];let n=t.preToolUse;if(!Array.isArray(n))return[];return n.filter((r)=>!!r&&typeof r==="object"&&!Array.isArray(r)&&r.command===It)}function m2(e){let t=[];if(e.length>1)t.push("Multiple managed cc-safety-net hooks found; reinstall to collapse duplicates");let n=e[0];if(n&&n.failClosed!==!0)t.push('Managed hook is missing "failClosed": true; reinstall to repair');if(n&&n.timeout!==30)t.push('Managed hook "timeout" is not 30; reinstall to repair');return t}function pa(e){let t=un(e.homeDir);if(!u2(t))return{platform:"cursor",status:"n/a",configPath:t};let n;try{n=JSON.parse(p2(t,"utf-8"))}catch(i){return{platform:"cursor",status:"n/a",configPath:t,errors:[`Failed to parse Cursor hooks config ${t}: ${i instanceof Error?i.message:String(i)}`]}}let r=f2(n);if(r.length===0)return{platform:"cursor",status:"n/a",configPath:t};let o=m2(r);return{platform:"cursor",status:"configured",method:"hook config",configPath:t,errors:o.length>0?o:void 0}}import{existsSync as g2}from"node:fs";import{join as Fr}from"node:path";var Hr="gemini-safety-net";function Mr(e){let t=Fr(e,".gemini","extensions"),n=Fr(t,Hr);if(!g2(n))return{platform:"gemini-cli",status:"n/a"};let r=Fr(t,"extension-enablement.json"),o=re(r);if(o.kind==="unreadable")return{platform:"gemini-cli",status:"not-inspected"};let i=o.kind==="ok"?b(b(o.value,Hr),"overrides"):void 0;if(Array.isArray(i)&&i.some((a)=>typeof a==="string"&&a.startsWith("!")))return{platform:"gemini-cli",status:"disabled",method:"extension config",configPath:r,errors:[`${Hr} is disabled in Gemini CLI`]};return{platform:"gemini-cli",status:"configured",method:"extension config",configPath:n}}function fa(e){return Mr(e.homeDir)}import{readFileSync as ka}from"node:fs";import{join as xa}from"node:path";var z="cc-safety-net",ma="# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent";function ga(e){return`# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent
32
32
  # version: ${e}
33
- `}function g2(e){return`${fa(e)}name: cc-safety-net
33
+ `}function h2(e){return`${ga(e)}name: cc-safety-net
34
34
  version: "${e}"
35
35
  description: "Block destructive commands and secret-file access before Hermes runs a tool."
36
36
  author: "cc-safety-net"
37
37
  provides_hooks:
38
38
  - pre_tool_call
39
- `}function h2(e){return`${fa(e)}"""CC Safety Net guard for Hermes Agent.
39
+ `}function y2(e){return`${ga(e)}"""CC Safety Net guard for Hermes Agent.
40
40
 
41
41
  Registers pre_tool_call and forwards the tool call to the packaged CC Safety Net
42
42
  adapter (cc-safety-net hook --hermes-agent) over JSON stdin. The adapter prints nothing
@@ -174,84 +174,84 @@ def _pre_tool_call(tool_name="", args=None, session_id="", task_id="", **_):
174
174
 
175
175
  def register(ctx):
176
176
  ctx.register_hook("pre_tool_call", _pre_tool_call)
177
- `}function It(e){return[{name:"__init__.py",content:h2(e)},{name:"plugin.yaml",content:g2(e)}]}import{mkdirSync as y2,readdirSync as L2,readFileSync as v2,rmSync as jr}from"node:fs";import{join as Ie}from"node:path";var b2="__pycache__";function Ur(e){let t=process.env.HERMES_HOME?.trim();return t?t:Ie(e,".hermes")}function Gr(e){return Ie(Ur(e),"plugins",z)}function Br(e){return e.startsWith(pa)}function qr(e,t){let n=Gr(e),r=E(n);if(r&&(r.isSymbolicLink()||!r.isDirectory()))throw Error(`Refusing to ${t} ${n}: not a regular directory. Move or remove it and rerun ${t==="install"?"install":"uninstall"} --hermes-agent.`);return n}function ma(e,t){let n=E(e);if(!n)return;if(n.isSymbolicLink()||!n.isFile())throw Error(`Refusing to ${t} ${e}: not a regular file. Move or remove it.`);let r=v2(e,"utf-8");if(!Br(r))throw Error(`Refusing to ${t} unmanaged file at ${e}. Move or remove it.`);return r}function ga(e){let t=qr(e,"install"),n=It(P());if(n.map((o)=>ma(Ie(t,o.name),"overwrite")).every((o,i)=>o===n[i]?.content))return{path:t,alreadyInstalled:!0};return y2(t,{recursive:!0}),n.forEach((o)=>{_(Ie(t,o.name),o.content)}),{path:t,alreadyInstalled:!1}}function Vr(e){let t=qr(e,"remove");if(!E(t))return[];return It(P()).filter((n)=>ma(Ie(t,n.name),"remove")!==void 0)}function ha(e){let t=qr(e,"remove");if(!E(t))return{path:t,alreadyInstalled:!1};let n=Vr(e);if(n.forEach((r)=>{jr(Ie(t,r.name))}),jr(Ie(t,b2),{recursive:!0,force:!0}),L2(t).length===0)jr(t,{recursive:!0});return{path:t,alreadyInstalled:n.length>0}}var pn="hermes-agent",ya=/^([^\s#][^:]*):/,w2=/^\s+([A-Za-z_][\w-]*):/,La=/^\s+-\s*(.*)$/;function k2(e){return e.trim().replace(/^(["'])(.*)\1$/,"$2")}function x2(e){let t=e.split(/\r?\n/),n=t.findIndex((i)=>ya.exec(i)?.[1]?.trim()==="plugins");if(n===-1)return[];let r=t.slice(n+1),o=r.findIndex((i)=>ya.test(i));return o===-1?r:r.slice(0,o)}function va(e,t){let n=x2(e),r=n.findIndex((s)=>w2.exec(s)?.[1]===t);if(r===-1)return[];let o=n.slice(r+1),i=o.findIndex((s)=>!La.test(s));return(i===-1?o:o.slice(0,i)).map((s)=>k2(La.exec(s)?.[1]??""))}function C2(e){try{return ba(wa(Ur(e),"config.yaml"),"utf-8")}catch{return}}function zr(e){let t=C2(e)??"";return va(t,"enabled").includes(z)&&!va(t,"disabled").includes(z)}function ka(e){return/^# version:\s*(.+)$/m.exec(e)?.[1]?.trim()}function S2(e,t){let n=E(e);if(!n)return{error:`${t.name} is missing from ${e}; run install --hermes-agent`};if(n.isSymbolicLink()||!n.isFile())return{error:`${e} is a symlink or not a regular file; move or remove it`};try{let r=ba(e,"utf-8");if(!Br(r))return{error:`Unmanaged ${t.name} occupies ${e}; move or remove it`};if(ka(r)===P()&&r!==t.content)return{error:`Modified ${t.name} occupies ${e}; run install --hermes-agent to restore it`};return{content:r}}catch(r){return{error:`Failed to read ${e}: ${r instanceof Error?r.message:String(r)}`}}}function xa(e){let t=Gr(e.homeDir),n=rn(pn,t);if(n)return n;let r=It(P()).map((a)=>S2(wa(t,a.name),a)),o=r.flatMap((a)=>("error"in a)?[a.error]:[]);if(o.length>0)return{platform:pn,status:"n/a",configPath:t,errors:o};let i=r.some((a)=>("content"in a)&&ka(a.content)!==P()),s=i?["Installed Hermes Agent plugin is outdated; run install --hermes-agent to update"]:[];if(!zr(e.homeDir))return{platform:pn,status:"disabled",method:"plugin directory",configPath:t,errors:[`${z} is not enabled in Hermes; run \`hermes plugins enable ${z}\``,...s]};return{platform:pn,status:"configured",method:"plugin directory",configPath:t,errors:i?s:void 0}}import{existsSync as D2,readFileSync as R2}from"node:fs";import{join as Ca}from"node:path";var A2=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*--kimi-code(\s|["']|$)/;function E2(e){return Ca(process.env.KIMI_CODE_HOME||Ca(e,".kimi-code"),"config.toml")}function _t(e){let t=E2(e.homeDir);if(!D2(t))return{platform:"kimi-code",status:"n/a",configPath:t};try{if(!A2.test(R2(t,"utf-8")))return{platform:"kimi-code",status:"n/a",configPath:t}}catch(n){return{platform:"kimi-code",status:"n/a",configPath:t,errors:[`Failed to read ${t}: ${n instanceof Error?n.message:String(n)}`]}}return{platform:"kimi-code",status:"configured",method:"hook config",configPath:t}}import{readFileSync as Oa}from"node:fs";import{join as $t}from"node:path";var A="cc-safety-net",K="index.js",ot="openclaw.plugin.json",it="package.json";var fn="// cc-safety-net managed OpenClaw plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --openclaw";import{existsSync as I2,lstatSync as _2,readdirSync as O2,readFileSync as $2}from"node:fs";import{dirname as Ra,join as ve}from"node:path";import{fileURLToPath as N2}from"node:url";import{spawn as P2}from"node:child_process";function T2(e){return e.join(" ")}function Kr(e,t,n){return[`Failed to run ${T2(e)}${t===null?"":` (exit ${t})`}.`,n.trim()].filter(Boolean).join(`
178
- `)}function Wr(e){let t={stdout:"",stderr:""};return e.stdout.setEncoding("utf-8"),e.stderr.setEncoding("utf-8"),e.stdout.on("data",(n)=>{t.stdout+=n}),e.stderr.on("data",(n)=>{t.stderr+=n}),t}function ie(e,t){return new Promise((n,r)=>{let o=Pe([...e],process.env),i=P2(o.cmd,o.args,{stdio:["ignore","pipe","pipe"]}),s=Wr(i),a=()=>[s.stdout,s.stderr].filter(Boolean).join(`
177
+ `}function _t(e){return[{name:"__init__.py",content:y2(e)},{name:"plugin.yaml",content:h2(e)}]}import{mkdirSync as L2,readdirSync as v2,readFileSync as b2,rmSync as jr}from"node:fs";import{join as _e}from"node:path";var w2="__pycache__";function Ur(e){let t=process.env.HERMES_HOME?.trim();return t?t:_e(e,".hermes")}function Gr(e){return _e(Ur(e),"plugins",z)}function Br(e){return e.startsWith(ma)}function qr(e,t){let n=Gr(e),r=E(n);if(r&&(r.isSymbolicLink()||!r.isDirectory()))throw Error(`Refusing to ${t} ${n}: not a regular directory. Move or remove it and rerun ${t==="install"?"install":"uninstall"} --hermes-agent.`);return n}function ha(e,t){let n=E(e);if(!n)return;if(n.isSymbolicLink()||!n.isFile())throw Error(`Refusing to ${t} ${e}: not a regular file. Move or remove it.`);let r=b2(e,"utf-8");if(!Br(r))throw Error(`Refusing to ${t} unmanaged file at ${e}. Move or remove it.`);return r}function ya(e){let t=qr(e,"install"),n=_t(P());if(n.map((o)=>ha(_e(t,o.name),"overwrite")).every((o,i)=>o===n[i]?.content))return{path:t,alreadyInstalled:!0};return L2(t,{recursive:!0}),n.forEach((o)=>{_(_e(t,o.name),o.content)}),{path:t,alreadyInstalled:!1}}function Vr(e){let t=qr(e,"remove");if(!E(t))return[];return _t(P()).filter((n)=>ha(_e(t,n.name),"remove")!==void 0)}function La(e){let t=qr(e,"remove");if(!E(t))return{path:t,alreadyInstalled:!1};let n=Vr(e);if(n.forEach((r)=>{jr(_e(t,r.name))}),jr(_e(t,w2),{recursive:!0,force:!0}),v2(t).length===0)jr(t,{recursive:!0});return{path:t,alreadyInstalled:n.length>0}}var pn="hermes-agent",va=/^([^\s#][^:]*):/,k2=/^\s+([A-Za-z_][\w-]*):/,ba=/^\s+-\s*(.*)$/;function x2(e){return e.trim().replace(/^(["'])(.*)\1$/,"$2")}function C2(e){let t=e.split(/\r?\n/),n=t.findIndex((i)=>va.exec(i)?.[1]?.trim()==="plugins");if(n===-1)return[];let r=t.slice(n+1),o=r.findIndex((i)=>va.test(i));return o===-1?r:r.slice(0,o)}function wa(e,t){let n=C2(e),r=n.findIndex((s)=>k2.exec(s)?.[1]===t);if(r===-1)return[];let o=n.slice(r+1),i=o.findIndex((s)=>!ba.test(s));return(i===-1?o:o.slice(0,i)).map((s)=>x2(ba.exec(s)?.[1]??""))}function S2(e){try{return ka(xa(Ur(e),"config.yaml"),"utf-8")}catch{return}}function zr(e){let t=S2(e)??"";return wa(t,"enabled").includes(z)&&!wa(t,"disabled").includes(z)}function Ca(e){return/^# version:\s*(.+)$/m.exec(e)?.[1]?.trim()}function D2(e,t){let n=E(e);if(!n)return{error:`${t.name} is missing from ${e}; run install --hermes-agent`};if(n.isSymbolicLink()||!n.isFile())return{error:`${e} is a symlink or not a regular file; move or remove it`};try{let r=ka(e,"utf-8");if(!Br(r))return{error:`Unmanaged ${t.name} occupies ${e}; move or remove it`};if(Ca(r)===P()&&r!==t.content)return{error:`Modified ${t.name} occupies ${e}; run install --hermes-agent to restore it`};return{content:r}}catch(r){return{error:`Failed to read ${e}: ${r instanceof Error?r.message:String(r)}`}}}function Sa(e){let t=Gr(e.homeDir),n=rn(pn,t);if(n)return n;let r=_t(P()).map((a)=>D2(xa(t,a.name),a)),o=r.flatMap((a)=>("error"in a)?[a.error]:[]);if(o.length>0)return{platform:pn,status:"n/a",configPath:t,errors:o};let i=r.some((a)=>("content"in a)&&Ca(a.content)!==P()),s=i?["Installed Hermes Agent plugin is outdated; run install --hermes-agent to update"]:[];if(!zr(e.homeDir))return{platform:pn,status:"disabled",method:"plugin directory",configPath:t,errors:[`${z} is not enabled in Hermes; run \`hermes plugins enable ${z}\``,...s]};return{platform:pn,status:"configured",method:"plugin directory",configPath:t,errors:i?s:void 0}}import{existsSync as R2,readFileSync as A2}from"node:fs";import{join as Da}from"node:path";var E2=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*--kimi-code(\s|["']|$)/;function P2(e){return Da(process.env.KIMI_CODE_HOME||Da(e,".kimi-code"),"config.toml")}function Ot(e){let t=P2(e.homeDir);if(!R2(t))return{platform:"kimi-code",status:"n/a",configPath:t};try{if(!E2.test(A2(t,"utf-8")))return{platform:"kimi-code",status:"n/a",configPath:t}}catch(n){return{platform:"kimi-code",status:"n/a",configPath:t,errors:[`Failed to read ${t}: ${n instanceof Error?n.message:String(n)}`]}}return{platform:"kimi-code",status:"configured",method:"hook config",configPath:t}}import{readFileSync as Na}from"node:fs";import{join as Nt}from"node:path";var A="cc-safety-net",K="index.js",it="openclaw.plugin.json",st="package.json";var fn="// cc-safety-net managed OpenClaw plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --openclaw";import{existsSync as _2,lstatSync as O2,readdirSync as $2,readFileSync as N2}from"node:fs";import{dirname as Ea,join as ve}from"node:path";import{fileURLToPath as F2}from"node:url";import{spawn as T2}from"node:child_process";function I2(e){return e.join(" ")}function Kr(e,t,n){return[`Failed to run ${I2(e)}${t===null?"":` (exit ${t})`}.`,n.trim()].filter(Boolean).join(`
178
+ `)}function Wr(e){let t={stdout:"",stderr:""};return e.stdout.setEncoding("utf-8"),e.stderr.setEncoding("utf-8"),e.stdout.on("data",(n)=>{t.stdout+=n}),e.stderr.on("data",(n)=>{t.stderr+=n}),t}function ie(e,t){return new Promise((n,r)=>{let o=Te([...e],process.env),i=T2(o.cmd,o.args,{stdio:["ignore","pipe","pipe"]}),s=Wr(i),a=()=>[s.stdout,s.stderr].filter(Boolean).join(`
179
179
  `),l=t?.timeoutMs??120000,c=setTimeout(()=>{i.kill(),r(Error(Kr(e,null,`Timed out after ${l}ms.
180
180
  ${a()}`.trim())))},l);i.on("error",(d)=>{clearTimeout(c),r(Error(Kr(e,null,`${d.message}
181
- ${a()}`.trim())))}),i.on("close",(d)=>{if(clearTimeout(c),d!==0){r(Error(Kr(e,d,a())));return}n(t?.stdoutOnly?s.stdout:a())})})}async function Jr(e){for(let t of e)await ie(t)}async function Sa(e){for(let t of e)try{await ie(t)}catch(n){console.warn(n instanceof Error?n.message:String(n))}}var Da=ve("openclaw",A),F2=[K,ot,it];function Yr(e,t){if(e==="~")return t;if(e.startsWith("~/")||e.startsWith("~\\"))return ve(t,e.slice(2));return e}function Aa(e){let t=process.env.OPENCLAW_STATE_DIR?.trim();if(t)return Yr(t,e);let n=process.env.OPENCLAW_CONFIG_PATH?.trim();return n?Ra(Yr(n,e)):ve(e,".openclaw")}function Ea(e){let t=process.env.OPENCLAW_CONFIG_PATH?.trim();return t?Yr(t,e):ve(Aa(e),"openclaw.json")}function Zr(e){return ve(Aa(e),"extensions",A)}function H2(e){let t=O2(e);if(t.length===0)return!0;if(t.some((o)=>!F2.includes(o)))return!1;let n=ve(e,K),r=E(n);return r!==void 0&&!r.isSymbolicLink()&&r.isFile()&&$2(n,"utf-8").startsWith(fn)}function Xr(e){let t=Zr(e),n=E(t);if(!n)return;if(!n.isSymbolicLink()&&n.isDirectory()&&H2(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 Pa(){let e=Ra(N2(import.meta.url));return[ve(e,"..",Da),ve(e,"..","..","..","dist",Da)]}function Qr(e=Pa()){return e.find((t)=>I2(t)&&_2(t).isDirectory())}function M2(e=Pa()){let t=Qr(e);if(!t)throw Error("Packaged OpenClaw plugin directory not found. Reinstall cc-safety-net and try again.");return t}function Ta(e=M2()){return[["openclaw","plugins","install",e,"--force"],["openclaw","plugins","enable",A]]}function j2(e){let t=(()=>{try{return JSON.parse(e)}catch{return}})(),n=b(b(t,"plugin"),"status");return typeof n==="string"?n:void 0}async function Ia(){let e=j2(await ie(["openclaw","plugins","inspect",A,"--runtime","--json"],{stdoutOnly:!0}));if(e==="loaded")return;throw Error(`${e===void 0?`The ${A} plugin's load state could not be verified: OpenClaw's runtime inspect report was unreadable.`:`OpenClaw reports the ${A} plugin with status "${e}".`} Run \`openclaw plugins inspect ${A} --runtime\` for details.`)}var mn="openclaw",Ot=`run \`openclaw plugins enable ${A}\``;function st(e,t){let n=$t(e,t),r=E(n);if(!r)return{error:`${t} is missing from ${n}; run install --openclaw`};if(r.isSymbolicLink()||!r.isFile())return{error:`${n} is a symlink or not a regular file; move or remove it`};try{return{content:Oa(n,"utf-8")}}catch(o){return{error:`Failed to read ${n}: ${o instanceof Error?o.message:String(o)}`}}}function $a(e){try{return JSON.parse(q(e))}catch{return}}function U2(e){let t=st(e,ot);if("error"in t)return t.error;if(b($a(t.content),"id")===A)return;return`${$t(e,ot)} is not a valid ${A} manifest; run install --openclaw`}function G2(e){let t=st(e,it);if("error"in t)return t.error;let n=b(b($a(t.content),"openclaw"),"extensions");if(Array.isArray(n)&&n.includes(`./${K}`))return;return`${$t(e,it)} does not point OpenClaw at ${K}; run install --openclaw`}function _a(e){return Array.isArray(e)?e.filter((t)=>typeof t==="string"):[]}function B2(e){let t=Ea(e);if(!E(t))return`${A} is not enabled; ${Ot}`;let n=(()=>{try{return JSON.parse(q(Oa(t,"utf-8")))}catch{return}})();if(n===void 0)return`Failed to read ${t}; fix it, then ${Ot}`;let r=b(n,"plugins");if(b(r,"enabled")===!1)return`plugins.enabled is false in ${t}; no OpenClaw plugin loads`;let o=b(b(b(r,"entries"),A),"enabled");if(_a(b(r,"deny")).includes(A)||o===!1)return`${A} is disabled in ${t}; ${Ot}`;let i=_a(b(r,"allow"));if(i.length>0&&!i.includes(A))return`plugins.allow in ${t} does not list ${A}; add it, then ${Ot}`;if(i.includes(A)||o===!0)return;return`${A} is not enabled; ${Ot}`}function Na(e){return/^\/\/ version:\s*(.+)$/m.exec(e)?.[1]?.trim()}function q2(e,t,n){if(n===void 0)return[];let r=st(n,K);if("error"in r||Na(r.content)!==t)return[];return[K,ot,it].flatMap((o)=>{let i=st(e,o),s=st(n,o);if("error"in i||"error"in s||i.content===s.content)return[];return[`Modified ${o} occupies ${$t(e,o)}; run install --openclaw to restore it`]})}function Fa(e){let t=Zr(e.homeDir),n=rn(mn,t);if(n)return n;let r=st(t,K),i=["error"in r?r.error:r.content.startsWith(fn)?void 0:`Unmanaged ${K} occupies ${$t(t,K)}; move or remove it`,U2(t),G2(t)].filter((d)=>d!==void 0),s="content"in r?Na(r.content):void 0,a=i.length>0?i:q2(t,s,Qr());if(a.length>0)return{platform:mn,status:"n/a",configPath:t,errors:a};let l=s===P()?[]:["Installed OpenClaw plugin is outdated; run install --openclaw to update"],c=B2(e.homeDir);if(c)return{platform:mn,status:"disabled",method:"plugin directory",configPath:t,errors:[c,...l]};return{platform:mn,status:"configured",method:"plugin directory",configPath:t,errors:l.length>0?l:void 0}}import{existsSync as tf,readFileSync as nf}from"node:fs";import{join as rf}from"node:path";import{existsSync as eo,readFileSync as Ga,rmSync as z2}from"node:fs";import{join as me}from"node:path";import{pathToFileURL as K2}from"node:url";function Ha(e){return e!==void 0&&/\s/.test(e)}function V2(e,t,n){let r=t+1,o=!1;while(r<e.length){let i=e[r];if(o){o=!1,r++;continue}if(i==="\\"){o=!0,r++;continue}if(i==='"')return r+1;r++}throw Error(n)}function gn(e,t,n){let r=e[t],o=r==="["?"]":"}",i=0,s=t;while(s<e.length){let a=n.skipComment?.(e,s)??s;if(a!==s){s=a;continue}if(e[s]==='"'){s=V2(e,s,n.stringError);continue}if(e[s]===r)i++;if(e[s]===o){if(i--,i===0)return s}s++}throw Error(n.bracketError)}function Ma(e,t){let n=e.lastIndexOf(`
182
- `,t)+1;return/^[ \t]*/.exec(e.slice(n))?.[0]??""}function hn(e,t){let{start:n,end:r,end:o}=t;while(Ha(e[o]))o++;if(e[o]===","){if(r=o+1,e[r]===`
183
- `)r++;return`${e.slice(0,n)}${e.slice(r)}`}o=t.start-1;while(Ha(e[o]))o--;if(e[o]===","){n=o;let i=e.lastIndexOf(`
184
- `,n-1);if(i!==-1&&/^\s*$/.test(e.slice(i+1,n)))n=i}return`${e.slice(0,n)}${e.slice(r)}`}var yn="cc-safety-net",Ba=`${yn}@latest`,qa=["opencode.json","opencode.jsonc"],ja="CCSafetyNetPlugin";function Ln(e){return me(process.env.XDG_CONFIG_HOME||me(e,".config"),"opencode")}function W2(e){return me(Ln(e),qa[0])}function J2(e){return qa.map((t)=>me(Ln(e),t))}function Va(e){return me(process.env.XDG_CACHE_HOME||me(e,".cache"),"opencode","packages",Ba)}function to(e){z2(Va(e),{recursive:!0,force:!0})}async function za(e){let t=me(Va(e),"node_modules",yn),n=me(t,"package.json");if(!eo(n))throw Error(`The OpenCode plugin cache at ${t} is missing its package, so OpenCode would load nothing and fail open. Run \`opencode plugin -g -f ${Ba}\` for details.`);let r=b(JSON.parse(Ga(n,"utf-8")),"main");if(typeof r!=="string")throw Error(`The cached OpenCode plugin at ${t} declares no "main" entry.`);let o=me(t,r);if(typeof(await import(K2(o).href))[ja]==="function")return;throw Error(`The cached OpenCode plugin at ${o} does not export a callable ${ja}, so OpenCode would load nothing and fail open.`)}function vn(e,t){if(e[t]==="/"&&e[t+1]==="/"){let n=e.indexOf(`
185
- `,t+2);return n===-1?e.length:n+1}if(e[t]==="/"&&e[t+1]==="*"){let n=e.indexOf("*/",t+2);return n===-1?e.length:n+2}return t}function Ua(e,t){let n=t;while(n<e.length){if(/\s/.test(e[n]??"")){n++;continue}let r=vn(e,n);if(r===n)return n;n=r}return n}function Ka(e,t){let n=t+1,r=!1;while(n<e.length){if(r){r=!1,n++;continue}if(e[n]==="\\"){r=!0,n++;continue}if(e[n]==='"')return n+1;n++}throw Error("Unterminated string in OpenCode config")}function Wa(e,t,n){return JSON.parse(e.slice(t,n))}function Y2(e,t){return gn(e,t,{skipComment:vn,stringError:"Unterminated string in OpenCode config",bracketError:"Unmatched plugin array in OpenCode config"})}function Z2(e){let t=0,n=0;while(n<e.length){let r=vn(e,n);if(r!==n){n=r;continue}if(e[n]==='"'){let o=Ka(e,n);if(t===1&&Wa(e,n,o)==="plugin"){let i=Ua(e,o),s=Ua(e,i+1);if(e[i]===":"&&e[s]==="[")return{start:s,end:Y2(e,s)}}n=o;continue}if(e[n]==="{"||e[n]==="[")t++;if(e[n]==="}"||e[n]==="]")t--;n++}return}function X2(e,t){let n=[],r=t.start+1;while(r<t.end){let o=vn(e,r);if(o!==r){r=o;continue}if(e[r]==='"'){let i=Ka(e,r),s=Wa(e,r,i);if(typeof s==="string"&&s.includes(yn))n.push({start:r,end:i});r=i;continue}r++}return n}function Ja(e,t){try{return JSON.parse(q(e))}catch(n){if(n instanceof SyntaxError)throw Error(`Failed to parse OpenCode config ${t}: ${n.message}`);throw n}}function Q2(e){if(!e||typeof e!=="object"||Array.isArray(e))return!1;let t=e.plugin;if(!Array.isArray(t))return!1;return t.some((n)=>typeof n==="string"&&n.includes(yn))}function ef(e,t){let n=Z2(e);if(!n)throw Error(`Failed to locate OpenCode plugin array in ${t}`);let r=[...X2(e,n)].reverse().reduce(hn,e);return Ja(r,t),r}function Ya(e){to(e);let t=J2(e),n=t.find((o)=>eo(o)),r=[];for(let o of t){if(!eo(o))continue;try{let i=Ga(o,"utf-8");if(!Q2(Ja(i,o)))continue;return _(o,ef(i,o)),{path:o,alreadyInstalled:!0}}catch(i){r.push(i instanceof Error?i.message:String(i))}}if(r.length>0)throw Error(r.join(`
186
- `));return{path:n??W2(e),alreadyInstalled:!1}}function Za(e){let t=[],n=Ln(e.homeDir),r=["opencode.json","opencode.jsonc"];for(let o of r){let i=rf(n,o);if(tf(i))try{let s=nf(i,"utf-8"),a=q(s);if((JSON.parse(a).plugin??[]).some((p)=>p.includes("cc-safety-net")))return{platform:"opencode",status:"configured",method:"plugin array",configPath:i,errors:t.length>0?t:void 0}}catch(s){t.push(`Failed to parse ${o}: ${s instanceof Error?s.message:String(s)}`)}}return{platform:"opencode",status:"n/a",errors:t.length>0?t:void 0}}import{join as of}from"node:path";function no(e){return of(e,".pi","agent","settings.json")}function ro(e){if(typeof e!=="string")return!1;return e==="npm:cc-safety-net"||e.startsWith("npm:cc-safety-net@")}function Xa(e){let t=no(e.homeDir),n=re(t);if(n.kind==="unreadable")return{platform:"pi",status:"not-inspected"};if(n.kind==="missing")return{platform:"pi",status:"n/a"};let r=b(n.value,"packages");if(!Array.isArray(r))return{platform:"pi",status:"n/a"};let o=r.find((a)=>ro(typeof a==="string"?a:b(a,"source")));if(o===void 0)return{platform:"pi",status:"n/a"};let i=b(o,"extensions");if(Array.isArray(i)&&i.some((a)=>typeof a==="string"&&a.startsWith("-")))return{platform:"pi",status:"disabled",method:"package config",configPath:t,errors:["npm:cc-safety-net is installed but its extension is disabled in Pi settings"]};return{platform:"pi",status:"configured",method:"package config",configPath:t}}var af={amp:Ms,"antigravity-cli":js,"claude-code":qs,codex:Vs,"copilot-cli":na,cursor:da,"gemini-cli":ua,"hermes-agent":xa,"kimi-code":_t,openclaw:Fa,opencode:Za,pi:Xa};function at(e,t){let n={...t,cwd:e,homeDir:t?.homeDir??sf()};return Wt.map((r)=>lf(af[r](n)))}function lf(e){if(e.status==="not-inspected")return{platform:e.platform,detected:!1,configured:!1,inspectionStatus:"not-inspected"};return{platform:e.platform,detected:e.status!=="n/a",configured:e.status==="configured",inspectionStatus:e.status!=="n/a"?"verified":e.errors&&e.errors.length>0?"failed":"not-applicable",method:e.method,configPath:e.configPath,configPaths:e.configPaths,errors:e.errors}}import{tmpdir as cf}from"node:os";import{join as df}from"node:path";var uf=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}]),pf=Object.freeze({state:"ready",diagnostics:Object.freeze([]),ruleMetadata:Object.freeze({}),policy:Object.freeze({rules:Object.freeze([]),transparentWrappers:Object.freeze([]),safety:Object.freeze({}),worktreeMode:!1,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:Object.freeze({}),destructiveCommandAllowPaths:Object.freeze([]),secretProtection:Object.freeze({enabled:!0,disabledRules:Object.freeze([]),denyPaths:Object.freeze([]),allowPaths:Object.freeze([])})})}),ff={strict:!1,paranoidRm:!1,paranoidInterpreters:!1,worktreeMode:!1,effectiveLevel:"standard",capabilities:{fail_closed:{enabled:!1,source:"preset",sources:[]},paranoid_rm:{enabled:!1,source:"preset",sources:[]},paranoid_interpreters:{enabled:!1,source:"preset",sources:[]}}};function Qa(){let e=df(cf(),"cc-safety-net-self-test"),t=uf.map((n)=>{let r=zt(Je("self-test",{command:n.command},{kind:"command",shell:"auto"},{configCwd:e,executionCwd:e},n.command),{guard:{dependencies:{loadPolicySnapshot:()=>pf,getModes:()=>ff,findPolicyMutation:()=>null}},audit:{agent:"self-test",getSessionId:()=>{return}}}),o=n.expectBlocked?"blocked":"allowed",i=r.decision.kind==="deny"?"blocked":"allowed";return{command:n.command,description:n.description,expected:o,actual:i,passed:o===i,reason:r.decision.kind==="deny"?r.decision.reason:void 0,ruleId:r.decision.kind==="deny"?r.decision.ruleId:void 0}});return{passed:t.filter((n)=>n.passed).length,failed:t.filter((n)=>!n.passed).length,total:t.length,results:t}}function oo(e){let t=T({label:"doctor",booleans:{json:["--json"],skipUpdateCheck:["--skip-update-check"]}},e);if(ae(t.errors))return null;return{json:t.flags.json,skipUpdateCheck:t.flags.skipUpdateCheck}}async function el(e={}){let t=await Et(!e.json,()=>{let n=mf(e);return{ready:n,finish:()=>n}},()=>At(),{loadingMessage:"Checking system status…"});if(e.json)console.log(JSON.stringify(t,null,2));else gf(t);return t.engineSelfTest.failed>0||t.findings.some((n)=>n.severity==="error")?1:0}async function mf(e){let t=e.cwd??process.cwd(),n=await Dt(),r=at(t,{ampPluginListOutput:n.ampPluginListOutput,codexPluginListOutput:n.codexPluginListOutput,copilotCliVersion:n.versions["copilot-cli"]}),o=cs(t),i=ds(),s=B({cwd:t}),a=s.policy,l=de(a),c=De(a,l.capabilities),d=Zt(7),p=e.skipUpdateCheck?{currentVersion:P(),latestVersion:null,updateAvailable:!1}:await tt(),g={hooks:r,engineSelfTest:Qa(),userConfig:o.userConfig,projectConfig:o.projectConfig,configState:wt(s),effectiveRules:o.effectiveRules,shadowedRules:o.shadowedRules,environment:i,effectiveSafety:{selectedPreset:a.safety.level??"standard",level:l.effectiveLevel,capabilities:l.capabilities,ruleOverrides:a.destructiveCommandRuleOverrides,weakenedRuleOverrides:Object.entries(c).filter(([,u])=>u.source==="rule_override"&&u.override==="off"&&u.inheritedEnabled&&u.changesInherited).map(([u])=>u),ruleCounts:{stored:Object.keys(a.destructiveCommandRuleOverrides).length,effective:Object.values(c).filter((u)=>u.changesInherited).length}},posture:Cs(o.userConfig.path),activity:d,update:p,system:n};return{...g,findings:ps(g)}}function gf(e){console.log(),console.log(ms(e.hooks)),console.log(),console.log(gs(e.engineSelfTest)),console.log(),console.log(hs(e)),console.log(),console.log(ys(e.environment)),console.log(),console.log(Ls(e)),console.log(),console.log(vs(e.findings)),console.log(),console.log(bs(e.activity)),console.log(),console.log(ks(e.system)),console.log(),console.log(ws(e.update)),console.log(xs(e))}import{existsSync as hf}from"node:fs";var yf=/^[A-Za-z0-9_@%+=:,./-]+$/,tl="Usage: cc-safety-net explain [--json] [--cwd <path>] <command>";function io(e){let t=T({label:"explain",booleans:{json:["--json"]},values:{cwd:["--cwd"]},positionals:"tail"},e);if(ae(t.errors))return console.error(tl),console.error("Pass -- before a command that starts with dashes."),null;if(t.values.cwd!==void 0&&!hf(t.values.cwd))return console.error(`Error: --cwd path does not exist: ${t.values.cwd}`),null;let n=t.positionals.length===1?t.positionals[0]:t.positionals.map((r)=>yf.test(r)?r:`'${r.replaceAll("'","'\\''")}'`).join(" ");if(!n)return console.error("Error: No command provided"),console.error(tl),null;return{json:t.flags.json,cwd:t.values.cwd,command:n}}function nl(e){if(e)return{dh:"=",dv:"|",dtl:"+",dtr:"+",dbl:"+",dbr:"+",h:"-",v:"|",tl:"+",tr:"+",bl:"+",br:"+",sh:"="};return{dh:"═",dv:"║",dtl:"╔",dtr:"╗",dbl:"╚",dbr:"╝",h:"─",v:"│",tl:"┌",tr:"┐",bl:"└",br:"┘",sh:"━"}}function rl(e,t){let r=t-18;return[`${e.dtl}${e.dh.repeat(t)}${e.dtr}`,`${e.dv} Command Analysis${" ".repeat(r)}${e.dv}`,`${e.dbl}${e.dh.repeat(t)}${e.dbr}`]}function so(e){return JSON.stringify(e)}function ol(e,t=0){return`[${e.map((r,o)=>fs(r,o,t)).join(",")}]`}function bn(e,t,n=70){let r=e.split(" "),o=[],i="";for(let s of r)if(i&&i.length+s.length+1>n)o.push(i),i=s;else i=i?`${i} ${s}`:s;if(i)o.push(i);return o.map((s,a)=>a===0?s:`${t}${s}`)}function il(e,t,n){let r=[];switch(e.type){case"parse":return null;case"env-strip":return r.push(""),r.push(`STEP ${t} ${n.h} Strip environment variables`),r.push(` Removed: ${e.envVars.map((o)=>`${o}=<redacted>`).join(", ")}`),r.push(` Tokens: ${so(e.output)}`),{lines:r,incrementStep:!0};case"leading-tokens-stripped":return r.push(""),r.push(`STEP ${t} ${n.h} Strip wrappers`),r.push(` Removed: ${e.removed.join(", ")}`),r.push(` Tokens: ${so(e.output)}`),{lines:r,incrementStep:!0};case"shell-wrapper":return r.push(""),r.push(`STEP ${t} ${n.h} Detect shell wrapper`),r.push(` Wrapper: ${e.wrapper} -c`),r.push(` Inner: ${e.innerCommand}`),{lines:r,incrementStep:!0};case"interpreter":{if(r.push(""),r.push(`STEP ${t} ${n.h} Detect interpreter`),r.push(` Interpreter: ${e.interpreter}`),r.push(` Code: ${e.codeArg}`),e.paranoidBlocked)r.push(" Result: ✗ BLOCKED (paranoid mode)");return{lines:r,incrementStep:!0}}case"busybox":return r.push(""),r.push(`STEP ${t} ${n.h} Busybox wrapper`),r.push(` Subcommand: ${e.subcommand}`),{lines:r,incrementStep:!0};case"transparent-wrapper":return r.push(""),r.push(`STEP ${t} ${n.h} Transparent wrapper`),r.push(` Wrapper: ${e.wrapper}`),r.push(` Tokens: ${so(e.output)}`),{lines:r,incrementStep:!0};case"recurse":return{lines:[],incrementStep:!1};case"rule-check":{if(r.push(""),r.push(`STEP ${t} ${n.h} Match rules`),r.push(` Rule: ${e.rule}()`),e.matched)r.push(" Result: MATCHED");else r.push(" Result: No match");return{lines:r,incrementStep:!0}}case"worktree-relaxation":return r.push(""),r.push(`STEP ${t} ${n.h} Worktree relaxation`),r.push(` Mode: ${S.worktree.name}`),r.push(` Git cwd: ${e.gitCwd}`),r.push(" Result: Allowed local discard in linked worktree"),{lines:r,incrementStep:!0};case"tmpdir-check":return null;case"fallback-scan":{if(e.embeddedCommandFound)return r.push(""),r.push(`STEP ${t} ${n.h} Fallback scan`),r.push(` Found: ${e.embeddedCommandFound}`),{lines:r,incrementStep:!0};return null}case"custom-rules-check":{if(e.rulesChecked){if(r.push(""),r.push(`STEP ${t} ${n.h} Custom rules`),e.matched)r.push(" Result: MATCHED");else r.push(" Result: No match");return{lines:r,incrementStep:!0}}return null}case"cwd-change":return null;case"dangerous-text":{if(e.matched)return r.push(""),r.push(`STEP ${t} ${n.h} Dangerous text check`),r.push(` Token: ${e.token}`),r.push(" Result: MATCHED"),{lines:r,incrementStep:!0};return null}case"strict-unparseable":return r.push(""),r.push(`STEP ${t} ${n.h} Strict mode check`),r.push(` Command: ${e.rawCommand}`),r.push(" Result: ✗ UNPARSEABLE"),{lines:r,incrementStep:!0};case"segment-skipped":return null;case"error":return r.push(""),r.push(`ERROR: ${e.message}`),{lines:r,incrementStep:!1};default:return e}}function ao(e,t){let n=nl(t?.asciiOnly??!1),r=58,o=[],i=1;o.push(...rl(n,58)),o.push("");let s=e.trace.steps.find((u)=>u.type==="error");if(s&&s.type==="error"){o.push("ERROR"),o.push(` ${s.message}`),o.push(""),o.push("RESULT"),o.push(` Status: ${e.result==="blocked"?h.red("BLOCKED"):h.green("ALLOWED")}`),o.push(""),o.push("CONFIG");let u=e.configSource??"none";return o.push(` Path: ${u}`),o.join(`
187
- `)}let a=e.trace.steps.find((u)=>u.type==="parse");if(a&&a.type==="parse"){o.push("INPUT"),o.push(` ${a.input}`),o.push(""),o.push(`STEP ${i} ${n.h} Split shell commands`),i++;for(let u=0;u<a.segments.length;u++){let m=a.segments[u];if(m){let f=Math.random();o.push(` Segment ${u+1}: ${ol(m,f)}`)}}}let l=e.trace.segments,c=l.length>1;for(let u of l){if(c){o.push("");let v="";if(a&&a.type==="parse"){let jn=a.segments[u.index];if(jn)v=jn.join(" ")}let k=54,y=v,x=` Segment ${u.index+1}: `,H=" ";if(v){if(x.length+v.length+H.length>k){let Kc=k-x.length-H.length;y=`${v.substring(0,Kc-1)}…`}}let he=v?`${x}${y}${H}`:` Segment ${u.index+1} `,Mn=v?`${x}${h.cyan(y)}${H}`:he,Io=58-he.length,_o=Math.floor(Io/2),zc=Io-_o;o.push(`${n.sh.repeat(_o)}${Mn}${n.sh.repeat(zc)}`)}if(u.steps.find((v)=>v.type==="segment-skipped")){o.push(""),o.push(" (skipped — prior segment blocked)");continue}let f=!1,L=!1;for(let v of u.steps){let k=il(v,i,n);if(k){if(L=!0,v.type==="recurse"){o.push("");let y=" RECURSING ",x=58-y.length-4;o.push(` ${n.tl}${n.h}${y}${n.h.repeat(x)}`),o.push(` ${n.v}`),f=!0;continue}for(let y of k.lines)if(f)o.push(` ${n.v} ${y}`);else o.push(y);if(k.incrementStep)i++}}if(f)o.push(` ${n.v}`),o.push(` ${n.bl}${n.h.repeat(56)}`),f=!1;if(!L)o.push(""),o.push(` ${h.green("✓")} Allowed (no matching rules)`)}if(o.push(""),o.push("RESULT"),e.result==="blocked"){if(o.push(` Status: ${h.red("BLOCKED")}`),e.customRule){if(o.push(` Rule: ${e.customRule.id}`),e.customRule.rulebook)o.push(` Rulebook: ${e.customRule.rulebook.name} ${e.customRule.rulebook.version}`);if(e.customRule.source)o.push(` Source: ${e.customRule.source}`);if(e.customRule.override)o.push(` Override: reason ${e.customRule.override.reason}`)}if(e.reason){let u=bn(e.reason," ");o.push(` Reason: ${u[0]}`);for(let m=1;m<u.length;m++)o.push(u[m]??"")}}else o.push(` Status: ${h.green("ALLOWED")}`);o.push(""),o.push("CONFIG");let d=e.configSource??"none",p=e.configValid?"":" (invalid)";o.push(` Path: ${d}${p}`),o.push(` Safety preset: ${e.selectedPreset??"standard"}`),o.push(` Effective capabilities: ${e.effectiveLevel}`);let g=Object.entries(e.destructiveCommandRuleOverrides??{});if(o.push(` Rule customizations: ${g.length}`),e.ruleActivation)o.push(` Rule activation: ${e.ruleActivation.id} — ${e.ruleActivation.enabled?"on":"off"} via ${e.ruleActivation.source}`);return o.join(`
188
- `)}function lo(e){return JSON.stringify(e,null,2)}function sl(e){return new Promise((t)=>{process.stdout.write(`${e}
189
- `,()=>t())})}async function al(e){let t=io(e);if(!t)return 1;try{let n=Ye(t.command,{cwd:t.cwd}),r=!!process.env.NO_COLOR||!process.stdout.isTTY;return await sl(t.json?lo(n):ao(n,{asciiOnly:r})),0}catch(n){if(!(n instanceof dr)&&!(n instanceof Se)&&!(n instanceof pe))throw n;if(t.json)return await sl(JSON.stringify({error:n.message})),1;return console.error(n.message),1}}var ll="2.0.11",W=" ",_e="cc-safety-net";function cl(e){return e.argument?`${e.flags} ${e.argument}`:e.flags}function Lf(e){return Math.max(...e.map((t)=>cl(t).length))}function vf(e){return Math.max(...e.map((t)=>t.usage.length))}function bf(e){return Math.max(...e.map((t)=>`${_e} ${t.usage}`.length))}function wf(e,t){let n=`${_e} ${e.usage}`;return`${W}${n.padEnd(t+2)}${e.description}`}function ge(e,t){return`${W}${e.padEnd(Math.max(40,e.length+2))}${t}`}function wn(e,t=console.log){let n=[];if(n.push(`${_e} ${e.name}`),n.push(""),n.push(`${W}${e.description}`),n.push(""),n.push("USAGE:"),n.push(`${W}${_e} ${e.usage}`),n.push(""),e.subcommands&&e.subcommands.length>0){n.push("SUBCOMMANDS:");let r=vf(e.subcommands);for(let o of e.subcommands)n.push(`${W}${o.usage.padEnd(r+2)}${o.description}`);n.push("")}if(e.options.length>0){n.push("OPTIONS:");let r=Lf(e.options);for(let o of e.options){let i=cl(o),s=o.default?`${o.description} (default: ${o.default})`:o.description;n.push(`${W}${i.padEnd(r+2)}${s}`)}n.push("")}if(e.examples&&e.examples.length>0){n.push("EXAMPLES:");for(let r of e.examples)n.push(`${W}${r}`)}t(n.join(`
190
- `))}function co(){let e=bf(Jt),t=[];t.push(`${_e} v${ll}`),t.push(""),t.push("Blocks destructive commands and secret access."),t.push(""),t.push("COMMANDS:");for(let n of Jt)t.push(wf(n,e));t.push(""),t.push("GLOBAL OPTIONS:"),t.push(`${W}-h, --help Show help (use with command for command-specific help)`),t.push(`${W}-V, --version Show version`),t.push(""),t.push("HELP:"),t.push(`${W}${_e} help <command> Show help for a specific command`),t.push(`${W}${_e} <command> --help Show help for a specific command`),t.push(""),t.push("ENVIRONMENT VARIABLES:"),t.push(ge(`${S.level.name}=standard|strict|paranoid`,"Set session safety level")),t.push(ge(`${S.worktree.name}=1`,"Allow local git discards in linked worktrees")),t.push(ge(`${S.debug.name}=1`,"Print diagnostic messages to stderr")),t.push(ge(`${S.auditScope.name}=all|blocked`,"Record all command decisions, or denials only")),t.push(ge("CC_SAFETY_NET_HOME","Override rule config home directory")),t.push(""),t.push("LEGACY ENVIRONMENT VARIABLES (STILL SUPPORTED):"),t.push(ge(`${S.strict.name}=1`,"Force safety.overrides.fail_closed on")),t.push(ge(`${S.paranoid.name}=1`,"Force paranoid_rm and paranoid_interpreters on")),t.push(ge(`${S.paranoidRm.name}=1`,"Force safety.overrides.paranoid_rm on")),t.push(ge(`${S.paranoidInterpreters.name}=1`,"Force safety.overrides.paranoid_interpreters on")),t.push(""),t.push("Documentation: https://ccsafetynet.com/docs"),console.log(t.join(`
191
- `))}function dl(){console.log(ll)}function Nt(e,t=console.log){let n=Yt(e);if(!n)return!1;if(n.name.toLowerCase()!==e.toLowerCase())return!1;return wn(n,t),!0}import{existsSync as ko,readFileSync as tc}from"node:fs";import{homedir as mm}from"node:os";import{join as bo}from"node:path";import*as be from"node:readline";function kf(e){return e==="install"?"Install":"Uninstall"}function xf(e){return e==="install"?"Installing":"Uninstalling"}function Cf(e){return e==="install"?"into":"from"}function fl(e){return e?.available===!0}function Sf(e,t){let n=new Set(t);return e.filter((r)=>n.has(r.target)).map((r)=>r.target)}function ul(e,t,n){if(e.length===0||e.every((r)=>!r.available))return t;return Array.from({length:e.length},(r,o)=>o+1).map((r)=>(t+r*n+e.length)%e.length).find((r)=>fl(e[r]))}function Df(e,t,n){if(n.ctrl&&n.name==="c")return"interrupt";if(n.name==="escape"||t==="q")return"abort";if(e==="install"&&(t==="u"||t==="U"))return"update";if(n.name==="up"||t==="k")return"up";if(n.name==="down"||t==="j")return"down";if(n.name==="space"||t===" ")return"toggle";if(n.name==="return"||n.name==="enter")return"confirm";return null}function Rf(e){return{cursor:e.findIndex((t)=>t.available),selected:[]}}function Af(e,t,n){if(n==="confirm"||n==="update"||n==="abort"||n==="interrupt")return{state:e,done:n};if(n==="up")return{state:{...e,cursor:ul(t,e.cursor,-1)}};if(n==="down")return{state:{...e,cursor:ul(t,e.cursor,1)}};let r=t[e.cursor];if(!fl(r))return{state:e};let o=e.selected.includes(r.target)?e.selected.filter((i)=>i!==r.target):Sf(t,[...e.selected,r.target]);return{state:{...e,selected:o}}}var ml="◉",gl="◯",hl=">",yl=" ";function Ef(e,t,n,r={}){let o=r.color!==!1,i=o?h.dim:(l)=>l,s=o?h.green:(l)=>l,a=o?h.bold:(l)=>l;return["",`${kf(e)} CC Safety Net ${Cf(e)}:`,"",...t.map((l,c)=>{let d=n.selected.includes(l.target),p=c===n.cursor,g=d?ml:gl,u=p?hl:yl,m=l.available?"":` (${l.unavailableReason??"not installed"})`,f=`${g} ${l.label}${m}`,L=!l.available?i(f):d?s(f):p?a(f):f;return`${u} ${L}`}),"",e==="install"?"Space: select Enter: confirm u: update installed Up/Down: move q/Esc: cancel":t.some((l)=>l.available)?"Space: select Enter: confirm Up/Down: move q/Esc: cancel":`No selectable integrations found for ${e}. q/Esc: close`].join(`
192
- `)}var pl=["global-hook","plugin"];function Pf(e,t,n={}){let r=n.color!==!1?h.bold:(i)=>i;return["","Install the Kimi Code integration as:","",...[`Global hook — ${t?"already installed; selecting it reports the current state":"write the hook into ~/.kimi-code/config.toml now"}`,"Native Kimi plugin — print the steps to run inside Kimi Code"].map((i,s)=>{let a=s===e,l=`${a?ml:gl} ${i}`;return`${a?hl:yl} ${a?r(l):l}`}),"","Enter: confirm Up/Down: move q/Esc: cancel"].join(`
193
- `)}function Ll(e){let{input:t,output:n}=e;be.emitKeypressEvents(t);let r=t.isRaw===!0;t.setRawMode(!0),t.resume();let o=0,i=()=>{if(o===0)return;be.moveCursor(n,0,-o),be.cursorTo(n,0),be.clearScreenDown(n)},s=()=>{i();let a=e.render();n.write(`${a}
181
+ ${a()}`.trim())))}),i.on("close",(d)=>{if(clearTimeout(c),d!==0){r(Error(Kr(e,d,a())));return}n(t?.stdoutOnly?s.stdout:a())})})}async function Jr(e){for(let t of e)await ie(t)}async function Ra(e){for(let t of e)try{await ie(t)}catch(n){console.warn(n instanceof Error?n.message:String(n))}}var Aa=ve("openclaw",A),H2=[K,it,st];function Yr(e,t){if(e==="~")return t;if(e.startsWith("~/")||e.startsWith("~\\"))return ve(t,e.slice(2));return e}function Pa(e){let t=process.env.OPENCLAW_STATE_DIR?.trim();if(t)return Yr(t,e);let n=process.env.OPENCLAW_CONFIG_PATH?.trim();return n?Ea(Yr(n,e)):ve(e,".openclaw")}function Ta(e){let t=process.env.OPENCLAW_CONFIG_PATH?.trim();return t?Yr(t,e):ve(Pa(e),"openclaw.json")}function Zr(e){return ve(Pa(e),"extensions",A)}function M2(e){let t=$2(e);if(t.length===0)return!0;if(t.some((o)=>!H2.includes(o)))return!1;let n=ve(e,K),r=E(n);return r!==void 0&&!r.isSymbolicLink()&&r.isFile()&&N2(n,"utf-8").startsWith(fn)}function Xr(e){let t=Zr(e),n=E(t);if(!n)return;if(!n.isSymbolicLink()&&n.isDirectory()&&M2(t))return;throw Error(`Refusing to modify ${t}: it does not hold a cc-safety-net managed OpenClaw plugin. Move or remove it, then run the command again.`)}function Ia(){let e=Ea(F2(import.meta.url));return[ve(e,"..",Aa),ve(e,"..","..","..","dist",Aa)]}function Qr(e=Ia()){return e.find((t)=>_2(t)&&O2(t).isDirectory())}function j2(e=Ia()){let t=Qr(e);if(!t)throw Error("Packaged OpenClaw plugin directory not found. Reinstall cc-safety-net and try again.");return t}function _a(e=j2()){return[["openclaw","plugins","install",e,"--force"],["openclaw","plugins","enable",A]]}function U2(e){let t=(()=>{try{return JSON.parse(e)}catch{return}})(),n=b(b(t,"plugin"),"status");return typeof n==="string"?n:void 0}async function Oa(){let e=U2(await ie(["openclaw","plugins","inspect",A,"--runtime","--json"],{stdoutOnly:!0}));if(e==="loaded")return;throw Error(`${e===void 0?`The ${A} plugin's load state could not be verified: OpenClaw's runtime inspect report was unreadable.`:`OpenClaw reports the ${A} plugin with status "${e}".`} Run \`openclaw plugins inspect ${A} --runtime\` for details.`)}var mn="openclaw",$t=`run \`openclaw plugins enable ${A}\``;function at(e,t){let n=Nt(e,t),r=E(n);if(!r)return{error:`${t} is missing from ${n}; run install --openclaw`};if(r.isSymbolicLink()||!r.isFile())return{error:`${n} is a symlink or not a regular file; move or remove it`};try{return{content:Na(n,"utf-8")}}catch(o){return{error:`Failed to read ${n}: ${o instanceof Error?o.message:String(o)}`}}}function Fa(e){try{return JSON.parse(q(e))}catch{return}}function G2(e){let t=at(e,it);if("error"in t)return t.error;if(b(Fa(t.content),"id")===A)return;return`${Nt(e,it)} is not a valid ${A} manifest; run install --openclaw`}function B2(e){let t=at(e,st);if("error"in t)return t.error;let n=b(b(Fa(t.content),"openclaw"),"extensions");if(Array.isArray(n)&&n.includes(`./${K}`))return;return`${Nt(e,st)} does not point OpenClaw at ${K}; run install --openclaw`}function $a(e){return Array.isArray(e)?e.filter((t)=>typeof t==="string"):[]}function q2(e){let t=Ta(e);if(!E(t))return`${A} is not enabled; ${$t}`;let n=(()=>{try{return JSON.parse(q(Na(t,"utf-8")))}catch{return}})();if(n===void 0)return`Failed to read ${t}; fix it, then ${$t}`;let r=b(n,"plugins");if(b(r,"enabled")===!1)return`plugins.enabled is false in ${t}; no OpenClaw plugin loads`;let o=b(b(b(r,"entries"),A),"enabled");if($a(b(r,"deny")).includes(A)||o===!1)return`${A} is disabled in ${t}; ${$t}`;let i=$a(b(r,"allow"));if(i.length>0&&!i.includes(A))return`plugins.allow in ${t} does not list ${A}; add it, then ${$t}`;if(i.includes(A)||o===!0)return;return`${A} is not enabled; ${$t}`}function Ha(e){return/^\/\/ version:\s*(.+)$/m.exec(e)?.[1]?.trim()}function V2(e,t,n){if(n===void 0)return[];let r=at(n,K);if("error"in r||Ha(r.content)!==t)return[];return[K,it,st].flatMap((o)=>{let i=at(e,o),s=at(n,o);if("error"in i||"error"in s||i.content===s.content)return[];return[`Modified ${o} occupies ${Nt(e,o)}; run install --openclaw to restore it`]})}function Ma(e){let t=Zr(e.homeDir),n=rn(mn,t);if(n)return n;let r=at(t,K),i=["error"in r?r.error:r.content.startsWith(fn)?void 0:`Unmanaged ${K} occupies ${Nt(t,K)}; move or remove it`,G2(t),B2(t)].filter((d)=>d!==void 0),s="content"in r?Ha(r.content):void 0,a=i.length>0?i:V2(t,s,Qr());if(a.length>0)return{platform:mn,status:"n/a",configPath:t,errors:a};let l=s===P()?[]:["Installed OpenClaw plugin is outdated; run install --openclaw to update"],c=q2(e.homeDir);if(c)return{platform:mn,status:"disabled",method:"plugin directory",configPath:t,errors:[c,...l]};return{platform:mn,status:"configured",method:"plugin directory",configPath:t,errors:l.length>0?l:void 0}}import{existsSync as nf,readFileSync as rf}from"node:fs";import{join as of}from"node:path";import{existsSync as eo,readFileSync as qa,rmSync as K2}from"node:fs";import{join as me}from"node:path";import{pathToFileURL as W2}from"node:url";function ja(e){return e!==void 0&&/\s/.test(e)}function z2(e,t,n){let r=t+1,o=!1;while(r<e.length){let i=e[r];if(o){o=!1,r++;continue}if(i==="\\"){o=!0,r++;continue}if(i==='"')return r+1;r++}throw Error(n)}function gn(e,t,n){let r=e[t],o=r==="["?"]":"}",i=0,s=t;while(s<e.length){let a=n.skipComment?.(e,s)??s;if(a!==s){s=a;continue}if(e[s]==='"'){s=z2(e,s,n.stringError);continue}if(e[s]===r)i++;if(e[s]===o){if(i--,i===0)return s}s++}throw Error(n.bracketError)}function Ua(e,t){let n=e.lastIndexOf(`
182
+ `,t)+1;return/^[ \t]*/.exec(e.slice(n))?.[0]??""}function hn(e,t){let{start:n,end:r,end:o}=t;while(ja(e[o]))o++;if(e[o]===","){if(r=o+1,e[r]===`
183
+ `)r++;return`${e.slice(0,n)}${e.slice(r)}`}o=t.start-1;while(ja(e[o]))o--;if(e[o]===","){n=o;let i=e.lastIndexOf(`
184
+ `,n-1);if(i!==-1&&/^\s*$/.test(e.slice(i+1,n)))n=i}return`${e.slice(0,n)}${e.slice(r)}`}var yn="cc-safety-net",Va=`${yn}@latest`,za=["opencode.json","opencode.jsonc"],Ga="CCSafetyNetPlugin";function Ln(e){return me(process.env.XDG_CONFIG_HOME||me(e,".config"),"opencode")}function J2(e){return me(Ln(e),za[0])}function Y2(e){return za.map((t)=>me(Ln(e),t))}function Ka(e){return me(process.env.XDG_CACHE_HOME||me(e,".cache"),"opencode","packages",Va)}function to(e){K2(Ka(e),{recursive:!0,force:!0})}async function Wa(e){let t=me(Ka(e),"node_modules",yn),n=me(t,"package.json");if(!eo(n))throw Error(`The OpenCode plugin cache at ${t} is missing its package, so OpenCode would load nothing and fail open. Run \`opencode plugin -g -f ${Va}\` for details.`);let r=b(JSON.parse(qa(n,"utf-8")),"main");if(typeof r!=="string")throw Error(`The cached OpenCode plugin at ${t} declares no "main" entry.`);let o=me(t,r);if(typeof(await import(W2(o).href))[Ga]==="function")return;throw Error(`The cached OpenCode plugin at ${o} does not export a callable ${Ga}, so OpenCode would load nothing and fail open.`)}function vn(e,t){if(e[t]==="/"&&e[t+1]==="/"){let n=e.indexOf(`
185
+ `,t+2);return n===-1?e.length:n+1}if(e[t]==="/"&&e[t+1]==="*"){let n=e.indexOf("*/",t+2);return n===-1?e.length:n+2}return t}function Ba(e,t){let n=t;while(n<e.length){if(/\s/.test(e[n]??"")){n++;continue}let r=vn(e,n);if(r===n)return n;n=r}return n}function Ja(e,t){let n=t+1,r=!1;while(n<e.length){if(r){r=!1,n++;continue}if(e[n]==="\\"){r=!0,n++;continue}if(e[n]==='"')return n+1;n++}throw Error("Unterminated string in OpenCode config")}function Ya(e,t,n){return JSON.parse(e.slice(t,n))}function Z2(e,t){return gn(e,t,{skipComment:vn,stringError:"Unterminated string in OpenCode config",bracketError:"Unmatched plugin array in OpenCode config"})}function X2(e){let t=0,n=0;while(n<e.length){let r=vn(e,n);if(r!==n){n=r;continue}if(e[n]==='"'){let o=Ja(e,n);if(t===1&&Ya(e,n,o)==="plugin"){let i=Ba(e,o),s=Ba(e,i+1);if(e[i]===":"&&e[s]==="[")return{start:s,end:Z2(e,s)}}n=o;continue}if(e[n]==="{"||e[n]==="[")t++;if(e[n]==="}"||e[n]==="]")t--;n++}return}function Q2(e,t){let n=[],r=t.start+1;while(r<t.end){let o=vn(e,r);if(o!==r){r=o;continue}if(e[r]==='"'){let i=Ja(e,r),s=Ya(e,r,i);if(typeof s==="string"&&s.includes(yn))n.push({start:r,end:i});r=i;continue}r++}return n}function Za(e,t){try{return JSON.parse(q(e))}catch(n){if(n instanceof SyntaxError)throw Error(`Failed to parse OpenCode config ${t}: ${n.message}`);throw n}}function ef(e){if(!e||typeof e!=="object"||Array.isArray(e))return!1;let t=e.plugin;if(!Array.isArray(t))return!1;return t.some((n)=>typeof n==="string"&&n.includes(yn))}function tf(e,t){let n=X2(e);if(!n)throw Error(`Failed to locate OpenCode plugin array in ${t}`);let r=[...Q2(e,n)].reverse().reduce(hn,e);return Za(r,t),r}function Xa(e){to(e);let t=Y2(e),n=t.find((o)=>eo(o)),r=[];for(let o of t){if(!eo(o))continue;try{let i=qa(o,"utf-8");if(!ef(Za(i,o)))continue;return _(o,tf(i,o)),{path:o,alreadyInstalled:!0}}catch(i){r.push(i instanceof Error?i.message:String(i))}}if(r.length>0)throw Error(r.join(`
186
+ `));return{path:n??J2(e),alreadyInstalled:!1}}function Qa(e){let t=[],n=Ln(e.homeDir),r=["opencode.json","opencode.jsonc"];for(let o of r){let i=of(n,o);if(nf(i))try{let s=rf(i,"utf-8"),a=q(s);if((JSON.parse(a).plugin??[]).some((p)=>p.includes("cc-safety-net")))return{platform:"opencode",status:"configured",method:"plugin array",configPath:i,errors:t.length>0?t:void 0}}catch(s){t.push(`Failed to parse ${o}: ${s instanceof Error?s.message:String(s)}`)}}return{platform:"opencode",status:"n/a",errors:t.length>0?t:void 0}}import{join as sf}from"node:path";function no(e){return sf(e,".pi","agent","settings.json")}function ro(e){if(typeof e!=="string")return!1;return e==="npm:cc-safety-net"||e.startsWith("npm:cc-safety-net@")}function el(e){let t=no(e.homeDir),n=re(t);if(n.kind==="unreadable")return{platform:"pi",status:"not-inspected"};if(n.kind==="missing")return{platform:"pi",status:"n/a"};let r=b(n.value,"packages");if(!Array.isArray(r))return{platform:"pi",status:"n/a"};let o=r.find((a)=>ro(typeof a==="string"?a:b(a,"source")));if(o===void 0)return{platform:"pi",status:"n/a"};let i=b(o,"extensions");if(Array.isArray(i)&&i.some((a)=>typeof a==="string"&&a.startsWith("-")))return{platform:"pi",status:"disabled",method:"package config",configPath:t,errors:["npm:cc-safety-net is installed but its extension is disabled in Pi settings"]};return{platform:"pi",status:"configured",method:"package config",configPath:t}}var lf={amp:Us,"antigravity-cli":Gs,"claude-code":zs,codex:Ks,"copilot-cli":oa,cursor:pa,"gemini-cli":fa,"hermes-agent":Sa,"kimi-code":Ot,openclaw:Ma,opencode:Qa,pi:el};function lt(e,t){let n={...t,cwd:e,homeDir:t?.homeDir??af()};return Wt.map((r)=>cf(lf[r](n)))}function cf(e){if(e.status==="not-inspected")return{platform:e.platform,detected:!1,configured:!1,inspectionStatus:"not-inspected"};return{platform:e.platform,detected:e.status!=="n/a",configured:e.status==="configured",inspectionStatus:e.status!=="n/a"?"verified":e.errors&&e.errors.length>0?"failed":"not-applicable",method:e.method,configPath:e.configPath,configPaths:e.configPaths,errors:e.errors}}import{tmpdir as df}from"node:os";import{join as uf}from"node:path";var pf=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}]),ff=Object.freeze({state:"ready",diagnostics:Object.freeze([]),ruleMetadata:Object.freeze({}),policy:Object.freeze({rules:Object.freeze([]),transparentWrappers:Object.freeze([]),safety:Object.freeze({}),worktreeMode:!1,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:Object.freeze({}),destructiveCommandAllowPaths:Object.freeze([]),secretProtection:Object.freeze({enabled:!0,disabledRules:Object.freeze([]),denyPaths:Object.freeze([]),allowPaths:Object.freeze([])})})}),mf={strict:!1,paranoidRm:!1,paranoidInterpreters:!1,worktreeMode:!1,effectiveLevel:"standard",capabilities:{fail_closed:{enabled:!1,source:"preset",sources:[]},paranoid_rm:{enabled:!1,source:"preset",sources:[]},paranoid_interpreters:{enabled:!1,source:"preset",sources:[]}}};function tl(){let e=uf(df(),"cc-safety-net-self-test"),t=pf.map((n)=>{let r=zt(Ye("self-test",{command:n.command},{kind:"command",shell:"auto"},{configCwd:e,executionCwd:e},n.command),{guard:{dependencies:{loadPolicySnapshot:()=>ff,getModes:()=>mf,findPolicyMutation:()=>null}},audit:{agent:"self-test",getSessionId:()=>{return}}}),o=n.expectBlocked?"blocked":"allowed",i=r.decision.kind==="deny"?"blocked":"allowed";return{command:n.command,description:n.description,expected:o,actual:i,passed:o===i,reason:r.decision.kind==="deny"?r.decision.reason:void 0,ruleId:r.decision.kind==="deny"?r.decision.ruleId:void 0}});return{passed:t.filter((n)=>n.passed).length,failed:t.filter((n)=>!n.passed).length,total:t.length,results:t}}function oo(e){let t=T({label:"doctor",booleans:{json:["--json"],skipUpdateCheck:["--skip-update-check"]}},e);if(ae(t.errors))return null;return{json:t.flags.json,skipUpdateCheck:t.flags.skipUpdateCheck}}async function nl(e={}){let t=await Pt(!e.json,()=>{let n=gf(e);return{ready:n,finish:()=>n}},()=>Et(),{loadingMessage:"Checking system status…"});if(e.json)console.log(JSON.stringify(t,null,2));else hf(t);return t.engineSelfTest.failed>0||t.findings.some((n)=>n.severity==="error")?1:0}async function gf(e){let t=e.cwd??process.cwd(),n=await Rt(),r=lt(t,{ampPluginListOutput:n.ampPluginListOutput,codexPluginListOutput:n.codexPluginListOutput,copilotCliVersion:n.versions["copilot-cli"]}),o=us(t),i=ps(),s=B({cwd:t}),a=s.policy,l=de(a),c=Re(a,l.capabilities),d=Zt(7),p=e.skipUpdateCheck?{currentVersion:P(),latestVersion:null,updateAvailable:!1}:await nt(),g={hooks:r,engineSelfTest:tl(),userConfig:o.userConfig,projectConfig:o.projectConfig,configState:kt(s),effectiveRules:o.effectiveRules,shadowedRules:o.shadowedRules,environment:i,effectiveSafety:{selectedPreset:a.safety.level??"standard",level:l.effectiveLevel,capabilities:l.capabilities,ruleOverrides:a.destructiveCommandRuleOverrides,weakenedRuleOverrides:Object.entries(c).filter(([,u])=>u.source==="rule_override"&&u.override==="off"&&u.inheritedEnabled&&u.changesInherited).map(([u])=>u),ruleCounts:{stored:Object.keys(a.destructiveCommandRuleOverrides).length,effective:Object.values(c).filter((u)=>u.changesInherited).length}},posture:Ds(o.userConfig.path),activity:d,update:p,system:n};return{...g,findings:ms(g)}}function hf(e){console.log(),console.log(hs(e.hooks)),console.log(),console.log(ys(e.engineSelfTest)),console.log(),console.log(Ls(e)),console.log(),console.log(vs(e.environment)),console.log(),console.log(bs(e)),console.log(),console.log(ws(e.findings)),console.log(),console.log(ks(e.activity)),console.log(),console.log(Cs(e.system)),console.log(),console.log(xs(e.update)),console.log(Ss(e))}import{existsSync as yf}from"node:fs";var Lf=/^[A-Za-z0-9_@%+=:,./-]+$/,rl="Usage: cc-safety-net explain [--json] [--cwd <path>] <command>";function io(e){let t=T({label:"explain",booleans:{json:["--json"]},values:{cwd:["--cwd"]},positionals:"tail"},e);if(ae(t.errors))return console.error(rl),console.error("Pass -- before a command that starts with dashes."),null;if(t.values.cwd!==void 0&&!yf(t.values.cwd))return console.error(`Error: --cwd path does not exist: ${t.values.cwd}`),null;let n=t.positionals.length===1?t.positionals[0]:t.positionals.map((r)=>Lf.test(r)?r:`'${r.replaceAll("'","'\\''")}'`).join(" ");if(!n)return console.error("Error: No command provided"),console.error(rl),null;return{json:t.flags.json,cwd:t.values.cwd,command:n}}function ol(e){if(e)return{dh:"=",dv:"|",dtl:"+",dtr:"+",dbl:"+",dbr:"+",h:"-",v:"|",tl:"+",tr:"+",bl:"+",br:"+",sh:"="};return{dh:"═",dv:"║",dtl:"╔",dtr:"╗",dbl:"╚",dbr:"╝",h:"─",v:"│",tl:"┌",tr:"┐",bl:"└",br:"┘",sh:"━"}}function il(e,t){let r=t-18;return[`${e.dtl}${e.dh.repeat(t)}${e.dtr}`,`${e.dv} Command Analysis${" ".repeat(r)}${e.dv}`,`${e.dbl}${e.dh.repeat(t)}${e.dbr}`]}function so(e){return JSON.stringify(e)}function sl(e,t=0){return`[${e.map((r,o)=>gs(r,o,t)).join(",")}]`}function bn(e,t,n=70){let r=e.split(" "),o=[],i="";for(let s of r)if(i&&i.length+s.length+1>n)o.push(i),i=s;else i=i?`${i} ${s}`:s;if(i)o.push(i);return o.map((s,a)=>a===0?s:`${t}${s}`)}function al(e,t,n){let r=[];switch(e.type){case"parse":return null;case"env-strip":return r.push(""),r.push(`STEP ${t} ${n.h} Strip environment variables`),r.push(` Removed: ${e.envVars.map((o)=>`${o}=<redacted>`).join(", ")}`),r.push(` Tokens: ${so(e.output)}`),{lines:r,incrementStep:!0};case"leading-tokens-stripped":return r.push(""),r.push(`STEP ${t} ${n.h} Strip wrappers`),r.push(` Removed: ${e.removed.join(", ")}`),r.push(` Tokens: ${so(e.output)}`),{lines:r,incrementStep:!0};case"shell-wrapper":return r.push(""),r.push(`STEP ${t} ${n.h} Detect shell wrapper`),r.push(` Wrapper: ${e.wrapper} -c`),r.push(` Inner: ${e.innerCommand}`),{lines:r,incrementStep:!0};case"interpreter":{if(r.push(""),r.push(`STEP ${t} ${n.h} Detect interpreter`),r.push(` Interpreter: ${e.interpreter}`),r.push(` Code: ${e.codeArg}`),e.paranoidBlocked)r.push(" Result: ✗ BLOCKED (paranoid mode)");return{lines:r,incrementStep:!0}}case"busybox":return r.push(""),r.push(`STEP ${t} ${n.h} Busybox wrapper`),r.push(` Subcommand: ${e.subcommand}`),{lines:r,incrementStep:!0};case"transparent-wrapper":return r.push(""),r.push(`STEP ${t} ${n.h} Transparent wrapper`),r.push(` Wrapper: ${e.wrapper}`),r.push(` Tokens: ${so(e.output)}`),{lines:r,incrementStep:!0};case"recurse":return{lines:[],incrementStep:!1};case"rule-check":{if(r.push(""),r.push(`STEP ${t} ${n.h} Match rules`),r.push(` Rule: ${e.rule}()`),e.matched)r.push(" Result: MATCHED");else r.push(" Result: No match");return{lines:r,incrementStep:!0}}case"worktree-relaxation":return r.push(""),r.push(`STEP ${t} ${n.h} Worktree relaxation`),r.push(` Mode: ${S.worktree.name}`),r.push(` Git cwd: ${e.gitCwd}`),r.push(" Result: Allowed local discard in linked worktree"),{lines:r,incrementStep:!0};case"tmpdir-check":return null;case"fallback-scan":{if(e.embeddedCommandFound)return r.push(""),r.push(`STEP ${t} ${n.h} Fallback scan`),r.push(` Found: ${e.embeddedCommandFound}`),{lines:r,incrementStep:!0};return null}case"custom-rules-check":{if(e.rulesChecked){if(r.push(""),r.push(`STEP ${t} ${n.h} Custom rules`),e.matched)r.push(" Result: MATCHED");else r.push(" Result: No match");return{lines:r,incrementStep:!0}}return null}case"cwd-change":return null;case"dangerous-text":{if(e.matched)return r.push(""),r.push(`STEP ${t} ${n.h} Dangerous text check`),r.push(` Token: ${e.token}`),r.push(" Result: MATCHED"),{lines:r,incrementStep:!0};return null}case"strict-unparseable":return r.push(""),r.push(`STEP ${t} ${n.h} Strict mode check`),r.push(` Command: ${e.rawCommand}`),r.push(" Result: ✗ UNPARSEABLE"),{lines:r,incrementStep:!0};case"segment-skipped":return null;case"error":return r.push(""),r.push(`ERROR: ${e.message}`),{lines:r,incrementStep:!1};default:return e}}function ao(e,t){let n=ol(t?.asciiOnly??!1),r=58,o=[],i=1;o.push(...il(n,58)),o.push("");let s=e.trace.steps.find((u)=>u.type==="error");if(s&&s.type==="error"){o.push("ERROR"),o.push(` ${s.message}`),o.push(""),o.push("RESULT"),o.push(` Status: ${e.result==="blocked"?h.red("BLOCKED"):h.green("ALLOWED")}`),o.push(""),o.push("CONFIG");let u=e.configSource??"none";return o.push(` Path: ${u}`),o.join(`
187
+ `)}let a=e.trace.steps.find((u)=>u.type==="parse");if(a&&a.type==="parse"){o.push("INPUT"),o.push(` ${a.input}`),o.push(""),o.push(`STEP ${i} ${n.h} Split shell commands`),i++;for(let u=0;u<a.segments.length;u++){let m=a.segments[u];if(m){let f=Math.random();o.push(` Segment ${u+1}: ${sl(m,f)}`)}}}let l=e.trace.segments,c=l.length>1;for(let u of l){if(c){o.push("");let v="";if(a&&a.type==="parse"){let jn=a.segments[u.index];if(jn)v=jn.join(" ")}let x=54,y=v,C=` Segment ${u.index+1}: `,H=" ";if(v){if(C.length+v.length+H.length>x){let Jc=x-C.length-H.length;y=`${v.substring(0,Jc-1)}…`}}let he=v?`${C}${y}${H}`:` Segment ${u.index+1} `,Mn=v?`${C}${h.cyan(y)}${H}`:he,Io=58-he.length,_o=Math.floor(Io/2),Wc=Io-_o;o.push(`${n.sh.repeat(_o)}${Mn}${n.sh.repeat(Wc)}`)}if(u.steps.find((v)=>v.type==="segment-skipped")){o.push(""),o.push(" (skipped — prior segment blocked)");continue}let f=!1,L=!1;for(let v of u.steps){let x=al(v,i,n);if(x){if(L=!0,v.type==="recurse"){o.push("");let y=" RECURSING ",C=58-y.length-4;o.push(` ${n.tl}${n.h}${y}${n.h.repeat(C)}`),o.push(` ${n.v}`),f=!0;continue}for(let y of x.lines)if(f)o.push(` ${n.v} ${y}`);else o.push(y);if(x.incrementStep)i++}}if(f)o.push(` ${n.v}`),o.push(` ${n.bl}${n.h.repeat(56)}`),f=!1;if(!L)o.push(""),o.push(` ${h.green("✓")} Allowed (no matching rules)`)}if(o.push(""),o.push("RESULT"),e.result==="blocked"){if(o.push(` Status: ${h.red("BLOCKED")}`),e.customRule){if(o.push(` Rule: ${e.customRule.id}`),e.customRule.rulebook)o.push(` Rulebook: ${e.customRule.rulebook.name} ${e.customRule.rulebook.version}`);if(e.customRule.source)o.push(` Source: ${e.customRule.source}`);if(e.customRule.override)o.push(` Override: reason ${e.customRule.override.reason}`)}if(e.reason){let u=bn(e.reason," ");o.push(` Reason: ${u[0]}`);for(let m=1;m<u.length;m++)o.push(u[m]??"")}}else o.push(` Status: ${h.green("ALLOWED")}`);o.push(""),o.push("CONFIG");let d=e.configSource??"none",p=e.configValid?"":" (invalid)";o.push(` Path: ${d}${p}`),o.push(` Safety preset: ${e.selectedPreset??"standard"}`),o.push(` Effective capabilities: ${e.effectiveLevel}`);let g=Object.entries(e.destructiveCommandRuleOverrides??{});if(o.push(` Rule customizations: ${g.length}`),e.ruleActivation)o.push(` Rule activation: ${e.ruleActivation.id} — ${e.ruleActivation.enabled?"on":"off"} via ${e.ruleActivation.source}`);return o.join(`
188
+ `)}function lo(e){return JSON.stringify(e,null,2)}function ll(e){return new Promise((t)=>{process.stdout.write(`${e}
189
+ `,()=>t())})}async function cl(e){let t=io(e);if(!t)return 1;try{let n=Ze(t.command,{cwd:t.cwd}),r=!!process.env.NO_COLOR||!process.stdout.isTTY;return await ll(t.json?lo(n):ao(n,{asciiOnly:r})),0}catch(n){if(!(n instanceof dr)&&!(n instanceof De)&&!(n instanceof pe))throw n;if(t.json)return await ll(JSON.stringify({error:n.message})),1;return console.error(n.message),1}}var dl="2.1.0",W=" ",Oe="cc-safety-net";function ul(e){return e.argument?`${e.flags} ${e.argument}`:e.flags}function vf(e){return Math.max(...e.map((t)=>ul(t).length))}function bf(e){return Math.max(...e.map((t)=>t.usage.length))}function wf(e){return Math.max(...e.map((t)=>`${Oe} ${t.usage}`.length))}function kf(e,t){let n=`${Oe} ${e.usage}`;return`${W}${n.padEnd(t+2)}${e.description}`}function ge(e,t){return`${W}${e.padEnd(Math.max(40,e.length+2))}${t}`}function wn(e,t=console.log){let n=[];if(n.push(`${Oe} ${e.name}`),n.push(""),n.push(`${W}${e.description}`),n.push(""),n.push("USAGE:"),n.push(`${W}${Oe} ${e.usage}`),n.push(""),e.subcommands&&e.subcommands.length>0){n.push("SUBCOMMANDS:");let r=bf(e.subcommands);for(let o of e.subcommands)n.push(`${W}${o.usage.padEnd(r+2)}${o.description}`);n.push("")}if(e.options.length>0){n.push("OPTIONS:");let r=vf(e.options);for(let o of e.options){let i=ul(o),s=o.default?`${o.description} (default: ${o.default})`:o.description;n.push(`${W}${i.padEnd(r+2)}${s}`)}n.push("")}if(e.examples&&e.examples.length>0){n.push("EXAMPLES:");for(let r of e.examples)n.push(`${W}${r}`)}t(n.join(`
190
+ `))}function co(){let e=wf(Jt),t=[];t.push(`${Oe} v${dl}`),t.push(""),t.push("Blocks destructive commands and secret access."),t.push(""),t.push("COMMANDS:");for(let n of Jt)t.push(kf(n,e));t.push(""),t.push("GLOBAL OPTIONS:"),t.push(`${W}-h, --help Show help (use with command for command-specific help)`),t.push(`${W}-V, --version Show version`),t.push(""),t.push("HELP:"),t.push(`${W}${Oe} help <command> Show help for a specific command`),t.push(`${W}${Oe} <command> --help Show help for a specific command`),t.push(""),t.push("ENVIRONMENT VARIABLES:"),t.push(ge(`${S.level.name}=standard|strict|paranoid`,"Set session safety level")),t.push(ge(`${S.worktree.name}=1`,"Allow local git discards in linked worktrees")),t.push(ge(`${S.debug.name}=1`,"Print diagnostic messages to stderr")),t.push(ge(`${S.auditScope.name}=all|blocked`,"Record all command decisions, or denials only")),t.push(ge("CC_SAFETY_NET_HOME","Override rule config home directory")),t.push(""),t.push("LEGACY ENVIRONMENT VARIABLES (STILL SUPPORTED):"),t.push(ge(`${S.strict.name}=1`,"Force safety.overrides.fail_closed on")),t.push(ge(`${S.paranoid.name}=1`,"Force paranoid_rm and paranoid_interpreters on")),t.push(ge(`${S.paranoidRm.name}=1`,"Force safety.overrides.paranoid_rm on")),t.push(ge(`${S.paranoidInterpreters.name}=1`,"Force safety.overrides.paranoid_interpreters on")),t.push(""),t.push("Documentation: https://ccsafetynet.com/docs"),console.log(t.join(`
191
+ `))}function pl(){console.log(dl)}function Ft(e,t=console.log){let n=Yt(e);if(!n)return!1;if(n.name.toLowerCase()!==e.toLowerCase())return!1;return wn(n,t),!0}import{existsSync as ko,readFileSync as rc}from"node:fs";import{homedir as gm}from"node:os";import{join as bo}from"node:path";import*as be from"node:readline";function xf(e){return e==="install"?"Install":"Uninstall"}function Cf(e){return e==="install"?"Installing":"Uninstalling"}function Sf(e){return e==="install"?"into":"from"}function gl(e){return e?.available===!0}function Df(e,t){let n=new Set(t);return e.filter((r)=>n.has(r.target)).map((r)=>r.target)}function fl(e,t,n){if(e.length===0||e.every((r)=>!r.available))return t;return Array.from({length:e.length},(r,o)=>o+1).map((r)=>(t+r*n+e.length)%e.length).find((r)=>gl(e[r]))}function Rf(e,t,n){if(n.ctrl&&n.name==="c")return"interrupt";if(n.name==="escape"||t==="q")return"abort";if(e==="install"&&(t==="u"||t==="U"))return"update";if(n.name==="up"||t==="k")return"up";if(n.name==="down"||t==="j")return"down";if(n.name==="space"||t===" ")return"toggle";if(n.name==="return"||n.name==="enter")return"confirm";return null}function Af(e){return{cursor:e.findIndex((t)=>t.available),selected:[]}}function Ef(e,t,n){if(n==="confirm"||n==="update"||n==="abort"||n==="interrupt")return{state:e,done:n};if(n==="up")return{state:{...e,cursor:fl(t,e.cursor,-1)}};if(n==="down")return{state:{...e,cursor:fl(t,e.cursor,1)}};let r=t[e.cursor];if(!gl(r))return{state:e};let o=e.selected.includes(r.target)?e.selected.filter((i)=>i!==r.target):Df(t,[...e.selected,r.target]);return{state:{...e,selected:o}}}var hl="◉",yl="◯",Ll=">",vl=" ";function Pf(e,t,n,r={}){let o=r.color!==!1,i=o?h.dim:(l)=>l,s=o?h.green:(l)=>l,a=o?h.bold:(l)=>l;return["",`${xf(e)} CC Safety Net ${Sf(e)}:`,"",...t.map((l,c)=>{let d=n.selected.includes(l.target),p=c===n.cursor,g=d?hl:yl,u=p?Ll:vl,m=l.available?"":` (${l.unavailableReason??"not installed"})`,f=`${g} ${l.label}${m}`,L=!l.available?i(f):d?s(f):p?a(f):f;return`${u} ${L}`}),"",e==="install"?"Space: select Enter: confirm u: update installed Up/Down: move q/Esc: cancel":t.some((l)=>l.available)?"Space: select Enter: confirm Up/Down: move q/Esc: cancel":`No selectable integrations found for ${e}. q/Esc: close`].join(`
192
+ `)}var ml=["global-hook","plugin"];function Tf(e,t,n={}){let r=n.color!==!1?h.bold:(i)=>i;return["","Install the Kimi Code integration as:","",...[`Global hook — ${t?"already installed; selecting it reports the current state":"write the hook into ~/.kimi-code/config.toml now"}`,"Native Kimi plugin — print the steps to run inside Kimi Code"].map((i,s)=>{let a=s===e,l=`${a?hl:yl} ${i}`;return`${a?Ll:vl} ${a?r(l):l}`}),"","Enter: confirm Up/Down: move q/Esc: cancel"].join(`
193
+ `)}function bl(e){let{input:t,output:n}=e;be.emitKeypressEvents(t);let r=t.isRaw===!0;t.setRawMode(!0),t.resume();let o=0,i=()=>{if(o===0)return;be.moveCursor(n,0,-o),be.cursorTo(n,0),be.clearScreenDown(n)},s=()=>{i();let a=e.render();n.write(`${a}
194
194
  `),o=a.split(`
195
- `).length};return new Promise((a)=>{let l=(d)=>{t.off("keypress",c),t.setRawMode(r),t.pause(),i(),a(d)};function c(d,p){e.onKey(d,p,{finish:l,draw:s})}t.on("keypress",c),s()})}function vl(e={}){let t=0;return Ll({input:e.input??process.stdin,output:e.output??process.stdout,render:()=>Pf(t,e.globalHookInstalled===!0),onKey:(n,r,o)=>{if(r.ctrl&&r.name==="c"){o.finish(null),(e.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(r.name==="escape"||n==="q")return o.finish(null);if(r.name==="return"||r.name==="enter")return o.finish(pl[t]);if(r.name==="up"||r.name==="down"||n==="k"||n==="j")t=(t+1)%pl.length,o.draw()}})}function uo(e=process.stdin,t=process.stdout){return Boolean(e.isTTY&&t.isTTY&&typeof e.setRawMode==="function")}function bl(e,t,n={}){let r=n.output??process.stdout,o=Rf(t);return Ll({input:n.input??process.stdin,output:r,render:()=>Ef(e,t,o),onKey:(i,s,a)=>{let l=Df(e,i,s);if(!l)return;let c=Af(o,t,l);if(o=c.state,c.done==="interrupt"){a.finish(null),(n.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(c.done==="abort")return a.finish(null);if(c.done==="update")return a.finish("update");if(c.done==="confirm"){if(o.selected.length===0){r.write("\x07"),a.draw();return}a.finish([...o.selected]),r.write(`${xf(e)} selected integrations...
196
- `);return}a.draw()}})}import{existsSync as kl,lstatSync as If,mkdirSync as _f,mkdtempSync as Of,readdirSync as $f,readFileSync as ct,rmSync as Cn}from"node:fs";import{tmpdir as Nf}from"node:os";import{basename as Ff,dirname as Hf,join as U}from"node:path";import{fileURLToPath as Mf}from"node:url";var po="// cc-safety-net managed Amp plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --amp",Oe="cc-safety-net",$e="cc-safety-net/index.ts";import{spawn as Tf}from"node:child_process";var fo=(e,t)=>{let n=Pe([...e],process.env);return new Promise((r)=>{let o=Tf(n.cmd,n.args,{cwd:t,stdio:["ignore","pipe","pipe"]}),i=Wr(o),s=!1,a=setTimeout(()=>{s=!0,o.kill()},120000);o.on("error",(l)=>{clearTimeout(a),r({status:null,errorCode:l.code,stdout:i.stdout,stderr:[l.message,i.stderr].filter(Boolean).join(`
197
- `)})}),o.on("close",(l)=>{clearTimeout(a),r({status:s?null:l,errorCode:s?"ETIMEDOUT":void 0,stdout:i.stdout,stderr:i.stderr})})})};var lt="cc-safety-net.ts",wl=U("amp",$e);function jf(e){return U(e,".config","amp","plugins","cc-safety-net.ts")}function Uf(){let e=Hf(Mf(import.meta.url));return[U(e,"..",wl),U(e,"..","..","..","dist",wl)]}function Gf(e=Uf()){let t=e.find((n)=>kl(n)&&If(n).isFile());if(!t)throw Error("Packaged Amp plugin artifact not found. Reinstall cc-safety-net and try again.");return t}function xl(e){try{return JSON.parse(e)}catch{return}}function Sn(e){return e.subarray(0,Buffer.byteLength(po)).toString("utf-8")===po}async function Ft(e,t,n){let r=await e(t,n);if(r.status===0)return r;throw Error([`Failed to run ${t.join(" ")}${r.status===null?"":` (exit ${r.status})`}.`,[r.stdout,r.stderr].filter(Boolean).join(`
195
+ `).length};return new Promise((a)=>{let l=(d)=>{t.off("keypress",c),t.setRawMode(r),t.pause(),i(),a(d)};function c(d,p){e.onKey(d,p,{finish:l,draw:s})}t.on("keypress",c),s()})}function wl(e={}){let t=0;return bl({input:e.input??process.stdin,output:e.output??process.stdout,render:()=>Tf(t,e.globalHookInstalled===!0),onKey:(n,r,o)=>{if(r.ctrl&&r.name==="c"){o.finish(null),(e.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(r.name==="escape"||n==="q")return o.finish(null);if(r.name==="return"||r.name==="enter")return o.finish(ml[t]);if(r.name==="up"||r.name==="down"||n==="k"||n==="j")t=(t+1)%ml.length,o.draw()}})}function uo(e=process.stdin,t=process.stdout){return Boolean(e.isTTY&&t.isTTY&&typeof e.setRawMode==="function")}function kl(e,t,n={}){let r=n.output??process.stdout,o=Af(t);return bl({input:n.input??process.stdin,output:r,render:()=>Pf(e,t,o),onKey:(i,s,a)=>{let l=Rf(e,i,s);if(!l)return;let c=Ef(o,t,l);if(o=c.state,c.done==="interrupt"){a.finish(null),(n.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(c.done==="abort")return a.finish(null);if(c.done==="update")return a.finish("update");if(c.done==="confirm"){if(o.selected.length===0){r.write("\x07"),a.draw();return}a.finish([...o.selected]),r.write(`${Cf(e)} selected integrations...
196
+ `);return}a.draw()}})}import{existsSync as Cl,lstatSync as _f,mkdirSync as Of,mkdtempSync as $f,readdirSync as Nf,readFileSync as dt,rmSync as Cn}from"node:fs";import{tmpdir as Ff}from"node:os";import{basename as Hf,dirname as Mf,join as U}from"node:path";import{fileURLToPath as jf}from"node:url";var po="// cc-safety-net managed Amp plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --amp",$e="cc-safety-net",Ne="cc-safety-net/index.ts";import{spawn as If}from"node:child_process";var fo=(e,t)=>{let n=Te([...e],process.env);return new Promise((r)=>{let o=If(n.cmd,n.args,{cwd:t,stdio:["ignore","pipe","pipe"]}),i=Wr(o),s=!1,a=setTimeout(()=>{s=!0,o.kill()},120000);o.on("error",(l)=>{clearTimeout(a),r({status:null,errorCode:l.code,stdout:i.stdout,stderr:[l.message,i.stderr].filter(Boolean).join(`
197
+ `)})}),o.on("close",(l)=>{clearTimeout(a),r({status:s?null:l,errorCode:s?"ETIMEDOUT":void 0,stdout:i.stdout,stderr:i.stderr})})})};var ct="cc-safety-net.ts",xl=U("amp",Ne);function Uf(e){return U(e,".config","amp","plugins","cc-safety-net.ts")}function Gf(){let e=Mf(jf(import.meta.url));return[U(e,"..",xl),U(e,"..","..","..","dist",xl)]}function Bf(e=Gf()){let t=e.find((n)=>Cl(n)&&_f(n).isFile());if(!t)throw Error("Packaged Amp plugin artifact not found. Reinstall cc-safety-net and try again.");return t}function Sl(e){try{return JSON.parse(e)}catch{return}}function Sn(e){return e.subarray(0,Buffer.byteLength(po)).toString("utf-8")===po}async function Ht(e,t,n){let r=await e(t,n);if(r.status===0)return r;throw Error([`Failed to run ${t.join(" ")}${r.status===null?"":` (exit ${r.status})`}.`,[r.stdout,r.stderr].filter(Boolean).join(`
198
198
  `).trim()].filter(Boolean).join(`
199
- `))}async function Cl(e){let t=await e(["amp","plugins","repositories","--json"]);if(t.status===null)throw Error(`${t.errorCode==="ENOENT"?'Amp CLI not found. Install the amp CLI, sign in with "amp login", and rerun install --amp.':`amp plugins repositories --json did not finish (${t.errorCode??"terminated"}). Check that the amp CLI responds and rerun install --amp.`}
199
+ `))}async function Dl(e){let t=await e(["amp","plugins","repositories","--json"]);if(t.status===null)throw Error(`${t.errorCode==="ENOENT"?'Amp CLI not found. Install the amp CLI, sign in with "amp login", and rerun install --amp.':`amp plugins repositories --json did not finish (${t.errorCode??"terminated"}). Check that the amp CLI responds and rerun install --amp.`}
200
200
  ${t.stderr}`.trim());if(t.status!==0)throw Error(`Failed to run amp plugins repositories --json (exit ${t.status}). Sign in with "amp login" and rerun install --amp.
201
201
  ${[t.stdout,t.stderr].filter(Boolean).join(`
202
- `)}`.trim());let n=xl(t.stdout),r=(Array.isArray(n)?n:[]).filter((o)=>b(o,"scope")==="user"&&b(o,"exists")===!0&&b(o,"viewerCanWrite")===!0).map((o)=>b(o,"cloneRef")).find((o)=>typeof o==="string"&&o.length>0);if(!r)throw Error('Your Amp account has no writable Personal Plugins repository. Sign in with "amp login", open Amp once to create it, and rerun install --amp.');return r}async function Sl(e,t){let n=Of(U(Nf(),"cc-safety-net-amp-"));try{return await Ft(e,["amp","clone","user-plugins",n]),await t(n)}finally{Cn(n,{recursive:!0,force:!0})}}function mo(e){return`rerun ${e==="overwrite"?"install":"uninstall"} --amp`}function Dl(e,t,n){let r=U(e,t),o=E(r);if(!o)return;if(o.isSymbolicLink()||!o.isFile())throw Error(`Refusing to ${n} ${t} in your Amp personal plugins repository: not a regular file. Remove it there and ${mo(n)}.`);let i=ct(r);if(Sn(i))return i;throw Error(`Refusing to ${n} unmanaged file ${t} in your Amp personal plugins repository. Remove it there and ${mo(n)}.`)}function Rl(e,t){let n=U(e,Oe),r=E(n);if(!r)return;if(r.isSymbolicLink()||!r.isDirectory())throw Error(`Refusing to ${t} ${Oe} in your Amp personal plugins repository: not a regular directory. Remove it there and ${mo(t)}.`);return Dl(e,$e,t)}function Bf(e){let t=U(e,lt),n=E(t);if(!n||n.isSymbolicLink()||!n.isFile())return;let r=ct(t);return Sn(r)?r:void 0}async function Al(e,t,n,r){if(await Ft(e,n,t),(await Ft(e,["git","status","--porcelain"],t)).stdout.trim()==="")return!1;return await Ft(e,["git","-c","commit.gpgsign=false","-c","user.name=cc-safety-net","-c","user.email=cc-safety-net@localhost","commit","-m",r],t),await Ft(e,["git","push","origin","HEAD"],t),!0}function kn(e,t){qf(e,t),Vf(e,t)}function El(e,t){if(t==="keep")return;throw Error(`Local Amp plugin ${e} is not a managed copy and masks the personal plugin. Remove it and rerun install --amp.`)}function qf(e,t){let n=jf(e),r=E(n);if(!r)return;if(!r.isSymbolicLink()&&r.isFile()&&Sn(ct(n))){Cn(n);return}El(n,t)}function Vf(e,t){let n=U(e,".config","amp","plugins",Oe),r=E(n);if(!r)return;if(!r.isSymbolicLink()&&r.isDirectory()&&zf(n)){Cn(n,{recursive:!0});return}El(n,t)}function zf(e){let t=Ff($e);if($f(e).join("\x00")!==t)return!1;let n=U(e,t),r=E(n);return!!r&&!r.isSymbolicLink()&&r.isFile()&&Sn(ct(n))}function Kf(){let e=bt();if(!kl(e))return"";let t=xl(ct(e,"utf-8"));if(!t||typeof t!=="object"||Array.isArray(t))return"";return`;globalThis.__CC_SAFETY_NET_EMBEDDED_POLICY__ = ${JSON.stringify(xn(t))};
203
- `}async function Pl(e,t=Gf(),n=fo){let r=Buffer.concat([ct(t),Buffer.from(Kf(),"utf-8")]),o=await Cl(n);return Sl(n,async(i)=>{let s=`${o}/${Oe}`,a=Rl(i,"overwrite"),l=Dl(i,lt,"overwrite");if(a?.equals(r)&&!l)return kn(e,"fail"),{path:s,alreadyInstalled:!0};if(_f(U(i,Oe),{recursive:!0}),_(U(i,$e),r),l)Cn(U(i,lt));let c=await Al(n,i,["git","add","--",$e,...l?[lt]:[]],`chore: update cc-safety-net plugin to v${P()}`);return kn(e,"fail"),{path:s,alreadyInstalled:!c}})}async function Tl(e,t=fo){let n=await Cl(t);return Sl(t,async(r)=>{let o=Rl(r,"remove"),i=Bf(r),s=`${n}/${i&&!o?lt:Oe}`;if(!o&&!i)return kn(e,"keep"),{path:s,alreadyInstalled:!1};return await Al(t,r,["git","rm","--",...o?[$e]:[],...i?[lt]:[]],`chore: remove cc-safety-net plugin v${P()}`),kn(e,"keep"),{path:s,alreadyInstalled:!0}})}import{existsSync as Il,mkdirSync as Wf,readFileSync as Jf}from"node:fs";import{dirname as Yf}from"node:path";var go="npx -y cc-safety-net hook --agy-cli",Ne="cc-safety-net";function Fe(e){return Boolean(e)&&typeof e==="object"&&!Array.isArray(e)}function Rn(){return{PreToolUse:[{hooks:[{type:"command",command:go,timeout:30}]}]}}function _l(e){try{let t=JSON.parse(Jf(e,"utf-8"));if(!t||typeof t!=="object"||Array.isArray(t))throw Error("Antigravity hooks config must be a JSON object");return t}catch(t){if(t instanceof SyntaxError)throw Error(`Failed to parse Antigravity hooks config ${e}: ${t.message}`);throw t}}function Ol(e){let t=e[Ne];if(t===void 0){let r=Rn();return e[Ne]=r,{definition:r,preToolUse:r.PreToolUse??[]}}if(!Fe(t))throw Error(`Antigravity hooks config entry "${Ne}" must be an object`);let n=Array.isArray(t.PreToolUse)?t.PreToolUse:[];return t.PreToolUse=n,{definition:t,preToolUse:n}}function $l(e){if(!Array.isArray(e.PreToolUse))return!1;return e.PreToolUse.some((t)=>Fe(t)&&Array.isArray(t.hooks)&&t.hooks.some((n)=>Fe(n)&&n.command===go))}function Zf(e){return Object.values(e).some((t)=>Fe(t)&&t.enabled!==!1&&$l(t))}function Xf(e){if(e[Ne]===void 0)return!1;let t=Ol(e);if(t.definition.enabled!==!1||!$l(t.definition))return!1;return t.definition.enabled=!0,!0}function Qf(e){if(e[Ne]===void 0){e[Ne]=Rn();return}let t=Ol(e);t.definition.enabled=!0,t.preToolUse.push(Rn().PreToolUse?.[0]??{hooks:[]})}function em(e){let t=!1;for(let n of Object.values(e)){if(!Fe(n)||!Array.isArray(n.PreToolUse))continue;n.PreToolUse=n.PreToolUse.flatMap((r)=>{if(!Fe(r)||!Array.isArray(r.hooks))return[r];let o=r.hooks.filter((i)=>!Fe(i)||i.command!==go);if(o.length!==r.hooks.length)t=!0;return o.length===0?[]:[{...r,hooks:o}]})}return t}function Dn(e,t){_(e,`${JSON.stringify(t,null,2)}
204
- `)}function Nl(e){let t=Ct(e);if(Wf(Yf(t),{recursive:!0}),!Il(t))return Dn(t,{[Ne]:Rn()}),{path:t,alreadyInstalled:!1};let n=_l(t);if(Zf(n))return{path:t,alreadyInstalled:!0};if(Xf(n))return Dn(t,n),{path:t,alreadyInstalled:!1};return Qf(n),Dn(t,n),{path:t,alreadyInstalled:!1}}function Fl(e){let t=Ct(e);if(!Il(t))return{path:t,alreadyInstalled:!1};let n=_l(t);if(!em(n))return{path:t,alreadyInstalled:!1};return Dn(t,n),{path:t,alreadyInstalled:!0}}import{spawn as tm}from"node:child_process";var se=V.map((e)=>({target:e.id,flag:e.flag,label:R(e.id),probeCommand:e.probeCommand}));function ho(e){let t=new Set(e);return se.map((n)=>n.target).filter((n)=>t.has(n))}async function Hl(e,t){for(let n of e)await t(n)}var nm=5000;function yo(e){return new Promise((t)=>{let n=Pe([...e],process.env),r=tm(n.cmd,n.args,{env:process.env,stdio:"ignore"}),o=!1,i=(a)=>{if(o)return;o=!0,clearTimeout(s),t(a)},s=setTimeout(()=>{r.kill(),i(!1)},nm);r.on("error",()=>i(!1)),r.on("close",(a)=>i(a===0))})}function Ml(e=yo,t={}){let n=new Set(t.configuredTargets??[]);return Promise.all(se.map(async(r)=>({target:r.target,flag:r.flag,label:r.label,...Ul(t.action,await e(r.probeCommand),n.has(r.target))})))}function jl(e,t){let n=new Set(t.configuredTargets??[]);return e.map((r)=>({...r,...Ul(t.action,r.available,n.has(r.target))}))}function Ul(e,t,n){if(e==="uninstall")return n?{available:!0}:{available:!1,unavailableReason:"not installed"};if(e==="install"&&n)return{available:!1,unavailableReason:"already installed"};if(!t)return{available:!1,unavailableReason:"CLI not installed"};return{available:!0}}import{existsSync as Gl,readdirSync as rm,rmSync as om}from"node:fs";import{join as dt}from"node:path";function An(e,t=process.platform){let n=dt(process.env.npm_config_cache||(t==="win32"?dt(process.env.LOCALAPPDATA||dt(e,"AppData","Local"),"npm-cache"):dt(e,".npm")),"_npx");if(!Gl(n))return;rm(n).filter((r)=>Gl(dt(n,r,"node_modules","cc-safety-net"))).forEach((r)=>{om(dt(n,r),{recursive:!0,force:!0})})}import{existsSync as ql,mkdirSync as im,readFileSync as Vl}from"node:fs";import{dirname as sm,join as Bl}from"node:path";var Ht="npx -y cc-safety-net hook --kimi-code",Lo=`[[hooks]]
202
+ `)}`.trim());let n=Sl(t.stdout),r=(Array.isArray(n)?n:[]).filter((o)=>b(o,"scope")==="user"&&b(o,"exists")===!0&&b(o,"viewerCanWrite")===!0).map((o)=>b(o,"cloneRef")).find((o)=>typeof o==="string"&&o.length>0);if(!r)throw Error('Your Amp account has no writable Personal Plugins repository. Sign in with "amp login", open Amp once to create it, and rerun install --amp.');return r}async function Rl(e,t){let n=$f(U(Ff(),"cc-safety-net-amp-"));try{return await Ht(e,["amp","clone","user-plugins",n]),await t(n)}finally{Cn(n,{recursive:!0,force:!0})}}function mo(e){return`rerun ${e==="overwrite"?"install":"uninstall"} --amp`}function Al(e,t,n){let r=U(e,t),o=E(r);if(!o)return;if(o.isSymbolicLink()||!o.isFile())throw Error(`Refusing to ${n} ${t} in your Amp personal plugins repository: not a regular file. Remove it there and ${mo(n)}.`);let i=dt(r);if(Sn(i))return i;throw Error(`Refusing to ${n} unmanaged file ${t} in your Amp personal plugins repository. Remove it there and ${mo(n)}.`)}function El(e,t){let n=U(e,$e),r=E(n);if(!r)return;if(r.isSymbolicLink()||!r.isDirectory())throw Error(`Refusing to ${t} ${$e} in your Amp personal plugins repository: not a regular directory. Remove it there and ${mo(t)}.`);return Al(e,Ne,t)}function qf(e){let t=U(e,ct),n=E(t);if(!n||n.isSymbolicLink()||!n.isFile())return;let r=dt(t);return Sn(r)?r:void 0}async function Pl(e,t,n,r){if(await Ht(e,n,t),(await Ht(e,["git","status","--porcelain"],t)).stdout.trim()==="")return!1;return await Ht(e,["git","-c","commit.gpgsign=false","-c","user.name=cc-safety-net","-c","user.email=cc-safety-net@localhost","commit","-m",r],t),await Ht(e,["git","push","origin","HEAD"],t),!0}function kn(e,t){Vf(e,t),zf(e,t)}function Tl(e,t){if(t==="keep")return;throw Error(`Local Amp plugin ${e} is not a managed copy and masks the personal plugin. Remove it and rerun install --amp.`)}function Vf(e,t){let n=Uf(e),r=E(n);if(!r)return;if(!r.isSymbolicLink()&&r.isFile()&&Sn(dt(n))){Cn(n);return}Tl(n,t)}function zf(e,t){let n=U(e,".config","amp","plugins",$e),r=E(n);if(!r)return;if(!r.isSymbolicLink()&&r.isDirectory()&&Kf(n)){Cn(n,{recursive:!0});return}Tl(n,t)}function Kf(e){let t=Hf(Ne);if(Nf(e).join("\x00")!==t)return!1;let n=U(e,t),r=E(n);return!!r&&!r.isSymbolicLink()&&r.isFile()&&Sn(dt(n))}function Wf(){let e=wt();if(!Cl(e))return"";let t=Sl(dt(e,"utf-8"));if(!t||typeof t!=="object"||Array.isArray(t))return"";return`;globalThis.__CC_SAFETY_NET_EMBEDDED_POLICY__ = ${JSON.stringify(xn(t))};
203
+ `}async function Il(e,t=Bf(),n=fo){let r=Buffer.concat([dt(t),Buffer.from(Wf(),"utf-8")]),o=await Dl(n);return Rl(n,async(i)=>{let s=`${o}/${$e}`,a=El(i,"overwrite"),l=Al(i,ct,"overwrite");if(a?.equals(r)&&!l)return kn(e,"fail"),{path:s,alreadyInstalled:!0};if(Of(U(i,$e),{recursive:!0}),_(U(i,Ne),r),l)Cn(U(i,ct));let c=await Pl(n,i,["git","add","--",Ne,...l?[ct]:[]],`chore: update cc-safety-net plugin to v${P()}`);return kn(e,"fail"),{path:s,alreadyInstalled:!c}})}async function _l(e,t=fo){let n=await Dl(t);return Rl(t,async(r)=>{let o=El(r,"remove"),i=qf(r),s=`${n}/${i&&!o?ct:$e}`;if(!o&&!i)return kn(e,"keep"),{path:s,alreadyInstalled:!1};return await Pl(t,r,["git","rm","--",...o?[Ne]:[],...i?[ct]:[]],`chore: remove cc-safety-net plugin v${P()}`),kn(e,"keep"),{path:s,alreadyInstalled:!0}})}import{existsSync as Ol,mkdirSync as Jf,readFileSync as Yf}from"node:fs";import{dirname as Zf}from"node:path";var go="npx -y cc-safety-net hook --agy-cli",Fe="cc-safety-net";function He(e){return Boolean(e)&&typeof e==="object"&&!Array.isArray(e)}function Rn(){return{PreToolUse:[{hooks:[{type:"command",command:go,timeout:30}]}]}}function $l(e){try{let t=JSON.parse(Yf(e,"utf-8"));if(!t||typeof t!=="object"||Array.isArray(t))throw Error("Antigravity hooks config must be a JSON object");return t}catch(t){if(t instanceof SyntaxError)throw Error(`Failed to parse Antigravity hooks config ${e}: ${t.message}`);throw t}}function Nl(e){let t=e[Fe];if(t===void 0){let r=Rn();return e[Fe]=r,{definition:r,preToolUse:r.PreToolUse??[]}}if(!He(t))throw Error(`Antigravity hooks config entry "${Fe}" must be an object`);let n=Array.isArray(t.PreToolUse)?t.PreToolUse:[];return t.PreToolUse=n,{definition:t,preToolUse:n}}function Fl(e){if(!Array.isArray(e.PreToolUse))return!1;return e.PreToolUse.some((t)=>He(t)&&Array.isArray(t.hooks)&&t.hooks.some((n)=>He(n)&&n.command===go))}function Xf(e){return Object.values(e).some((t)=>He(t)&&t.enabled!==!1&&Fl(t))}function Qf(e){if(e[Fe]===void 0)return!1;let t=Nl(e);if(t.definition.enabled!==!1||!Fl(t.definition))return!1;return t.definition.enabled=!0,!0}function em(e){if(e[Fe]===void 0){e[Fe]=Rn();return}let t=Nl(e);t.definition.enabled=!0,t.preToolUse.push(Rn().PreToolUse?.[0]??{hooks:[]})}function tm(e){let t=!1;for(let n of Object.values(e)){if(!He(n)||!Array.isArray(n.PreToolUse))continue;n.PreToolUse=n.PreToolUse.flatMap((r)=>{if(!He(r)||!Array.isArray(r.hooks))return[r];let o=r.hooks.filter((i)=>!He(i)||i.command!==go);if(o.length!==r.hooks.length)t=!0;return o.length===0?[]:[{...r,hooks:o}]})}return t}function Dn(e,t){_(e,`${JSON.stringify(t,null,2)}
204
+ `)}function Hl(e){let t=St(e);if(Jf(Zf(t),{recursive:!0}),!Ol(t))return Dn(t,{[Fe]:Rn()}),{path:t,alreadyInstalled:!1};let n=$l(t);if(Xf(n))return{path:t,alreadyInstalled:!0};if(Qf(n))return Dn(t,n),{path:t,alreadyInstalled:!1};return em(n),Dn(t,n),{path:t,alreadyInstalled:!1}}function Ml(e){let t=St(e);if(!Ol(t))return{path:t,alreadyInstalled:!1};let n=$l(t);if(!tm(n))return{path:t,alreadyInstalled:!1};return Dn(t,n),{path:t,alreadyInstalled:!0}}import{spawn as nm}from"node:child_process";var se=V.map((e)=>({target:e.id,flag:e.flag,label:R(e.id),probeCommand:e.probeCommand}));function ho(e){let t=new Set(e);return se.map((n)=>n.target).filter((n)=>t.has(n))}async function jl(e,t){for(let n of e)await t(n)}var rm=5000;function yo(e){return new Promise((t)=>{let n=Te([...e],process.env),r=nm(n.cmd,n.args,{env:process.env,stdio:"ignore"}),o=!1,i=(a)=>{if(o)return;o=!0,clearTimeout(s),t(a)},s=setTimeout(()=>{r.kill(),i(!1)},rm);r.on("error",()=>i(!1)),r.on("close",(a)=>i(a===0))})}function Ul(e=yo,t={}){let n=new Set(t.configuredTargets??[]);return Promise.all(se.map(async(r)=>({target:r.target,flag:r.flag,label:r.label,...Bl(t.action,await e(r.probeCommand),n.has(r.target))})))}function Gl(e,t){let n=new Set(t.configuredTargets??[]);return e.map((r)=>({...r,...Bl(t.action,r.available,n.has(r.target))}))}function Bl(e,t,n){if(e==="uninstall")return n?{available:!0}:{available:!1,unavailableReason:"not installed"};if(e==="install"&&n)return{available:!1,unavailableReason:"already installed"};if(!t)return{available:!1,unavailableReason:"CLI not installed"};return{available:!0}}import{existsSync as ql,readdirSync as om,rmSync as im}from"node:fs";import{join as ut}from"node:path";function An(e,t=process.platform){let n=ut(process.env.npm_config_cache||(t==="win32"?ut(process.env.LOCALAPPDATA||ut(e,"AppData","Local"),"npm-cache"):ut(e,".npm")),"_npx");if(!ql(n))return;om(n).filter((r)=>ql(ut(n,r,"node_modules","cc-safety-net"))).forEach((r)=>{im(ut(n,r),{recursive:!0,force:!0})})}import{existsSync as zl,mkdirSync as sm,readFileSync as Kl}from"node:fs";import{dirname as am,join as Vl}from"node:path";var Mt="npx -y cc-safety-net hook --kimi-code",Lo=`[[hooks]]
205
205
  event = "PreToolUse"
206
- command = "${Ht}"`,vo=`{ event = "PreToolUse", command = "${Ht}" }`;function zl(e){return Bl(process.env.KIMI_CODE_HOME??Bl(e,".kimi-code"),"config.toml")}function am(e){return e.split(`
206
+ command = "${Mt}"`,vo=`{ event = "PreToolUse", command = "${Mt}" }`;function Wl(e){return Vl(process.env.KIMI_CODE_HOME??Vl(e,".kimi-code"),"config.toml")}function lm(e){return e.split(`
207
207
  `).reduce((n,r)=>{if(/^\s*\[/.test(r))return n.activeTable=!0,n.lines.push(r),n;if(!n.activeTable&&/^\s*hooks\s*=\s*\[\s*]\s*(?:#.*)?$/.test(r))return n;return n.lines.push(r),n},{activeTable:!1,lines:[]}).lines.join(`
208
- `)}function lm(e,t){if(e[t]!=="#")return t;let n=e.indexOf(`
209
- `,t+1);return n===-1?e.length:n+1}function cm(e,t){return gn(e,t,{skipComment:lm,stringError:"Unterminated string in Kimi Code config",bracketError:"Unmatched hooks array in Kimi Code config"})}function Kl(e){let t=!1,n=0;while(n<e.length){let r=e.indexOf(`
210
- `,n),o=r===-1?e.length:r,i=e.slice(n,o);if(/^\s*\[/.test(i))t=!0;if(!t){let s=/^(\s*)hooks\s*=\s*\[/.exec(i);if(s){let a=n+s[0].lastIndexOf("[");return{start:a,end:cm(e,a)}}}n=r===-1?e.length:r+1}return}function dm(e,t){let n=e.slice(0,t.end).trimEnd(),r=Ma(e,t.end),o=r===""?" ":`${r} `,i=!n.endsWith("[")&&!n.endsWith(",");return`${n}${i?",":""}
211
- ${o}${vo}${e.slice(t.end)}`}function um(e){let t=Kl(e);if(t&&e.slice(t.start+1,t.end).trim())return dm(e,t);let n=am(e).trimEnd();if(n==="")return`${Lo}
208
+ `)}function cm(e,t){if(e[t]!=="#")return t;let n=e.indexOf(`
209
+ `,t+1);return n===-1?e.length:n+1}function dm(e,t){return gn(e,t,{skipComment:cm,stringError:"Unterminated string in Kimi Code config",bracketError:"Unmatched hooks array in Kimi Code config"})}function Jl(e){let t=!1,n=0;while(n<e.length){let r=e.indexOf(`
210
+ `,n),o=r===-1?e.length:r,i=e.slice(n,o);if(/^\s*\[/.test(i))t=!0;if(!t){let s=/^(\s*)hooks\s*=\s*\[/.exec(i);if(s){let a=n+s[0].lastIndexOf("[");return{start:a,end:dm(e,a)}}}n=r===-1?e.length:r+1}return}function um(e,t){let n=e.slice(0,t.end).trimEnd(),r=Ua(e,t.end),o=r===""?" ":`${r} `,i=!n.endsWith("[")&&!n.endsWith(",");return`${n}${i?",":""}
211
+ ${o}${vo}${e.slice(t.end)}`}function pm(e){let t=Jl(e);if(t&&e.slice(t.start+1,t.end).trim())return um(e,t);let n=lm(e).trimEnd();if(n==="")return`${Lo}
212
212
  `;return`${n}
213
213
 
214
214
  ${Lo}
215
- `}function pm(e){return e.split(/(?=^\s*\[)/m).filter((n)=>!/^\s*\[\[hooks]]\s*$/m.test(n)||!n.includes(Ht)).join("").trimEnd()}function fm(e,t){let n=e.indexOf(vo,t.start);if(n===-1||n>t.end)return e;return hn(e,{start:n,end:n+vo.length})}function Wl(e){let t=zl(e);if(im(sm(t),{recursive:!0}),!ql(t))return _(t,`${Lo}
216
- `),{path:t,alreadyInstalled:!1};let n=Vl(t,"utf-8");if(n.includes(Ht))return{path:t,alreadyInstalled:!0};return _(t,um(n)),{path:t,alreadyInstalled:!1}}function Jl(e){let t=zl(e);if(!ql(t))return{path:t,alreadyInstalled:!1};let n=Vl(t,"utf-8");if(!n.includes(Ht))return{path:t,alreadyInstalled:!1};let r=Kl(n),o=r?fm(n,r):`${pm(n)}
217
- `;return _(t,o),{path:t,alreadyInstalled:!0}}var wo="safety-net@cc-marketplace",Yl=new Set(["claude-code","codex","copilot-cli","gemini-cli","hermes-agent","openclaw","opencode","pi"]),Zl=new Set(["antigravity-cli","cursor","hermes-agent","kimi-code"]);function xo(e){return/^\s*safety-net@cc-marketplace[^a-z0-9-][^\n]*installed,/m.test(e??"")}function nc(e){return/^\s*cc-safety-net[^a-z0-9-][^\n]*installed,/m.test(e??"")}function gm(e){return/^Marketplace `cc-marketplace`\s*$/m.test(e??"")}var rc={"claude-code":{installCommands:(e)=>{let t=on(e,"cc-safety-net@cc-marketplace");return{commands:[...t?[["claude","plugin","marketplace","update","cc-marketplace"],["claude","plugin","update","cc-safety-net@cc-marketplace"]]:[["claude","plugin","marketplace","add","kenryu42/cc-marketplace"],["claude","plugin","marketplace","update","cc-marketplace"],["claude","plugin","install","cc-safety-net@cc-marketplace"]],...Ir(e).status==="disabled"?[["claude","plugin","enable","cc-safety-net@cc-marketplace"]]:[]],cleanupCommands:on(e,wo)?[["claude","plugin","uninstall",wo]]:[],update:t}},uninstallCommands:[["claude","plugin","uninstall","cc-safety-net@cc-marketplace"],["claude","plugin","marketplace","remove","cc-marketplace"]]},codex:{installCommands:async(e,t)=>{let n=t??await ie(["codex","plugin","list"]),r=nc(n);return{commands:[r||gm(n)?["codex","plugin","marketplace","upgrade","cc-marketplace"]:["codex","plugin","marketplace","add","kenryu42/cc-marketplace"],["codex","plugin","add","cc-safety-net@cc-marketplace"]],cleanupCommands:xo(n)?[["codex","plugin","remove","safety-net@cc-marketplace"]]:[],update:r}},uninstallCommands:[["codex","plugin","remove","cc-safety-net@cc-marketplace"],["codex","plugin","marketplace","remove","cc-marketplace"]],postInstallMessage:"Start Codex, open `/hooks`, select the cc-safety-net PreToolUse hook, and press `t` to trust it."},"copilot-cli":{installCommands:async()=>{let e=await ie(["copilot","plugin","list"]),t=[...Zs(e)?[["copilot","plugin","uninstall","copilot-safety-net"]]:[],...Xs(e)?[["copilot","plugin","uninstall",Ws]]:[]];if(Js(e))return{commands:[["copilot","plugin","marketplace","update","cc-marketplace"],["copilot","plugin","update",oe]],cleanupCommands:t,update:!0};return{commands:[Ys(await ie(["copilot","plugin","marketplace","list"]))?["copilot","plugin","marketplace","update","cc-marketplace"]:["copilot","plugin","marketplace","add","kenryu42/cc-marketplace"],["copilot","plugin","install",oe]],cleanupCommands:t}},uninstallCommands:[["copilot","plugin","uninstall","cc-safety-net@cc-marketplace"],["copilot","plugin","marketplace","remove","cc-marketplace"]]},"gemini-cli":{installCommands:(e)=>{let t=Mr(e);if(t.status==="configured")return{commands:[["gemini","extensions","update","gemini-safety-net"]],update:!0};if(t.status==="disabled")return{commands:[["gemini","extensions","update","gemini-safety-net"],["gemini","extensions","enable","gemini-safety-net"]],update:!0};return{commands:[["gemini","extensions","install","https://github.com/kenryu42/gemini-safety-net","--consent"]]}},uninstallCommands:[["gemini","extensions","uninstall","gemini-safety-net"]]},openclaw:{beforeInstall:Xr,installCommands:()=>({commands:Ta()}),uninstallCommands:[["openclaw","plugins","uninstall",A,"--force"]],postInstallMessage:["Restart the OpenClaw Gateway to apply the change.","If plugins.allow is set in openclaw.json, it must also list cc-safety-net."].join(`
218
- `)},opencode:{beforeInstall:to,installCommands:[["opencode","plugin","-g","-f","cc-safety-net@latest"]]},pi:{installCommands:[["pi","install","npm:cc-safety-net"]],uninstallCommands:[["pi","uninstall","npm:cc-safety-net"]]}};function Tn(){return process.env.HOME??mm()}function oc(e,t=(n)=>n){try{let n=JSON.parse(t(tc(e,"utf-8")));if(!n||typeof n!=="object"||Array.isArray(n))throw Error(`Settings file ${e} must be a JSON object`);return n}catch(n){if(n instanceof SyntaxError)throw Error(`Failed to parse ${e}: ${n.message}`);throw n}}function hm(e){let t=bo(Pt(e),"settings.json");if(!ko(t))return;let n=oc(t,q),r=n.enabledPlugins;if(!r||typeof r!=="object"||Array.isArray(r))return;if(r[oe]!==!1)return;let o=tc(t,"utf-8"),i=o.replace(new RegExp(`("${oe}"\\s*:\\s*)false`),"$1true");return r[oe]=!0,_(t,i!==o?i:`${JSON.stringify(n,null,2)}
219
- `),`Enabled ${oe} plugin in ${t}`}function ym(e){let t=no(e);if(!ko(t))return;let n=oc(t);if(!Array.isArray(n.packages))return;let r=n.packages.find((o)=>!!o&&typeof o==="object"&&!Array.isArray(o)&&ro(o.source)&&("extensions"in o));if(!r)return;return delete r.extensions,_(t,`${JSON.stringify(n,null,2)}
220
- `),`Enabled npm:cc-safety-net extensions in ${t}`}function Xl(e,t){let n=T({label:t,booleans:Object.fromEntries(se.map((i)=>[i.target,[i.flag]]))},e),r=n.errors[0];if(r)throw Error(r);let o=se.filter((i)=>n.flags[i.target]).map((i)=>i.target);if(o.length!==1)throw Error(`Choose exactly one ${t} target: ${se.map((i)=>i.flag).join(", ")}`);return o[0]}async function ic(e=Tn(),t=et){let[n,r,o]=await Promise.all([t(["amp","plugins","list"],30000),t(["codex","plugin","list"],30000),t(["copilot","--binary-version"])]);return{codexPluginListOutput:r,hooks:at(process.cwd(),{homeDir:e,ampPluginListOutput:n,codexPluginListOutput:r,copilotCliVersion:o})}}async function Lm(e,t=et){let n=await ic(Tn(),t);return n.hooks.filter((r)=>e==="install"?r.configured:r.detected||r.inspectionStatus==="not-inspected").filter((r)=>r.platform!=="codex"||!xo(n.codexPluginListOutput)||nc(n.codexPluginListOutput)).map((r)=>r.platform)}function vm(e,t,n){if(t.length>0)return{finish:async()=>[Xl(t,e)]};if(!n.selectTargets&&!uo(n.input,n.output))return{finish:async()=>[Xl(t,e)]};let r=n.detectConfiguredTargets??(()=>Lm(e,n.fetchVersion)),o=Promise.all([Ml(n.probeTargets),r()]);return{ready:o,finish:async()=>{let[i,s]=await o,a=jl(i,{action:e,configuredTargets:s}),l=n.selectTargets?await n.selectTargets(e,ec(e,a)):await bl(e,ec(e,a),{input:n.input,output:n.output});if(l==="update")return l;if(!l||l.length===0)return null;return ho(l)}}}async function He(e,t,n=!1,r){let o=rc[e];o.beforeInstall?.(t);let i=typeof o.installCommands==="function"?await o.installCommands(t,r):{commands:o.installCommands};return await Jr(i.commands),await Sa(i.cleanupCommands??[]),[`${i.update||n?"Updated":"Installed"} ${R(e)} integration`,o.postInstallMessage].filter(Boolean).join(`
221
- `)}async function ut(e){let t=rc[e];if(!t.uninstallCommands)throw Error(`${R(e)} uninstall is not supported`);return await Jr(t.uninstallCommands),`Uninstalled ${R(e)} integration`}function bm(e){let t=Ya(e);return t.alreadyInstalled?`Uninstalled OpenCode plugin from ${t.path}`:`OpenCode plugin not installed in ${t.path}`}var wm={"antigravity-cli":{install:Nl,uninstall:Fl},cursor:{install:la,uninstall:ca},"kimi-code":{install:Wl,uninstall:Jl}};function pt(e,t,n,r=!1){if(e==="install"&&!r)An(n);let o=wm[t][e](n),i=R(t),s=e!=="install"?"Uninstalled":r?"Updated":"Installed";return e==="install"&&o.alreadyInstalled?r?`${i} hook up to date in ${o.path}`:`${i} hook already installed in ${o.path}`:e==="uninstall"&&!o.alreadyInstalled?`${i} hook not installed in ${o.path}`:`${s} ${i} hook ${e==="install"?"in":"from"} ${o.path}`}var km={amp:{install:Pl,uninstall:Tl,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:ga,uninstall:ha,afterInstall:async(e)=>{let t=zr(e);return await ie(["hermes","plugins","enable",z,"--no-allow-tool-override"]),!t},beforeUninstall:async(e)=>{Vr(e);try{await ie(["hermes","plugins","disable",z])}catch(t){console.warn(`${t instanceof Error?t.message:String(t)}
222
- Removing the plugin files anyway; ${z} may still be listed in the Hermes config.`)}},restartNote:"Restart Hermes to apply the change."}};async function En(e,t,n,r=!1){let o=km[t];if(e==="uninstall")await o.beforeUninstall?.(n);let i=e==="install"?await o.install(n):await o.uninstall(n),s=e==="install"&&await o.afterInstall?.(n),a=R(t),l=!s&&(e==="install"&&i.alreadyInstalled||e==="uninstall"&&!i.alreadyInstalled);return[l?e==="install"?`${a} plugin ${r?"up to date":"already installed"} at ${i.path}`:`${a} plugin not installed at ${i.path}`:`${e!=="install"?"Uninstalled":r?"Updated":"Installed"} ${a} plugin ${e==="install"?"at":"from"} ${i.path}`,l?void 0:o.restartNote].filter(Boolean).join(`
223
- `)}var xm={amp:{install:(e,t)=>En("install","amp",e,t),uninstall:(e)=>En("uninstall","amp",e)},"antigravity-cli":{install:(e,t)=>pt("install","antigravity-cli",e,t),uninstall:(e)=>pt("uninstall","antigravity-cli",e)},"claude-code":{install:(e,t)=>He("claude-code",e,t),uninstall:()=>ut("claude-code")},codex:{install:(e,t,n)=>He("codex",e,t,n),uninstall:()=>ut("codex")},"copilot-cli":{install:async(e,t)=>[await He("copilot-cli",e,t),hm(e)].filter(Boolean).join(`
224
- `),uninstall:()=>ut("copilot-cli")},cursor:{install:(e,t)=>pt("install","cursor",e,t),uninstall:(e)=>pt("uninstall","cursor",e)},"gemini-cli":{install:(e,t)=>He("gemini-cli",e,t),uninstall:()=>ut("gemini-cli")},"hermes-agent":{install:(e,t)=>{if(!t)An(e);return En("install","hermes-agent",e,t)},uninstall:(e)=>En("uninstall","hermes-agent",e)},"kimi-code":{install:(e,t)=>pt("install","kimi-code",e,t),uninstall:(e)=>pt("uninstall","kimi-code",e)},openclaw:{install:async(e,t)=>{let n=await He("openclaw",e,t);return await Ia(),n},uninstall:(e)=>(Xr(e),ut("openclaw"))},opencode:{install:async(e,t)=>{let n=await He("opencode",e,t);return await za(e),n},uninstall:(e)=>bm(e)},pi:{install:async(e,t)=>[await He("pi",e,t),ym(e)].filter(Boolean).join(`
225
- `),uninstall:()=>ut("pi")}},Ql=["Install CC Safety Net as a native Kimi Code plugin:",""," 1. Start Kimi Code and run: /plugins install https://github.com/kenryu42/cc-safety-net"," Confirm the trust prompt; it defaults to cancel."," 2. Run /reload, or start a new session.","","Note: Kimi Code hooks are fail-open. When the hook process cannot start, crashes, or times","out, Kimi Code allows the tool call."].join(`
226
- `);function Cm(e){if(_t({homeDir:e,cwd:process.cwd()}).status!=="configured")return Ql;return[Ql,"",h.red(["CAUTION: the global Kimi Code hook is installed and will run alongside the plugin.","After the plugin is active, remove it with: cc-safety-net uninstall --kimi-code"].join(`
215
+ `}function fm(e){return e.split(/(?=^\s*\[)/m).filter((n)=>!/^\s*\[\[hooks]]\s*$/m.test(n)||!n.includes(Mt)).join("").trimEnd()}function mm(e,t){let n=e.indexOf(vo,t.start);if(n===-1||n>t.end)return e;return hn(e,{start:n,end:n+vo.length})}function Yl(e){let t=Wl(e);if(sm(am(t),{recursive:!0}),!zl(t))return _(t,`${Lo}
216
+ `),{path:t,alreadyInstalled:!1};let n=Kl(t,"utf-8");if(n.includes(Mt))return{path:t,alreadyInstalled:!0};return _(t,pm(n)),{path:t,alreadyInstalled:!1}}function Zl(e){let t=Wl(e);if(!zl(t))return{path:t,alreadyInstalled:!1};let n=Kl(t,"utf-8");if(!n.includes(Mt))return{path:t,alreadyInstalled:!1};let r=Jl(n),o=r?mm(n,r):`${fm(n)}
217
+ `;return _(t,o),{path:t,alreadyInstalled:!0}}var wo="safety-net@cc-marketplace",Xl=new Set(["claude-code","codex","copilot-cli","gemini-cli","hermes-agent","openclaw","opencode","pi"]),Ql=new Set(["antigravity-cli","cursor","hermes-agent","kimi-code"]);function xo(e){return/^\s*safety-net@cc-marketplace[^a-z0-9-][^\n]*installed,/m.test(e??"")}function oc(e){return/^\s*cc-safety-net[^a-z0-9-][^\n]*installed,/m.test(e??"")}function hm(e){return/^Marketplace `cc-marketplace`\s*$/m.test(e??"")}var ic={"claude-code":{installCommands:(e)=>{let t=on(e,"cc-safety-net@cc-marketplace");return{commands:[...t?[["claude","plugin","marketplace","update","cc-marketplace"],["claude","plugin","update","cc-safety-net@cc-marketplace"]]:[["claude","plugin","marketplace","add","kenryu42/cc-marketplace"],["claude","plugin","marketplace","update","cc-marketplace"],["claude","plugin","install","cc-safety-net@cc-marketplace"]],...Ir(e).status==="disabled"?[["claude","plugin","enable","cc-safety-net@cc-marketplace"]]:[]],cleanupCommands:on(e,wo)?[["claude","plugin","uninstall",wo]]:[],update:t}},uninstallCommands:[["claude","plugin","uninstall","cc-safety-net@cc-marketplace"],["claude","plugin","marketplace","remove","cc-marketplace"]]},codex:{installCommands:async(e,t)=>{let n=t??await ie(["codex","plugin","list"]),r=oc(n);return{commands:[r||hm(n)?["codex","plugin","marketplace","upgrade","cc-marketplace"]:["codex","plugin","marketplace","add","kenryu42/cc-marketplace"],["codex","plugin","add","cc-safety-net@cc-marketplace"]],cleanupCommands:xo(n)?[["codex","plugin","remove","safety-net@cc-marketplace"]]:[],update:r}},uninstallCommands:[["codex","plugin","remove","cc-safety-net@cc-marketplace"],["codex","plugin","marketplace","remove","cc-marketplace"]],postInstallMessage:"Start Codex, open `/hooks`, select the cc-safety-net PreToolUse hook, and press `t` to trust it."},"copilot-cli":{installCommands:async()=>{let e=await ie(["copilot","plugin","list"]),t=[...Qs(e)?[["copilot","plugin","uninstall","copilot-safety-net"]]:[],...ea(e)?[["copilot","plugin","uninstall",Ys]]:[]];if(Zs(e))return{commands:[["copilot","plugin","marketplace","update","cc-marketplace"],["copilot","plugin","update",oe]],cleanupCommands:t,update:!0};return{commands:[Xs(await ie(["copilot","plugin","marketplace","list"]))?["copilot","plugin","marketplace","update","cc-marketplace"]:["copilot","plugin","marketplace","add","kenryu42/cc-marketplace"],["copilot","plugin","install",oe]],cleanupCommands:t}},uninstallCommands:[["copilot","plugin","uninstall","cc-safety-net@cc-marketplace"],["copilot","plugin","marketplace","remove","cc-marketplace"]]},"gemini-cli":{installCommands:(e)=>{let t=Mr(e);if(t.status==="configured")return{commands:[["gemini","extensions","update","gemini-safety-net"]],update:!0};if(t.status==="disabled")return{commands:[["gemini","extensions","update","gemini-safety-net"],["gemini","extensions","enable","gemini-safety-net"]],update:!0};return{commands:[["gemini","extensions","install","https://github.com/kenryu42/gemini-safety-net","--consent"]]}},uninstallCommands:[["gemini","extensions","uninstall","gemini-safety-net"]]},openclaw:{beforeInstall:Xr,installCommands:()=>({commands:_a()}),uninstallCommands:[["openclaw","plugins","uninstall",A,"--force"]],postInstallMessage:["Restart the OpenClaw Gateway to apply the change.","If plugins.allow is set in openclaw.json, it must also list cc-safety-net."].join(`
218
+ `)},opencode:{beforeInstall:to,installCommands:[["opencode","plugin","-g","-f","cc-safety-net@latest"]]},pi:{installCommands:[["pi","install","npm:cc-safety-net"]],uninstallCommands:[["pi","uninstall","npm:cc-safety-net"]]}};function Tn(){return process.env.HOME??gm()}function sc(e,t=(n)=>n){try{let n=JSON.parse(t(rc(e,"utf-8")));if(!n||typeof n!=="object"||Array.isArray(n))throw Error(`Settings file ${e} must be a JSON object`);return n}catch(n){if(n instanceof SyntaxError)throw Error(`Failed to parse ${e}: ${n.message}`);throw n}}function ym(e){let t=bo(Tt(e),"settings.json");if(!ko(t))return;let n=sc(t,q),r=n.enabledPlugins;if(!r||typeof r!=="object"||Array.isArray(r))return;if(r[oe]!==!1)return;let o=rc(t,"utf-8"),i=o.replace(new RegExp(`("${oe}"\\s*:\\s*)false`),"$1true");return r[oe]=!0,_(t,i!==o?i:`${JSON.stringify(n,null,2)}
219
+ `),`Enabled ${oe} plugin in ${t}`}function Lm(e){let t=no(e);if(!ko(t))return;let n=sc(t);if(!Array.isArray(n.packages))return;let r=n.packages.find((o)=>!!o&&typeof o==="object"&&!Array.isArray(o)&&ro(o.source)&&("extensions"in o));if(!r)return;return delete r.extensions,_(t,`${JSON.stringify(n,null,2)}
220
+ `),`Enabled npm:cc-safety-net extensions in ${t}`}function ec(e,t){let n=T({label:t,booleans:Object.fromEntries(se.map((i)=>[i.target,[i.flag]]))},e),r=n.errors[0];if(r)throw Error(r);let o=se.filter((i)=>n.flags[i.target]).map((i)=>i.target);if(o.length!==1)throw Error(`Choose exactly one ${t} target: ${se.map((i)=>i.flag).join(", ")}`);return o[0]}async function ac(e=Tn(),t=tt){let[n,r,o]=await Promise.all([t(["amp","plugins","list"],30000),t(["codex","plugin","list"],30000),t(["copilot","--binary-version"])]);return{codexPluginListOutput:r,hooks:lt(process.cwd(),{homeDir:e,ampPluginListOutput:n,codexPluginListOutput:r,copilotCliVersion:o})}}async function vm(e,t=tt){let n=await ac(Tn(),t);return n.hooks.filter((r)=>e==="install"?r.configured:r.detected||r.inspectionStatus==="not-inspected").filter((r)=>r.platform!=="codex"||!xo(n.codexPluginListOutput)||oc(n.codexPluginListOutput)).map((r)=>r.platform)}function bm(e,t,n){if(t.length>0)return{finish:async()=>[ec(t,e)]};if(!n.selectTargets&&!uo(n.input,n.output))return{finish:async()=>[ec(t,e)]};let r=n.detectConfiguredTargets??(()=>vm(e,n.fetchVersion)),o=Promise.all([Ul(n.probeTargets),r()]);return{ready:o,finish:async()=>{let[i,s]=await o,a=Gl(i,{action:e,configuredTargets:s}),l=n.selectTargets?await n.selectTargets(e,nc(e,a)):await kl(e,nc(e,a),{input:n.input,output:n.output});if(l==="update")return l;if(!l||l.length===0)return null;return ho(l)}}}async function Me(e,t,n=!1,r){let o=ic[e];o.beforeInstall?.(t);let i=typeof o.installCommands==="function"?await o.installCommands(t,r):{commands:o.installCommands};return await Jr(i.commands),await Ra(i.cleanupCommands??[]),[`${i.update||n?"Updated":"Installed"} ${R(e)} integration`,o.postInstallMessage].filter(Boolean).join(`
221
+ `)}async function pt(e){let t=ic[e];if(!t.uninstallCommands)throw Error(`${R(e)} uninstall is not supported`);return await Jr(t.uninstallCommands),`Uninstalled ${R(e)} integration`}function wm(e){let t=Xa(e);return t.alreadyInstalled?`Uninstalled OpenCode plugin from ${t.path}`:`OpenCode plugin not installed in ${t.path}`}var km={"antigravity-cli":{install:Hl,uninstall:Ml},cursor:{install:da,uninstall:ua},"kimi-code":{install:Yl,uninstall:Zl}};function ft(e,t,n,r=!1){if(e==="install"&&!r)An(n);let o=km[t][e](n),i=R(t),s=e!=="install"?"Uninstalled":r?"Updated":"Installed";return e==="install"&&o.alreadyInstalled?r?`${i} hook up to date in ${o.path}`:`${i} hook already installed in ${o.path}`:e==="uninstall"&&!o.alreadyInstalled?`${i} hook not installed in ${o.path}`:`${s} ${i} hook ${e==="install"?"in":"from"} ${o.path}`}var xm={amp:{install:Il,uninstall:_l,restartNote:'Amp personal plugins apply to every Amp session, including Orb threads. Restart Amp or run "plugins: reload" to apply the change.'},"hermes-agent":{install:ya,uninstall:La,afterInstall:async(e)=>{let t=zr(e);return await ie(["hermes","plugins","enable",z,"--no-allow-tool-override"]),!t},beforeUninstall:async(e)=>{Vr(e);try{await ie(["hermes","plugins","disable",z])}catch(t){console.warn(`${t instanceof Error?t.message:String(t)}
222
+ Removing the plugin files anyway; ${z} may still be listed in the Hermes config.`)}},restartNote:"Restart Hermes to apply the change."}};async function En(e,t,n,r=!1){let o=xm[t];if(e==="uninstall")await o.beforeUninstall?.(n);let i=e==="install"?await o.install(n):await o.uninstall(n),s=e==="install"&&await o.afterInstall?.(n),a=R(t),l=!s&&(e==="install"&&i.alreadyInstalled||e==="uninstall"&&!i.alreadyInstalled);return[l?e==="install"?`${a} plugin ${r?"up to date":"already installed"} at ${i.path}`:`${a} plugin not installed at ${i.path}`:`${e!=="install"?"Uninstalled":r?"Updated":"Installed"} ${a} plugin ${e==="install"?"at":"from"} ${i.path}`,l?void 0:o.restartNote].filter(Boolean).join(`
223
+ `)}var Cm={amp:{install:(e,t)=>En("install","amp",e,t),uninstall:(e)=>En("uninstall","amp",e)},"antigravity-cli":{install:(e,t)=>ft("install","antigravity-cli",e,t),uninstall:(e)=>ft("uninstall","antigravity-cli",e)},"claude-code":{install:(e,t)=>Me("claude-code",e,t),uninstall:()=>pt("claude-code")},codex:{install:(e,t,n)=>Me("codex",e,t,n),uninstall:()=>pt("codex")},"copilot-cli":{install:async(e,t)=>[await Me("copilot-cli",e,t),ym(e)].filter(Boolean).join(`
224
+ `),uninstall:()=>pt("copilot-cli")},cursor:{install:(e,t)=>ft("install","cursor",e,t),uninstall:(e)=>ft("uninstall","cursor",e)},"gemini-cli":{install:(e,t)=>Me("gemini-cli",e,t),uninstall:()=>pt("gemini-cli")},"hermes-agent":{install:(e,t)=>{if(!t)An(e);return En("install","hermes-agent",e,t)},uninstall:(e)=>En("uninstall","hermes-agent",e)},"kimi-code":{install:(e,t)=>ft("install","kimi-code",e,t),uninstall:(e)=>ft("uninstall","kimi-code",e)},openclaw:{install:async(e,t)=>{let n=await Me("openclaw",e,t);return await Oa(),n},uninstall:(e)=>(Xr(e),pt("openclaw"))},opencode:{install:async(e,t)=>{let n=await Me("opencode",e,t);return await Wa(e),n},uninstall:(e)=>wm(e)},pi:{install:async(e,t)=>[await Me("pi",e,t),Lm(e)].filter(Boolean).join(`
225
+ `),uninstall:()=>pt("pi")}},tc=["Install CC Safety Net as a native Kimi Code plugin:",""," 1. Start Kimi Code and run: /plugins install https://github.com/kenryu42/cc-safety-net"," Confirm the trust prompt; it defaults to cancel."," 2. Run /reload, or start a new session.","","Note: Kimi Code hooks are fail-open. When the hook process cannot start, crashes, or times","out, Kimi Code allows the tool call."].join(`
226
+ `);function Sm(e){if(Ot({homeDir:e,cwd:process.cwd()}).status!=="configured")return tc;return[tc,"",h.red(["CAUTION: the global Kimi Code hook is installed and will run alongside the plugin.","After the plugin is active, remove it with: cc-safety-net uninstall --kimi-code"].join(`
227
227
  `))].join(`
228
- `)}function ec(e,t){return t.map((n)=>e==="install"&&n.target==="kimi-code"&&n.unavailableReason==="already installed"?{...n,available:!0,unavailableReason:void 0,label:`${n.label} (global hook installed)`}:n)}function Sm(e,t){if(e.selectKimiInstallMethod)return e.selectKimiInstallMethod();if(!uo(e.input,e.output))return Promise.resolve("global-hook");return vl({input:e.input,output:e.output,globalHookInstalled:_t({homeDir:t,cwd:process.cwd()}).status==="configured"})}async function sc(e,t,n,r=!1,o){return xm[t][e](n,r,o)}function Dm(e){let t=T({label:"update"},e).errors[0];if(t)throw Error(t)}async function Rm(e,t=et){let n=await ic(e,t),r=bo(Pt(e),"installed-plugins");return{targets:ho([...n.hooks.filter((i)=>i.platform!=="copilot-cli"&&i.detected).map((i)=>i.platform),...[sn,Ks,zs].flatMap((i)=>ko(bo(r,...i))?["copilot-cli"]:[]),...on(e,wo)?["claude-code"]:[],...xo(n.codexPluginListOutput)?["codex"]:[]]),codexPluginListOutput:n.codexPluginListOutput}}async function Am(e){let t=Tn(),n=e.output??process.stdout,r=Rm(t,e.fetchVersion??et).then(async(a)=>{let l=new Set(a.targets);return{targets:a.targets,codexPluginListOutput:a.codexPluginListOutput,available:new Map(await Promise.all(se.filter((c)=>l.has(c.target)&&Yl.has(c.target)).map(async(c)=>[c.target,await yo(c.probeCommand)])))}}),o=await Et(e.showBanner??!0,()=>({ready:r,finish:()=>r}),()=>At({input:e.input??process.stdin,output:n}),{loadingMessage:"Checking installed integrations…",output:n});if(o.targets.length===0)return n.write("No installed integrations found. Run `cc-safety-net install` to set one up.\n"),0;let i=o.targets.some((a)=>Zl.has(a))?await Promise.resolve().then(()=>(An(t),null)).catch((a)=>Pn(a)):null,s=await tn(Promise.all(o.targets.map((a)=>{if(Yl.has(a)&&!o.available.get(a))return Promise.resolve({message:`${R(a)} not found; skipped`,failed:!1});if(i!==null&&Zl.has(a))return Promise.resolve({message:i,failed:!0});return sc("install",a,t,!0,o.codexPluginListOutput).then((l)=>({message:l,failed:!1}),(l)=>({message:Pn(l),failed:!0}))})),{loadingMessage:`Updating ${o.targets.length} integration${o.targets.length===1?"":"s"}…`,output:n});return s.forEach((a)=>{a.failed?console.error(a.message):n.write(`${a.message}
229
- `)}),s.some((a)=>a.failed)?1:0}function Co(e,t={}){return Promise.resolve().then(()=>Dm(e)).then(()=>Am(t)).catch((n)=>(console.error(Pn(n)),1))}async function Mt(e,t,n={}){try{let r=await Et(!0,()=>vm(e,t,n),()=>At({input:n.input??process.stdin,output:n.output??process.stdout}),{loadingMessage:e==="install"?"Checking available integrations…":"Checking installed integrations…",output:n.output??process.stdout});if(!r)return(n.output??process.stdout).write(`Cancelled: nothing was ${e}ed.
230
- `),0;if(r==="update")return(n.runUpdate??(()=>Co([],{fetchVersion:n.fetchVersion,input:n.input,output:n.output,showBanner:!1})))();let o=Tn(),i=n.output??process.stdout;return await Hl(r,async(s)=>{if(s==="kimi-code"&&e==="install"){let l=await Sm(n,o);if(l===null){i.write(`Cancelled: Kimi Code integration was not installed.
231
- `);return}if(l==="plugin"){i.write(`${Cm(o)}
232
- `);return}}let a=await tn(sc(e,s,o),{loadingMessage:`${e==="install"?"Installing":"Uninstalling"} ${R(s)} integration…`,output:i});i.write(`${a}
228
+ `)}function nc(e,t){return t.map((n)=>e==="install"&&n.target==="kimi-code"&&n.unavailableReason==="already installed"?{...n,available:!0,unavailableReason:void 0,label:`${n.label} (global hook installed)`}:n)}function Dm(e,t){if(e.selectKimiInstallMethod)return e.selectKimiInstallMethod();if(!uo(e.input,e.output))return Promise.resolve("global-hook");return wl({input:e.input,output:e.output,globalHookInstalled:Ot({homeDir:t,cwd:process.cwd()}).status==="configured"})}async function lc(e,t,n,r=!1,o){return Cm[t][e](n,r,o)}function Rm(e){let t=T({label:"update"},e).errors[0];if(t)throw Error(t)}async function Am(e,t=tt){let n=await ac(e,t),r=bo(Tt(e),"installed-plugins");return{targets:ho([...n.hooks.filter((i)=>i.platform!=="copilot-cli"&&i.detected).map((i)=>i.platform),...[sn,Js,Ws].flatMap((i)=>ko(bo(r,...i))?["copilot-cli"]:[]),...on(e,wo)?["claude-code"]:[],...xo(n.codexPluginListOutput)?["codex"]:[]]),codexPluginListOutput:n.codexPluginListOutput}}async function Em(e){let t=Tn(),n=e.output??process.stdout,r=Am(t,e.fetchVersion??tt).then(async(a)=>{let l=new Set(a.targets);return{targets:a.targets,codexPluginListOutput:a.codexPluginListOutput,available:new Map(await Promise.all(se.filter((c)=>l.has(c.target)&&Xl.has(c.target)).map(async(c)=>[c.target,await yo(c.probeCommand)])))}}),o=await Pt(e.showBanner??!0,()=>({ready:r,finish:()=>r}),()=>Et({input:e.input??process.stdin,output:n}),{loadingMessage:"Checking installed integrations…",output:n});if(o.targets.length===0)return n.write("No installed integrations found. Run `cc-safety-net install` to set one up.\n"),0;let i=o.targets.some((a)=>Ql.has(a))?await Promise.resolve().then(()=>(An(t),null)).catch((a)=>Pn(a)):null,s=await tn(Promise.all(o.targets.map((a)=>{if(Xl.has(a)&&!o.available.get(a))return Promise.resolve({message:`${R(a)} not found; skipped`,failed:!1});if(i!==null&&Ql.has(a))return Promise.resolve({message:i,failed:!0});return lc("install",a,t,!0,o.codexPluginListOutput).then((l)=>({message:l,failed:!1}),(l)=>({message:Pn(l),failed:!0}))})),{loadingMessage:`Updating ${o.targets.length} integration${o.targets.length===1?"":"s"}…`,output:n});return s.forEach((a)=>{a.failed?console.error(a.message):n.write(`${a.message}
229
+ `)}),s.some((a)=>a.failed)?1:0}function Co(e,t={}){return Promise.resolve().then(()=>Rm(e)).then(()=>Em(t)).catch((n)=>(console.error(Pn(n)),1))}async function jt(e,t,n={}){try{let r=await Pt(!0,()=>bm(e,t,n),()=>Et({input:n.input??process.stdin,output:n.output??process.stdout}),{loadingMessage:e==="install"?"Checking available integrations…":"Checking installed integrations…",output:n.output??process.stdout});if(!r)return(n.output??process.stdout).write(`Cancelled: nothing was ${e}ed.
230
+ `),0;if(r==="update")return(n.runUpdate??(()=>Co([],{fetchVersion:n.fetchVersion,input:n.input,output:n.output,showBanner:!1})))();let o=Tn(),i=n.output??process.stdout;return await jl(r,async(s)=>{if(s==="kimi-code"&&e==="install"){let l=await Dm(n,o);if(l===null){i.write(`Cancelled: Kimi Code integration was not installed.
231
+ `);return}if(l==="plugin"){i.write(`${Sm(o)}
232
+ `);return}}let a=await tn(lc(e,s,o),{loadingMessage:`${e==="install"?"Installing":"Uninstalling"} ${R(s)} integration…`,output:i});i.write(`${a}
233
233
  `)}),0}catch(r){return console.error(Pn(r)),1}}function Pn(e){let t=e instanceof Error?e.message:String(e),n=typeof e==="object"&&e!==null&&"code"in e?e.code:null;if(n==="EACCES"||n==="EPERM")return`${t}
234
234
  Check file permissions for the target config file and parent directory.`;if(n==="ENOENT")return`${t}
235
235
  Check that the target config path and parent directory exist.`;if(n==="ENOTDIR")return`${t}
236
- Check that every parent path component is a directory.`;return t}import{join as pg}from"node:path";var ac="# Custom Rules Reference\n\nAgent reference for generating CC Safety Net rulebook configuration.\n\n## Config Locations\n\n| Scope | Config path | Rulebook path | Cache path | Priority |\n|-------|-------------|---------------|------------|----------|\n| User | `~/.cc-safety-net/rules/rule.json` | `~/.cc-safety-net/rules/<rulebook-name>/rulebook.json` | `~/.cc-safety-net/cache/rulebooks/` | First |\n| Project | `.cc-safety-net/rules/rule.json` | `.cc-safety-net/rules/<rulebook-name>/rulebook.json` | `.cc-safety-net/cache/rulebooks/` | Second |\n| GitHub source | Listed in a local `rule.json` | `.cc-safety-net/rules/<rulebook-name>/rulebook.json` in the source repository | Consumer local cache | Source order |\n\nUser scope is evaluated before project scope; within a scope, sources apply in `rules` array order. A duplicate active rulebook name keeps the first claim and ignores the later rulebook with a warning, so a user-scoped name shadows a project-scoped one.\n\nUse `cc-safety-net rule init` to create an inert local config. Use `--global` for user scope. Use `cc-safety-net rule init --example` to also create an inactive example rulebook. `CC_SAFETY_NET_HOME` overrides the `~/.cc-safety-net` user root.\n\nLegacy inline `.safety-net.json` and `~/.cc-safety-net/config.json` files are not loaded at runtime. Convert them with `cc-safety-net rule migrate`.\n\n## rule.json Schema\n\n```json\n{\n \"version\": 1,\n \"rules\": [\"project-rules\", \"owner/repo#main/team-rules\"],\n \"overrides\": {\n \"project-rules/block-docker-system-prune\": {\n \"reason\": \"Use targeted Docker cleanup commands.\"\n },\n \"team-rules/block-npm-global\": \"off\"\n },\n \"transparent_wrappers\": [\"rtk\"]\n}\n```\n\n- `version`: Required. Must be `1`.\n- `$schema`: Optional. `cc-safety-net rule verify` inserts it into a valid `rule.json` that lacks it.\n- `rules`: Optional array of rulebook source strings. Missing `rules` is treated as `[]`.\n- `overrides`: Optional object keyed by `<rulebook-name>/<rule-name>`.\n- `overrides` values are either `\"off\"` to disable a rule or an object with a required `reason` (replacement block reason) and an optional `intent` (one of `hard_stop`, `use_alternative`, `scope_down`, `manual_only`, `stop_and_explain`).\n- A project override cannot target a user-scoped rule: only that override is ignored, the user rule keeps its configured state, and `rule sync`/`rule verify` report the diagnostic as a failure.\n- `transparent_wrappers`: Optional array of command names that transparently execute a visible child command.\n- Transparent wrappers have no built-in defaults. Configure only wrappers you intentionally trust, such as `\"rtk\"`.\n- Use `cc-safety-net rule wrapper add rtk` to configure RTK without manually editing `rule.json`.\n\n## Rulebook Sources\n\n- Local sources are bare rulebook names such as `project-rules`; the rulebook file is `.cc-safety-net/rules/project-rules/rulebook.json`.\n- GitHub sources use `owner/repo#ref/<rulebook-name>`.\n- GitHub refs must be one path segment, such as a tag, SHA, or branch name without `/`.\n- The GitHub source name, the repository directory name, and the rulebook `name` must match exactly.\n- Rulebook source strings must be unique in a config.\n\n## rulebook.json Schema\n\n```json\n{\n \"rulebook_version\": 1,\n \"name\": \"project-rules\",\n \"version\": \"1.0.0\",\n \"description\": \"Project-specific CC Safety Net rules.\",\n \"author\": \"project\",\n \"allowed_commands\": [\"docker\"],\n \"rules\": [\n {\n \"name\": \"block-docker-system-prune\",\n \"command\": \"docker\",\n \"subcommand\": \"system\",\n \"block_args\": [\"prune\"],\n \"reason\": \"Use targeted cleanup instead.\"\n }\n ],\n \"tests\": [\n {\n \"command\": \"docker system prune\",\n \"expect\": \"blocked\",\n \"rule\": \"block-docker-system-prune\"\n },\n {\n \"command\": \"docker ps\",\n \"expect\": \"allowed\"\n }\n ]\n}\n```\n\n### Rulebook Fields\n\n| Field | Required | Constraints |\n|-------|----------|-------------|\n| `rulebook_version` | Yes | Must be `1` |\n| `name` | Yes | `^[a-zA-Z][a-zA-Z0-9_-]{0,63}$` |\n| `version` | Yes | Non-empty string |\n| `description` | No | Free text; not type-checked at runtime |\n| `author` | No | Free text; not type-checked at runtime |\n| `allowed_commands` | Yes | Unique command names matching `^[a-zA-Z][a-zA-Z0-9_-]*$` |\n| `rules` | Yes | Array of rule objects |\n| `tests` | No | Array of fixtures |\n\n### Rule Fields\n\n| Field | Required | Constraints |\n|-------|----------|-------------|\n| `name` | Yes | Unique within the rulebook (case-insensitive); same pattern as rulebook `name` |\n| `command` | Yes | Must be listed in `allowed_commands`; basename only, not path |\n| `subcommand` | No | Same pattern as `command`; omit to match any subcommand |\n| `intent` | No | One of `hard_stop`, `use_alternative`, `scope_down`, `manual_only`, `stop_and_explain` |\n| `block_args` | Yes | Non-empty array of non-empty strings |\n| `reason` | Yes | Non-empty string, max 256 chars |\n\n### Test Fixture Fields\n\n| Field | Required | Constraints |\n|-------|----------|-------------|\n| `command` | Yes | Non-empty shell command string |\n| `expect` | Yes | `\"blocked\"` or `\"allowed\"` |\n| `rule` | Required for blocked fixtures | Rule name expected to block the command |\n\nFixtures are optional documentation of intended behavior. Fixtures are shape-validated only; CC Safety Net does not execute them.\n\n## Matching Behavior\n\n- **Command**: Normalized to lowercase basename with any trailing `.exe` removed (`/usr/bin/git` → `git`).\n- **Subcommand**: The first command token after recognized Git and Docker global options and their values; `--` ends option parsing. An unrecognized option without `=` may consume the following token as its value.\n- **Arguments**: Each `block_args` value is compared literally against every command token, including expanded short options. The command is blocked if **any** item matches.\n- **Short options**: Expanded (`-Ap` matches `-A`).\n- **Long options**: Exact match (`--all-files` does not match `--all`).\n- **Execution order**: Built-in rules first, then custom rulebooks. Custom rules only add restrictions.\n- **Transparent wrappers**: A configured wrapper such as `rtk` lets `rtk git commit` be analyzed as `git commit` only when `git` is protected by built-in analyzers or active custom rules. `rtk -- git commit` is also supported.\n\n## Workflow\n\n1. Run `cc-safety-net rule init` or create `rule.json` manually.\n2. Optionally run `cc-safety-net rule init --example` to create an inactive example rulebook.\n3. Use `cc-safety-net rule wrapper add rtk` for trusted transparent wrappers.\n4. Run `cc-safety-net rule add <source>` after creating or choosing a rulebook source; it adds the source and syncs it.\n5. Run `cc-safety-net rule sync` after manual `rule.json` changes or local rulebook edits.\n6. Run `cc-safety-net rule verify` to validate config, lock/cache state, local rulebooks, and shareable GitHub-source rulebook directories in the current repository (it does not fetch remote content).\n7. Run `cc-safety-net rule list` to inspect active rulebooks and transparent wrappers.\n\nAn edited or invalid local rulebook keeps its last synced, digest-verified cached version enforced until `cc-safety-net rule sync` validates the edit. A missing lock entry or cache, a cache digest mismatch, or an invalid cached rulebook makes that source inactive; a missing lockfile or an unreadable or invalid `rule.json` makes every source in its scope inactive. Inactive sources stop applying their rules while other custom rules and all built-in protections stay active. Repair the reported condition, then run `cc-safety-net rule sync`. Run `cc-safety-net status` to see degraded sources.\n";function jt(e,t){if(!e.ok){Im(e);return}_m(e),console.log(t),console.log("Rule config synced."),console.log(""),Em(e.entries)}function Em(e){if(e.length===0){console.log("Active rulebooks: (none)");return}console.log(`Active rulebooks (${e.length}):`);for(let t of e)console.log(` - ${t.name} ${t.version} (${Pm(t.ruleCount??0)})`),console.log(` Source: ${ir(t)}`)}function Pm(e){return`${e} ${e===1?"rule":"rules"}`}function cc(e,t){Me("Active sources",e.rulebooks,(n)=>[`[${n.source}] ${n.name} ${n.version}`,` Source: ${t[n.source].get(n.spec)??n.spec}`]),Me("Active rules",e.rules,(n)=>[`[${Tm(e,n.name)}] ${n.name}`,` Command: ${n.subcommand?`${n.command} ${n.subcommand}`:n.command}`,` Block args: ${n.block_args.join(", ")}`,` Reason: ${n.reason}`]),Me("Disabled rules",lc(e,"off"),(n)=>[n.key]),Me("Reason overrides",lc(e,"reason"),(n)=>[n.key,` Reason: ${n.value.reason}`]),Me("Transparent wrappers",e.transparent_wrappers,(n)=>[n]),Me("Issues",e.errors,(n)=>[n]),Me("Warnings",e.warnings,(n)=>[n])}function Me(e,t,n){if(t.length===0){console.log(`${e}: (none)`);return}console.log(`${e} (${t.length}):`);for(let r of t){let[o,...i]=n(r);console.log(` - ${o}`);for(let s of i)console.log(` ${s}`)}}function Tm(e,t){return e.rulebooks.find((n)=>n.rules.includes(t))?.source??"project"}function lc(e,t){return Object.entries({...e.userConfig?.overrides??{},...e.projectConfig?.overrides??{}}).filter((n)=>{if(t==="off")return n[1]==="off";return!!n[1]&&typeof n[1]==="object"}).map(([n,r])=>({key:n,value:r}))}function Im(e){for(let t of e.errors)console.error(t)}function _m(e){if(!e.warnings||e.warnings.length===0)return;for(let t of e.warnings)console.warn(t)}import{dirname as dc,join as In}from"node:path";var Om=".safety-net.json",$m="~/.cc-safety-net/config.json";async function fc(e){return[await uc({legacyPath:pc({cwd:e.cwd}),configPath:X(e.cwd),defaultRulebookName:"project-rules",migratedFrom:Om,cleanup:e.cleanup,syncOptions:{cwd:e.cwd}}),await uc({legacyPath:ht(),configPath:Q(),defaultRulebookName:"user-rules",migratedFrom:$m,cleanup:e.cleanup,syncOptions:{cwd:e.cwd,global:!0}})].every((n)=>n)?0:1}async function uc(e){let t=J(e.syncOptions),n=C(t.filesystemScope,e.legacyPath),r=w(n);if(r===null)return console.log(`No legacy config found at ${e.legacyPath}`),!0;let o=Fm(r);if(!o.ok){for(let g of o.errors)console.error(g);return!1}let i=Y(t.configTarget);if(i.errors.length>0){for(let g of i.errors)console.error(g);return!1}let s=i.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},a=Hm(dc(e.configPath),s.rules,e.defaultRulebookName,e.migratedFrom,t.filesystemScope),l=In(dc(e.configPath),a,"rulebook.json"),c=C(t.filesystemScope,l),d=[So(t.configTarget),So(c),So(t.lockTarget)],p=await Nm(e,t.configTarget,c,a,o.config.rules,s.rules.includes(a)?s.rules:[...s.rules,a],s.overrides??{},s.transparent_wrappers??[]);if(!p.ok){Um(d);for(let g of p.errors)console.error(g);return!1}if(!e.cleanup)return console.log(`Migrated legacy config at ${e.legacyPath}. Legacy file is no longer used.`),!0;if(!jm(t.configTarget,c,a,e.migratedFrom,o.config.rules))return console.error(`Migration cleanup verification failed for ${e.legacyPath}`),!1;return mt(n),console.log(`Deleted legacy config at ${e.legacyPath}`),!0}async function Nm(e,t,n,r,o,i,s,a){try{return Z(t,{version:1,rules:i,overrides:s,transparent_wrappers:a}),Z(n,Mm(r,e.migratedFrom,o)),await ze(e.syncOptions)}catch(l){return{ok:!1,errors:[l instanceof Error?l.message:String(l)]}}}function Fm(e){try{let t=JSON.parse(e),n=zn(t);if(n.errors.length>0)return{ok:!1,errors:n.errors};return{ok:!0,config:{version:1,rules:t.rules??[]}}}catch{return{ok:!1,errors:["Invalid JSON"]}}}function Hm(e,t,n,r,o){let i=t.find((s)=>Gm(C(o,In(e,s,"rulebook.json")))===r);if(i)return i;if(w(C(o,In(e,n,"rulebook.json")))===null)return n;for(let s=2;;s++){let a=`${n}-${s}`;if(w(C(o,In(e,a,"rulebook.json")))===null)return a}}function Mm(e,t,n){return{rulebook_version:1,name:e,version:"1.0.0",description:"Migrated CC Safety Net rules.",author:"project",migrated_from:t,allowed_commands:[...new Set(n.map((r)=>r.command))],rules:n,tests:n.map((r)=>({command:[r.command,r.subcommand,r.block_args[0]].filter(Boolean).join(" "),expect:"blocked",rule:r.name}))}}function jm(e,t,n,r,o){if(!Y(e).config?.rules.includes(n))return!1;try{let s=w(t);if(s===null)return!1;let a=JSON.parse(s);return a.migrated_from===r&&JSON.stringify(a.rules)===JSON.stringify(o)}catch{return!1}}function So(e){return{target:e,content:w(e)}}function Um(e){for(let t of e){if(t.content===null){mt(t.target);continue}ke(t.target,t.content)}}function Gm(e){let t=w(e);if(t===null)return null;try{let n=JSON.parse(t);return typeof n.migrated_from==="string"?n.migrated_from:null}catch{return null}}import{mkdir as Bm,readFile as qm,writeFile as Vm}from"node:fs/promises";import{dirname as zm,join as Km}from"node:path";var Wm=86400000,Jm=604800000;async function gc(e=Date.now()){if(process.env.CC_SAFETY_NET_NO_UPDATE_CHECK)return null;let t=lr();if(!t)return null;let n=Km(t,".cc-safety-net","update-check.json"),r=await Ym(n,e);if(!r.lastCheck||e-r.lastCheck>Wm){let s=await tt();if(r.lastCheck=e,s.latestVersion)r.latestVersion=s.latestVersion;if(!await mc(n,r))return null;if(s.error)return null}let o=r.latestVersion,i=P();if(!o||!Rr(o,i))return null;if(r.notifiedVersion===o&&r.notifiedAt!==void 0&&e-r.notifiedAt<Jm)return null;if(r.notifiedVersion=o,r.notifiedAt=e,!await mc(n,r))return null;return`UPDATE_AVAILABLE: cc-safety-net v${o} is available (running v${i}). Ask the user once whether to run \`npx -y cc-safety-net@latest update\`; continue the current task either way and do not raise this again.`}async function Ym(e,t){let n=await qm(e,"utf8").then((i)=>JSON.parse(i)).catch(()=>{return});if(!n||typeof n!=="object"||Array.isArray(n))return{};let r=n,o=(i)=>typeof i==="number"&&Number.isFinite(i)&&i<=t?i:void 0;return{lastCheck:o(r.lastCheck),latestVersion:typeof r.latestVersion==="string"?r.latestVersion:void 0,notifiedVersion:typeof r.notifiedVersion==="string"?r.notifiedVersion:void 0,notifiedAt:o(r.notifiedAt)}}async function mc(e,t){return Bm(zm(e),{recursive:!0,mode:448}).then(()=>Vm(e,JSON.stringify(t),{mode:384})).then(()=>!0).catch(()=>!1)}import{dirname as Zm,join as Xm,resolve as Do}from"node:path";var yc="CC Safety Net Config",Qm="═".repeat(yc.length),eg="https://raw.githubusercontent.com/kenryu42/cc-safety-net/main/assets/cc-safety-net.schema.json",tg=new Set(["rule.json","rule.lock","cache"]);function Lc(e={}){try{return ng(e)}catch(t){if(t instanceof N)return console.error(t.message),1;throw t}}function ng(e){let t=e.cwd??process.cwd(),n=e.userConfigPath??Q(),r=e.projectConfigPath??X(t),o=e.legacyUserConfigPath??ht(),i=e.legacyProjectConfigPath??Jo(t),s=Do(t,or),a=Zm(n),l=ee({cwd:t,userConfigPath:n,projectConfigPath:r}),c=ee({cwd:t}),d=C(l.userScope,n),p=C(l.projectScope,r),g=e.legacyUserConfigPath?ft(e.legacyUserConfigPath,"user policy"):C(c.userScope,o),u=e.legacyProjectConfigPath?ft(e.legacyProjectConfigPath,"project policy"):C(c.projectScope,i),m=!1,f=!1,L=[],v=[],k=rg(C(c.projectScope,s));if(ig(),w(d)!==null){let y=le(d);if(y.errors.push(...ce(n,Ke({userConfigDir:a}),{userConfigDir:a},l.userScope)),L.push({scope:"User",path:n,result:y,schema:"rules",sourceDisplayMap:xe(n,l.userScope),target:d}),y.errors.length>0)m=!0}if(w(g)!==null)if(f=!0,w(d)!==null)v.push(_n("user","cleanup"));else{let y=Kn(g);if(L.push({scope:"User",path:o,result:y,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:g}),v.push(_n("user",y.errors.length>0?"fix-or-delete":"migrate")),y.errors.length>0)m=!0}if(w(p)!==null){let y=le(p);if(y.errors.push(...ce(r,We(r),{userConfigDir:a},l.projectScope)),L.push({scope:"Project",path:Do(r),result:y,schema:"rules",sourceDisplayMap:xe(r,l.projectScope),target:p}),y.errors.length>0)m=!0;if(w(u)!==null)f=!0,v.push(_n("project","cleanup"))}else if(w(u)!==null){f=!0,m=!0;let y=Kn(u);L.push({scope:"Project",path:Do(i),result:y,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:u}),v.push(_n("project",y.errors.length>0?"fix-or-delete":"migrate"))}if(k?.result.errors.length)m=!0;if(L.length===0&&!k)return console.log(`
237
- No config files found. Using built-in rules only.`),0;for(let y of L)if(y.inactive)ag(y.scope,y.path,y.result,y.sourceDisplayMap);else if(y.result.errors.length>0)lg(y.scope,y.path,y.result.errors);else{if(y.schema==="rules"&&ug(y.target))console.log(`
238
- Added $schema to ${y.scope.toLowerCase()} config.`);sg(y.scope,y.path,y.result,y.schema,y.sourceDisplayMap)}for(let y of v)console.error(`
239
- ${h.red(y)}`);if(k)if(k.result.errors.length>0)dg(k.path,k.result.errors);else cg(k.path,k.result);if(m)return console.error(`
236
+ Check that every parent path component is a directory.`;return t}import{join as fg}from"node:path";var cc="# 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 Ut(e,t){if(!e.ok){_m(e);return}Om(e),console.log(t),console.log("Rule config synced."),console.log(""),Pm(e.entries)}function Pm(e){if(e.length===0){console.log("Active rulebooks: (none)");return}console.log(`Active rulebooks (${e.length}):`);for(let t of e)console.log(` - ${t.name} ${t.version} (${Tm(t.ruleCount??0)})`),console.log(` Source: ${ir(t)}`)}function Tm(e){return`${e} ${e===1?"rule":"rules"}`}function uc(e,t){je("Active sources",e.rulebooks,(n)=>[`[${n.source}] ${n.name} ${n.version}`,` Source: ${t[n.source].get(n.spec)??n.spec}`]),je("Active rules",e.rules,(n)=>[`[${Im(e,n.name)}] ${n.name}`,` Command: ${n.subcommand?`${n.command} ${n.subcommand}`:n.command}`,` Block args: ${n.block_args.join(", ")}`,` Reason: ${n.reason}`]),je("Disabled rules",dc(e,"off"),(n)=>[n.key]),je("Reason overrides",dc(e,"reason"),(n)=>[n.key,` Reason: ${n.value.reason}`]),je("Transparent wrappers",e.transparent_wrappers,(n)=>[n]),je("Issues",e.errors,(n)=>[n]),je("Warnings",e.warnings,(n)=>[n])}function je(e,t,n){if(t.length===0){console.log(`${e}: (none)`);return}console.log(`${e} (${t.length}):`);for(let r of t){let[o,...i]=n(r);console.log(` - ${o}`);for(let s of i)console.log(` ${s}`)}}function Im(e,t){return e.rulebooks.find((n)=>n.rules.includes(t))?.source??"project"}function dc(e,t){return Object.entries({...e.userConfig?.overrides??{},...e.projectConfig?.overrides??{}}).filter((n)=>{if(t==="off")return n[1]==="off";return!!n[1]&&typeof n[1]==="object"}).map(([n,r])=>({key:n,value:r}))}function _m(e){for(let t of e.errors)console.error(t)}function Om(e){if(!e.warnings||e.warnings.length===0)return;for(let t of e.warnings)console.warn(t)}import{dirname as pc,join as In}from"node:path";var $m=".safety-net.json",Nm="~/.cc-safety-net/config.json";async function gc(e){return[await fc({legacyPath:mc({cwd:e.cwd}),configPath:X(e.cwd),defaultRulebookName:"project-rules",migratedFrom:$m,cleanup:e.cleanup,syncOptions:{cwd:e.cwd}}),await fc({legacyPath:yt(),configPath:Q(),defaultRulebookName:"user-rules",migratedFrom:Nm,cleanup:e.cleanup,syncOptions:{cwd:e.cwd,global:!0}})].every((n)=>n)?0:1}async function fc(e){let t=J(e.syncOptions),n=k(t.filesystemScope,e.legacyPath),r=w(n);if(r===null)return console.log(`No legacy config found at ${e.legacyPath}`),!0;let o=Hm(r);if(!o.ok){for(let g of o.errors)console.error(g);return!1}let i=Y(t.configTarget);if(i.errors.length>0){for(let g of i.errors)console.error(g);return!1}let s=i.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},a=Mm(pc(e.configPath),s.rules,e.defaultRulebookName,e.migratedFrom,t.filesystemScope),l=In(pc(e.configPath),a,"rulebook.json"),c=k(t.filesystemScope,l),d=[So(t.configTarget),So(c),So(t.lockTarget)],p=await Fm(e,t.configTarget,c,a,o.config.rules,s.rules.includes(a)?s.rules:[...s.rules,a],s.overrides??{},s.transparent_wrappers??[]);if(!p.ok){Gm(d);for(let g of p.errors)console.error(g);return!1}if(!e.cleanup)return console.log(`Migrated legacy config at ${e.legacyPath}. Legacy file is no longer used.`),!0;if(!Um(t.configTarget,c,a,e.migratedFrom,o.config.rules))return console.error(`Migration cleanup verification failed for ${e.legacyPath}`),!1;return ze(n),console.log(`Deleted legacy config at ${e.legacyPath}`),!0}async function Fm(e,t,n,r,o,i,s,a){try{return Z(t,{version:1,rules:i,overrides:s,transparent_wrappers:a}),Z(n,jm(r,e.migratedFrom,o)),await Ke(e.syncOptions)}catch(l){return{ok:!1,errors:[l instanceof Error?l.message:String(l)]}}}function Hm(e){try{let t=JSON.parse(e),n=zn(t);if(n.errors.length>0)return{ok:!1,errors:n.errors};return{ok:!0,config:{version:1,rules:t.rules??[]}}}catch{return{ok:!1,errors:["Invalid JSON"]}}}function Mm(e,t,n,r,o){let i=t.find((s)=>Bm(k(o,In(e,s,"rulebook.json")))===r);if(i)return i;if(w(k(o,In(e,n,"rulebook.json")))===null)return n;for(let s=2;;s++){let a=`${n}-${s}`;if(w(k(o,In(e,a,"rulebook.json")))===null)return a}}function jm(e,t,n){return{rulebook_version:1,name:e,version:"1.0.0",description:"Migrated CC Safety Net rules.",author:"project",migrated_from:t,allowed_commands:[...new Set(n.map((r)=>r.command))],rules:n,tests:n.map((r)=>({command:[r.command,r.subcommand,r.block_args[0]].filter(Boolean).join(" "),expect:"blocked",rule:r.name}))}}function Um(e,t,n,r,o){if(!Y(e).config?.rules.includes(n))return!1;try{let s=w(t);if(s===null)return!1;let a=JSON.parse(s);return a.migrated_from===r&&JSON.stringify(a.rules)===JSON.stringify(o)}catch{return!1}}function So(e){return{target:e,content:w(e)}}function Gm(e){for(let t of e){if(t.content===null){ze(t.target);continue}ke(t.target,t.content)}}function Bm(e){let t=w(e);if(t===null)return null;try{let n=JSON.parse(t);return typeof n.migrated_from==="string"?n.migrated_from:null}catch{return null}}import{mkdir as qm,readFile as Vm,writeFile as zm}from"node:fs/promises";import{dirname as Km,join as Wm}from"node:path";var Jm=86400000,Ym=604800000;async function yc(e=Date.now()){if(process.env.CC_SAFETY_NET_NO_UPDATE_CHECK)return null;let t=lr();if(!t)return null;let n=Wm(t,".cc-safety-net","update-check.json"),r=await Zm(n,e);if(!r.lastCheck||e-r.lastCheck>Jm){let s=await nt();if(r.lastCheck=e,s.latestVersion)r.latestVersion=s.latestVersion;if(!await hc(n,r))return null;if(s.error)return null}let o=r.latestVersion,i=P();if(!o||!Rr(o,i))return null;if(r.notifiedVersion===o&&r.notifiedAt!==void 0&&e-r.notifiedAt<Ym)return null;if(r.notifiedVersion=o,r.notifiedAt=e,!await hc(n,r))return null;return`UPDATE_AVAILABLE: cc-safety-net v${o} is available (running v${i}). Ask the user once whether to run \`npx -y cc-safety-net@latest update\`; continue the current task either way and do not raise this again.`}async function Zm(e,t){let n=await Vm(e,"utf8").then((i)=>JSON.parse(i)).catch(()=>{return});if(!n||typeof n!=="object"||Array.isArray(n))return{};let r=n,o=(i)=>typeof i==="number"&&Number.isFinite(i)&&i<=t?i:void 0;return{lastCheck:o(r.lastCheck),latestVersion:typeof r.latestVersion==="string"?r.latestVersion:void 0,notifiedVersion:typeof r.notifiedVersion==="string"?r.notifiedVersion:void 0,notifiedAt:o(r.notifiedAt)}}async function hc(e,t){return qm(Km(e),{recursive:!0,mode:448}).then(()=>zm(e,JSON.stringify(t),{mode:384})).then(()=>!0).catch(()=>!1)}import{dirname as Xm,join as Qm,resolve as Do}from"node:path";var vc="CC Safety Net Config",eg="═".repeat(vc.length),tg="https://raw.githubusercontent.com/kenryu42/cc-safety-net/main/assets/cc-safety-net.schema.json",ng=new Set(["rule.json","rule.lock","cache"]);function bc(e={}){try{return rg(e)}catch(t){if(t instanceof N)return console.error(t.message),1;throw t}}function rg(e){let t=e.cwd??process.cwd(),n=e.userConfigPath??Q(),r=e.projectConfigPath??X(t),o=e.legacyUserConfigPath??yt(),i=e.legacyProjectConfigPath??Jo(t),s=Do(t,or),a=Xm(n),l=ee({cwd:t,userConfigPath:n,projectConfigPath:r}),c=ee({cwd:t}),d=k(l.userScope,n),p=k(l.projectScope,r),g=e.legacyUserConfigPath?mt(e.legacyUserConfigPath,"user policy"):k(c.userScope,o),u=e.legacyProjectConfigPath?mt(e.legacyProjectConfigPath,"project policy"):k(c.projectScope,i),m=!1,f=!1,L=[],v=[],x=og(k(c.projectScope,s));if(sg(),w(d)!==null){let y=le(d);if(y.errors.push(...ce(n,We({userConfigDir:a}),{userConfigDir:a},l.userScope)),L.push({scope:"User",path:n,result:y,schema:"rules",sourceDisplayMap:Ce(n,l.userScope),target:d}),y.errors.length>0)m=!0}if(w(g)!==null)if(f=!0,w(d)!==null)v.push(_n("user","cleanup"));else{let y=Kn(g);if(L.push({scope:"User",path:o,result:y,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:g}),v.push(_n("user",y.errors.length>0?"fix-or-delete":"migrate")),y.errors.length>0)m=!0}if(w(p)!==null){let y=le(p);if(y.errors.push(...ce(r,Je(r),{userConfigDir:a},l.projectScope)),L.push({scope:"Project",path:Do(r),result:y,schema:"rules",sourceDisplayMap:Ce(r,l.projectScope),target:p}),y.errors.length>0)m=!0;if(w(u)!==null)f=!0,v.push(_n("project","cleanup"))}else if(w(u)!==null){f=!0,m=!0;let y=Kn(u);L.push({scope:"Project",path:Do(i),result:y,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:u}),v.push(_n("project",y.errors.length>0?"fix-or-delete":"migrate"))}if(x?.result.errors.length)m=!0;if(L.length===0&&!x)return console.log(`
237
+ No config files found. Using built-in rules only.`),0;for(let y of L)if(y.inactive)lg(y.scope,y.path,y.result,y.sourceDisplayMap);else if(y.result.errors.length>0)cg(y.scope,y.path,y.result.errors);else{if(y.schema==="rules"&&pg(y.target))console.log(`
238
+ Added $schema to ${y.scope.toLowerCase()} config.`);ag(y.scope,y.path,y.result,y.schema,y.sourceDisplayMap)}for(let y of v)console.error(`
239
+ ${h.red(y)}`);if(x)if(x.result.errors.length>0)ug(x.path,x.result.errors);else dg(x.path,x.result);if(m)return console.error(`
240
240
  Config validation failed.`),1;return console.log(f?`
241
241
  Configs valid with warnings.`:`
242
- All configs valid.`),0}function _n(e,t){let n=`legacy ${e} config`;if(t==="cleanup")return`Warning: Legacy ${e} config is no longer needed. Run \`npx -y cc-safety-net rule migrate --cleanup\` to clean it up safely.`;if(t==="migrate")return`Warning: Legacy ${e} config is ignored by CC Safety Net. Run \`npx -y cc-safety-net rule migrate\`.`;return`Warning: Legacy ${e} config is no longer supported. Fix or delete the ${n}, then run \`npx -y cc-safety-net rule migrate\`.`}function rg(e){if(Ve(e)===null)return null;let t=og(e);if(t.ruleNames.size===0&&t.errors.length===0)return null;return{path:e.path,result:t}}function og(e){let t=[],n=new Set,r=(Ve(e)??[]).filter((o)=>!tg.has(o.name)).sort((o,i)=>o.name.localeCompare(i.name));if(r.length===0)return{errors:t,ruleNames:n};for(let o of r){if(!gt.test(o.name)){t.push(`rulebook directory names must match ${gt}: ${o.name}`);continue}if(o.kind!=="directory"){t.push(`${o.name} must be a rulebook directory`);continue}let i=C(e.scope,Xm(e.path,o.name,"rulebook.json")),s=w(i);if(s===null){t.push(`${o.name}/rulebook.json is required`);continue}try{let a;try{a=JSON.parse(s)}catch{t.push(`${o.name}/rulebook.json: invalid JSON`);continue}let l=hc(a);if(l.name!==o.name){t.push(`rulebook name "${l.name}" must match folder "${o.name}"`);continue}n.add(o.name)}catch(a){t.push(a instanceof Error?`${o.name}/rulebook.json: ${a.message}`:`${o.name}/rulebook.json: ${String(a)}`)}}return{errors:t,ruleNames:n}}function ig(){console.log(yc),console.log(Qm)}function sg(e,t,n,r,o){if(console.log(`
243
- ✓ ${e} config: ${t}`),console.log(` Schema: ${r==="rules"?"rulebook sources":"legacy inline rules"}`),n.ruleNames.size>0){console.log(` ${r==="rules"?"Sources":"Rules"}:`);let i=1;for(let s of n.ruleNames)console.log(` ${i}. ${o.get(s)??s}`),i++}else console.log(` ${r==="rules"?"Sources":"Rules"}: (none)`)}function ag(e,t,n,r){if(console.error(`
244
- ✗ Legacy ${e.toLowerCase()} config: ${t}`),console.error(" Schema: legacy inline rules"),console.error(" Status: ignored by CC Safety Net"),n.errors.length>0){console.error(" Errors:");let o=1;for(let i of n.errors)for(let s of i.split("; "))console.error(` ${o}. ${s}`),o++;return}if(n.ruleNames.size>0){console.error(" Rules:");let o=1;for(let i of n.ruleNames)console.error(` ${o}. ${r.get(i)??i}`),o++;return}console.error(" Rules: (none)")}function lg(e,t,n){vc(`${e} config`,t,n)}function cg(e,t){console.log(`
245
- ✓ GitHub source rules: ${e}`),console.log(" Rulebooks:");let n=1;for(let r of t.ruleNames)console.log(` ${n}. ${r}`),n++}function dg(e,t){vc("GitHub source rules",e,t)}function vc(e,t,n){console.error(`
246
- ✗ ${e}: ${t}`),console.error(" Errors:");let r=1;for(let o of n)for(let i of o.split("; "))console.error(` ${r}. ${i}`),r++}function ug(e){try{let t=w(e);if(t===null)return!1;let n=JSON.parse(t);if(n.$schema)return!1;return ke(e,JSON.stringify({$schema:eg,...n},null,2)),!0}catch(t){if(t instanceof N)throw t;return!1}}var bc=new Set(["init","add","remove","update","sync","list","wrapper","migrate","doc","verify"]),fg=new Set(["add","remove","list"]);async function kc(e){try{return await mg(e)}catch(t){if(t instanceof N)return console.error(t.message),1;throw t}}async function mg(e){let t=hg(e),n=t.help?gg(t.positionals):null;if(n)return wn(n),0;if(t.errors.length>0){for(let s of t.errors)console.error(s);return 1}let r=t.positionals[0];if(!r)return wn(Qe,console.error),1;let o=t.positionals[1],i={global:t.global,check:t.check};if(r==="init"){let s=J(i),a=s.configDir;vg(s.configTarget),wc(C(s.filesystemScope,qt({...i,cacheConfigDir:a})));let l=pg(a,"example-rules","rulebook.json"),c=C(s.filesystemScope,l);if(t.example&&w(c)===null)ar(c,"example-rules");let d=await ze(i);return jt(d,"Rule config initialized."),d.ok?0:1}if(r==="add"){if(!o)return console.error("rule add requires a source"),1;let s=await tr(o,i);return jt(s,`Added rulebook source: ${o}`),s.ok?0:1}if(r==="remove"){if(!o)return console.error("rule remove requires a source"),1;let s=await rr(o,{...i,deleteSource:t.deleteSource});return jt(s,`Removed rulebook source: ${o}`),s.ok?0:1}if(r==="update"||r==="sync"){let s=await ze({...i,only:r==="update"?o:void 0});return jt(s,t.check?"Rule config checked.":"Rule config synced."),s.ok?0:1}if(r==="list"){let s=Le(),a=ee({});return cc(s,{user:xe(s.userConfigPath,a.userScope),project:xe(s.projectConfigPath,a.projectScope)}),s.errors.length>0?1:0}if(r==="wrapper")return bg(t);if(r==="migrate")return fc({cleanup:t.cleanup,cwd:process.cwd()});if(r==="doc"){console.log(ac);let s=await gc();if(s)console.error(s);return 0}if(r==="verify")return Lc();return 1}function gg(e){if(e.length===0)return Qe;let t=Qe.subcommands.filter((r)=>r.usage.split(" ")[0]===e[0]);if(t.length===0)return null;if(e.length===1&&t.length>1)return{name:`rule ${e[0]}`,description:`Subcommands of rule ${e[0]}`,usage:`rule ${e[0]} <subcommand>`,subcommands:t,options:[]};let n=e.length===1?t[0]:t.find((r)=>r.usage.split(" ")[1]===e[1]);if(!n)return null;return{name:`rule ${e[0]}`,description:n.description,usage:`rule ${n.usage}`,options:[]}}function hg(e){let t=T({label:"rule",booleans:{global:["-g","--global"],check:["--check"],cleanup:["--cleanup"],deleteSource:["--delete-source"],example:["--example"]},positionals:"list"},e),n={...t.flags,help:t.help,positionals:t.positionals,errors:t.errors};return yg(n),n}function yg(e){let[t]=e.positionals;if(t&&!bc.has(t))e.errors.push(`Unknown rule subcommand: ${t}`);if(e.deleteSource&&t!=="remove")if(t&&bc.has(t))e.errors.push(`Unknown option for rule ${t}: --delete-source`);else e.errors.push("--delete-source is only valid with 'rule remove'");if(e.cleanup&&t!=="migrate")e.errors.push(On(t,"--cleanup"));if(e.example&&t!=="init")e.errors.push(On(t,"--example"));if(t==="migrate"){if(e.global)e.errors.push(On(t,"--global"));if(e.check)e.errors.push(On(t,"--check"));if(e.positionals.length>1)e.errors.push(`Unexpected rule migrate argument: ${e.positionals[1]}`)}else if(t==="wrapper")Lg(e);else if(e.positionals.length>2)e.errors.push(`Unexpected rule argument: ${e.positionals[2]}`);if(t==="list"&&e.global)e.errors.push("Unknown option for rule list: --global")}function On(e,t){return e?`Unknown option for rule ${e}: ${t}`:`Unknown option for rule: ${t}`}function Lg(e){let t=e.positionals[1],n=e.positionals[2];if(!t){e.errors.push("rule wrapper requires add, remove, or list");return}if(!fg.has(t)){e.errors.push(`Unknown rule wrapper action: ${t}`);return}if(t==="list"){if(n)e.errors.push(`Unexpected rule wrapper argument: ${n}`);return}if(!n){e.errors.push(`rule wrapper ${t} requires a command`);return}if(e.positionals.length>3)e.errors.push(`Unexpected rule wrapper argument: ${e.positionals[3]}`)}function vg(e){if(w(e)===null){sr(e);return}let t=Y(e);if(!t.config)return;Z(e,{version:1,rules:t.config.rules,overrides:t.config.overrides??{},transparent_wrappers:t.config.transparent_wrappers??[]})}async function bg(e){let t=e.positionals[1],n=e.positionals[2],r=J({global:e.global}).configTarget;if(t==="list"){let a=Y(r);if(a.errors.length>0){for(let l of a.errors)console.error(l);return 1}return wg(a.config?.transparent_wrappers??[]),0}if(!n||!cr.test(n))return console.error("transparent wrapper must match command pattern"),1;if(ur(n))return console.error(`reserved command "${n}" cannot be a wrapper`),1;let o=Y(r);if(o.errors.length>0){for(let a of o.errors)console.error(a);return 1}let i=o.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},s=t==="add"?[...new Set([...i.transparent_wrappers??[],n])]:(i.transparent_wrappers??[]).filter((a)=>a!==n);return Z(r,{version:1,rules:i.rules,overrides:i.overrides??{},transparent_wrappers:s}),console.log(t==="add"?`Added transparent wrapper: ${n}`:`Removed transparent wrapper: ${n}`),0}function wg(e){if(e.length===0){console.log("Transparent wrappers: (none)");return}console.log(`Transparent wrappers (${e.length}):`);for(let t of e)console.log(` - ${t}`)}import{homedir as xc}from"node:os";import{existsSync as kg,readFileSync as xg}from"node:fs";import{homedir as Cg}from"node:os";import{join as Sg}from"node:path";async function Dg(e){if(e.isTTY)return null;return(await Lr(e).catch(()=>null))?.trim()||null}function Rg(){if(process.env.CLAUDE_SETTINGS_PATH)return process.env.CLAUDE_SETTINGS_PATH;return Sg(Cg(),".claude","settings.json")}function Ro(){let e=Rg();if(!kg(e))return!1;try{let t=xg(e,"utf-8"),n=JSON.parse(t);if(!n.enabledPlugins)return!1;let r="cc-safety-net@cc-marketplace";if(!(r in n.enabledPlugins))return!1;return n.enabledPlugins[r]===!0}catch(t){if(vt(S.debug))console.error(`CC Safety Net debug: failed to read Claude settings: ${e}: ${t instanceof Error?t.message:String(t)}`);return!1}}async function Ao(e=process.stdin){let t=Ro(),n;if(!t)n="\uD83D\uDEE1️ CC Safety Net ❌";else{let o=B({cwd:process.cwd()}),i=o.policy,s=de(i),a=Object.values(De(i,s.capabilities)).some((c)=>c.changesInherited);n=`\uD83D\uDEE1️ CC Safety Net ${{standard:"✅",strict:"\uD83D\uDD12",paranoid:"\uD83D\uDC41️",custom:"\uD83D\uDD27"}[a?"custom":s.effectiveLevel]}${s.worktreeMode?"\uD83C\uDF33":""}${o.state==="degraded"?"⚠️":""}`}let r=await Dg(e);if(r&&!r.startsWith("{"))console.log(`${r} | ${n}`);else console.log(n)}function Cc(){let e=B({cwd:process.cwd()}),t=e.policy,n=de(t),r=!!process.env.NO_COLOR||!process.stdout.isTTY,o=Math.min(process.stdout.columns||80,100),i=r?"ok":"✔",s=r?"OFF":"✘",a=(u,m)=>{let f=` ${u.padEnd(13)}${m}`;return(f.length>o?`${f.slice(0,o-1)}…`:f).replaceAll(s,h.red(s))},l=Object.values(De(t,n.capabilities)).some((u)=>u.changesInherited),c=bt(),d={ready:h.green,degraded:h.yellow}[e.state],p=[...Ro()?[]:["plugin cc-safety-net@cc-marketplace is disabled in Claude Code; nothing is enforced in Claude Code until it is re-enabled. Other integrations are not affected."],...e.diagnostics],g=r?"-":"·";console.log([`${r?"":"\uD83D\uDEE1️ "}CC Safety Net — ${d(e.state)}`,"",a("Protection",`destructive ${t.destructiveCommandProtectionEnabled?i:s} secrets ${t.secretProtection.enabled?i:s}`),a("Level",l?`${n.effectiveLevel} (customised)`:n.effectiveLevel),a("Rules",t.rules.length===0?"none active":`${t.rules.length} active`),a("Policy",c.startsWith(xc())?`~${c.slice(xc().length)}`:c),...n.worktreeMode?[a("Worktree","relaxations active")]:[],"",...p.length===0?[" Everything configured is active."]:[" Not active",...p.flatMap((u)=>bn(u," ",o-6).map((m,f)=>f===0?` ${g} ${m}`:m)),""," Full report: cc-safety-net doctor"]].join(`
247
- `))}import{spawn as Bc}from"node:child_process";import{randomBytes as Hg}from"node:crypto";import{createServer as Mg}from"node:http";import{Writable as jg}from"node:stream";import{homedir as Ag}from"node:os";var $n=500;function Eg(e){let t=e.filter((o)=>o.decision!=="allow"),n=e.filter((o)=>o.decision==="allow"),r=Math.min(t.length,Math.max($n-n.length,Math.ceil($n/2)));return[...t.slice(0,r),...n.slice(0,$n-r)]}function Sc(e,t=ue()){if(t)Ce(t);let n=(f)=>new Date(f.getFullYear(),f.getMonth(),f.getDate()).getTime(),r=n(new Date),o=new Date(r);o.setDate(o.getDate()-(e-1));let i=o.getTime(),s=[],a={count:0};for(let f of t?ye(t,a):[])for(let L of we(f,a)){if(!L||typeof L.ts!=="string"||typeof L.command!=="string")continue;let v=new Date(L.ts).getTime();if(!Number.isFinite(v))continue;if(v>=i)s.push(L)}s.sort((f,L)=>new Date(L.ts).getTime()-new Date(f.ts).getTime());let l=Array.from({length:e},()=>0),c=Array.from({length:e},()=>0),d={},p={},g={},u=0,m=0;for(let f of s){let L=f.agent||"unknown";d[L]=(d[L]??0)+1;let v=Math.round((r-n(new Date(f.ts)))/86400000),k=e-1-v,y=v>=0&&v<e;if(y)c[k]=(c[k]??0)+1;if(f.decision!=="allow"){if(u++,f.ruleId)p[f.ruleId]=(p[f.ruleId]??0)+1;let x=je(f.segment||f.command);if(x)g[x]=(g[x]??0)+1;if(f.failureStage)m++;if(y)l[k]=(l[k]??0)+1}}return{days:e,logsDir:t,homeDir:Ag(),totalInWindow:s.length,truncated:s.length>$n,unreadable:a.count,counts:{blocked:u,allowed:s.length-u,agents:d,blockedByDay:l,analyzedByDay:c,rules:p,commands:g,errors:m},entries:Eg(s).sort((f,L)=>new Date(L.ts).getTime()-new Date(f.ts).getTime())}}import{spawn as Pg}from"node:child_process";import{existsSync as Tg,statSync as Dc}from"node:fs";import{delimiter as Ig,join as _g}from"node:path";var Og=120000,Nn="Choose the project folder",$g=`try
242
+ All configs valid.`),0}function _n(e,t){let n=`legacy ${e} config`;if(t==="cleanup")return`Warning: Legacy ${e} config is no longer needed. Run \`npx -y cc-safety-net rule migrate --cleanup\` to clean it up safely.`;if(t==="migrate")return`Warning: Legacy ${e} config is ignored by CC Safety Net. Run \`npx -y cc-safety-net rule migrate\`.`;return`Warning: Legacy ${e} config is no longer supported. Fix or delete the ${n}, then run \`npx -y cc-safety-net rule migrate\`.`}function og(e){if(xe(e)===null)return null;let t=ig(e);if(t.ruleNames.size===0&&t.errors.length===0)return null;return{path:e.path,result:t}}function ig(e){let t=[],n=new Set,r=(xe(e)??[]).filter((o)=>!ng.has(o.name)).sort((o,i)=>o.name.localeCompare(i.name));if(r.length===0)return{errors:t,ruleNames:n};for(let o of r){if(!ht.test(o.name)){t.push(`rulebook directory names must match ${ht}: ${o.name}`);continue}if(o.kind!=="directory"){t.push(`${o.name} must be a rulebook directory`);continue}let i=k(e.scope,Qm(e.path,o.name,"rulebook.json")),s=w(i);if(s===null){t.push(`${o.name}/rulebook.json is required`);continue}try{let a;try{a=JSON.parse(s)}catch{t.push(`${o.name}/rulebook.json: invalid JSON`);continue}let l=Lc(a);if(l.name!==o.name){t.push(`rulebook name "${l.name}" must match folder "${o.name}"`);continue}n.add(o.name)}catch(a){t.push(a instanceof Error?`${o.name}/rulebook.json: ${a.message}`:`${o.name}/rulebook.json: ${String(a)}`)}}return{errors:t,ruleNames:n}}function sg(){console.log(vc),console.log(eg)}function ag(e,t,n,r,o){if(console.log(`
243
+ ✓ ${e} config: ${t}`),console.log(` Schema: ${r==="rules"?"rulebook sources":"legacy inline rules"}`),n.ruleNames.size>0){console.log(` ${r==="rules"?"Sources":"Rules"}:`);let i=1;for(let s of n.ruleNames)console.log(` ${i}. ${o.get(s)??s}`),i++}else console.log(` ${r==="rules"?"Sources":"Rules"}: (none)`)}function lg(e,t,n,r){if(console.error(`
244
+ ✗ Legacy ${e.toLowerCase()} config: ${t}`),console.error(" Schema: legacy inline rules"),console.error(" Status: ignored by CC Safety Net"),n.errors.length>0){console.error(" Errors:");let o=1;for(let i of n.errors)for(let s of i.split("; "))console.error(` ${o}. ${s}`),o++;return}if(n.ruleNames.size>0){console.error(" Rules:");let o=1;for(let i of n.ruleNames)console.error(` ${o}. ${r.get(i)??i}`),o++;return}console.error(" Rules: (none)")}function cg(e,t,n){wc(`${e} config`,t,n)}function dg(e,t){console.log(`
245
+ ✓ GitHub source rules: ${e}`),console.log(" Rulebooks:");let n=1;for(let r of t.ruleNames)console.log(` ${n}. ${r}`),n++}function ug(e,t){wc("GitHub source rules",e,t)}function wc(e,t,n){console.error(`
246
+ ✗ ${e}: ${t}`),console.error(" Errors:");let r=1;for(let o of n)for(let i of o.split("; "))console.error(` ${r}. ${i}`),r++}function pg(e){try{let t=w(e);if(t===null)return!1;let n=JSON.parse(t);if(n.$schema)return!1;return ke(e,JSON.stringify({$schema:tg,...n},null,2)),!0}catch(t){if(t instanceof N)throw t;return!1}}var kc=new Set(["init","add","remove","update","sync","list","wrapper","migrate","doc","verify"]),mg=new Set(["add","remove","list"]);async function Cc(e){try{return await gg(e)}catch(t){if(t instanceof N)return console.error(t.message),1;throw t}}async function gg(e){let t=yg(e),n=t.help?hg(t.positionals):null;if(n)return wn(n),0;if(t.errors.length>0){for(let s of t.errors)console.error(s);return 1}let r=t.positionals[0];if(!r)return wn(et,console.error),1;let o=t.positionals[1],i={global:t.global,check:t.check};if(r==="init"){let s=J(i),a=s.configDir;bg(s.configTarget),xc(k(s.filesystemScope,qt({...i,cacheConfigDir:a})));let l=fg(a,"example-rules","rulebook.json"),c=k(s.filesystemScope,l);if(t.example&&w(c)===null)ar(c,"example-rules");let d=await Ke(i);return Ut(d,"Rule config initialized."),d.ok?0:1}if(r==="add"){if(!o)return console.error("rule add requires a source"),1;let s=await tr(o,i);return Ut(s,`Added rulebook source: ${o}`),s.ok?0:1}if(r==="remove"){if(!o)return console.error("rule remove requires a source"),1;let s=await rr(o,{...i,deleteSource:t.deleteSource});return Ut(s,`Removed rulebook source: ${o}`),s.ok?0:1}if(r==="update"||r==="sync"){let s=await Ke({...i,only:r==="update"?o:void 0});return Ut(s,t.check?"Rule config checked.":"Rule config synced."),s.ok?0:1}if(r==="list"){let s=Le(),a=ee({});return uc(s,{user:Ce(s.userConfigPath,a.userScope),project:Ce(s.projectConfigPath,a.projectScope)}),s.errors.length>0?1:0}if(r==="wrapper")return wg(t);if(r==="migrate")return gc({cleanup:t.cleanup,cwd:process.cwd()});if(r==="doc"){console.log(cc);let s=await yc();if(s)console.error(s);return 0}if(r==="verify")return bc();return 1}function hg(e){if(e.length===0)return et;let t=et.subcommands.filter((r)=>r.usage.split(" ")[0]===e[0]);if(t.length===0)return null;if(e.length===1&&t.length>1)return{name:`rule ${e[0]}`,description:`Subcommands of rule ${e[0]}`,usage:`rule ${e[0]} <subcommand>`,subcommands:t,options:[]};let n=e.length===1?t[0]:t.find((r)=>r.usage.split(" ")[1]===e[1]);if(!n)return null;return{name:`rule ${e[0]}`,description:n.description,usage:`rule ${n.usage}`,options:[]}}function yg(e){let t=T({label:"rule",booleans:{global:["-g","--global"],check:["--check"],cleanup:["--cleanup"],deleteSource:["--delete-source"],example:["--example"]},positionals:"list"},e),n={...t.flags,help:t.help,positionals:t.positionals,errors:t.errors};return Lg(n),n}function Lg(e){let[t]=e.positionals;if(t&&!kc.has(t))e.errors.push(`Unknown rule subcommand: ${t}`);if(e.deleteSource&&t!=="remove")if(t&&kc.has(t))e.errors.push(`Unknown option for rule ${t}: --delete-source`);else e.errors.push("--delete-source is only valid with 'rule remove'");if(e.cleanup&&t!=="migrate")e.errors.push(On(t,"--cleanup"));if(e.example&&t!=="init")e.errors.push(On(t,"--example"));if(t==="migrate"){if(e.global)e.errors.push(On(t,"--global"));if(e.check)e.errors.push(On(t,"--check"));if(e.positionals.length>1)e.errors.push(`Unexpected rule migrate argument: ${e.positionals[1]}`)}else if(t==="wrapper")vg(e);else if(e.positionals.length>2)e.errors.push(`Unexpected rule argument: ${e.positionals[2]}`);if(t==="list"&&e.global)e.errors.push("Unknown option for rule list: --global")}function On(e,t){return e?`Unknown option for rule ${e}: ${t}`:`Unknown option for rule: ${t}`}function vg(e){let t=e.positionals[1],n=e.positionals[2];if(!t){e.errors.push("rule wrapper requires add, remove, or list");return}if(!mg.has(t)){e.errors.push(`Unknown rule wrapper action: ${t}`);return}if(t==="list"){if(n)e.errors.push(`Unexpected rule wrapper argument: ${n}`);return}if(!n){e.errors.push(`rule wrapper ${t} requires a command`);return}if(e.positionals.length>3)e.errors.push(`Unexpected rule wrapper argument: ${e.positionals[3]}`)}function bg(e){if(w(e)===null){sr(e);return}let t=Y(e);if(!t.config)return;Z(e,{version:1,rules:t.config.rules,overrides:t.config.overrides??{},transparent_wrappers:t.config.transparent_wrappers??[]})}async function wg(e){let t=e.positionals[1],n=e.positionals[2],r=J({global:e.global}).configTarget;if(t==="list"){let a=Y(r);if(a.errors.length>0){for(let l of a.errors)console.error(l);return 1}return kg(a.config?.transparent_wrappers??[]),0}if(!n||!cr.test(n))return console.error("transparent wrapper must match command pattern"),1;if(ur(n))return console.error(`reserved command "${n}" cannot be a wrapper`),1;let o=Y(r);if(o.errors.length>0){for(let a of o.errors)console.error(a);return 1}let i=o.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},s=t==="add"?[...new Set([...i.transparent_wrappers??[],n])]:(i.transparent_wrappers??[]).filter((a)=>a!==n);return Z(r,{version:1,rules:i.rules,overrides:i.overrides??{},transparent_wrappers:s}),console.log(t==="add"?`Added transparent wrapper: ${n}`:`Removed transparent wrapper: ${n}`),0}function kg(e){if(e.length===0){console.log("Transparent wrappers: (none)");return}console.log(`Transparent wrappers (${e.length}):`);for(let t of e)console.log(` - ${t}`)}import{homedir as Sc}from"node:os";import{existsSync as xg,readFileSync as Cg}from"node:fs";import{homedir as Sg}from"node:os";import{join as Dg}from"node:path";async function Rg(e){if(e.isTTY)return null;return(await Lr(e).catch(()=>null))?.trim()||null}function Ag(){if(process.env.CLAUDE_SETTINGS_PATH)return process.env.CLAUDE_SETTINGS_PATH;return Dg(Sg(),".claude","settings.json")}function Ro(){let e=Ag();if(!xg(e))return!1;try{let t=Cg(e,"utf-8"),n=JSON.parse(t);if(!n.enabledPlugins)return!1;let r="cc-safety-net@cc-marketplace";if(!(r in n.enabledPlugins))return!1;return n.enabledPlugins[r]===!0}catch(t){if(bt(S.debug))console.error(`CC Safety Net debug: failed to read Claude settings: ${e}: ${t instanceof Error?t.message:String(t)}`);return!1}}async function Ao(e=process.stdin){let t=Ro(),n;if(!t)n="\uD83D\uDEE1️ CC Safety Net ❌";else{let o=B({cwd:process.cwd()}),i=o.policy,s=de(i),a=Object.values(Re(i,s.capabilities)).some((c)=>c.changesInherited);n=`\uD83D\uDEE1️ CC Safety Net ${{standard:"✅",strict:"\uD83D\uDD12",paranoid:"\uD83D\uDC41️",custom:"\uD83D\uDD27"}[a?"custom":s.effectiveLevel]}${s.worktreeMode?"\uD83C\uDF33":""}${o.state==="degraded"?"⚠️":""}`}let r=await Rg(e);if(r&&!r.startsWith("{"))console.log(`${r} | ${n}`);else console.log(n)}function Dc(){let e=B({cwd:process.cwd()}),t=e.policy,n=de(t),r=!!process.env.NO_COLOR||!process.stdout.isTTY,o=Math.min(process.stdout.columns||80,100),i=r?"ok":"✔",s=r?"OFF":"✘",a=(u,m)=>{let f=` ${u.padEnd(13)}${m}`;return(f.length>o?`${f.slice(0,o-1)}…`:f).replaceAll(s,h.red(s))},l=Object.values(Re(t,n.capabilities)).some((u)=>u.changesInherited),c=wt(),d={ready:h.green,degraded:h.yellow}[e.state],p=[...Ro()?[]:["plugin cc-safety-net@cc-marketplace is disabled in Claude Code; nothing is enforced in Claude Code until it is re-enabled. Other integrations are not affected."],...e.diagnostics],g=r?"-":"·";console.log([`${r?"":"\uD83D\uDEE1️ "}CC Safety Net — ${d(e.state)}`,"",a("Protection",`destructive ${t.destructiveCommandProtectionEnabled?i:s} secrets ${t.secretProtection.enabled?i:s}`),a("Level",l?`${n.effectiveLevel} (customised)`:n.effectiveLevel),a("Rules",t.rules.length===0?"none active":`${t.rules.length} active`),a("Policy",c.startsWith(Sc())?`~${c.slice(Sc().length)}`:c),...n.worktreeMode?[a("Worktree","relaxations active")]:[],"",...p.length===0?[" Everything configured is active."]:[" Not active",...p.flatMap((u)=>bn(u," ",o-6).map((m,f)=>f===0?` ${g} ${m}`:m)),""," Full report: cc-safety-net doctor"]].join(`
247
+ `))}import{spawn as Vc}from"node:child_process";import{randomBytes as Mg}from"node:crypto";import{createServer as jg}from"node:http";import{Writable as Ug}from"node:stream";import{homedir as Eg}from"node:os";var $n=500;function Pg(e){let t=e.filter((o)=>o.decision!=="allow"),n=e.filter((o)=>o.decision==="allow"),r=Math.min(t.length,Math.max($n-n.length,Math.ceil($n/2)));return[...t.slice(0,r),...n.slice(0,$n-r)]}function Rc(e,t=ue()){if(t)Se(t);let n=(f)=>new Date(f.getFullYear(),f.getMonth(),f.getDate()).getTime(),r=n(new Date),o=new Date(r);o.setDate(o.getDate()-(e-1));let i=o.getTime(),s=[],a={count:0};for(let f of t?ye(t,a):[])for(let L of we(f,a)){if(!L||typeof L.ts!=="string"||typeof L.command!=="string")continue;let v=new Date(L.ts).getTime();if(!Number.isFinite(v))continue;if(v>=i)s.push(L)}s.sort((f,L)=>new Date(L.ts).getTime()-new Date(f.ts).getTime());let l=Array.from({length:e},()=>0),c=Array.from({length:e},()=>0),d={},p={},g={},u=0,m=0;for(let f of s){let L=f.agent||"unknown";d[L]=(d[L]??0)+1;let v=Math.round((r-n(new Date(f.ts)))/86400000),x=e-1-v,y=v>=0&&v<e;if(y)c[x]=(c[x]??0)+1;if(f.decision!=="allow"){if(u++,f.ruleId)p[f.ruleId]=(p[f.ruleId]??0)+1;let C=Ue(f.segment||f.command);if(C)g[C]=(g[C]??0)+1;if(f.failureStage)m++;if(y)l[x]=(l[x]??0)+1}}return{days:e,logsDir:t,homeDir:Eg(),totalInWindow:s.length,truncated:s.length>$n,unreadable:a.count,counts:{blocked:u,allowed:s.length-u,agents:d,blockedByDay:l,analyzedByDay:c,rules:p,commands:g,errors:m},entries:Pg(s).sort((f,L)=>new Date(L.ts).getTime()-new Date(f.ts).getTime())}}import{spawn as Tg}from"node:child_process";import{existsSync as Ig,statSync as Ac}from"node:fs";import{delimiter as _g,join as Og}from"node:path";var $g=120000,Nn="Choose the project folder",Ng=`try
248
248
  return POSIX path of (choose folder with prompt "${Nn}")
249
249
  on error number -128
250
250
  return ""
251
- end try`,Ng=`Add-Type -AssemblyName System.Windows.Forms
251
+ end try`,Fg=`Add-Type -AssemblyName System.Windows.Forms
252
252
  $dialog = New-Object System.Windows.Forms.FolderBrowserDialog
253
253
  $dialog.Description = '${Nn}'
254
- if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { [Console]::Out.Write($dialog.SelectedPath) }`,Rc=[{binary:"zenity",args:["--file-selection","--directory",`--title=${Nn}`]},{binary:"kdialog",args:["--getexistingdirectory",".","--title",Nn]}],Ac=(e,t)=>(t.PATH??"").split(Ig).some((n)=>{if(n.length===0)return!1;try{let r=Dc(_g(n,e));return r.isFile()&&(r.mode&73)!==0}catch{return!1}});function Ec(e,t){if(e==="darwin"||e==="win32")return!0;if(e!=="linux")return!1;if(!t.DISPLAY&&!t.WAYLAND_DISPLAY)return!1;return Rc.some((n)=>Ac(n.binary,t))}function Fg(e,t){if(e==="darwin")return{cmd:"osascript",args:["-e",$g]};if(e==="win32")return{cmd:"powershell.exe",args:["-NoProfile","-STA","-Command",Ng]};let n=Rc.find((r)=>Ac(r.binary,t));return n?{cmd:n.binary,args:n.args}:null}function Pc(e=process.platform,t=process.env){let n=Fg(e,t);if(!n)return Promise.resolve({error:"No folder dialog is available on this system"});return new Promise((r)=>{let o=Pg(n.cmd,n.args,{env:t,stdio:["ignore","pipe","pipe"]}),i="",s=!1,a=(c)=>{if(s)return;s=!0,clearTimeout(l),r(c)},l=setTimeout(()=>{o.kill(),a({error:"The folder dialog timed out"})},Og);o.stdout.on("data",(c)=>{i+=c.toString()}),o.on("error",()=>a({error:`Could not open the folder dialog (${n.cmd})`})),o.on("close",()=>{let c=i.trim().replace(/\/+$/,"");if(!c)return a({cancelled:!0});if(!Tg(c)||!Dc(c).isDirectory())return a({error:"That selection is not a folder on disk"});a({path:c})})})}var Tc=`<!doctype html>
254
+ if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { [Console]::Out.Write($dialog.SelectedPath) }`,Ec=[{binary:"zenity",args:["--file-selection","--directory",`--title=${Nn}`]},{binary:"kdialog",args:["--getexistingdirectory",".","--title",Nn]}],Pc=(e,t)=>(t.PATH??"").split(_g).some((n)=>{if(n.length===0)return!1;try{let r=Ac(Og(n,e));return r.isFile()&&(r.mode&73)!==0}catch{return!1}});function Tc(e,t){if(e==="darwin"||e==="win32")return!0;if(e!=="linux")return!1;if(!t.DISPLAY&&!t.WAYLAND_DISPLAY)return!1;return Ec.some((n)=>Pc(n.binary,t))}function Hg(e,t){if(e==="darwin")return{cmd:"osascript",args:["-e",Ng]};if(e==="win32")return{cmd:"powershell.exe",args:["-NoProfile","-STA","-Command",Fg]};let n=Ec.find((r)=>Pc(r.binary,t));return n?{cmd:n.binary,args:n.args}:null}function Ic(e=process.platform,t=process.env){let n=Hg(e,t);if(!n)return Promise.resolve({error:"No folder dialog is available on this system"});return new Promise((r)=>{let o=Tg(n.cmd,n.args,{env:t,stdio:["ignore","pipe","pipe"]}),i="",s=!1,a=(c)=>{if(s)return;s=!0,clearTimeout(l),r(c)},l=setTimeout(()=>{o.kill(),a({error:"The folder dialog timed out"})},$g);o.stdout.on("data",(c)=>{i+=c.toString()}),o.on("error",()=>a({error:`Could not open the folder dialog (${n.cmd})`})),o.on("close",()=>{let c=i.trim().replace(/\/+$/,"");if(!c)return a({cancelled:!0});if(!Ig(c)||!Ac(c).isDirectory())return a({error:"That selection is not a folder on disk"});a({path:c})})})}var _c=`<!doctype html>
255
255
  <html lang="en">
256
256
  <head>
257
257
  <meta charset="utf-8">
@@ -5307,5 +5307,5 @@ load().then((loaded) => {
5307
5307
  </script>
5308
5308
  </body>
5309
5309
  </html>
5310
- `;var Ic='<script id="ccsn-data" type="application/json">';function _c(e){return Tc.replace(Ic,()=>Ic+JSON.stringify({token:e}).replaceAll("<","\\u003c"))}var Hn="kenryu42/cc-safety-net",Ug=`https://github.com/${Hn}`,To=1e4,Gg=7;async function qc(e,t={}){let n=T({label:"gui",booleans:{noOpen:["--no-open"]}},e),r=t.log??console.log,o=t.error??console.error;if(n.errors.length>0){for(let s of n.errors)o(s);return o("Usage: cc-safety-net gui [--no-open]"),1}let i=await Bg(t);if(r(`CC Safety Net policy GUI: ${i.url}`),!n.flags.noOpen)try{await(t.openBrowser??Xg)(i.url)}catch(s){o(`Failed to open browser: ${s instanceof Error?s.message:String(s)}`),o(`Open this URL manually: ${i.url}`)}if(t.keepAlive===!1)return await i.close(),0;return await Zg(i),0}async function Bg(e={}){let t=Hg(24).toString("base64url"),n=Mg((i,s)=>{qg(i,s,t,e)});await new Promise((i,s)=>{n.once("error",s),n.listen(0,"127.0.0.1",()=>{n.off("error",s),i()})});let o=`http://127.0.0.1:${n.address().port}`;return{origin:o,token:t,url:`${o}/?token=${encodeURIComponent(t)}`,close:()=>Yg(n)}}async function qg(e,t,n,r){let o=new URL(e.url??"/","http://127.0.0.1");if(e.method==="GET"&&o.pathname==="/favicon.ico"){t.writeHead(204,{"cache-control":"no-store"}),t.end();return}if(!Kg(e,o,n)){D(t,403,{error:"Forbidden"});return}if(e.method==="GET"&&o.pathname==="/"){Jg(t,_c(n));return}if(e.method==="GET"&&o.pathname==="/api/policy"){let i=Fc(r);D(t,200,{...i,configState:wt(B(r)),destructiveCommandRules:yt,secretPatterns:$c,version:P(),preview:i.errors.length>0?null:Mc(i.policy)});return}if(e.method==="POST"&&o.pathname==="/api/policy/preview"){let i=await Fn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=Hc(i.value);D(t,s.errors.length>0?400:200,s);return}if(e.method==="POST"&&o.pathname==="/api/policy/explain"){let i=await Fn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=i.value;if(s===null||typeof s.command!=="string"){D(t,400,{errors:["command must be a string"]});return}let a=gr(s.policy);if(a.length>0){D(t,400,{errors:a});return}D(t,200,Vg(s.command,s.policy,r));return}if(e.method==="POST"&&o.pathname==="/api/policy"){let i=await Fn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=Eo(i.value,r);D(t,s.errors.length>0?400:200,s);return}if(e.method==="POST"&&o.pathname==="/api/reset"){D(t,200,Eo(Nc,r));return}if(e.method==="POST"&&o.pathname==="/api/repair"){D(t,200,jc(r));return}if(e.method==="GET"&&o.pathname==="/api/activity"){let i=Ze(r),s=zg(o.searchParams.get("days"),i);if(s===null){D(t,400,{error:`days must be an integer between 1 and ${i}`});return}D(t,200,Sc(s,r.activityLogsDir));return}if(e.method==="POST"&&o.pathname==="/api/rules/choose-directory"){D(t,200,await Pc());return}if(e.method==="GET"&&o.pathname==="/api/rules"){let i=Le(r),s=new Map(i.rules.map((a)=>[a.name,a]));D(t,200,{projectPath:r.cwd??process.cwd(),canPickDirectory:Ec(process.platform,process.env),rulebooks:i.rulebooks.map((a)=>({source:a.source,spec:a.spec,name:a.name,version:a.version,rules:a.rules.flatMap((l)=>{let c=s.get(l);if(!c)return[];return[{name:c.name,command:c.command,subcommand:c.subcommand,block_args:c.block_args,reason:c.reason}]})})),errors:i.errors,warnings:i.warnings});return}if(e.method==="GET"&&o.pathname==="/api/star/context"){D(t,200,await(r.fetchStarContext??(()=>r1({logsDir:r.activityLogsDir})))());return}if(e.method==="POST"&&o.pathname==="/api/star"){let i=await(r.starRepo??Qg)();D(t,200,i.ok?{ok:!0}:{ok:!1,fallbackUrl:Ug});return}if(e.method==="GET"&&o.pathname==="/api/integrations"){D(t,200,await(r.fetchIntegrations??e1)());return}if(e.method==="GET"&&o.pathname==="/api/health"){D(t,200,await(r.fetchHealth??t1)());return}if(e.method==="POST"&&(o.pathname==="/api/install"||o.pathname==="/api/uninstall")){let i=await Fn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=i.value?.target;if(typeof s!=="string"||!se.some((l)=>l.target===s)){D(t,400,{error:"unknown target"});return}let a=o.pathname==="/api/install"?"install":"uninstall";D(t,200,await(r.runIntegration??n1)(a,s));return}D(t,404,{error:"Not found"})}function Vg(e,t,n){let r=xn(t),o=B(n),i=Lt({rules:o.policy.rules,transparentWrappers:o.policy.transparentWrappers,safety:Gc(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:Uc(r.secret_protection.overrides),denyPaths:r.secret_protection.deny_paths,allowPaths:r.secret_protection.allow_paths}});return Ye(e,{policySnapshot:i,cwd:n.cwd,userConfigDir:n.userConfigDir})}function zg(e,t){if(e===null)return Math.min(Gg,t);let n=Number(e);if(!Number.isInteger(n)||n<1||n>t)return null;return n}function Kg(e,t,n){if(t.searchParams.get("token")!==n)return!1;if(e.method!=="POST")return!0;return e.headers["x-cc-safety-net-token"]===n}var Wg=1048576;async function Fn(e){let t=[],n=0;for await(let r of e){let o=r;if(n+=o.byteLength,n>Wg)return{ok:!1,status:413,error:"Request body is too large"};t.push(o)}try{return{ok:!0,value:JSON.parse(Buffer.concat(t).toString("utf-8")||"{}")}}catch(r){return{ok:!1,status:400,error:`Invalid JSON: ${r instanceof Error?r.message:String(r)}`}}}function Jg(e,t){e.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),e.end(t)}function D(e,t,n){e.writeHead(t,{"content-type":"application/json; charset=utf-8","cache-control":"no-store"}),e.end(JSON.stringify(n))}function Yg(e){return new Promise((t,n)=>{e.close((r)=>r?n(r):t())})}function Zg(e){return new Promise((t)=>{let n=()=>{process.off("SIGINT",r),process.off("SIGTERM",r)},r=()=>{n(),e.close().then(t)};process.once("SIGINT",r),process.once("SIGTERM",r)})}function Xg(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",n=process.platform==="win32"?["/c","start","",e]:[e];return new Promise((r,o)=>{let i=Bc(t,n,{detached:!0,stdio:"ignore"}),s=(l)=>{i.off("spawn",a),o(l)},a=()=>{i.off("error",s),i.unref(),r()};i.once("error",s),i.once("spawn",a)})}async function Qg(e="gh",t=To){return{ok:await Po(e,["api","-X","PUT",`/user/starred/${Hn}`],t)===0}}async function e1(e={}){let t=await Dt(e.fetcher),n=Vc(t,e.homeDir);return{targets:V.map((r)=>{let o=n.find((i)=>i.platform===r.id);return{target:r.id,label:R(r.id),version:t.versions[r.id]??null,status:o?.configured?"active":o?.detected?"disabled":o?.inspectionStatus==="not-inspected"?"not-inspected":"not-installed"}}),system:{version:t.version,nodeVersion:t.nodeVersion,platform:t.platform}}}function Vc(e,t){return at(process.cwd(),{homeDir:t,ampPluginListOutput:e.ampPluginListOutput,codexPluginListOutput:e.codexPluginListOutput,copilotCliVersion:e.versions["copilot-cli"]})}async function t1(e={}){let[t,n]=await Promise.all([Dt(e.fetcher),(e.checkUpdates??tt)()]);return{hooks:Vc(t,e.homeDir).filter((r)=>r.detected).map((r)=>({platform:r.platform,label:R(r.platform),configured:r.configured})),update:{currentVersion:n.currentVersion,latestVersion:n.latestVersion??null,updateAvailable:n.updateAvailable}}}var Oc=Promise.resolve();function n1(e,t,n={}){let r=async()=>{let i=[],s=console.log,a=console.error;console.log=(...l)=>i.push(l.map(String).join(" ")),console.error=console.log;try{return{ok:await Mt(e,[],{selectTargets:async()=>[t],output:new jg({write(c,d,p){i.push(String(c).replace(/\n$/,"")),p()}}),...n})===0,output:i.join(`
5311
- `)}}finally{console.log=s,console.error=a}},o=Oc.then(r);return Oc=o.then(()=>{return},()=>{return}),o}async function r1(e={}){let[t,n,r]=await Promise.all([o1(e.command),i1(e.fetchRepo),Promise.resolve(Zt(Ze(),e.logsDir).totalBlocked)]);return{starred:t,starCount:n,blockedTotal:r}}async function o1(e="gh",t=To){if(await Po(e,["auth","status"],t)!==0)return null;let n=await Po(e,["api",`/user/starred/${Hn}`],t);if(n===0)return!0;if(n===null)return null;return!1}function Po(e,t,n){return new Promise((r)=>{let o=Bc(e,t,{stdio:"ignore",windowsHide:!0}),i=!1,s,a=(l)=>{if(i)return;if(i=!0,s)clearTimeout(s);r(l)};o.once("error",()=>a(null)),o.once("close",a),s=setTimeout(()=>{o.kill(),a(null)},n)})}async function i1(e=fetch){try{let t=await e(`https://api.github.com/repos/${Hn}`,{headers:{accept:"application/vnd.github+json"},signal:AbortSignal.timeout(To)});if(!t.ok)return null;let n=await t.json();return typeof n.stargazers_count==="number"?n.stargazers_count:null}catch{return null}}function s1(e){if(e[0]!=="help")return!1;let t=e[1];if(!t)co(),process.exit(0);if(Nt(t))process.exit(0);console.error(`Unknown command: ${t}`),console.error("Run 'cc-safety-net --help' for available commands."),process.exit(1)}var a1={hook:async(e)=>{let t=Qi(e);if(t){await t.run();return}console.error("hook requires exactly one integration flag. Try: cc-safety-net hook --kimi-code"),Nt("hook",console.error),process.exit(1)},install:async(e)=>{process.exit(await Mt("install",e))},update:async(e)=>{process.exit(await Co(e))},uninstall:async(e)=>{process.exit(await Mt("uninstall",e))},rule:async(e)=>{process.exit(await kc(e))},status:async(e)=>{if(ae(T({label:"status"},e).errors))process.exit(1);Cc()},statusline:async(e)=>{let t=T({label:"statusline",booleans:{claudeCode:["-cc","--claude-code"]}},e);if(t.errors.length===0&&t.flags.claudeCode){await Ao();return}if(ae(t.errors),!t.flags.claudeCode)console.error("statusline requires --claude-code (-cc)");Nt("statusline",console.error),process.exit(1)},doctor:async(e)=>{let t=oo(e);if(!t)process.exit(1);let n=await el({json:t.json,skipUpdateCheck:t.skipUpdateCheck});process.exit(n)},logs:async(e)=>{process.exit(await ki(e))},gui:async(e)=>{process.exit(await qc(e))},explain:async(e)=>{process.exit(await al(e))}};async function l1(){let e=process.argv.slice(2),t=T({label:"cc-safety-net",booleans:{version:["-V","--version"]},positionals:"list"},e);if(s1(e))return;let n=e[0],r=n?Yt(n):void 0;if(t.help&&r&&r.name!=="rule")Nt(r.name),process.exit(0);if(!n||t.help&&!r)co(),process.exit(0);if(t.flags.version)dl(),process.exit(0);if(r){await a1[r.name](e.slice(1));return}let o=es(n);if(o){await o.run();return}if(n==="--statusline"){await Ao();return}console.error(n.startsWith("-")?`Unknown option: ${n}`:`Unknown command: ${n}`),console.error("Run 'cc-safety-net --help' for usage."),process.exit(1)}l1().catch((e)=>{console.error("CC Safety Net error:",e),process.exit(1)});
5310
+ `;var Oc='<script id="ccsn-data" type="application/json">';function $c(e){return _c.replace(Oc,()=>Oc+JSON.stringify({token:e}).replaceAll("<","\\u003c"))}var Hn="kenryu42/cc-safety-net",Gg=`https://github.com/${Hn}`,To=1e4,Bg=7;async function zc(e,t={}){let n=T({label:"gui",booleans:{noOpen:["--no-open"]}},e),r=t.log??console.log,o=t.error??console.error;if(n.errors.length>0){for(let s of n.errors)o(s);return o("Usage: cc-safety-net gui [--no-open]"),1}let i=await qg(t);if(r(`CC Safety Net policy GUI: ${i.url}`),!n.flags.noOpen)try{await(t.openBrowser??Qg)(i.url)}catch(s){o(`Failed to open browser: ${s instanceof Error?s.message:String(s)}`),o(`Open this URL manually: ${i.url}`)}if(t.keepAlive===!1)return await i.close(),0;return await Xg(i),0}async function qg(e={}){let t=Mg(24).toString("base64url"),n=jg((i,s)=>{Vg(i,s,t,e)});await new Promise((i,s)=>{n.once("error",s),n.listen(0,"127.0.0.1",()=>{n.off("error",s),i()})});let o=`http://127.0.0.1:${n.address().port}`;return{origin:o,token:t,url:`${o}/?token=${encodeURIComponent(t)}`,close:()=>Zg(n)}}async function Vg(e,t,n,r){let o=new URL(e.url??"/","http://127.0.0.1");if(e.method==="GET"&&o.pathname==="/favicon.ico"){t.writeHead(204,{"cache-control":"no-store"}),t.end();return}if(!Wg(e,o,n)){D(t,403,{error:"Forbidden"});return}if(e.method==="GET"&&o.pathname==="/"){Yg(t,$c(n));return}if(e.method==="GET"&&o.pathname==="/api/policy"){let i=Mc(r);D(t,200,{...i,configState:kt(B(r)),destructiveCommandRules:Lt,secretPatterns:Fc,version:P(),preview:i.errors.length>0?null:Uc(i.policy)});return}if(e.method==="POST"&&o.pathname==="/api/policy/preview"){let i=await Fn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=jc(i.value);D(t,s.errors.length>0?400:200,s);return}if(e.method==="POST"&&o.pathname==="/api/policy/explain"){let i=await Fn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=i.value;if(s===null||typeof s.command!=="string"){D(t,400,{errors:["command must be a string"]});return}let a=gr(s.policy);if(a.length>0){D(t,400,{errors:a});return}D(t,200,zg(s.command,s.policy,r));return}if(e.method==="POST"&&o.pathname==="/api/policy"){let i=await Fn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=Eo(i.value,r);D(t,s.errors.length>0?400:200,s);return}if(e.method==="POST"&&o.pathname==="/api/reset"){D(t,200,Eo(Hc,r));return}if(e.method==="POST"&&o.pathname==="/api/repair"){D(t,200,Gc(r));return}if(e.method==="GET"&&o.pathname==="/api/activity"){let i=Xe(r),s=Kg(o.searchParams.get("days"),i);if(s===null){D(t,400,{error:`days must be an integer between 1 and ${i}`});return}D(t,200,Rc(s,r.activityLogsDir));return}if(e.method==="POST"&&o.pathname==="/api/rules/choose-directory"){D(t,200,await Ic());return}if(e.method==="GET"&&o.pathname==="/api/rules"){let i=Le(r),s=new Map(i.rules.map((a)=>[a.name,a]));D(t,200,{projectPath:r.cwd??process.cwd(),canPickDirectory:Tc(process.platform,process.env),rulebooks:i.rulebooks.map((a)=>({source:a.source,spec:a.spec,name:a.name,version:a.version,rules:a.rules.flatMap((l)=>{let c=s.get(l);if(!c)return[];return[{name:c.name,command:c.command,subcommand:c.subcommand,block_args:c.block_args,reason:c.reason}]})})),errors:i.errors,warnings:i.warnings});return}if(e.method==="GET"&&o.pathname==="/api/star/context"){D(t,200,await(r.fetchStarContext??(()=>o1({logsDir:r.activityLogsDir})))());return}if(e.method==="POST"&&o.pathname==="/api/star"){let i=await(r.starRepo??e1)();D(t,200,i.ok?{ok:!0}:{ok:!1,fallbackUrl:Gg});return}if(e.method==="GET"&&o.pathname==="/api/integrations"){D(t,200,await(r.fetchIntegrations??t1)());return}if(e.method==="GET"&&o.pathname==="/api/health"){D(t,200,await(r.fetchHealth??n1)());return}if(e.method==="POST"&&(o.pathname==="/api/install"||o.pathname==="/api/uninstall")){let i=await Fn(e);if(!i.ok){D(t,i.status,{errors:[i.error]});return}let s=i.value?.target;if(typeof s!=="string"||!se.some((l)=>l.target===s)){D(t,400,{error:"unknown target"});return}let a=o.pathname==="/api/install"?"install":"uninstall";D(t,200,await(r.runIntegration??r1)(a,s));return}D(t,404,{error:"Not found"})}function zg(e,t,n){let r=xn(t),o=B(n),i=vt({rules:o.policy.rules,transparentWrappers:o.policy.transparentWrappers,safety:qc(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:Bc(r.secret_protection.overrides),denyPaths:r.secret_protection.deny_paths,allowPaths:r.secret_protection.allow_paths}});return Ze(e,{policySnapshot:i,cwd:n.cwd,userConfigDir:n.userConfigDir})}function Kg(e,t){if(e===null)return Math.min(Bg,t);let n=Number(e);if(!Number.isInteger(n)||n<1||n>t)return null;return n}function Wg(e,t,n){if(t.searchParams.get("token")!==n)return!1;if(e.method!=="POST")return!0;return e.headers["x-cc-safety-net-token"]===n}var Jg=1048576;async function Fn(e){let t=[],n=0;for await(let r of e){let o=r;if(n+=o.byteLength,n>Jg)return{ok:!1,status:413,error:"Request body is too large"};t.push(o)}try{return{ok:!0,value:JSON.parse(Buffer.concat(t).toString("utf-8")||"{}")}}catch(r){return{ok:!1,status:400,error:`Invalid JSON: ${r instanceof Error?r.message:String(r)}`}}}function Yg(e,t){e.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),e.end(t)}function D(e,t,n){e.writeHead(t,{"content-type":"application/json; charset=utf-8","cache-control":"no-store"}),e.end(JSON.stringify(n))}function Zg(e){return new Promise((t,n)=>{e.close((r)=>r?n(r):t())})}function Xg(e){return new Promise((t)=>{let n=()=>{process.off("SIGINT",r),process.off("SIGTERM",r)},r=()=>{n(),e.close().then(t)};process.once("SIGINT",r),process.once("SIGTERM",r)})}function Qg(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",n=process.platform==="win32"?["/c","start","",e]:[e];return new Promise((r,o)=>{let i=Vc(t,n,{detached:!0,stdio:"ignore"}),s=(l)=>{i.off("spawn",a),o(l)},a=()=>{i.off("error",s),i.unref(),r()};i.once("error",s),i.once("spawn",a)})}async function e1(e="gh",t=To){return{ok:await Po(e,["api","-X","PUT",`/user/starred/${Hn}`],t)===0}}async function t1(e={}){let t=await Rt(e.fetcher),n=Kc(t,e.homeDir);return{targets:V.map((r)=>{let o=n.find((i)=>i.platform===r.id);return{target:r.id,label:R(r.id),version:t.versions[r.id]??null,status:o?.configured?"active":o?.detected?"disabled":o?.inspectionStatus==="not-inspected"?"not-inspected":"not-installed"}}),system:{version:t.version,nodeVersion:t.nodeVersion,platform:t.platform}}}function Kc(e,t){return lt(process.cwd(),{homeDir:t,ampPluginListOutput:e.ampPluginListOutput,codexPluginListOutput:e.codexPluginListOutput,copilotCliVersion:e.versions["copilot-cli"]})}async function n1(e={}){let[t,n]=await Promise.all([Rt(e.fetcher),(e.checkUpdates??nt)()]);return{hooks:Kc(t,e.homeDir).filter((r)=>r.detected).map((r)=>({platform:r.platform,label:R(r.platform),configured:r.configured})),update:{currentVersion:n.currentVersion,latestVersion:n.latestVersion??null,updateAvailable:n.updateAvailable}}}var Nc=Promise.resolve();function r1(e,t,n={}){let r=async()=>{let i=[],s=console.log,a=console.error;console.log=(...l)=>i.push(l.map(String).join(" ")),console.error=console.log;try{return{ok:await jt(e,[],{selectTargets:async()=>[t],output:new Ug({write(c,d,p){i.push(String(c).replace(/\n$/,"")),p()}}),...n})===0,output:i.join(`
5311
+ `)}}finally{console.log=s,console.error=a}},o=Nc.then(r);return Nc=o.then(()=>{return},()=>{return}),o}async function o1(e={}){let[t,n,r]=await Promise.all([i1(e.command),s1(e.fetchRepo),Promise.resolve(Zt(Xe(),e.logsDir).totalBlocked)]);return{starred:t,starCount:n,blockedTotal:r}}async function i1(e="gh",t=To){if(await Po(e,["auth","status"],t)!==0)return null;let n=await Po(e,["api",`/user/starred/${Hn}`],t);if(n===0)return!0;if(n===null)return null;return!1}function Po(e,t,n){return new Promise((r)=>{let o=Vc(e,t,{stdio:"ignore",windowsHide:!0}),i=!1,s,a=(l)=>{if(i)return;if(i=!0,s)clearTimeout(s);r(l)};o.once("error",()=>a(null)),o.once("close",a),s=setTimeout(()=>{o.kill(),a(null)},n)})}async function s1(e=fetch){try{let t=await e(`https://api.github.com/repos/${Hn}`,{headers:{accept:"application/vnd.github+json"},signal:AbortSignal.timeout(To)});if(!t.ok)return null;let n=await t.json();return typeof n.stargazers_count==="number"?n.stargazers_count:null}catch{return null}}function a1(e){if(e[0]!=="help")return!1;let t=e[1];if(!t)co(),process.exit(0);if(Ft(t))process.exit(0);console.error(`Unknown command: ${t}`),console.error("Run 'cc-safety-net --help' for available commands."),process.exit(1)}var l1={hook:async(e)=>{let t=ts(e);if(t){await t.run();return}console.error("hook requires exactly one integration flag. Try: cc-safety-net hook --kimi-code"),Ft("hook",console.error),process.exit(1)},install:async(e)=>{process.exit(await jt("install",e))},update:async(e)=>{process.exit(await Co(e))},uninstall:async(e)=>{process.exit(await jt("uninstall",e))},rule:async(e)=>{process.exit(await Cc(e))},status:async(e)=>{if(ae(T({label:"status"},e).errors))process.exit(1);Dc()},statusline:async(e)=>{let t=T({label:"statusline",booleans:{claudeCode:["-cc","--claude-code"]}},e);if(t.errors.length===0&&t.flags.claudeCode){await Ao();return}if(ae(t.errors),!t.flags.claudeCode)console.error("statusline requires --claude-code (-cc)");Ft("statusline",console.error),process.exit(1)},doctor:async(e)=>{let t=oo(e);if(!t)process.exit(1);let n=await nl({json:t.json,skipUpdateCheck:t.skipUpdateCheck});process.exit(n)},logs:async(e)=>{process.exit(await Ci(e))},gui:async(e)=>{process.exit(await zc(e))},explain:async(e)=>{process.exit(await cl(e))}};async function c1(){let e=process.argv.slice(2),t=T({label:"cc-safety-net",booleans:{version:["-V","--version"]},positionals:"list"},e);if(a1(e))return;let n=e[0],r=n?Yt(n):void 0;if(t.help&&r&&r.name!=="rule")Ft(r.name),process.exit(0);if(!n||t.help&&!r)co(),process.exit(0);if(t.flags.version)pl(),process.exit(0);if(r){await l1[r.name](e.slice(1));return}let o=ns(n);if(o){await o.run();return}if(n==="--statusline"){await Ao();return}console.error(n.startsWith("-")?`Unknown option: ${n}`:`Unknown command: ${n}`),console.error("Run 'cc-safety-net --help' for usage."),process.exit(1)}c1().catch((e)=>{console.error("CC Safety Net error:",e),process.exit(1)});