cc-safety-net 2.0.3 → 2.0.5

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,43 +1,43 @@
1
1
  #!/usr/bin/env node
2
- import{$ as nr,$a as Ue,A as Ln,Aa as Ze,B as Nl,Ba as Nt,C as P,Ca as Qe,D as U,Da as Xe,E as Mt,Ea as O,F as Qt,Fa as Ht,G as Hn,Ga as Gt,H as Xt,Ha as Ct,I as G2,Ia as T,J as $2,Ja as g3,K as Ut,Ka as vn,L as s2,La as D3,M as b1,Ma as fe,N as It,Na as m3,O as An,Oa as k3,P as f1,Pa as q3,Q as y1,Qa as ct,R as Rn,Ra as j3,S as Vn,Sa as F3,T as fn,Ta as r1,U as yn,Ua as e1,V as Ee,Va as a1,W as pn,Wa as l1,X as g2,Xa as r3,Y as Ot,Ya as Ge,Z as C2,Za as Ce,_ as h1,_a as At,aa as $1,ab as Oe,b as $e,ba as g1,bb as o2,c as ge,ca as _e,cb as x2,d as A,da as je,db as l2,e as De,ea as Pe,eb as Te,f as zt,fa as Ne,fb as W,g as Z,ga as Ie,gb as bn,h as D,ha as Tt,hb as un,i as dn,ia as Fe,ib as x1,j as g,ja as m,jb as hn,k as w2,ka as Et,kb as c2,l as Ae,la as w1,lb as B1,m as A2,ma as d2,mb as Wn,n as sn,na as on,o as s3,oa as _t,p as Zt,pa as Pt,q as We,qa as n1,r as cn,ra as t1,s as Re,sa as ze,t as Kt,ta as K2,u as Ve,ua as Yt,v as Ke,va as St,w as E,wa as Me,x as _,xa as S2,y as R2,ya as $3,z as V2,za as Je}from"../chunks/index-3k09xczv.js";var X3=["-h","--help"];function F(n,t){let r=Object.entries(n.booleans??{}),e=Object.entries(n.values??{}),a=Object.fromEntries(r.map(([i])=>[i,!1])),l={},d=[],s=[],c=!1,L=-1;for(let[i,u]of t.entries()){if(i<=L)continue;if(u==="--"){d.push(...t.slice(i+1));break}if(X3.includes(u)){c=!0;continue}let v=r.find(([,f])=>f.includes(u));if(v){a[v[0]]=!0;continue}let p=e.find(([,f])=>f.includes(u));if(p){let f=t[i+1];if(f===void 0||f.startsWith("-")){s.push(`${u} requires a value`);continue}l[p[0]]=f,L=i+1;continue}if(u.startsWith("-")){s.push(`Unknown option for ${n.label}: ${u}`);continue}if(n.positionals==="tail"){d.push(...t.slice(i));break}d.push(u)}if(n.positionals!=="list"&&n.positionals!=="tail")s.push(...d.map((i)=>`Unexpected argument for ${n.label}: ${i}`));return{flags:a,values:l,positionals:d,help:c,errors:s}}function e2(n){for(let t of n)console.error(t);return n.length>0}import{readdirSync as wd,statSync as s1,unlinkSync as xd}from"node:fs";import{basename as c1,dirname as $d,join as gd,resolve as Dd}from"node:path";function z(n){return Array.from(n,(t)=>{let r=t.charCodeAt(0);if(r<=31||r>=127&&r<=159)return`\\x${r.toString(16).padStart(2,"0")}`;return t}).join("")}var kt=(n)=>{let t=Date.now()-new Date(n).getTime();if(!Number.isFinite(t))return"";let r=Math.floor(t/60000),e=Math.floor(r/60),a=Math.floor(e/24);if(a>0)return`${a}d ago`;if(e>0)return`${e}h ago`;if(r>0)return`${r}m ago`;return"just now"},Q2=(n)=>{let t=(n??"").trim().split(/\s+/).filter((a)=>a&&!/^[A-Za-z_][A-Za-z0-9_]*=/.test(a)),r=t[0]?.split("/").pop();if(!r)return null;let e=t[1];return e&&/^[a-z][a-z0-9-]*$/.test(e)?`${r} ${e}`:r};import{existsSync as Y3,readdirSync as S3,readFileSync as H3}from"node:fs";import{join as A3}from"node:path";function u2(n,t){try{return S3(n,{withFileTypes:!0,encoding:"utf8"}).flatMap((r)=>{let e=A3(n,r.name);if(r.isDirectory())return u2(e,t);if(r.name.endsWith(".jsonl"))return[e];return[]})}catch{if(t&&Y3(n))t.count++;return[]}}function qt(n){let t=(a)=>`${a.sessionId}
3
- ${Q2(a.segment||a.command)}`,r=n.filter((a)=>a.decision!=="allow"),e=r.filter((a)=>a.sessionId).reduce((a,l)=>a.set(t(l),(a.get(t(l))??0)+1),new Map);return new Set(r.filter((a)=>a.failureStage||(e.get(t(a))??0)>=2))}function ln(n,t){try{return H3(n,"utf-8").split(`
4
- `).filter(Boolean).flatMap((r)=>{try{return[JSON.parse(r)]}catch{if(t)t.count++;return[]}})}catch{if(t)t.count++;return[]}}import{resolve as pd}from"node:path";var W3=["AKIA","ASIA","ghp_","gho_","ghu_","ghs_","ghr_","github_pat_","glpat-","xox","npm_","pypi-","rk_","sk-","sk_","gsk_","xai-","pplx-","bastn_","tgp_v1_","flp_","wfr_","fw_","fwp_","tp-","psk-"];function me(n){let t=0,r={allocateSegment(){return t++},getNextSegmentIndex(){return t},recordGlobal(e){n.record({kind:"step",scope:"global",step:e})},recordSegment(e,a=r.currentSegmentIndex){if(a===void 0)return;n.record({kind:"step",scope:"segment",segmentIndex:a,step:e})}};return r}function ke(n={}){let t=[],r=n.maxEvents??512,e={maxTextLength:n.maxTextLength??2048,maxListLength:n.maxListLength??128,maxObjectProperties:n.maxObjectProperties??n.maxListLength??128,maxDepth:n.maxDepth??16},a=0,l,d=new Set;return{record(s){if(l)return;try{if(!s||t.length>=r){a++;return}t.push(Ft(R3(s,e,d)))}catch{a++}},finish(s){if(l)return l;try{l=Ft({events:Object.freeze(t),droppedEvents:a,terminal:V3(s,e,d)})}catch{a++,l=Object.freeze({events:Object.freeze(t),droppedEvents:a,terminal:Object.freeze({result:"blocked",reason:"trace unavailable".slice(0,e.maxTextLength),segment:"trace unavailable".slice(0,e.maxTextLength)})})}return l}}}function R3(n,t,r){if(n.kind!=="step")throw TypeError("invalid trace event");let{scope:e,step:a}=n;Xn(a,r,t);let l=X2(a,t,r);if(e==="global")return{kind:"step",scope:"global",step:l};if(e!=="segment")throw TypeError("invalid trace event scope");return{kind:"step",scope:"segment",segmentIndex:n.segmentIndex,step:l}}function V3(n,t,r){let e=n.result;if(e==="allowed")return Object.freeze({result:"allowed"});if(e!=="blocked")throw TypeError("invalid trace terminal");let a=n.ruleId;return Object.freeze({result:"blocked",reason:X2(n.reason,t,r),segment:X2(n.segment,t,r),...a?{ruleId:X2(a,t,r)}:{}})}function Xn(n,t,r,e=0,a=new WeakSet){if(typeof n==="string"){let s=n.slice(0,r.maxTextLength);if(!zt(s))return;for(let c of De(s))for(let L of c.match(/[^\s"'()$]+/g)??[])t.add(qe(L));return}if(!n||typeof n!=="object"||e>=r.maxDepth||a.has(n))return;if(a.add(n),Array.isArray(n)){let s=Math.min(n.length,r.maxListLength);for(let c=0;c<s;c++)Xn(n[c],t,r,e+1,a);return}let l=0,d=new Set;for(let s in n){if(!Object.hasOwn(n,s))continue;if(l>=r.maxObjectProperties)break;l++,Xn(s,t,r);let c=jt(s,r,t);if(d.has(c))continue;d.add(c),Xn(n[s],t,r,e+1,a)}}function X2(n,t,r,e=0,a=new WeakSet){if(typeof n==="string")return jt(n,t,r);if(!n||typeof n!=="object")return n;if(e>=t.maxDepth)return;if(a.has(n))return;if(a.add(n),Array.isArray(n)){let s=[],c=Math.min(n.length,t.maxListLength);for(let L=0;L<c;L++)s.push(X2(n[L],t,r,e+1,a));return s}let l={},d=0;for(let s in n){if(!Object.hasOwn(n,s))continue;if(d>=t.maxObjectProperties)break;d++;let c=jt(s,t,r);if(Object.hasOwn(l,c))continue;Object.defineProperty(l,c,{value:X2(n[s],t,r,e+1,a),enumerable:!0,configurable:!0,writable:!0})}return l}function jt(n,t,r){let e=n.slice(0,t.maxTextLength),a=zt(e)?ge(e):e,l=r.size>0?M3(a,r):a;return(K3(l)?$e(l):l).slice(0,t.maxTextLength)}function K3(n){return n.includes("PRIVATE KEY")||n.includes("://")||n.includes("eyJ")||n.includes(":")&&/(?:authorization|cookie|x-api-key|api-key|(?:^|\s)(?:-u|--user)(?:\s|=))/i.test(n)||n.length>=14&&W3.some((t)=>n.includes(t))||n.length>=49&&/\b[a-f0-9]{32}\.[A-Za-z0-9]{16}\b/.test(n)}function M3(n,t){return n.replace(/[^\s"'()$]+/g,(r)=>t.has(qe(r))?"<redacted>":r)}function qe(n){let t=2166136261,r=2166136261;for(let e=0;e<n.length;e++)t=Math.imul(t^n.charCodeAt(e),16777619),r=Math.imul(r^n.charCodeAt(n.length-e-1),16777619);return`${t>>>0}:${r>>>0}:${n.length}`}function Ft(n){if(n&&typeof n==="object"&&!Object.isFrozen(n)){for(let t of Object.values(n))Ft(t);Object.freeze(n)}return n}function Be(n,t,r,e){let a=e??je(),l=r??a.getCommandProgram(n,t.shell??"auto"),d=ke(),s=me(d),c=l.dialect==="powershell"?a.getCommandProgram(n,"posix"):l,L=Fe(c);s.recordGlobal({type:"parse",input:n,segments:L.map((v)=>[...v])});let i=ze(n,{...t,analyzePartialProgram:!0,trace:s},l,a),u=s.getNextSegmentIndex();if(i&&u>0&&u<L.length)s.recordSegment({type:"segment-skipped",index:u,reason:"prior-segment-blocked"},u);return Object.freeze({decision:i,trace:d.finish(i?{result:"blocked",reason:i.reason,segment:i.evidence.find((v)=>v.kind==="command")?.segment??n,...i.ruleId?{ruleId:i.ruleId}:{}}:{result:"allowed"}),program:l})}import{resolve as G3}from"node:path";function Bt(n){let t=Je().safeParse(n);return{errors:t.success?[]:Qe(t.error.issues),ruleNames:new Set(Ze(n).map((r)=>r.toLowerCase()))}}function Jt(n){let t=Ye(n);if(!t.ok)return t.result;return Bt(t.parsed)}function Ye(n){let t=[],r=new Set;try{let e=typeof n==="string"?dn(n):n,a=g(e);if(a===null)return t.push(`File not found: ${e.path}`),{ok:!1,result:{errors:t,ruleNames:r}};if(!a.trim())return t.push("Config file is empty"),{ok:!1,result:{errors:t,ruleNames:r}};return{ok:!0,parsed:JSON.parse(a)}}catch(e){return t.push(e instanceof Z?e.message:"Invalid JSON"),{ok:!1,result:{errors:t,ruleNames:r}}}}function Se(n){return G3(n??process.cwd(),".safety-net.json")}function a2(n){let t=Ye(n);if(!t.ok)return t.result;let r=Xe(t.parsed);return{errors:r.errors,ruleNames:r.sources}}import{isAbsolute as C3,join as Yn,relative as U3,resolve as He,sep as O3}from"node:path";async function W2(n={}){let t=Rt(n);return T3(t,await Sn(t,S2()))}function T3(n,t){if(!t.ok)return t;let r=U(n),e=[...new Set(l2(r.configPath,r.lockPath,n,r.filesystemScope))];if(e.length===0)return t;return{ok:!1,errors:e,warnings:t.warnings,entries:t.entries}}async function Sn(n,t,r,e={}){let a=null,l=!1;try{let d=U(n),s=Ht(d.configTarget);if(!s.ok)return s.result;let c=s.config;if(n.check)return nd(c,d,n);a={target:d.lockTarget,content:g(d.lockTarget)};let L=At(d.lockTarget);if(L.errors.some((y)=>y.startsWith("Unable to access ")))return{ok:!1,errors:L.errors,warnings:[],entries:[]};if(n.only&&L.errors.length>0)return{ok:!1,errors:L.errors,warnings:[],entries:[]};let i=L.errors.length>0?null:L.lock,u=n.only?Ge(c,i,n.only):{ok:!0,specs:c.rules};if(!u.ok)return u.result;if(n.only&&!i&&u.specs.length<c.rules.length)return{ok:!1,errors:[`No lockfile available for partial update; run ${Ke}`],warnings:[],entries:[]};let v=(await _3(u.specs,(y)=>Ue(y,d.configDir,n,i,d.filesystemScope,t),t)).map((y)=>td(y,i,r));for(let y of v)ad(y.content,y.entry,d.configDir,n,d.filesystemScope);let p=n.only?rd(c,i,v):v.map((y)=>y.entry);l=!0,T(d.lockTarget,{version:1,rulebooks:p},void 0,e._testAfterPolicyRename);let f=new Map(v.map((y)=>[y.entry.spec,y.rulebook.rules.length])),o=ld(p,d.configDir,n,d.filesystemScope,e);return{ok:!0,errors:[],warnings:o,entries:p.map((y)=>ed(y,f))}}catch(d){if(l&&a)try{Y2(a.target,a.content)}catch(s){return H2(s)}return H2(d)}}async function Wt(n,t={}){return E3(n,Rt(t),S2())}async function E3(n,t,r,e={}){let a=null,l=!1;try{let d=U(t),s=g(d.configTarget);a={target:d.configTarget,content:s};let c=Ht(d.configTarget);if(!c.ok)return c.result;let L=c.config,i=Ve(n)?await Oe(n,r):[{spec:n}],u=i.map((f)=>f.spec),v=[...new Set([...L.rules,...u])];if(v.length>Yt)return P3();if(v.length!==L.rules.length)l=!0,T(d.configTarget,{version:1,rules:v,overrides:L.overrides??{},transparent_wrappers:L.transparent_wrappers??[]},void 0,e._testAfterPolicyRename);let p=await Sn(t,r,new Map(i.filter((f)=>!!f.display_ref).map((f)=>[f.spec,f.display_ref])),e);if(!p.ok)Y2(d.configTarget,s);return p}catch(d){if(l&&a)try{Y2(a.target,a.content)}catch(s){return H2(s)}return H2(d)}}async function _3(n,t,r=S2()){if(n.length>Yt)throw Error(St);let e=Array(n.length),a=0,l,d=Array.from({length:Math.min(n.length,Me.concurrency)},async()=>{while(!l){let s=a;if(s>=n.length)return;a++;try{e[s]=await t(n[s],s,r.controller.signal)}catch(c){if(!l)l={value:c},a=n.length,r.controller.abort(c);return}}});if(await Promise.all(d),l)throw l.value;return e}function P3(){return{ok:!1,errors:[St],warnings:[],entries:[]}}function Rt(n){return{cwd:n.cwd,cacheConfigDir:n.cacheConfigDir,userConfigDir:n.userConfigDir,userConfigPath:n.userConfigPath,projectConfigPath:n.projectConfigPath,global:n.global,check:n.check,only:n.only,refresh:n.refresh}}function N3(n){return{...Rt(n),deleteSource:n.deleteSource}}async function Vt(n,t={}){try{return await I3(n,N3(t),{})}catch(r){return H2(r)}}async function I3(n,t,r){let e=U(t),a=O(e.configTarget);if(a.errors.length>0)return{ok:!1,errors:a.errors,warnings:[],entries:[]};if(!a.config)return{ok:!1,errors:[`No config found at ${e.configPath}`],warnings:[],entries:[]};let l=At(e.lockTarget);if(l.errors.length>0)return{ok:!1,errors:l.errors,warnings:[],entries:[]};let d=Ce(a.config.rules,l.lock,n);if(!d.ok)return d.result;let s=t.deleteSource?dd(e.configDir,d.specs,l.lock,e.filesystemScope):{ok:!0,dirs:[]};if(!s.ok)return s.result;let c=g(e.configTarget);if(c===null)return H2(Error("Rules config is unavailable."));try{T(e.configTarget,{version:1,rules:a.config.rules.filter((u)=>!d.specs.includes(u)),overrides:a.config.overrides??{},transparent_wrappers:a.config.transparent_wrappers??[]},void 0,r._testAfterPolicyRename)}catch(u){throw Y2(e.configTarget,c),u}let L=await Sn(t,S2(),void 0,r);if(!L.ok)return Y2(e.configTarget,c),L;let i=cd(s.dirs,r,e.filesystemScope);if(!i.ok){Y2(e.configTarget,c);let u=await Sn(t,S2(),void 0,r);if(!u.ok)return{ok:!1,errors:[...i.result.errors,...u.errors],warnings:u.warnings,entries:u.entries};return i.result}return L}async function nd(n,t,r){let e=Te(n,t.lockPath,t.configDir,r,r.global?"user":"project",t.filesystemScope);return{ok:e.errors.length===0&&e.warnings.length===0,errors:[...e.errors,...e.warnings],warnings:[],entries:e.entries}}function td(n,t,r){let e=t?.rulebooks.find((l)=>l.spec===n.entry.spec&&l.kind==="github"),a=r?.get(n.entry.spec)??(e?.kind==="github"?e.display_ref:void 0);if(!a||n.entry.kind!=="github")return n;return{...n,entry:{...n.entry,display_ref:a}}}function rd(n,t,r){let e=new Set(n.rules),a=new Set(t?.rulebooks.map((d)=>d.spec)??[]),l=new Map(r.map((d)=>[d.entry.spec,d.entry]));return[...(t?.rulebooks.filter((d)=>e.has(d.spec))??[]).map((d)=>l.get(d.spec)??d),...r.filter((d)=>!a.has(d.entry.spec)).map((d)=>d.entry)]}function ed(n,t){return{...n,ruleCount:t.get(n.spec)}}function ad(n,t,r,e,a){let l=Qt(t,Xt(r,e));w2(D(a,l),n)}function ld(n,t,r,e,a){let l=Xt(t,r),d=Hn(l),s=D(e,d),c=A2(s);if(!c)return[];let L=n.map((u)=>D(e,Qt(u,l))),i=c.filter((u)=>u.kind==="directory").map((u)=>({directory:D(e,Yn(d,u.name)),identity:D(e,Yn(d,u.name,Re))})).filter((u)=>!L.some((v)=>Ae(u.identity,v))).map((u)=>u.directory);for(let u of i)We(u);return i.flatMap((u)=>{try{return Ld(u,a),[]}catch{return["Unable to prune rules policy cache safely."]}})}function dd(n,t,r,e){let a=new Map(r?.rulebooks.map((L)=>[L.spec,L])??[]),l=t.flatMap((L)=>{let i=a.get(L);if(!i)return cn.test(L)?[]:["--delete-source can only delete local rulebook sources"];return i.kind==="local-directory"?[]:["--delete-source can only delete local rulebook sources"]}),d=t.map((L)=>{let i=a.get(L);return Yn(n,i?.kind==="local-directory"?i.path:L)}),s=l.length>0?[]:d.flatMap((L)=>sd(n,L,e)),c=[...l,...s];return c.length>0?{ok:!1,result:{ok:!1,errors:c,warnings:[],entries:[]}}:{ok:!0,dirs:d}}function sd(n,t,r){let e=He(n),a=He(t),l=U3(e,a);if(l===""||l===".."||l.startsWith(`..${O3}`)||C3(l))return[`Refusing to delete local rulebook source outside ${n}: ${t}`];let d=D(r,a),s=A2(d);if(!s)return[`Local rulebook source directory not found: ${t}`];let c=s.find((L)=>L.name==="rulebook.json");if(!c)return[`Local rulebook source directory is missing rulebook.json: ${t}`];if(c.kind!=="file")throw new Z(r.label);if(g(D(r,Yn(a,"rulebook.json"))),s.length>1)return[`Local rulebook source directory contains extra files: ${t}. delete manually if you really want to remove the directory.`];return[]}function cd(n,t,r){let e=n.flatMap((a)=>{try{return id(D(r,a),t),[]}catch(l){return[`Failed to delete local rulebook source ${a}: ${l instanceof Error?l.message:String(l)}`]}});return e.length>0?{ok:!1,result:{ok:!1,errors:e,warnings:[],entries:[]}}:{ok:!0}}function Ld(n,t){if(t._testPruneRulebookCacheDir){t._testPruneRulebookCacheDir(n.path);return}Zt(n)}function id(n,t){if(t._testDeleteLocalSourceDir){t._testDeleteLocalSourceDir(n.path);return}Zt(n)}function Y2(n,t){if(t===null){sn(n);return}w2(n,t)}function H2(n){return{ok:!1,errors:[n instanceof Error?n.message:String(n)],warnings:[],entries:[]}}function M2(n,t){let r=od(t),e=n1(r),a={effectiveLevel:e.effectiveLevel,selectedPreset:r.policySnapshot.policy.safety.level??"standard",effectiveCapabilities:e.effectiveCapabilities,destructiveCommandRuleOverrides:r.policySnapshot.policy.destructiveCommandRuleOverrides},{configSource:l,configValid:d}=ud({cwd:t?.cwd,userConfigDir:t?.userConfigDir});if(!n||!n.trim())return{trace:{steps:[{type:"error",message:"No command provided"}],segments:[]},result:"allowed",configSource:l,configValid:d,...a};let s=vd(n,r);if(s)return{trace:{steps:[],segments:[{index:0,steps:[{type:"rule-check",ruleModule:s.ruleModule,ruleFunction:s.ruleFunction,matched:!0,reason:s.reason}]}]},result:"blocked",reason:A(s.reason),segment:A(s.target),...s.ruleId?{ruleId:A(s.ruleId)}:{},configSource:l,configValid:d,...a};let c=Be(n,r),L=c.decision,i=L?.ruleId??bd(n,r),u=pn.find((p)=>p.id===i&&p.activationCapability),v=u?e.policy.effectiveDestructiveCommandRules[u.id]:void 0;return{trace:yd(c.trace),result:L?"blocked":"allowed",reason:L?A(L.reason):void 0,segment:L?A(L.evidence.find((p)=>p.kind==="command")?.segment??n):void 0,ruleId:L?.ruleId?A(L.ruleId):void 0,customRule:fd(hd(L?.ruleId,r.policySnapshot)),configSource:l,configValid:d,...a,...u&&v?{ruleActivation:{id:u.id,...v}}:{}}}function ud(n){let t=E(n?.cwd),r=n?.userConfigPath??_(n),e=P({cwd:n?.cwd,userConfigDir:n?.userConfigDir,userConfigPath:n?.userConfigPath});try{if(g(e.projectConfigTarget)!==null){if(a2(e.projectConfigTarget).errors.length===0)return{configSource:t,configValid:!0};return{configSource:t,configValid:!1}}}catch(a){if(a instanceof Z)return{configSource:t,configValid:!1};throw a}try{if(g(e.userConfigTarget)!==null){let a=a2(e.userConfigTarget);return{configSource:r,configValid:a.errors.length===0}}return{configSource:null,configValid:!0}}catch(a){if(a instanceof Z)return{configSource:r,configValid:!1};throw a}}function od(n){let t=pd(n?.cwd??process.cwd()),r=n?.policySnapshot??W({cwd:t,userConfigDir:n?.userConfigDir}),e=d2(r.policy);return{cwd:t,effectiveCwd:t,policySnapshot:r,environment:Ee(),protectedGitMetadata:Ie(t),effectiveCapabilities:e.capabilities,strict:n?.strict??e.strict,paranoidRm:e.paranoidRm,paranoidInterpreters:e.paranoidInterpreters,worktreeMode:e.worktreeMode}}function vd(n,t){let r=t.cwd??process.cwd(),e=_e(K2("",{command:n},{kind:"command",shell:"posix"},{executionCwd:r,configCwd:r},n)),a=e1(e);if(a)return{reason:r1,target:a.target,ruleId:"policy-protection",ruleModule:"policy-protection",ruleFunction:"findPolicyConfigMutationTarget"};let l=Ne(e,t.protectedGitMetadata);if(l)return{reason:Pe,target:l.target,ruleId:"git-metadata-protection",ruleModule:"git-metadata-protection",ruleFunction:"findGitMetadataMutationTarget"};let d=t.policySnapshot.policy,s=d.secretProtection.enabled===!1?null:l1(e,d.secretProtection,{strict:t.strict});if(s)return{reason:a1,target:s.target,ruleId:s.ruleId,ruleModule:"secret-protection",ruleFunction:"findSensitiveTarget"};return null}function bd(n,t){let r=t.policySnapshot.policy,e=un({...r,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:{...r.destructiveCommandRuleOverrides,...Object.fromEntries(pn.flatMap((a)=>a.activationCapability?[[a.id,"on"]]:[]))}},t.policySnapshot.state==="degraded"?{diagnostics:t.policySnapshot.diagnostics,reason:t.policySnapshot.reason}:void 0);return t1(n,{...t,policySnapshot:e,strict:!0,paranoidRm:!0,paranoidInterpreters:!0})?.ruleId}function fd(n){if(!n)return;return{id:A(n.id),...n.rulebook?{rulebook:{name:A(n.rulebook.name),version:A(n.rulebook.version)}}:{},...n.source?{source:A(n.source)}:{},...n.override?{override:{type:"reason",reason:A(n.override.reason)}}:{}}}function yd(n){let t=n.events.flatMap((e)=>e.kind==="step"&&e.scope==="global"?[e.step]:[]),r=new Map;for(let e of n.events){if(e.kind!=="step"||e.scope!=="segment")continue;let a=r.get(e.segmentIndex)??{index:e.segmentIndex,steps:[]};a.steps.push(e.step),r.set(e.segmentIndex,a)}return{steps:t,segments:[...r.values()]}}function hd(n,t){let r=n?.replace(/^custom\./,"");if(!r||!t.policy.rules.some((e)=>e.name===r))return;return t.ruleMetadata[r]??Object.freeze({id:r})}function md(n){let t=G2(),r=F({label:"logs",booleans:{all:["--all"],suspect:["--suspect"],json:["--json"],pruneLegacy:["--prune-legacy"],dryRun:["--dry-run"]},values:{id:["--id"],limit:["--limit"],since:["--since"],agent:["--agent"],rule:["--rule"],session:["--session"],project:["--project"]}},n);if(e2(r.errors))return null;if(r.values.id!==void 0&&!/^[a-f0-9]{16}$/.test(r.values.id))return console.error("--id must be 16 hexadecimal characters"),null;let e=r.values.limit===void 0?20:d1(r.values.limit);if(e===null)return console.error("--limit must be a positive number"),null;let a=r.values.since===void 0?Math.min(30,t):d1(r.values.since);if(a===null||a>t)return console.error(`--since must be a positive number of days no greater than ${t}`),null;let l={limit:e,limitExplicit:r.values.limit!==void 0,since:a,sinceExplicit:r.values.since!==void 0,all:r.flags.all,json:r.flags.json,suspect:r.flags.suspect,pruneLegacy:r.flags.pruneLegacy,dryRun:r.flags.dryRun,id:r.values.id,agent:r.values.agent,rule:r.values.rule,session:r.values.session,project:r.values.project===void 0?void 0:Dd(r.values.project)};if(l.id&&(l.agent!==void 0||l.rule!==void 0||l.session!==void 0||l.project!==void 0||l.suspect||l.sinceExplicit||l.limitExplicit))return console.error("--id cannot be combined with --agent, --rule, --session, --project, --suspect, --since, or --limit"),null;if(l.pruneLegacy&&(l.id!==void 0||l.agent!==void 0||l.rule!==void 0||l.session!==void 0||l.project!==void 0||l.suspect||l.all||l.sinceExplicit||l.limitExplicit))return console.error("--prune-legacy cannot be combined with --id, --agent, --rule, --session, --project, --suspect, --all, --since, or --limit"),null;if(l.dryRun&&!l.pruneLegacy)return console.error("--dry-run requires --prune-legacy"),null;return l}async function L1(n,t={}){let r=md(n);if(!r)return 1;let e=t.logsDir??s2();if(r.pruneLegacy)return kd(e,r.json,r.dryRun);if(!e)return console.log(r.json?"[]":r.id?`No retained audit log entry found for id ${z(r.id)}.`:"No audit log entries found."),0;$2(e);let a={count:0},l=u2(e,a).flatMap((i)=>ln(i,a).map((u)=>({entry:u,file:i})));if(a.count>0)console.error(`warning: ${a.count} audit log ${a.count===1?"source":"sources"} could not be read; these results are incomplete`);if(r.id)return zd(l,r,t.timeZone);let d=Date.now()-r.since*24*60*60*1000,s=l.filter((i)=>Bd(i,r,e,d)),c=r.suspect?qt(s.map((i)=>i.entry)):null,L=(c?s.filter((i)=>c.has(i.entry)):s).sort((i,u)=>Date.parse(u.entry.ts)-Date.parse(i.entry.ts)).slice(0,r.limit);if(r.json)return console.log(JSON.stringify(L.map((i)=>i.entry),null,2)),0;if(L.length===0)return console.log("No audit log entries found."),0;for(let i of L)console.log(Qd(i.entry,t.timeZone));return 0}function kd(n,t,r){let e=n?jd(n).map((s)=>gd(n,s)):[];if(r)return qd(e,t);let a=[],l=0,d=0;for(let s of e){let c=s1(s,{throwIfNoEntry:!1})?.size??0,L=Fd(s);if(L){a.push(`${c1(s)}: ${L}`);continue}l++,d+=c}if(t)return console.log(JSON.stringify({removedFiles:l,removedBytes:d,failedFiles:a.length})),a.length===0?0:1;console.log(l===0&&a.length===0?"No legacy audit log files found.":`Removed ${l} legacy audit log ${l===1?"file":"files"} (${i1(d)}).`);for(let s of a)console.error(`Could not remove ${z(s)}`);if(console.log("Nested v2 audit logs were not changed."),l>0)console.log("This deletion cannot be undone.");return a.length===0?0:1}function qd(n,t){let r=n.reduce((e,a)=>e+(s1(a,{throwIfNoEntry:!1})?.size??0),0);if(t)return console.log(JSON.stringify({dryRun:!0,files:n.length,bytes:r})),0;if(console.log(n.length===0?"No legacy audit log files found.":`Would remove ${n.length} legacy audit log ${n.length===1?"file":"files"} (${i1(r)}).`),console.log("Nested v2 audit logs are not included."),n.length>0)console.log("Run the same command without --dry-run to delete them.");return 0}function jd(n){try{return wd(n,{withFileTypes:!0}).filter((t)=>t.isFile()&&t.name.endsWith(".jsonl")).map((t)=>t.name)}catch{return[]}}function Fd(n){try{return xd(n),null}catch(t){return t instanceof Error?t.message:String(t)}}function i1(n){let t=["B","KiB","MiB","GiB"],r=Math.min(Math.floor(Math.log2(Math.max(n,1))/10),t.length-1);return`${Math.round(n/1024**r*10)/10} ${t[r]}`}function zd(n,t,r){let e=n.filter((l)=>l.entry.id===t.id);if(e.length>1)return console.error(`Multiple audit log entries found for id ${z(t.id??"")}.`),1;if(t.json)return console.log(JSON.stringify(e.map((l)=>l.entry),null,2)),0;let a=e[0];if(!a)return console.log(`No retained audit log entry found for id ${z(t.id??"")}.`),0;return console.log(Xd(a.entry,r)),0}function Bd(n,t,r,e){if(!t.all&&n.entry.decision==="allow")return!1;if(Date.parse(n.entry.ts)<e)return!1;if(t.agent!==void 0&&n.entry.agent!==t.agent)return!1;if(t.rule!==void 0&&n.entry.ruleId!==t.rule)return!1;if(t.session!==void 0&&!Jd(n,r,t.session))return!1;if(t.project!==void 0&&!Zd(n.entry.cwd,t.project))return!1;return!0}function Jd(n,t,r){if(n.entry.sessionId===r)return!0;return $d(n.file)===t&&c1(n.file,".jsonl")===r}function Zd(n,t){if(!n)return!1;return n===t||n.startsWith(`${t}/`)}function Qd(n,t){let r=z(n.id??"-"),e=z(n.decision??"deny"),a=n.cwd?` [${z(n.cwd)}]`:"",l=n.segment||n.command,d=l===n.command?"":"↳ ",s=l.length>50?`${l.slice(0,50)}…`:l;return`${r.padEnd(16)} ${z(p1(n.ts,t))} ${e.padEnd(5)} ${z(n.agent??"-").padEnd(15)} ${z(n.ruleId??"-").padEnd(20)} ${d}${z(s)}${a}`}function Xd(n,t){let r=(a)=>z(a===void 0||a===null||a===""?"-":a),e=n.shape?`${n.agent??"-"} (shape: ${n.shape})`:n.agent??"-";return[`id: ${r(n.id)}`,`ts: ${r(p1(n.ts,t))}`,`decision: ${r(n.decision)}`,`agent: ${r(e)}`,`level: ${r(n.level)}`,`tool: ${r(n.toolName)}`,`rule: ${r(n.ruleId)}`,`intent: ${r(n.intent)}`,`stage: ${r(n.failureStage)}`,`error: ${r(n.errorCode)}`,`session: ${r(n.sessionId)}`,`cwd: ${r(n.cwd)}`,`version: ${r(n.v)}`,`truncated: ${r(n.truncated===!0?"yes":void 0)}`,`reason: ${r(n.reason)}`,`command: ${r(n.command)}`,`segment: ${r(n.segment)}`].join(`
5
- `)}function p1(n,t){let r=new Date(n);if(Number.isNaN(r.getTime()))return n;return new Intl.DateTimeFormat("sv-SE",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hourCycle:"h23",timeZone:t}).format(r)}function d1(n){let t=Number(n);return Number.isFinite(t)&&t>0?t:null}var u1={name:"doctor",aliases:["--doctor"],description:"Run diagnostic checks to verify installation and configuration",usage:"doctor [options]",options:[{flags:"--json",description:"Output diagnostics as JSON"},{flags:"--skip-update-check",description:"Skip npm registry version check"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net doctor","cc-safety-net doctor --json","cc-safety-net doctor --skip-update-check"]};var o1={name:"explain",description:"Show step-by-step analysis trace of how a command would be analyzed",usage:"explain [options] <command>",argument:"<command>",options:[{flags:"--json",description:"Output analysis as JSON"},{flags:"--cwd",argument:"<path>",description:"Use custom working directory"},{flags:"-h, --help",description:"Show this help"}],examples:['cc-safety-net explain "git reset --hard"','cc-safety-net explain --json "rm -rf /"','cc-safety-net explain --cwd /tmp "git status"']};var v1={name:"gui",description:"Open the local policy editor GUI",usage:"gui [options]",options:[{flags:"--no-open",description:"Print the URL without opening a browser"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net gui","cc-safety-net gui --no-open"]};import{isAbsolute as D1,relative as Cd}from"node:path";var Yd=8388608;function Sd(n,t){console.log(JSON.stringify(n(f1(t))))}async function Hd(n){let t;try{t=(await tr(process.stdin)).trim()}catch{n({reason:"Failed to parse hook input JSON."});return}if(!t){n({reason:"Missing hook input JSON."});return}return rr(t,n,"Failed to parse hook input JSON.")}async function tr(n){let t=[],r=0;for await(let e of n){let a=typeof e==="string"?Buffer.from(e,"utf-8"):Buffer.from(e.buffer,e.byteOffset,e.byteLength);if(r+=a.byteLength,r>Yd)throw Ad(n),Error("hook input byte limit exceeded");t.push(a)}return Buffer.concat(t,r).toString("utf-8")}function Ad(n){let t=n.destroy??n.cancel;if(!t)return;try{Promise.resolve(t.call(n)).catch(()=>{})}catch{}}function rr(n,t,r){try{return JSON.parse(n)}catch{t({reason:r});return}}function X(n,t){let r=t.get(n);return r?{kind:"command",shell:r}:{kind:h1(n)}}function N(n,t,r,e){let a=n===void 0?process.cwd():n,l=typeof a==="string"&&a.trim()!==""?c2([a]):void 0;if(l)return{configCwd:l,executionCwd:l};return H(e,t,r,Kd(a)),null}function H(n,t,r,e){let a;try{a=nr(t)}catch(l){if(!(l instanceof C2))throw l}n(An({command:a,segment:e,toolName:r}))}async function Wd(n){let t=await Hd(n.outputDeny);if(t===void 0)return;if(!t||typeof t!=="object"||Array.isArray(t)){H(n.outputDeny);return}if(!n.isSupported(t))return;let r=n.getAgent?.(t)??n.agent,e=n.agent===r?void 0:n.agent,a=Gd(t),l=(p,f)=>{b1(p,()=>n.getSessionId(t),{agent:r,shape:e,toolName:f,cwd:a}),n.outputDeny(p)},d=n.getToolName(t);if(typeof d!=="string"||d.trim()===""){H((p)=>l(p),Md(t));return}let s=d,c=(p)=>l(p,s),L;try{L=n.getToolInput(t,s,c)}catch(p){if(!(p instanceof C2))throw p;H(c,void 0,s);return}if(!L.ok)return;let i=n.getContext(t,L.input,s,c);if(!i)return;let u;try{u=nr(L.input)}catch(p){if(!(p instanceof C2))throw p;H(c,void 0,s);return}let v=K2(s,L.input,L.route,i,u??null);try{let p=Wn(v,{guard:{auditAllowed:w1(),dependencies:n.guardDependencies},audit:{agent:r,shape:e,getSessionId:()=>n.getSessionId(t)}}),f=It(p,{includeEvidence:!0,toolName:p.stage==="command-analysis"?void 0:s});if(f){n.outputDeny(f);return}n.outputAllow?.()}catch(p){if(!(p instanceof x1))throw p;Rd(p);let f=It(p.evaluation,{includeEvidence:!0,toolName:p.evaluation.stage==="command-analysis"?void 0:s});if(f)n.outputDeny(f);return}}function Rd(n){if(!on(m.debug))return;console.error(`CC Safety Net debug: ${Vd(n.stage)}: ${y1(n.cause)}`)}function Vd(n){if(n==="policy-protection")return"hook policy protection failed";if(n==="config-load")return"hook config loading failed";if(n==="secret-protection")return"hook secret protection failed";return"hook analysis failed"}function Kd(n){return typeof n==="string"?n:void 0}function Md(n){if(!n||typeof n!=="object"||Array.isArray(n))return;if(Object.hasOwn(n,"tool_input"))return n.tool_input;let t=n.toolCall;if(t&&typeof t==="object"&&!Array.isArray(t))return t.args;return}function Gd(n){if(!n||typeof n!=="object"||Array.isArray(n))return null;let t=n.cwd;if(typeof t==="string")return t;let r=n.toolCall;if(!r||typeof r!=="object"||Array.isArray(r))return null;let e=r.args;if(!e||typeof e!=="object"||Array.isArray(e))return null;let a=e.Cwd;return typeof a==="string"?a:null}async function Y(n){let t=(a)=>Sd(n.createDenyOutput,a),r=n.createAllowOutput;await Wd({...n,outputDeny:t,outputAllow:r?()=>console.log(JSON.stringify(r())):void 0})}var Ud=new Map([["run_command","auto"]]),Od=new Set(["absolutepath","directorypath","file_path","filepath","path","searchdirectory","searchpath","target_file","targetfile"]);function m1(n){return X(n,Ud)}async function k1(){await Y({agent:"antigravity-cli",createDenyOutput:(n)=>({decision:"deny",reason:n}),isSupported:()=>!0,getToolName:(n)=>n.toolCall?.name,getToolInput:(n,t)=>({ok:!0,input:Nd(n.toolCall?.args,t),route:m1(t)}),getContext:Td,getSessionId:(n)=>n.conversationId})}function Td(n,t,r,e){let l=Pd(n).flatMap((L)=>{let i=c2([L]);return i?[i]:[]});if(!l[0])return D2(e,t,r),null;if(r!=="run_command"){let L;try{L=Ed(t,r,l)}catch(i){if(i instanceof C2)return D2(e,void 0,r),null;if(!(i instanceof Rn))throw i;return D2(e,t,r),null}if(!L)return D2(e,t,r),null;return{configCwd:L,executionCwd:L,policyConfigCwds:l}}let d=n.toolCall?.args;if(!d||!Object.hasOwn(d,"Cwd"))return{configCwd:l[0],executionCwd:l[0],policyConfigCwds:l};let s=d.Cwd;if(typeof s!=="string"||s.trim()==="")return D2(e,t,r),null;let c=hn(s,l);if(c){let L=q1(c,l);if(!L)return D2(e,t,r,s),null;return{configCwd:L,executionCwd:c,policyConfigCwds:l}}return D2(e,t,r,s),null}function Ed(n,t,r){let e=m1(t),a=[...$1(n,Od),...e.kind==="patch"?g1(n):[]].filter(D1),l=Vn(),d=new Set(a.flatMap((s)=>{let c=q1(fn(s,yn,l),r);return c?[c]:[]}));if(d.size>1)return null;return[...d][0]??r[0]??null}function q1(n,t){return t.filter((r)=>_d(n,r)).reduce((r,e)=>e.length>r.length?e:r,"")||null}function _d(n,t){let r=Cd(t,n);return r===""||!r.startsWith("..")&&!D1(r)}function D2(n,t,r,e){let a=t&&typeof t==="object"?t.command:void 0;n(An({command:typeof a==="string"?a:void 0,segment:e,toolName:r}))}function Pd(n){if(n.workspacePaths===void 0)return[process.cwd()];let t=Array.isArray(n.workspacePaths)?n.workspacePaths.filter((r)=>typeof r==="string"&&r.trim()!==""):[];return c2(t)?t:[]}function Nd(n,t){if(!n)return;if(t!=="run_command")return n;return{...n,command:typeof n.CommandLine==="string"&&n.CommandLine!==""?n.CommandLine:void 0}}var U2=[{id:"antigravity-cli",displayName:"Antigravity CLI",doctorOrder:3,runtime:{order:1,flags:["-ac","--agy-cli"],description:"Run as Antigravity CLI PreToolUse hook",legacyTopLevelFlags:[]},install:{order:2,flag:"--agy-cli",installLabel:"Antigravity CLI",helpTarget:"Antigravity CLI hook config",probeCommand:["agy","--version"]}},{id:"claude-code",displayName:"Claude Code",doctorOrder:1,runtime:{order:2,displayName:"Coding CLI",flags:["-cc","--coding-cli"],legacyFlags:["--claude-code"],description:"Run as Coding CLI PreToolUse hook",legacyTopLevelFlags:["-cc","--claude-code"]},install:{order:3,flag:"--claude-code",installLabel:"Claude Code",helpTarget:"Claude Code plugin",probeCommand:["claude","--version"]}},{id:"codex",displayName:"Codex",doctorOrder:4,install:{order:4,flag:"--codex",installLabel:"Codex",helpTarget:"Codex plugin",probeCommand:["codex","--version"]}},{id:"copilot-cli",displayName:"GitHub Copilot CLI",doctorOrder:7,runtime:{order:5,flags:["-cp","--copilot-cli"],description:"Run as GitHub Copilot CLI PreToolUse hook",legacyTopLevelFlags:["-cp","--copilot-cli"]},install:{order:7,flag:"--copilot-cli",installLabel:"GitHub Copilot CLI",helpTarget:"GitHub Copilot CLI plugin",probeCommand:["copilot","--binary-version"]}},{id:"gemini-cli",displayName:"Gemini CLI",doctorOrder:6,runtime:{order:4,flags:["-gc","--gemini-cli"],description:"Run as Gemini CLI BeforeTool hook",legacyTopLevelFlags:["-gc","--gemini-cli"]},install:{order:6,flag:"--gemini-cli",installLabel:"Gemini CLI",helpTarget:"Gemini CLI extension",probeCommand:["gemini","--version"]}},{id:"hermes-agent",displayName:"Hermes Agent",doctorOrder:8,runtime:{order:6,flags:["-ha","--hermes-agent"],description:"Run as Hermes Agent pre_tool_call hook",legacyTopLevelFlags:[]},install:{order:8,flag:"--hermes-agent",installLabel:"Hermes Agent",helpTarget:"Hermes Agent plugin",probeCommand:["hermes","--version"]}},{id:"kimi-code",displayName:"Kimi Code",doctorOrder:9,runtime:{order:7,flags:["-kc","--kimi-code"],description:"Run as Kimi Code PreToolUse hook",legacyTopLevelFlags:[]},install:{order:9,flag:"--kimi-code",installLabel:"Kimi Code",helpTarget:"Kimi Code hook config",probeCommand:["kimi","--version"]}},{id:"openclaw",displayName:"OpenClaw",doctorOrder:10,install:{order:10,flag:"--openclaw",installLabel:"OpenClaw",helpTarget:"OpenClaw plugin",probeCommand:["openclaw","--version"]}},{id:"opencode",displayName:"OpenCode",doctorOrder:11,install:{order:11,flag:"--opencode",installLabel:"OpenCode",helpTarget:"OpenCode plugin",probeCommand:["opencode","--version"]}},{id:"pi",displayName:"Pi",doctorOrder:12,install:{order:12,flag:"--pi",installLabel:"Pi",helpTarget:"Pi package",probeCommand:["pi","--version"]}},{id:"cursor",displayName:"Cursor",doctorOrder:5,runtime:{order:3,flags:["-cu","--cursor"],description:"Run as Cursor preToolUse hook",legacyTopLevelFlags:[]},install:{order:5,flag:"--cursor",installLabel:"Cursor",helpTarget:"Cursor hook config",probeCommand:["cursor","--version"]}},{id:"amp",displayName:"Amp Code",doctorOrder:2,install:{order:1,flag:"--amp",installLabel:"Amp Code",helpTarget:"Amp Code plugin",probeCommand:["amp","--version"]}}],j1=U2.slice().sort((n,t)=>n.doctorOrder-t.doctorOrder).map((n)=>n.id),F1=U2.filter((n)=>("runtime"in n)).slice().sort((n,t)=>n.runtime.order-t.runtime.order).map((n)=>({id:n.id,displayName:"displayName"in n.runtime?n.runtime.displayName:n.displayName,flags:n.runtime.flags,legacyFlags:"legacyFlags"in n.runtime?n.runtime.legacyFlags:[],description:n.runtime.description,legacyTopLevelFlags:n.runtime.legacyTopLevelFlags})),L2=U2.slice().sort((n,t)=>n.install.order-t.install.order).map((n)=>({id:n.id,...n.install})).map(({order:n,...t})=>t),z6=Object.fromEntries(U2.map((n)=>[n.id,n.displayName]));function v2(n){return U2.find((t)=>t.id===n)?.displayName??n}function b2(n){return U2.find((t)=>t.id===n)?.install.installLabel??n}import{homedir as Id}from"node:os";import{isAbsolute as z1,join as er}from"node:path";function J1(n){if(n!==void 0&&n!==null&&!z1(n))return"unknown";try{let t=Vn(),r=n?fn(n,yn,t):void 0,e=process.env.HOME||Id(),a=[["codex",process.env.CODEX_HOME||er(e,".codex")],["copilot-cli",process.env.COPILOT_HOME||er(e,".copilot")],["claude-code",process.env.CLAUDE_CONFIG_DIR||er(e,".claude")]],l=r?a.flatMap(([d,s])=>{if(!z1(s))return[];return B1(r,fn(s,yn,t))?[d]:[]}):[];if(l.length===1)return l[0]??"unknown";if(l.length>1)return"unknown"}catch(t){if(t instanceof Rn)return"unknown";return"unknown"}if(process.env.CLAUDECODE==="1"||Boolean(process.env.CLAUDE_CODE_ENTRYPOINT))return"claude-code";return"unknown"}var ar="PreToolUse",Z1="BeforeTool",Q1="pre_tool_call",lr="PreToolUse";var ns=new Map([["Bash","posix"],["PowerShell","powershell"]]);function ts(n){return X(n,ns)}async function X1(){await Y({agent:"claude-code",getAgent:(n)=>J1(n.transcript_path),createDenyOutput:(n)=>({hookSpecificOutput:{hookEventName:ar,permissionDecision:"deny",permissionDecisionReason:n}}),isSupported:(n)=>n.hook_event_name===ar,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:ts(t)}),getContext:(n,t,r,e)=>N(n.cwd,t,r,e),getSessionId:(n)=>n.session_id})}var rs=new Map([["bash","auto"],["Bash","auto"]]);function es(n){return X(n,rs)}async function Y1(){await Y({agent:"copilot-cli",createDenyOutput:(n)=>({permissionDecision:"deny",permissionDecisionReason:n}),isSupported:()=>!0,getToolName:(n)=>n.toolName,getToolInput:(n,t,r)=>{if(typeof n.toolArgs!=="string")return r({reason:"Failed to parse toolArgs JSON."}),{ok:!1};let e=rr(n.toolArgs,r,"Failed to parse toolArgs JSON.");if(e===void 0)return{ok:!1};return{ok:!0,input:e,route:es(t)}},getContext:(n,t,r,e)=>N(n.cwd,t,r,e),getSessionId:(n)=>typeof n.sessionId==="string"&&n.sessionId.trim()?n.sessionId:void 0})}var as=new Map([["Shell","auto"]]);function ls(n){return X(n,as)}async function S1(){await Y({agent:"cursor",createDenyOutput:(n)=>({permission:"deny",user_message:n,agent_message:n}),createAllowOutput:()=>({permission:"allow"}),isSupported:()=>!0,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:ls(t)}),getContext:ds,getSessionId:(n)=>n.conversation_id})}function ds(n,t,r,e){let a=ss(n);if(!a[0])return H(e,t,r),null;let l=hn(Ls(n.cwd),a);if(!l)return H(e,t,r,typeof n.cwd==="string"?n.cwd:void 0),null;if(t===null||typeof t!=="object"||Array.isArray(t))return{configCwd:l,executionCwd:l,policyConfigCwds:a};if(!Object.hasOwn(t,"working_directory"))return{configCwd:l,executionCwd:l,policyConfigCwds:a};let d=t.working_directory;if(typeof d!=="string"||d.trim()==="")return H(e,t,r),null;let s=hn(d,a);if(!s)return H(e,t,r,d),null;return{configCwd:l,executionCwd:s,policyConfigCwds:a}}function ss(n){return cs(n).flatMap((t)=>{let r=c2([t]);return r?[r]:[]})}function cs(n){if(n.workspace_roots===void 0)return typeof n.cwd==="string"&&n.cwd.trim()!==""?[n.cwd]:[];if(!Array.isArray(n.workspace_roots))return[];return n.workspace_roots.filter((t)=>typeof t==="string"&&t.trim()!=="")}function Ls(n){return typeof n==="string"&&n.trim()!==""?n:"."}var is=new Map([["run_shell_command","auto"]]);function ps(n){return X(n,is)}async function H1(){await Y({agent:"gemini-cli",createDenyOutput:(n)=>({decision:"deny",reason:n,systemMessage:n}),isSupported:(n)=>n.hook_event_name===Z1,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:ps(t)}),getContext:(n,t,r,e)=>N(n.cwd,t,r,e),getSessionId:(n)=>n.session_id})}import{resolve as us}from"node:path";var os=new Map([["terminal","posix"]]);async function A1(){await Y({agent:"hermes-agent",createDenyOutput:(n)=>({action:"block",message:n}),isSupported:(n)=>n.hook_event_name===Q1,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:X(t,os)}),getContext:vs,getSessionId:(n)=>n.session_id})}function vs(n,t,r,e){let a=N(n.cwd,t,r,e);if(!a)return null;if(!t||typeof t!=="object"||Array.isArray(t))return a;if(!Object.hasOwn(t,"workdir"))return a;let l=t.workdir;if(typeof l!=="string"||l.trim()==="")return H(e,t,r),null;let d=c2([us(a.configCwd,l)]);if(!d)return H(e,t,r,l),null;return{...a,executionCwd:d}}var bs=new Map([["Bash","posix"]]);function fs(n){return X(n,bs)}async function W1(){await Y({agent:"kimi-code",createDenyOutput:(n)=>({hookSpecificOutput:{hookEventName:lr,permissionDecision:"deny",permissionDecisionReason:n}}),isSupported:(n)=>n.hook_event_name===lr,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:fs(t)}),getContext:(n,t,r,e)=>N(n.cwd,t,r,e),getSessionId:(n)=>n.session_id})}var ys={"antigravity-cli":k1,"claude-code":X1,"copilot-cli":Y1,cursor:S1,"gemini-cli":H1,"hermes-agent":A1,"kimi-code":W1},O2=F1.map((n)=>({...n,run:ys[n.id]}));function R1(n){let t=F({label:"hook",booleans:Object.fromEntries(O2.map((e)=>[e.id,[...e.flags,...e.legacyFlags]]))},n);if(t.errors.length>0)return;let r=O2.filter((e)=>t.flags[e.id]);return r.length===1?r[0]:void 0}function V1(n){return O2.find((t)=>t.legacyTopLevelFlags.some((r)=>r===n))}var hs=O2.map((n)=>({flags:n.flags.join(", "),description:n.description})),ws=O2.flatMap((n)=>n.flags.map((t)=>`cc-safety-net hook ${t}`)),K1={name:"hook",description:"Run as an agent CLI hook (reads JSON from stdin)",usage:"hook INTEGRATION_FLAG",options:[...hs,{flags:"-h, --help",description:"Show this help"}],examples:ws};var M1={name:"install",description:"Install CC Safety Net into a coding agent CLI",usage:"install [TARGET_FLAG]",options:[...L2.map((n)=>({flags:n.flag,description:`Install ${n.helpTarget}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net install",...L2.map((n)=>`cc-safety-net install ${n.flag}`)]},G1={name:"uninstall",description:"Uninstall CC Safety Net from a coding agent CLI",usage:"uninstall [TARGET_FLAG]",options:[...L2.map((n)=>({flags:n.flag,description:`Uninstall ${n.helpTarget}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net uninstall",...L2.map((n)=>`cc-safety-net uninstall ${n.flag}`)]},C1={name:"update",description:"Update every installed CC Safety Net integration to the latest version",usage:"update",options:[{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net update"]};var U1={name:"logs",description:"Browse audit log entries recorded by hooks",usage:"logs [options]",options:[{flags:"--id",argument:"<id>",description:"Show one entry from retained history by its 16-character id (not guaranteed once it is older than the configured retention)"},{flags:"--limit",argument:"<n>",description:"Maximum entries to print",default:"20"},{flags:"--since",argument:"<days>",description:"Only include entries newer than this many days (max: the configured audit retention, 1-365)",default:"30"},{flags:"--agent",argument:"<name>",description:"Filter by agent name"},{flags:"--rule",argument:"<ruleId>",description:"Filter by rule id"},{flags:"--session",argument:"<id>",description:"Filter by session id"},{flags:"--project",argument:"<path>",description:"Filter by project path"},{flags:"--suspect",description:"Only denials that look like false positives"},{flags:"--all",description:"Include allow entries"},{flags:"--prune-legacy",description:"Permanently delete all legacy root-level logs; nested logs are untouched"},{flags:"--dry-run",description:"With --prune-legacy, report what would be deleted and delete nothing"},{flags:"--json",description:"Output entries as JSON"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net logs --id 3fa9c2d1a70e8b42","cc-safety-net logs --agent claude-code","cc-safety-net logs --project . --since 7","cc-safety-net logs --suspect --since 7","cc-safety-net logs --json","cc-safety-net logs --prune-legacy --dry-run","cc-safety-net logs --prune-legacy"]};var T2={name:"rule",description:"Manage CC Safety Net rule config and rulebook sources",usage:"rule <subcommand>",subcommands:[{usage:"init [--example]",description:"Create inert rule config"},{usage:"add <source>",description:"Add a rulebook source and sync"},{usage:"remove <source>",description:"Remove a rulebook source and sync"},{usage:"update [source]",description:"Refresh rulebook lock/cache state"},{usage:"sync",description:"Sync configured rulebooks"},{usage:"list",description:"List active rulebooks"},{usage:"wrapper add <command>",description:"Trust a transparent command wrapper"},{usage:"wrapper remove <command>",description:"Remove a transparent command wrapper"},{usage:"wrapper list",description:"List transparent command wrappers"},{usage:"migrate [--cleanup]",description:"Migrate legacy inline rules"},{usage:"doc",description:"Print the rulebook authoring guide"},{usage:"verify",description:"Validate rule config files"}],options:[{flags:"-g, --global",description:"Use user-scope rule config"},{flags:"--check",description:"Check without changing lock/cache state"},{flags:"--cleanup",description:"Delete legacy files after rule migrate verifies them"},{flags:"--delete-source",description:"Delete clean local source directory on remove"},{flags:"--example",description:"Create an inactive example rulebook with rule init"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net rule init","cc-safety-net rule init --example","cc-safety-net rule wrapper add rtk","cc-safety-net rule add project-rules","cc-safety-net rule sync","cc-safety-net rule migrate --cleanup","cc-safety-net rule verify"]};var O1={name:"status",description:"Show what the runtime is enforcing right now",usage:"status",options:[{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net status"]};var T1={name:"statusline",description:"Print status line with mode indicators for shell integration",usage:"statusline --claude-code",options:[{flags:"-cc, --claude-code",description:"Print status line for Claude Code"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net statusline -cc","cc-safety-net statusline --claude-code"]};var E1=[O1,u1,U1,o1,T2,M1,C1,G1,K1,v1,T1];function xs(n){return n.aliases??[]}function $s(n){return!n.hidden}function Kn(n){let t=n.toLowerCase();return E1.find((r)=>r.name.toLowerCase()===t||xs(r).some((e)=>e.toLowerCase()===t))}function _1(){return E1.filter($s)}import{readFileSync as gs}from"node:fs";import{basename as Ds}from"node:path";function Mn(n=7,t=s2()){let r=Date.now()-n*24*60*60*1000,e=[],a=new Set,l=0,d,s,c,L;if(t)$2(t);let i={count:0},u=t?u2(t,i):[];for(let p of u)try{let o=gs(p,"utf-8").trim().split(`
6
- `).filter(Boolean);for(let y of o)try{let x=JSON.parse(y);if(x.decision==="allow")continue;let w=new Date(x.ts).getTime();if(w>=r){if(l++,a.add(x.sessionId??Ds(p,".jsonl")),s===void 0||w<=s)d=x.ts,s=w;if(L===void 0||w>L)c=x.ts,L=w;ms(e,x,w)}}catch{i.count++}}catch{i.count++}let v=e.map((p)=>({timestamp:p.ts,command:p.command,reason:p.reason,relativeTime:kt(new Date(p.ts))}));return{totalBlocked:l,sessionCount:a.size,recentEntries:v,oldestEntry:d,newestEntry:c,unreadable:i.count}}function ms(n,t,r){let e=n.findIndex((a)=>r>new Date(a.ts).getTime());if(e===-1){if(n.length<3)n.push(t);return}if(n.splice(e,0,t),n.length>3)n.pop()}import{dirname as ks}from"node:path";function P1(n,t,r,e,a){let l;try{if(g(e)===null)return{path:n,exists:!1,valid:!1,ruleCount:0};l=a2(e),l.errors.push(...l2(n,t,{userConfigDir:r},a))}catch(d){if(!(d instanceof Z))throw d;l={errors:[d.message],ruleNames:new Set}}return{path:n,exists:!0,valid:l.errors.length===0,ruleCount:l.ruleNames.size,...l.errors.length>0?{errors:l.errors}:{}}}function qs(n,t){return{source:t,name:n.name,command:n.command,subcommand:n.subcommand,blockArgs:[...n.block_args],reason:n.reason}}function N1(n,t){let r=t?.userConfigPath??_(),e=t?.projectConfigPath??E(n),a=ks(r),l=o2({cwd:n,userConfigPath:r,projectConfigPath:e,userConfigDir:a}),d=P({cwd:n,userConfigPath:r,projectConfigPath:e,userConfigDir:a}),s=new Map(l.rulebooks.flatMap((c)=>c.rules.map((L)=>[L,c.source])));return{userConfig:P1(r,R2({userConfigPath:r}),a,d.userConfigTarget,d.userScope),projectConfig:P1(e,V2(e),a,d.projectConfigTarget,d.projectScope),effectiveRules:l.rules.map((c)=>qs(c,s.get(c.name)??"project")),shadowedRules:[]}}var js=[{flag:m.level,description:"Safety level preset: standard, strict, or paranoid",defaultBehavior:"standard"},{flag:m.strict,description:"Legacy; equivalent to safety.overrides.fail_closed",defaultBehavior:"permissive"},{flag:m.paranoid,description:"Legacy; equivalent to safety.overrides.paranoid_rm and paranoid_interpreters",defaultBehavior:"off"},{flag:m.paranoidRm,description:"Legacy; equivalent to safety.overrides.paranoid_rm",defaultBehavior:"off"},{flag:m.paranoidInterpreters,description:"Legacy; equivalent to safety.overrides.paranoid_interpreters",defaultBehavior:"off"},{flag:m.worktree,description:"Allow local git discards in linked worktrees",defaultBehavior:"off"},{flag:m.debug,description:"Print diagnostic messages to stderr",defaultBehavior:"off"},{flag:m.auditScope,description:"Command decisions recorded: all, or blocked (privacy-minimizing, denials only)",defaultBehavior:"all"}];function I1(){return[...js.map((n)=>({name:n.flag.name,value:_t(n.flag),isSet:Pt(n.flag),legacyName:n.flag.legacyName,legacyValue:n.flag.legacyName?process.env[n.flag.legacyName]:void 0,legacyIsSet:n.flag.legacyName?process.env[n.flag.legacyName]!==void 0:void 0,description:n.description,defaultBehavior:n.defaultBehavior})),{name:"CC_SAFETY_NET_HOME",value:process.env.CC_SAFETY_NET_HOME,isSet:process.env.CC_SAFETY_NET_HOME!==void 0,description:"Override user-scope config/cache directory",defaultBehavior:"~/.cc-safety-net"}]}var na={error:0,warning:1,info:2},Fs=["policy","config","audit"];function zs(n){return n.map((t)=>{if(t==="ownership")return"is not owned by the current user";if(t==="permissions")return"has unsafe permissions";if(t==="symlink")return"is a symbolic link";return"is not a directory"}).join(" and ")}var Bs=[{derive:(n)=>n.hooks.length>0&&n.hooks.every((t)=>!t.configured)?[{checkId:"integration.none-configured",severity:"error",title:"No integration configured",detail:"CC Safety Net is not connected to any supported coding-agent integration.",fixHint:"Run `cc-safety-net install` and configure at least one integration."}]:[]},{derive:(n)=>n.hooks.filter((t)=>t.inspectionStatus==="failed").map((t)=>{let r=v2(t.platform);return{checkId:"integration.inspection-failed",severity:"error",title:`${r} inspection failed`,detail:`Doctor could not verify the ${r} integration configuration.`,fixHint:`Correct the reported ${r} configuration error, then run \`cc-safety-net doctor\` again.`,integration:t.platform}})},{derive:(n)=>n.userConfig.exists&&!n.userConfig.valid?[{checkId:"config.user-invalid",severity:"error",title:"User configuration is invalid",detail:"Doctor could not load a valid user rules configuration.",fixHint:"Run `cc-safety-net rule verify`, correct the reported error, then rerun doctor.",path:n.userConfig.path}]:[]},{derive:(n)=>n.projectConfig.exists&&!n.projectConfig.valid?[{checkId:"config.project-invalid",severity:"error",title:"Project configuration is invalid",detail:"Doctor could not load a valid project rules configuration.",fixHint:"Run `cc-safety-net rule verify`, correct the reported error, then rerun doctor.",path:n.projectConfig.path}]:[]},{derive:(n)=>n.configState.state==="degraded"?[{checkId:"config.runtime-degraded",severity:"warning",title:"Runtime is enforcing a fallback configuration",detail:`The rejected candidate configuration is not active: ${n.configState.reason}`,fixHint:"Correct the named source, run `cc-safety-net rule sync` for a rule source, then rerun doctor."}]:[]},{derive:(n)=>{let t=n.environment.find((r)=>r.name==="CC_SAFETY_NET_AUDIT_SCOPE");return Et(t?.value)==="invalid"?[{checkId:"environment.audit-scope-invalid",severity:"warning",title:"Audit scope value is invalid",detail:"CC_SAFETY_NET_AUDIT_SCOPE is not `all` or `blocked`, so allowed command decisions are not recorded.",fixHint:"Set CC_SAFETY_NET_AUDIT_SCOPE to `all` or `blocked`, then restart the integration."}]:[]}},...Fs.map((n)=>({derive:(t)=>t.posture.directories.filter((r)=>r.kind===n&&r.status==="unsafe").map((r)=>({checkId:`posture.${n}-directory-unsafe`,severity:"error",title:`${n[0]?.toUpperCase()}${n.slice(1)} directory is unsafe`,detail:`The ${n} directory ${zs(r.issues)}.`,fixHint:"Ensure this is a real directory owned by the current user with no group or other write access, then rerun doctor.",...r.path?{path:r.path}:{}}))})),{derive:(n)=>{let t=[...n.effectiveSafety.weakenedRuleOverrides].sort();return t.length>0?[{checkId:"posture.rule-overrides-weaken-preset",severity:"warning",title:"Rule overrides weaken the selected preset",detail:`Explicit overrides disable rules the resolved preset would enable: ${t.join(", ")}.`,fixHint:`Remove these \`off\` overrides or set them to \`on\`: ${t.join(", ")}.`}]:[]}}];function ta(n){return Bs.flatMap((t,r)=>t.derive(n).map((e,a)=>({finding:e,catalogOrder:r,occurrence:a}))).sort((t,r)=>na[t.finding.severity]-na[r.finding.severity]||t.catalogOrder-r.catalogOrder||t.occurrence-r.occurrence).map((t)=>t.finding)}function I(){return Boolean(process.stdout.isTTY&&!process.env.NO_COLOR)}var Js=(n)=>I()?`\x1B[32m${n}\x1B[0m`:n,Zs=(n)=>I()?`\x1B[33m${n}\x1B[0m`:n,Qs=(n)=>I()?`\x1B[34m${n}\x1B[0m`:n,Xs=(n)=>I()?`\x1B[35m${n}\x1B[0m`:n,Ys=(n)=>I()?`\x1B[36m${n}\x1B[0m`:n,Ss=(n)=>I()?`\x1B[31m${n}\x1B[0m`:n,Hs=(n)=>I()?`\x1B[2m${n}\x1B[0m`:n,As=(n)=>I()?`\x1B[1m${n}\x1B[0m`:n,b={green:Js,yellow:Zs,blue:Qs,magenta:Xs,cyan:Ys,red:Ss,dim:Hs,bold:As},Ws="\x1B[0m",Rs=[39,82,198,226,208,51,196,46,201,214,93,154,220,27,49,190,200,33,129,227,45,160,63,118,123,202];function Vs(n){let t=n;return()=>{return t=(t*1664525+1013904223)%4294967296,t/4294967296}}function Ks(n){let t=[...Rs],r=Vs(n);for(let e=t.length-1;e>0;e--){let a=Math.floor(r()*(e+1)),l=t[e];t[e]=t[a],t[a]=l}return t}function Ms(n,t=0){if(!I())return"";let r=Ks(t);return`\x1B[38;5;${r[n%r.length]}m`}function ra(n,t,r=0){if(!I())return`"${n}"`;return`${Ms(t,r)}"${n}"${Ws}`}var Gs=new RegExp("\x1B\\[[0-9;]*m","g"),dr=(n)=>n.replace(Gs,"").length;function m2(n){let t=(n.headers??n.rows[0]??[]).map((d,s)=>{let c=Math.max(...n.rows.map((L)=>dr(L[s]??"")));return Math.max(dr(d),c)}),r=(d,s)=>d+" ".repeat(Math.max(0,s-dr(d))),e=(d,s)=>s[0]+t.map((c)=>d.repeat(c+2)).join(s[1])+s[2],a=(d)=>`│ ${d.map((s,c)=>r(s,t[c]??0)).join(" │ ")} │`,l=n.headers?[` ${a(n.headers)}`,` ${e("─",["├","┼","┤"])}`]:[];return[` ${e("─",["┌","┬","┐"])}`,...l,...n.rows.map((d)=>` ${a(d)}`),` ${e("─",["└","┴","┘"])}`].join(`
7
- `)}function ea(n){let t=[];t.push("Hook Integration"),t.push(Cs(n));let r=[],e=[];for(let a of n){let l=v2(a.platform);if(a.errors&&a.errors.length>0)for(let d of a.errors)if(a.configured)r.push({platform:l,message:d});else e.push({platform:l,message:d})}for(let a of r)t.push(` Warning (${a.platform}): ${a.message}`);for(let a of e)t.push(b.red(` Error (${a.platform}): ${a.message}`));return t.join(`
8
- `)}function Cs(n){let t=["Platform","Discovery","Configuration","Inspection"],r=n.map((e)=>{let a=v2(e.platform);if(e.inspectionStatus==="not-inspected"){let c=b.dim("Not inspected");return[a,c,c,c]}let l=e.detected?b.green("Detected"):e.inspectionStatus==="failed"?b.red("Unknown"):b.dim("Not detected"),d=e.configured?b.green("Configured"):e.detected?b.yellow("Not configured"):e.inspectionStatus==="failed"?b.red("Unknown"):b.dim("Not applicable"),s=e.inspectionStatus==="verified"?b.green("Verified"):e.inspectionStatus==="failed"?b.red("Failed"):b.dim("Not applicable");return[a,l,d,s]});return m2({headers:t,rows:r})}function aa(n){let r=["Guard Engine Verification",` Synthetic self-test: ${n.failed>0?b.red(`${n.passed}/${n.total} FAIL`):b.green(`${n.passed}/${n.total} passed`)}`],e=n.results.filter((a)=>!a.passed);if(e.length>0){r.push(""),r.push(b.red(" Failures:"));for(let a of e)r.push(b.red(` • ${a.description}`)),r.push(b.red(` expected ${a.expected}, got ${a.actual}`))}return r.join(`
9
- `)}function Us(n){if(n.length===0)return" (no custom rules)";let t=["Source","Name","Command","Block Args"],r=n.map((e)=>[e.source,e.name,e.subcommand?`${e.command} ${e.subcommand}`:e.command,e.blockArgs.join(", ")]);return m2({headers:t,rows:r})}function la(n){let t=[];if(t.push("Configuration"),t.push(Os(n.userConfig,n.projectConfig)),t.push(""),n.effectiveRules.length>0)t.push(` Effective rules (${n.effectiveRules.length} total):`),t.push(Us(n.effectiveRules));else t.push(" Effective rules: (none - using built-in rules only)");for(let r of n.shadowedRules)t.push(""),t.push(` Note: Project rule "${r.name}" shadows user rule with same name`);return t.join(`
10
- `)}function Os(n,t){let r=["Scope","Status"],e=(l)=>{if(!l.exists)return b.dim("N/A");if(!l.valid)return b.red(`Invalid (${l.errors?.[0]??"unknown error"})`);return b.green("Configured")},a=[["User",e(n)],["Project",e(t)]];return m2({headers:r,rows:a})}function da(n){let t=[];return t.push("Environment"),t.push(Ts(n)),t.join(`
2
+ import{$ as ar,$a as U1,A as pn,Aa as Z1,B as Nl,Ba as rr,C as P,Ca as Q1,D as U,Da as X1,E as Ot,Ea as O,F as Ht,Fa as Kt,G as Wn,Ga as Tt,H as At,Ha as _t,I as G2,Ia as T,J as $2,Ja as D3,K as Et,Ka as bn,L as s2,La as m3,M as be,Ma as f1,N as er,Na as k3,O as Rn,Oa as q3,P as fe,Pa as j3,Q as ye,Qa as ct,R as Mn,Ra as F3,S as Vn,Sa as z3,T as yn,Ta as re,U as hn,Ua as ee,V as _1,Va as ae,W as un,Wa as le,X as g2,Xa as e3,Y as Pt,Ya as G1,Z as C2,Za as C1,_ as he,_a as Mt,aa as $e,ab as O1,b as $1,ba as ge,bb as v2,c as g1,ca as E1,cb as x2,d as A,da as j1,db as l2,e as D1,ea as P1,eb as T1,f as Qt,fa as I1,fb as W,g as Z,ga as N1,gb as fn,h as D,ha as It,hb as vn,i as sn,ia as F1,ib as xe,j as g,ja as m,jb as wn,k as w2,ka as Nt,kb as L2,l as A1,la as we,lb as Be,m as A2,ma as d2,mb as Kn,n as Ln,na as on,o as L3,oa as nr,p as St,pa as tr,q as W1,qa as ne,r as cn,ra as te,s as R1,sa as z1,t as Ut,ta as M2,u as K1,ua as Wt,v as M1,va as Rt,w as _,wa as V1,x as E,xa as S2,y as R2,ya as g3,z as K2,za as J1}from"../chunks/index-bmvm3x9s.js";var Y3=["-h","--help"];function F(n,t){let r=Object.entries(n.booleans??{}),e=Object.entries(n.values??{}),a=Object.fromEntries(r.map(([i])=>[i,!1])),l={},d=[],s=[],L=!1,c=-1;for(let[i,u]of t.entries()){if(i<=c)continue;if(u==="--"){d.push(...t.slice(i+1));break}if(Y3.includes(u)){L=!0;continue}let o=r.find(([,f])=>f.includes(u));if(o){a[o[0]]=!0;continue}let p=e.find(([,f])=>f.includes(u));if(p){let f=t[i+1];if(f===void 0||f.startsWith("-")){s.push(`${u} requires a value`);continue}l[p[0]]=f,c=i+1;continue}if(u.startsWith("-")){s.push(`Unknown option for ${n.label}: ${u}`);continue}if(n.positionals==="tail"){d.push(...t.slice(i));break}d.push(u)}if(n.positionals!=="list"&&n.positionals!=="tail")s.push(...d.map((i)=>`Unexpected argument for ${n.label}: ${i}`));return{flags:a,values:l,positionals:d,help:L,errors:s}}function e2(n){for(let t of n)console.error(t);return n.length>0}import{readdirSync as xd,statSync as se,unlinkSync as $d}from"node:fs";import{basename as Le,dirname as gd,join as Dd,resolve as md}from"node:path";function z(n){return Array.from(n,(t)=>{let r=t.charCodeAt(0);if(r<=31||r>=127&&r<=159)return`\\x${r.toString(16).padStart(2,"0")}`;return t}).join("")}var zt=(n)=>{let t=Date.now()-new Date(n).getTime();if(!Number.isFinite(t))return"";let r=Math.floor(t/60000),e=Math.floor(r/60),a=Math.floor(e/24);if(a>0)return`${a}d ago`;if(e>0)return`${e}h ago`;if(r>0)return`${r}m ago`;return"just now"},Q2=(n)=>{let t=(n??"").trim().split(/\s+/).filter((a)=>a&&!/^[A-Za-z_][A-Za-z0-9_]*=/.test(a)),r=t[0]?.split("/").pop();if(!r)return null;let e=t[1];return e&&/^[a-z][a-z0-9-]*$/.test(e)?`${r} ${e}`:r};import{existsSync as S3,readdirSync as H3,readFileSync as A3}from"node:fs";import{join as W3}from"node:path";function u2(n,t){try{return H3(n,{withFileTypes:!0,encoding:"utf8"}).flatMap((r)=>{let e=W3(n,r.name);if(r.isDirectory())return u2(e,t);if(r.name.endsWith(".jsonl"))return[e];return[]})}catch{if(t&&S3(n))t.count++;return[]}}function Bt(n){let t=(a)=>`${a.sessionId}
3
+ ${Q2(a.segment||a.command)}`,r=n.filter((a)=>a.decision!=="allow"),e=r.filter((a)=>a.sessionId).reduce((a,l)=>a.set(t(l),(a.get(t(l))??0)+1),new Map);return new Set(r.filter((a)=>a.failureStage||(e.get(t(a))??0)>=2))}function dn(n,t){try{return A3(n,"utf-8").split(`
4
+ `).filter(Boolean).flatMap((r)=>{try{return[JSON.parse(r)]}catch{if(t)t.count++;return[]}})}catch{if(t)t.count++;return[]}}import{resolve as ud}from"node:path";var R3=["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 m1(n){let t=0,r={allocateSegment(){return t++},getNextSegmentIndex(){return t},recordGlobal(e){n.record({kind:"step",scope:"global",step:e})},recordSegment(e,a=r.currentSegmentIndex){if(a===void 0)return;n.record({kind:"step",scope:"segment",segmentIndex:a,step:e})}};return r}function k1(n={}){let t=[],r=n.maxEvents??512,e={maxTextLength:n.maxTextLength??2048,maxListLength:n.maxListLength??128,maxObjectProperties:n.maxObjectProperties??n.maxListLength??128,maxDepth:n.maxDepth??16},a=0,l,d=new Set;return{record(s){if(l)return;try{if(!s||t.length>=r){a++;return}t.push(Zt(K3(s,e,d)))}catch{a++}},finish(s){if(l)return l;try{l=Zt({events:Object.freeze(t),droppedEvents:a,terminal:M3(s,e,d)})}catch{a++,l=Object.freeze({events:Object.freeze(t),droppedEvents:a,terminal:Object.freeze({result:"blocked",reason:"trace unavailable".slice(0,e.maxTextLength),segment:"trace unavailable".slice(0,e.maxTextLength)})})}return l}}}function K3(n,t,r){if(n.kind!=="step")throw TypeError("invalid trace event");let{scope:e,step:a}=n;Sn(a,r,t);let l=X2(a,t,r);if(e==="global")return{kind:"step",scope:"global",step:l};if(e!=="segment")throw TypeError("invalid trace event scope");return{kind:"step",scope:"segment",segmentIndex:n.segmentIndex,step:l}}function M3(n,t,r){let e=n.result;if(e==="allowed")return Object.freeze({result:"allowed"});if(e!=="blocked")throw TypeError("invalid trace terminal");let a=n.ruleId;return Object.freeze({result:"blocked",reason:X2(n.reason,t,r),segment:X2(n.segment,t,r),...a?{ruleId:X2(a,t,r)}:{}})}function Sn(n,t,r,e=0,a=new WeakSet){if(typeof n==="string"){let s=n.slice(0,r.maxTextLength);if(!Qt(s))return;for(let L of D1(s))for(let c of L.match(/[^\s"'()$]+/g)??[])t.add(q1(c));return}if(!n||typeof n!=="object"||e>=r.maxDepth||a.has(n))return;if(a.add(n),Array.isArray(n)){let s=Math.min(n.length,r.maxListLength);for(let L=0;L<s;L++)Sn(n[L],t,r,e+1,a);return}let l=0,d=new Set;for(let s in n){if(!Object.hasOwn(n,s))continue;if(l>=r.maxObjectProperties)break;l++,Sn(s,t,r);let L=Jt(s,r,t);if(d.has(L))continue;d.add(L),Sn(n[s],t,r,e+1,a)}}function X2(n,t,r,e=0,a=new WeakSet){if(typeof n==="string")return Jt(n,t,r);if(!n||typeof n!=="object")return n;if(e>=t.maxDepth)return;if(a.has(n))return;if(a.add(n),Array.isArray(n)){let s=[],L=Math.min(n.length,t.maxListLength);for(let c=0;c<L;c++)s.push(X2(n[c],t,r,e+1,a));return s}let l={},d=0;for(let s in n){if(!Object.hasOwn(n,s))continue;if(d>=t.maxObjectProperties)break;d++;let L=Jt(s,t,r);if(Object.hasOwn(l,L))continue;Object.defineProperty(l,L,{value:X2(n[s],t,r,e+1,a),enumerable:!0,configurable:!0,writable:!0})}return l}function Jt(n,t,r){let e=n.slice(0,t.maxTextLength),a=Qt(e)?g1(e):e,l=r.size>0?G3(a,r):a;return(V3(l)?$1(l):l).slice(0,t.maxTextLength)}function V3(n){return n.includes("PRIVATE KEY")||n.includes("://")||n.includes("eyJ")||n.includes(":")&&/(?:authorization|cookie|x-api-key|api-key|(?:^|\s)(?:-u|--user)(?:\s|=))/i.test(n)||n.length>=14&&R3.some((t)=>n.includes(t))||n.length>=49&&/\b[a-f0-9]{32}\.[A-Za-z0-9]{16}\b/.test(n)}function G3(n,t){return n.replace(/[^\s"'()$]+/g,(r)=>t.has(q1(r))?"<redacted>":r)}function q1(n){let t=2166136261,r=2166136261;for(let e=0;e<n.length;e++)t=Math.imul(t^n.charCodeAt(e),16777619),r=Math.imul(r^n.charCodeAt(n.length-e-1),16777619);return`${t>>>0}:${r>>>0}:${n.length}`}function Zt(n){if(n&&typeof n==="object"&&!Object.isFrozen(n)){for(let t of Object.values(n))Zt(t);Object.freeze(n)}return n}function B1(n,t,r,e){let a=e??j1(),l=r??a.getCommandProgram(n,t.shell??"auto"),d=k1(),s=m1(d),L=l.dialect==="powershell"?a.getCommandProgram(n,"posix"):l,c=F1(L);s.recordGlobal({type:"parse",input:n,segments:c.map((o)=>[...o])});let i=z1(n,{...t,analyzePartialProgram:!0,trace:s},l,a),u=s.getNextSegmentIndex();if(i&&u>0&&u<c.length)s.recordSegment({type:"segment-skipped",index:u,reason:"prior-segment-blocked"},u);return Object.freeze({decision:i,trace:d.finish(i?{result:"blocked",reason:i.reason,segment:i.evidence.find((o)=>o.kind==="command")?.segment??n,...i.ruleId?{ruleId:i.ruleId}:{}}:{result:"allowed"}),program:l})}import{resolve as C3}from"node:path";function Xt(n){let t=J1().safeParse(n);return{errors:t.success?[]:Q1(t.error.issues),ruleNames:new Set(Z1(n).map((r)=>r.toLowerCase()))}}function Yt(n){let t=Y1(n);if(!t.ok)return t.result;return Xt(t.parsed)}function Y1(n){let t=[],r=new Set;try{let e=typeof n==="string"?sn(n):n,a=g(e);if(a===null)return t.push(`File not found: ${e.path}`),{ok:!1,result:{errors:t,ruleNames:r}};if(!a.trim())return t.push("Config file is empty"),{ok:!1,result:{errors:t,ruleNames:r}};return{ok:!0,parsed:JSON.parse(a)}}catch(e){if(e instanceof Z)return t.push(e.message),{ok:!1,result:{errors:t,ruleNames:r}};let a=e instanceof Error?e.message:String(e);return t.push(e instanceof SyntaxError?"Invalid JSON":a),{ok:!1,result:{errors:t,ruleNames:r}}}}function S1(n){return C3(n??process.cwd(),".safety-net.json")}function a2(n){let t=Y1(n);if(!t.ok)return t.result;let r=X1(t.parsed);return{errors:r.errors,ruleNames:r.sources}}import{isAbsolute as U3,join as Hn,relative as O3,resolve as H1,sep as T3}from"node:path";async function W2(n={}){let t=Gt(n);return _3(t,await An(t,S2()))}function _3(n,t){if(!t.ok)return t;let r=U(n),e=[...new Set(l2(r.configPath,r.lockPath,n,r.filesystemScope))];if(e.length===0)return t;return{ok:!1,errors:e,warnings:t.warnings,entries:t.entries}}async function An(n,t,r,e={}){let a=null,l=!1;try{let d=U(n),s=Kt(d.configTarget);if(!s.ok)return s.result;let L=s.config;if(n.check)return td(L,d,n);a={target:d.lockTarget,content:g(d.lockTarget)};let c=Mt(d.lockTarget);if(c.errors.some((y)=>y.startsWith("Unable to access ")))return{ok:!1,errors:c.errors,warnings:[],entries:[]};if(n.only&&c.errors.length>0)return{ok:!1,errors:c.errors,warnings:[],entries:[]};let i=c.errors.length>0?null:c.lock,u=n.only?G1(L,i,n.only):{ok:!0,specs:L.rules};if(!u.ok)return u.result;if(n.only&&!i&&u.specs.length<L.rules.length)return{ok:!1,errors:[`No lockfile available for partial update; run ${M1}`],warnings:[],entries:[]};let o=(await P3(u.specs,(y)=>U1(y,d.configDir,n,i,d.filesystemScope,t),t)).map((y)=>rd(y,i,r));for(let y of o)ld(y.content,y.entry,d.configDir,n,d.filesystemScope);let p=n.only?ed(L,i,o):o.map((y)=>y.entry);l=!0,T(d.lockTarget,{version:1,rulebooks:p},void 0,e._testAfterPolicyRename);let f=new Map(o.map((y)=>[y.entry.spec,y.rulebook.rules.length])),v=dd(p,d.configDir,n,d.filesystemScope,e);return{ok:!0,errors:[],warnings:v,entries:p.map((y)=>ad(y,f))}}catch(d){if(l&&a)try{Y2(a.target,a.content)}catch(s){return H2(s)}return H2(d)}}async function Vt(n,t={}){return E3(n,Gt(t),S2())}async function E3(n,t,r,e={}){let a=null,l=!1;try{let d=U(t),s=g(d.configTarget);a={target:d.configTarget,content:s};let L=Kt(d.configTarget);if(!L.ok)return L.result;let c=L.config,i=K1(n)?await O1(n,r):[{spec:n}],u=i.map((f)=>f.spec),o=[...new Set([...c.rules,...u])];if(o.length>Wt)return I3();if(o.length!==c.rules.length)l=!0,T(d.configTarget,{version:1,rules:o,overrides:c.overrides??{},transparent_wrappers:c.transparent_wrappers??[]},void 0,e._testAfterPolicyRename);let p=await An(t,r,new Map(i.filter((f)=>!!f.display_ref).map((f)=>[f.spec,f.display_ref])),e);if(!p.ok)Y2(d.configTarget,s);return p}catch(d){if(l&&a)try{Y2(a.target,a.content)}catch(s){return H2(s)}return H2(d)}}async function P3(n,t,r=S2()){if(n.length>Wt)throw Error(Rt);let e=Array(n.length),a=0,l,d=Array.from({length:Math.min(n.length,V1.concurrency)},async()=>{while(!l){let s=a;if(s>=n.length)return;a++;try{e[s]=await t(n[s],s,r.controller.signal)}catch(L){if(!l)l={value:L},a=n.length,r.controller.abort(L);return}}});if(await Promise.all(d),l)throw l.value;return e}function I3(){return{ok:!1,errors:[Rt],warnings:[],entries:[]}}function Gt(n){return{cwd:n.cwd,cacheConfigDir:n.cacheConfigDir,userConfigDir:n.userConfigDir,userConfigPath:n.userConfigPath,projectConfigPath:n.projectConfigPath,global:n.global,check:n.check,only:n.only,refresh:n.refresh}}function N3(n){return{...Gt(n),deleteSource:n.deleteSource}}async function Ct(n,t={}){try{return await nd(n,N3(t),{})}catch(r){return H2(r)}}async function nd(n,t,r){let e=U(t),a=O(e.configTarget);if(a.errors.length>0)return{ok:!1,errors:a.errors,warnings:[],entries:[]};if(!a.config)return{ok:!1,errors:[`No config found at ${e.configPath}`],warnings:[],entries:[]};let l=Mt(e.lockTarget);if(l.errors.length>0)return{ok:!1,errors:l.errors,warnings:[],entries:[]};let d=C1(a.config.rules,l.lock,n);if(!d.ok)return d.result;let s=t.deleteSource?sd(e.configDir,d.specs,l.lock,e.filesystemScope):{ok:!0,dirs:[]};if(!s.ok)return s.result;let L=g(e.configTarget);if(L===null)return H2(Error("Rules config is unavailable."));try{T(e.configTarget,{version:1,rules:a.config.rules.filter((u)=>!d.specs.includes(u)),overrides:a.config.overrides??{},transparent_wrappers:a.config.transparent_wrappers??[]},void 0,r._testAfterPolicyRename)}catch(u){throw Y2(e.configTarget,L),u}let c=await An(t,S2(),void 0,r);if(!c.ok)return Y2(e.configTarget,L),c;let i=cd(s.dirs,r,e.filesystemScope);if(!i.ok){Y2(e.configTarget,L);let u=await An(t,S2(),void 0,r);if(!u.ok)return{ok:!1,errors:[...i.result.errors,...u.errors],warnings:u.warnings,entries:u.entries};return i.result}return c}async function td(n,t,r){let e=T1(n,t.lockPath,t.configDir,r,r.global?"user":"project",t.filesystemScope);return{ok:e.errors.length===0&&e.warnings.length===0,errors:[...e.errors,...e.warnings],warnings:[],entries:e.entries}}function rd(n,t,r){let e=t?.rulebooks.find((l)=>l.spec===n.entry.spec&&l.kind==="github"),a=r?.get(n.entry.spec)??(e?.kind==="github"?e.display_ref:void 0);if(!a||n.entry.kind!=="github")return n;return{...n,entry:{...n.entry,display_ref:a}}}function ed(n,t,r){let e=new Set(n.rules),a=new Set(t?.rulebooks.map((d)=>d.spec)??[]),l=new Map(r.map((d)=>[d.entry.spec,d.entry]));return[...(t?.rulebooks.filter((d)=>e.has(d.spec))??[]).map((d)=>l.get(d.spec)??d),...r.filter((d)=>!a.has(d.entry.spec)).map((d)=>d.entry)]}function ad(n,t){return{...n,ruleCount:t.get(n.spec)}}function ld(n,t,r,e,a){let l=Ht(t,At(r,e));w2(D(a,l),n)}function dd(n,t,r,e,a){let l=At(t,r),d=Wn(l),s=D(e,d),L=A2(s);if(!L)return[];let c=n.map((u)=>D(e,Ht(u,l))),i=L.filter((u)=>u.kind==="directory").map((u)=>({directory:D(e,Hn(d,u.name)),identity:D(e,Hn(d,u.name,R1))})).filter((u)=>!c.some((o)=>A1(u.identity,o))).map((u)=>u.directory);for(let u of i)W1(u);return i.flatMap((u)=>{try{return id(u,a),[]}catch{return["Unable to prune rules policy cache safely."]}})}function sd(n,t,r,e){let a=new Map(r?.rulebooks.map((c)=>[c.spec,c])??[]),l=t.flatMap((c)=>{let i=a.get(c);if(!i)return cn.test(c)?[]:["--delete-source can only delete local rulebook sources"];return i.kind==="local-directory"?[]:["--delete-source can only delete local rulebook sources"]}),d=t.map((c)=>{let i=a.get(c);return Hn(n,i?.kind==="local-directory"?i.path:c)}),s=l.length>0?[]:d.flatMap((c)=>Ld(n,c,e)),L=[...l,...s];return L.length>0?{ok:!1,result:{ok:!1,errors:L,warnings:[],entries:[]}}:{ok:!0,dirs:d}}function Ld(n,t,r){let e=H1(n),a=H1(t),l=O3(e,a);if(l===""||l===".."||l.startsWith(`..${T3}`)||U3(l))return[`Refusing to delete local rulebook source outside ${n}: ${t}`];let d=D(r,a),s=A2(d);if(!s)return[`Local rulebook source directory not found: ${t}`];let L=s.find((c)=>c.name==="rulebook.json");if(!L)return[`Local rulebook source directory is missing rulebook.json: ${t}`];if(L.kind!=="file")throw new Z(r.label);if(g(D(r,Hn(a,"rulebook.json"))),s.length>1)return[`Local rulebook source directory contains extra files: ${t}. delete manually if you really want to remove the directory.`];return[]}function cd(n,t,r){let e=n.flatMap((a)=>{try{return pd(D(r,a),t),[]}catch(l){return[`Failed to delete local rulebook source ${a}: ${l instanceof Error?l.message:String(l)}`]}});return e.length>0?{ok:!1,result:{ok:!1,errors:e,warnings:[],entries:[]}}:{ok:!0}}function id(n,t){if(t._testPruneRulebookCacheDir){t._testPruneRulebookCacheDir(n.path);return}St(n)}function pd(n,t){if(t._testDeleteLocalSourceDir){t._testDeleteLocalSourceDir(n.path);return}St(n)}function Y2(n,t){if(t===null){Ln(n);return}w2(n,t)}function H2(n){return{ok:!1,errors:[n instanceof Error?n.message:String(n)],warnings:[],entries:[]}}function V2(n,t){let r=od(t),e=ne(r),a={effectiveLevel:e.effectiveLevel,selectedPreset:r.policySnapshot.policy.safety.level??"standard",effectiveCapabilities:e.effectiveCapabilities,destructiveCommandRuleOverrides:r.policySnapshot.policy.destructiveCommandRuleOverrides},{configSource:l,configValid:d}=vd({cwd:t?.cwd,userConfigDir:t?.userConfigDir});if(!n||!n.trim())return{trace:{steps:[{type:"error",message:"No command provided"}],segments:[]},result:"allowed",configSource:l,configValid:d,...a};let s=bd(n,r);if(s)return{trace:{steps:[],segments:[{index:0,steps:[{type:"rule-check",ruleModule:s.ruleModule,ruleFunction:s.ruleFunction,matched:!0,reason:s.reason}]}]},result:"blocked",reason:A(s.reason),segment:A(s.target),...s.ruleId?{ruleId:A(s.ruleId)}:{},configSource:l,configValid:d,...a};let L=B1(n,r),c=L.decision,i=c?.ruleId??fd(n,r),u=un.find((p)=>p.id===i&&p.activationCapability),o=u?e.policy.effectiveDestructiveCommandRules[u.id]:void 0;return{trace:hd(L.trace),result:c?"blocked":"allowed",reason:c?A(c.reason):void 0,segment:c?A(c.evidence.find((p)=>p.kind==="command")?.segment??n):void 0,ruleId:c?.ruleId?A(c.ruleId):void 0,customRule:yd(wd(c?.ruleId,r.policySnapshot)),configSource:l,configValid:d,...a,...u&&o?{ruleActivation:{id:u.id,...o}}:{}}}function vd(n){let t=_(n?.cwd),r=n?.userConfigPath??E(n),e=P({cwd:n?.cwd,userConfigDir:n?.userConfigDir,userConfigPath:n?.userConfigPath});try{if(g(e.projectConfigTarget)!==null){if(a2(e.projectConfigTarget).errors.length===0)return{configSource:t,configValid:!0};return{configSource:t,configValid:!1}}}catch(a){if(a instanceof Z)return{configSource:t,configValid:!1};throw a}try{if(g(e.userConfigTarget)!==null){let a=a2(e.userConfigTarget);return{configSource:r,configValid:a.errors.length===0}}return{configSource:null,configValid:!0}}catch(a){if(a instanceof Z)return{configSource:r,configValid:!1};throw a}}function od(n){let t=ud(n?.cwd??process.cwd()),r=n?.policySnapshot??W({cwd:t,userConfigDir:n?.userConfigDir}),e=d2(r.policy);return{cwd:t,effectiveCwd:t,policySnapshot:r,environment:_1(),protectedGitMetadata:N1(t),effectiveCapabilities:e.capabilities,strict:n?.strict??e.strict,paranoidRm:e.paranoidRm,paranoidInterpreters:e.paranoidInterpreters,worktreeMode:e.worktreeMode}}function bd(n,t){let r=t.cwd??process.cwd(),e=E1(M2("",{command:n},{kind:"command",shell:"posix"},{executionCwd:r,configCwd:r},n)),a=ee(e);if(a)return{reason:re,target:a.target,ruleId:"policy-protection",ruleModule:"policy-protection",ruleFunction:"findPolicyConfigMutationTarget"};let l=I1(e,t.protectedGitMetadata);if(l)return{reason:P1,target:l.target,ruleId:"git-metadata-protection",ruleModule:"git-metadata-protection",ruleFunction:"findGitMetadataMutationTarget"};let d=t.policySnapshot.policy,s=d.secretProtection.enabled===!1?null:le(e,d.secretProtection,{strict:t.strict});if(s)return{reason:ae,target:s.target,ruleId:s.ruleId,ruleModule:"secret-protection",ruleFunction:"findSensitiveTarget"};return null}function fd(n,t){let r=t.policySnapshot.policy,e=vn({...r,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:{...r.destructiveCommandRuleOverrides,...Object.fromEntries(un.flatMap((a)=>a.activationCapability?[[a.id,"on"]]:[]))}},t.policySnapshot.state==="degraded"?{diagnostics:t.policySnapshot.diagnostics,reason:t.policySnapshot.reason}:void 0);return te(n,{...t,policySnapshot:e,strict:!0,paranoidRm:!0,paranoidInterpreters:!0})?.ruleId}function yd(n){if(!n)return;return{id:A(n.id),...n.rulebook?{rulebook:{name:A(n.rulebook.name),version:A(n.rulebook.version)}}:{},...n.source?{source:A(n.source)}:{},...n.override?{override:{type:"reason",reason:A(n.override.reason)}}:{}}}function hd(n){let t=n.events.flatMap((e)=>e.kind==="step"&&e.scope==="global"?[e.step]:[]),r=new Map;for(let e of n.events){if(e.kind!=="step"||e.scope!=="segment")continue;let a=r.get(e.segmentIndex)??{index:e.segmentIndex,steps:[]};a.steps.push(e.step),r.set(e.segmentIndex,a)}return{steps:t,segments:[...r.values()]}}function wd(n,t){let r=n?.replace(/^custom\./,"");if(!r||!t.policy.rules.some((e)=>e.name===r))return;return t.ruleMetadata[r]??Object.freeze({id:r})}function kd(n){let t=G2(),r=F({label:"logs",booleans:{all:["--all"],suspect:["--suspect"],json:["--json"],pruneLegacy:["--prune-legacy"],dryRun:["--dry-run"]},values:{id:["--id"],limit:["--limit"],since:["--since"],agent:["--agent"],rule:["--rule"],session:["--session"],project:["--project"]}},n);if(e2(r.errors))return null;if(r.values.id!==void 0&&!/^[a-f0-9]{16}$/.test(r.values.id))return console.error("--id must be 16 hexadecimal characters"),null;let e=r.values.limit===void 0?20:de(r.values.limit);if(e===null)return console.error("--limit must be a positive number"),null;let a=r.values.since===void 0?Math.min(30,t):de(r.values.since);if(a===null||a>t)return console.error(`--since must be a positive number of days no greater than ${t}`),null;let l={limit:e,limitExplicit:r.values.limit!==void 0,since:a,sinceExplicit:r.values.since!==void 0,all:r.flags.all,json:r.flags.json,suspect:r.flags.suspect,pruneLegacy:r.flags.pruneLegacy,dryRun:r.flags.dryRun,id:r.values.id,agent:r.values.agent,rule:r.values.rule,session:r.values.session,project:r.values.project===void 0?void 0:md(r.values.project)};if(l.id&&(l.agent!==void 0||l.rule!==void 0||l.session!==void 0||l.project!==void 0||l.suspect||l.sinceExplicit||l.limitExplicit))return console.error("--id cannot be combined with --agent, --rule, --session, --project, --suspect, --since, or --limit"),null;if(l.pruneLegacy&&(l.id!==void 0||l.agent!==void 0||l.rule!==void 0||l.session!==void 0||l.project!==void 0||l.suspect||l.all||l.sinceExplicit||l.limitExplicit))return console.error("--prune-legacy cannot be combined with --id, --agent, --rule, --session, --project, --suspect, --all, --since, or --limit"),null;if(l.dryRun&&!l.pruneLegacy)return console.error("--dry-run requires --prune-legacy"),null;return l}async function ce(n,t={}){let r=kd(n);if(!r)return 1;let e=t.logsDir??s2();if(r.pruneLegacy)return qd(e,r.json,r.dryRun);if(!e)return console.log(r.json?"[]":r.id?`No retained audit log entry found for id ${z(r.id)}.`:"No audit log entries found."),0;$2(e);let a={count:0},l=u2(e,a).flatMap((i)=>dn(i,a).map((u)=>({entry:u,file:i})));if(a.count>0)console.error(`warning: ${a.count} audit log ${a.count===1?"source":"sources"} could not be read; these results are incomplete`);if(r.id)return Bd(l,r,t.timeZone);let d=Date.now()-r.since*24*60*60*1000,s=l.filter((i)=>Jd(i,r,e,d)),L=r.suspect?Bt(s.map((i)=>i.entry)):null,c=(L?s.filter((i)=>L.has(i.entry)):s).sort((i,u)=>Date.parse(u.entry.ts)-Date.parse(i.entry.ts)).slice(0,r.limit);if(r.json)return console.log(JSON.stringify(c.map((i)=>i.entry),null,2)),0;if(c.length===0)return console.log("No audit log entries found."),0;for(let i of c)console.log(Xd(i.entry,t.timeZone));return 0}function qd(n,t,r){let e=n?Fd(n).map((s)=>Dd(n,s)):[];if(r)return jd(e,t);let a=[],l=0,d=0;for(let s of e){let L=se(s,{throwIfNoEntry:!1})?.size??0,c=zd(s);if(c){a.push(`${Le(s)}: ${c}`);continue}l++,d+=L}if(t)return console.log(JSON.stringify({removedFiles:l,removedBytes:d,failedFiles:a.length})),a.length===0?0:1;console.log(l===0&&a.length===0?"No legacy audit log files found.":`Removed ${l} legacy audit log ${l===1?"file":"files"} (${ie(d)}).`);for(let s of a)console.error(`Could not remove ${z(s)}`);if(console.log("Nested v2 audit logs were not changed."),l>0)console.log("This deletion cannot be undone.");return a.length===0?0:1}function jd(n,t){let r=n.reduce((e,a)=>e+(se(a,{throwIfNoEntry:!1})?.size??0),0);if(t)return console.log(JSON.stringify({dryRun:!0,files:n.length,bytes:r})),0;if(console.log(n.length===0?"No legacy audit log files found.":`Would remove ${n.length} legacy audit log ${n.length===1?"file":"files"} (${ie(r)}).`),console.log("Nested v2 audit logs are not included."),n.length>0)console.log("Run the same command without --dry-run to delete them.");return 0}function Fd(n){try{return xd(n,{withFileTypes:!0}).filter((t)=>t.isFile()&&t.name.endsWith(".jsonl")).map((t)=>t.name)}catch{return[]}}function zd(n){try{return $d(n),null}catch(t){return t instanceof Error?t.message:String(t)}}function ie(n){let t=["B","KiB","MiB","GiB"],r=Math.min(Math.floor(Math.log2(Math.max(n,1))/10),t.length-1);return`${Math.round(n/1024**r*10)/10} ${t[r]}`}function Bd(n,t,r){let e=n.filter((l)=>l.entry.id===t.id);if(e.length>1)return console.error(`Multiple audit log entries found for id ${z(t.id??"")}.`),1;if(t.json)return console.log(JSON.stringify(e.map((l)=>l.entry),null,2)),0;let a=e[0];if(!a)return console.log(`No retained audit log entry found for id ${z(t.id??"")}.`),0;return console.log(Yd(a.entry,r)),0}function Jd(n,t,r,e){if(!t.all&&n.entry.decision==="allow")return!1;if(Date.parse(n.entry.ts)<e)return!1;if(t.agent!==void 0&&n.entry.agent!==t.agent)return!1;if(t.rule!==void 0&&n.entry.ruleId!==t.rule)return!1;if(t.session!==void 0&&!Zd(n,r,t.session))return!1;if(t.project!==void 0&&!Qd(n.entry.cwd,t.project))return!1;return!0}function Zd(n,t,r){if(n.entry.sessionId===r)return!0;return gd(n.file)===t&&Le(n.file,".jsonl")===r}function Qd(n,t){if(!n)return!1;return n===t||n.startsWith(`${t}/`)}function Xd(n,t){let r=z(n.id??"-"),e=z(n.decision??"deny"),a=n.cwd?` [${z(n.cwd)}]`:"",l=n.segment||n.command,d=l===n.command?"":"↳ ",s=l.length>50?`${l.slice(0,50)}…`:l;return`${r.padEnd(16)} ${z(pe(n.ts,t))} ${e.padEnd(5)} ${z(n.agent??"-").padEnd(15)} ${z(n.ruleId??"-").padEnd(20)} ${d}${z(s)}${a}`}function Yd(n,t){let r=(a)=>z(a===void 0||a===null||a===""?"-":a),e=n.shape?`${n.agent??"-"} (shape: ${n.shape})`:n.agent??"-";return[`id: ${r(n.id)}`,`ts: ${r(pe(n.ts,t))}`,`decision: ${r(n.decision)}`,`agent: ${r(e)}`,`level: ${r(n.level)}`,`tool: ${r(n.toolName)}`,`rule: ${r(n.ruleId)}`,`intent: ${r(n.intent)}`,`stage: ${r(n.failureStage)}`,`error: ${r(n.errorCode)}`,`session: ${r(n.sessionId)}`,`cwd: ${r(n.cwd)}`,`version: ${r(n.v)}`,`truncated: ${r(n.truncated===!0?"yes":void 0)}`,`reason: ${r(n.reason)}`,`command: ${r(n.command)}`,`segment: ${r(n.segment)}`].join(`
5
+ `)}function pe(n,t){let r=new Date(n);if(Number.isNaN(r.getTime()))return n;return new Intl.DateTimeFormat("sv-SE",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hourCycle:"h23",timeZone:t}).format(r)}function de(n){let t=Number(n);return Number.isFinite(t)&&t>0?t:null}var ue={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 ve={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 oe={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 De,relative as Ud}from"node:path";var Sd=8388608;function Hd(n,t){console.log(JSON.stringify(n(fe(t))))}async function Ad(n){let t;try{t=(await lr(process.stdin)).trim()}catch{n({reason:"Failed to parse hook input JSON."});return}if(!t){n({reason:"Missing hook input JSON."});return}return dr(t,n,"Failed to parse hook input JSON.")}async function lr(n){let t=[],r=0;for await(let e of n){let a=typeof e==="string"?Buffer.from(e,"utf-8"):Buffer.from(e.buffer,e.byteOffset,e.byteLength);if(r+=a.byteLength,r>Sd)throw Wd(n),Error("hook input byte limit exceeded");t.push(a)}return Buffer.concat(t,r).toString("utf-8")}function Wd(n){let t=n.destroy??n.cancel;if(!t)return;try{Promise.resolve(t.call(n)).catch(()=>{})}catch{}}function dr(n,t,r){try{return JSON.parse(n)}catch{t({reason:r});return}}function X(n,t){let r=t.get(n);return r?{kind:"command",shell:r}:{kind:he(n)}}function I(n,t,r,e){let a=n===void 0?process.cwd():n,l=typeof a==="string"&&a.trim()!==""?L2([a]):void 0;if(l)return{configCwd:l,executionCwd:l};return H(e,t,r,Vd(a)),null}function H(n,t,r,e){let a;try{a=ar(t)}catch(l){if(!(l instanceof C2))throw l}n(Rn({command:a,segment:e,toolName:r}))}async function Rd(n){let t=await Ad(n.outputDeny);if(t===void 0)return;if(!t||typeof t!=="object"||Array.isArray(t)){H(n.outputDeny);return}if(!n.isSupported(t))return;let r=n.getAgent?.(t)??n.agent,e=n.agent===r?void 0:n.agent,a=Cd(t),l=(p,f)=>{be(p,()=>n.getSessionId(t),{agent:r,shape:e,toolName:f,cwd:a}),n.outputDeny(p)},d=n.getToolName(t);if(typeof d!=="string"||d.trim()===""){H((p)=>l(p),Gd(t));return}let s=d,L=(p)=>l(p,s),c;try{c=n.getToolInput(t,s,L)}catch(p){if(!(p instanceof C2))throw p;H(L,void 0,s);return}if(!c.ok)return;let i=n.getContext(t,c.input,s,L);if(!i)return;let u;try{u=ar(c.input)}catch(p){if(!(p instanceof C2))throw p;H(L,void 0,s);return}let o=M2(s,c.input,c.route,i,u??null);try{let p=Kn(o,{guard:{auditAllowed:we(),dependencies:n.guardDependencies},audit:{agent:r,shape:e,getSessionId:()=>n.getSessionId(t)}}),f=er(p,{includeEvidence:!0,toolName:p.stage==="command-analysis"?void 0:s});if(f){n.outputDeny(f);return}n.outputAllow?.()}catch(p){if(!(p instanceof xe))throw p;Kd(p);let f=er(p.evaluation,{includeEvidence:!0,toolName:p.evaluation.stage==="command-analysis"?void 0:s});if(f)n.outputDeny(f);return}}function Kd(n){if(!on(m.debug))return;console.error(`CC Safety Net debug: ${Md(n.stage)}: ${ye(n.cause)}`)}function Md(n){if(n==="policy-protection")return"hook policy protection failed";if(n==="config-load")return"hook config loading failed";if(n==="secret-protection")return"hook secret protection failed";return"hook analysis failed"}function Vd(n){return typeof n==="string"?n:void 0}function Gd(n){if(!n||typeof n!=="object"||Array.isArray(n))return;if(Object.hasOwn(n,"tool_input"))return n.tool_input;let t=n.toolCall;if(t&&typeof t==="object"&&!Array.isArray(t))return t.args;return}function Cd(n){if(!n||typeof n!=="object"||Array.isArray(n))return null;let t=n.cwd;if(typeof t==="string")return t;let r=n.toolCall;if(!r||typeof r!=="object"||Array.isArray(r))return null;let e=r.args;if(!e||typeof e!=="object"||Array.isArray(e))return null;let a=e.Cwd;return typeof a==="string"?a:null}async function Y(n){let t=(a)=>Hd(n.createDenyOutput,a),r=n.createAllowOutput;await Rd({...n,outputDeny:t,outputAllow:r?()=>console.log(JSON.stringify(r())):void 0})}var Od=new Map([["run_command","auto"]]),Td=new Set(["absolutepath","directorypath","file_path","filepath","path","searchdirectory","searchpath","target_file","targetfile"]);function me(n){return X(n,Od)}async function ke(){await Y({agent:"antigravity-cli",createDenyOutput:(n)=>({decision:"deny",reason:n}),isSupported:()=>!0,getToolName:(n)=>n.toolCall?.name,getToolInput:(n,t)=>({ok:!0,input:Nd(n.toolCall?.args,t),route:me(t)}),getContext:_d,getSessionId:(n)=>n.conversationId})}function _d(n,t,r,e){let l=Id(n).flatMap((c)=>{let i=L2([c]);return i?[i]:[]});if(!l[0])return D2(e,t,r),null;if(r!=="run_command"){let c;try{c=Ed(t,r,l)}catch(i){if(i instanceof C2)return D2(e,void 0,r),null;if(!(i instanceof Mn))throw i;return D2(e,t,r),null}if(!c)return D2(e,t,r),null;return{configCwd:c,executionCwd:c,policyConfigCwds:l}}let d=n.toolCall?.args;if(!d||!Object.hasOwn(d,"Cwd"))return{configCwd:l[0],executionCwd:l[0],policyConfigCwds:l};let s=d.Cwd;if(typeof s!=="string"||s.trim()==="")return D2(e,t,r),null;let L=wn(s,l);if(L){let c=qe(L,l);if(!c)return D2(e,t,r,s),null;return{configCwd:c,executionCwd:L,policyConfigCwds:l}}return D2(e,t,r,s),null}function Ed(n,t,r){let e=me(t),a=[...$e(n,Td),...e.kind==="patch"?ge(n):[]].filter(De),l=Vn(),d=new Set(a.flatMap((s)=>{let L=qe(yn(s,hn,l),r);return L?[L]:[]}));if(d.size>1)return null;return[...d][0]??r[0]??null}function qe(n,t){return t.filter((r)=>Pd(n,r)).reduce((r,e)=>e.length>r.length?e:r,"")||null}function Pd(n,t){let r=Ud(t,n);return r===""||!r.startsWith("..")&&!De(r)}function D2(n,t,r,e){let a=t&&typeof t==="object"?t.command:void 0;n(Rn({command:typeof a==="string"?a:void 0,segment:e,toolName:r}))}function Id(n){if(n.workspacePaths===void 0)return[process.cwd()];let t=Array.isArray(n.workspacePaths)?n.workspacePaths.filter((r)=>typeof r==="string"&&r.trim()!==""):[];return L2(t)?t:[]}function Nd(n,t){if(!n)return;if(t!=="run_command")return n;return{...n,command:typeof n.CommandLine==="string"&&n.CommandLine!==""?n.CommandLine:void 0}}var U2=[{id:"antigravity-cli",displayName:"Antigravity CLI",doctorOrder:3,runtime:{order:1,flags:["-ac","--agy-cli"],description:"Run as Antigravity CLI PreToolUse hook",legacyTopLevelFlags:[]},install:{order:2,flag:"--agy-cli",installLabel:"Antigravity CLI",helpTarget:"Antigravity CLI hook config",probeCommand:["agy","--version"]}},{id:"claude-code",displayName:"Claude Code",doctorOrder:1,runtime:{order:2,displayName:"Coding CLI",flags:["-cc","--coding-cli"],legacyFlags:["--claude-code"],description:"Run as Coding CLI PreToolUse hook",legacyTopLevelFlags:["-cc","--claude-code"]},install:{order:3,flag:"--claude-code",installLabel:"Claude Code",helpTarget:"Claude Code plugin",probeCommand:["claude","--version"]}},{id:"codex",displayName:"Codex",doctorOrder:4,install:{order:4,flag:"--codex",installLabel:"Codex",helpTarget:"Codex plugin",probeCommand:["codex","--version"]}},{id:"copilot-cli",displayName:"GitHub Copilot CLI",doctorOrder:7,runtime:{order:5,flags:["-cp","--copilot-cli"],description:"Run as GitHub Copilot CLI PreToolUse hook",legacyTopLevelFlags:["-cp","--copilot-cli"]},install:{order:7,flag:"--copilot-cli",installLabel:"GitHub Copilot CLI",helpTarget:"GitHub Copilot CLI plugin",probeCommand:["copilot","--binary-version"]}},{id:"gemini-cli",displayName:"Gemini CLI",doctorOrder:6,runtime:{order:4,flags:["-gc","--gemini-cli"],description:"Run as Gemini CLI BeforeTool hook",legacyTopLevelFlags:["-gc","--gemini-cli"]},install:{order:6,flag:"--gemini-cli",installLabel:"Gemini CLI",helpTarget:"Gemini CLI extension",probeCommand:["gemini","--version"]}},{id:"hermes-agent",displayName:"Hermes Agent",doctorOrder:8,runtime:{order:6,flags:["-ha","--hermes-agent"],description:"Run as Hermes Agent pre_tool_call hook",legacyTopLevelFlags:[]},install:{order:8,flag:"--hermes-agent",installLabel:"Hermes Agent",helpTarget:"Hermes Agent plugin",probeCommand:["hermes","--version"]}},{id:"kimi-code",displayName:"Kimi Code",doctorOrder:9,runtime:{order:7,flags:["-kc","--kimi-code"],description:"Run as Kimi Code PreToolUse hook",legacyTopLevelFlags:[]},install:{order:9,flag:"--kimi-code",installLabel:"Kimi Code",helpTarget:"Kimi Code hook config",probeCommand:["kimi","--version"]}},{id:"openclaw",displayName:"OpenClaw",doctorOrder:10,install:{order:10,flag:"--openclaw",installLabel:"OpenClaw",helpTarget:"OpenClaw plugin",probeCommand:["openclaw","--version"]}},{id:"opencode",displayName:"OpenCode",doctorOrder:11,install:{order:11,flag:"--opencode",installLabel:"OpenCode",helpTarget:"OpenCode plugin",probeCommand:["opencode","--version"]}},{id:"pi",displayName:"Pi",doctorOrder:12,install:{order:12,flag:"--pi",installLabel:"Pi",helpTarget:"Pi package",probeCommand:["pi","--version"]}},{id:"cursor",displayName:"Cursor",doctorOrder:5,runtime:{order:3,flags:["-cu","--cursor"],description:"Run as Cursor preToolUse hook",legacyTopLevelFlags:[]},install:{order:5,flag:"--cursor",installLabel:"Cursor",helpTarget:"Cursor hook config",probeCommand:["cursor","--version"]}},{id:"amp",displayName:"Amp Code",doctorOrder:2,install:{order:1,flag:"--amp",installLabel:"Amp Code",helpTarget:"Amp Code plugin",probeCommand:["amp","--version"]}}],je=U2.slice().sort((n,t)=>n.doctorOrder-t.doctorOrder).map((n)=>n.id),Fe=U2.filter((n)=>("runtime"in n)).slice().sort((n,t)=>n.runtime.order-t.runtime.order).map((n)=>({id:n.id,displayName:"displayName"in n.runtime?n.runtime.displayName:n.displayName,flags:n.runtime.flags,legacyFlags:"legacyFlags"in n.runtime?n.runtime.legacyFlags:[],description:n.runtime.description,legacyTopLevelFlags:n.runtime.legacyTopLevelFlags})),c2=U2.slice().sort((n,t)=>n.install.order-t.install.order).map((n)=>({id:n.id,...n.install})).map(({order:n,...t})=>t),B6=Object.fromEntries(U2.map((n)=>[n.id,n.displayName]));function o2(n){return U2.find((t)=>t.id===n)?.displayName??n}function b2(n){return U2.find((t)=>t.id===n)?.install.installLabel??n}import{homedir as ns}from"node:os";import{isAbsolute as ze,join as sr}from"node:path";function Je(n){if(n!==void 0&&n!==null&&!ze(n))return"unknown";try{let t=Vn(),r=n?yn(n,hn,t):void 0,e=process.env.HOME||ns(),a=[["codex",process.env.CODEX_HOME||sr(e,".codex")],["copilot-cli",process.env.COPILOT_HOME||sr(e,".copilot")],["claude-code",process.env.CLAUDE_CONFIG_DIR||sr(e,".claude")]],l=r?a.flatMap(([d,s])=>{if(!ze(s))return[];return Be(r,yn(s,hn,t))?[d]:[]}):[];if(l.length===1)return l[0]??"unknown";if(l.length>1)return"unknown"}catch(t){if(t instanceof Mn)return"unknown";return"unknown"}if(process.env.CLAUDECODE==="1"||Boolean(process.env.CLAUDE_CODE_ENTRYPOINT))return"claude-code";return"unknown"}var Lr="PreToolUse",Ze="BeforeTool",Qe="pre_tool_call",cr="PreToolUse";var ts=new Map([["Bash","posix"],["PowerShell","powershell"]]);function rs(n){return X(n,ts)}async function Xe(){await Y({agent:"claude-code",getAgent:(n)=>Je(n.transcript_path),createDenyOutput:(n)=>({hookSpecificOutput:{hookEventName:Lr,permissionDecision:"deny",permissionDecisionReason:n}}),isSupported:(n)=>n.hook_event_name===Lr,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:rs(t)}),getContext:(n,t,r,e)=>I(n.cwd,t,r,e),getSessionId:(n)=>n.session_id})}var es=new Map([["bash","auto"],["Bash","auto"]]);function as(n){return X(n,es)}async function Ye(){await Y({agent:"copilot-cli",createDenyOutput:(n)=>({permissionDecision:"deny",permissionDecisionReason:n}),isSupported:()=>!0,getToolName:(n)=>n.toolName,getToolInput:(n,t,r)=>{if(typeof n.toolArgs!=="string")return r({reason:"Failed to parse toolArgs JSON."}),{ok:!1};let e=dr(n.toolArgs,r,"Failed to parse toolArgs JSON.");if(e===void 0)return{ok:!1};return{ok:!0,input:e,route:as(t)}},getContext:(n,t,r,e)=>I(n.cwd,t,r,e),getSessionId:(n)=>typeof n.sessionId==="string"&&n.sessionId.trim()?n.sessionId:void 0})}var ls=new Map([["Shell","auto"]]);function ds(n){return X(n,ls)}async function Se(){await Y({agent:"cursor",createDenyOutput:(n)=>({permission:"deny",user_message:n,agent_message:n}),createAllowOutput:()=>({permission:"allow"}),isSupported:()=>!0,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:ds(t)}),getContext:ss,getSessionId:(n)=>n.conversation_id})}function ss(n,t,r,e){let a=Ls(n);if(!a[0])return H(e,t,r),null;let l=wn(is(n.cwd),a);if(!l)return H(e,t,r,typeof n.cwd==="string"?n.cwd:void 0),null;if(t===null||typeof t!=="object"||Array.isArray(t))return{configCwd:l,executionCwd:l,policyConfigCwds:a};if(!Object.hasOwn(t,"working_directory"))return{configCwd:l,executionCwd:l,policyConfigCwds:a};let d=t.working_directory;if(typeof d!=="string"||d.trim()==="")return H(e,t,r),null;let s=wn(d,a);if(!s)return H(e,t,r,d),null;return{configCwd:l,executionCwd:s,policyConfigCwds:a}}function Ls(n){return cs(n).flatMap((t)=>{let r=L2([t]);return r?[r]:[]})}function cs(n){if(n.workspace_roots===void 0)return typeof n.cwd==="string"&&n.cwd.trim()!==""?[n.cwd]:[];if(!Array.isArray(n.workspace_roots))return[];return n.workspace_roots.filter((t)=>typeof t==="string"&&t.trim()!=="")}function is(n){return typeof n==="string"&&n.trim()!==""?n:"."}var ps=new Map([["run_shell_command","auto"]]);function us(n){return X(n,ps)}async function He(){await Y({agent:"gemini-cli",createDenyOutput:(n)=>({decision:"deny",reason:n,systemMessage:n}),isSupported:(n)=>n.hook_event_name===Ze,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:us(t)}),getContext:(n,t,r,e)=>I(n.cwd,t,r,e),getSessionId:(n)=>n.session_id})}import{resolve as vs}from"node:path";var os=new Map([["terminal","posix"]]);async function Ae(){await Y({agent:"hermes-agent",createDenyOutput:(n)=>({action:"block",message:n}),isSupported:(n)=>n.hook_event_name===Qe,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:X(t,os)}),getContext:bs,getSessionId:(n)=>n.session_id})}function bs(n,t,r,e){let a=I(n.cwd,t,r,e);if(!a)return null;if(!t||typeof t!=="object"||Array.isArray(t))return a;if(!Object.hasOwn(t,"workdir"))return a;let l=t.workdir;if(typeof l!=="string"||l.trim()==="")return H(e,t,r),null;let d=L2([vs(a.configCwd,l)]);if(!d)return H(e,t,r,l),null;return{...a,executionCwd:d}}var fs=new Map([["Bash","posix"]]);function ys(n){return X(n,fs)}async function We(){await Y({agent:"kimi-code",createDenyOutput:(n)=>({hookSpecificOutput:{hookEventName:cr,permissionDecision:"deny",permissionDecisionReason:n}}),isSupported:(n)=>n.hook_event_name===cr,getToolName:(n)=>n.tool_name,getToolInput:(n,t)=>({ok:!0,input:n.tool_input,route:ys(t)}),getContext:(n,t,r,e)=>I(n.cwd,t,r,e),getSessionId:(n)=>n.session_id})}var hs={"antigravity-cli":ke,"claude-code":Xe,"copilot-cli":Ye,cursor:Se,"gemini-cli":He,"hermes-agent":Ae,"kimi-code":We},O2=Fe.map((n)=>({...n,run:hs[n.id]}));function Re(n){let t=F({label:"hook",booleans:Object.fromEntries(O2.map((e)=>[e.id,[...e.flags,...e.legacyFlags]]))},n);if(t.errors.length>0)return;let r=O2.filter((e)=>t.flags[e.id]);return r.length===1?r[0]:void 0}function Ke(n){return O2.find((t)=>t.legacyTopLevelFlags.some((r)=>r===n))}var ws=O2.map((n)=>({flags:n.flags.join(", "),description:n.description})),xs=O2.flatMap((n)=>n.flags.map((t)=>`cc-safety-net hook ${t}`)),Me={name:"hook",description:"Run as an agent CLI hook (reads JSON from stdin)",usage:"hook INTEGRATION_FLAG",options:[...ws,{flags:"-h, --help",description:"Show this help"}],examples:xs};var Ve={name:"install",description:"Install CC Safety Net into a coding agent CLI",usage:"install [TARGET_FLAG]",options:[...c2.map((n)=>({flags:n.flag,description:`Install ${n.helpTarget}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net install",...c2.map((n)=>`cc-safety-net install ${n.flag}`)]},Ge={name:"uninstall",description:"Uninstall CC Safety Net from a coding agent CLI",usage:"uninstall [TARGET_FLAG]",options:[...c2.map((n)=>({flags:n.flag,description:`Uninstall ${n.helpTarget}`})),{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net uninstall",...c2.map((n)=>`cc-safety-net uninstall ${n.flag}`)]},Ce={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 Ue={name:"logs",description:"Browse audit log entries recorded by hooks",usage:"logs [options]",options:[{flags:"--id",argument:"<id>",description:"Show one entry from retained history by its 16-character id (not guaranteed once it is older than the configured retention)"},{flags:"--limit",argument:"<n>",description:"Maximum entries to print",default:"20"},{flags:"--since",argument:"<days>",description:"Only include entries newer than this many days (max: the configured audit retention, 1-365)",default:"30"},{flags:"--agent",argument:"<name>",description:"Filter by agent name"},{flags:"--rule",argument:"<ruleId>",description:"Filter by rule id"},{flags:"--session",argument:"<id>",description:"Filter by session id"},{flags:"--project",argument:"<path>",description:"Filter by project path"},{flags:"--suspect",description:"Only denials that look like false positives"},{flags:"--all",description:"Include allow entries"},{flags:"--prune-legacy",description:"Permanently delete all legacy root-level logs; nested logs are untouched"},{flags:"--dry-run",description:"With --prune-legacy, report what would be deleted and delete nothing"},{flags:"--json",description:"Output entries as JSON"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net logs --id 3fa9c2d1a70e8b42","cc-safety-net logs --agent claude-code","cc-safety-net logs --project . --since 7","cc-safety-net logs --suspect --since 7","cc-safety-net logs --json","cc-safety-net logs --prune-legacy --dry-run","cc-safety-net logs --prune-legacy"]};var T2={name:"rule",description:"Manage CC Safety Net rule config and rulebook sources",usage:"rule <subcommand>",subcommands:[{usage:"init [--example]",description:"Create inert rule config"},{usage:"add <source>",description:"Add a rulebook source and sync"},{usage:"remove <source>",description:"Remove a rulebook source and sync"},{usage:"update [source]",description:"Refresh rulebook lock/cache state"},{usage:"sync",description:"Sync configured rulebooks"},{usage:"list",description:"List active rulebooks"},{usage:"wrapper add <command>",description:"Trust a transparent command wrapper"},{usage:"wrapper remove <command>",description:"Remove a transparent command wrapper"},{usage:"wrapper list",description:"List transparent command wrappers"},{usage:"migrate [--cleanup]",description:"Migrate legacy inline rules"},{usage:"doc",description:"Print the rulebook authoring guide"},{usage:"verify",description:"Validate rule config files"}],options:[{flags:"-g, --global",description:"Use user-scope rule config"},{flags:"--check",description:"Check without changing lock/cache state"},{flags:"--cleanup",description:"Delete legacy files after rule migrate verifies them"},{flags:"--delete-source",description:"Delete clean local source directory on remove"},{flags:"--example",description:"Create an inactive example rulebook with rule init"},{flags:"-h, --help",description:"Show this help"}],examples:["cc-safety-net rule init","cc-safety-net rule init --example","cc-safety-net rule wrapper add rtk","cc-safety-net rule add project-rules","cc-safety-net rule sync","cc-safety-net rule migrate --cleanup","cc-safety-net rule verify"]};var Oe={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 Te={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 _e=[Oe,ue,Ue,ve,T2,Ve,Ce,Ge,Me,oe,Te];function $s(n){return n.aliases??[]}function gs(n){return!n.hidden}function Gn(n){let t=n.toLowerCase();return _e.find((r)=>r.name.toLowerCase()===t||$s(r).some((e)=>e.toLowerCase()===t))}function Ee(){return _e.filter(gs)}import{readFileSync as Ds}from"node:fs";import{basename as ms}from"node:path";function Cn(n=7,t=s2()){let r=Date.now()-n*24*60*60*1000,e=[],a=new Set,l=0,d,s,L,c;if(t)$2(t);let i={count:0},u=t?u2(t,i):[];for(let p of u)try{let v=Ds(p,"utf-8").trim().split(`
6
+ `).filter(Boolean);for(let y of v)try{let x=JSON.parse(y);if(x.decision==="allow")continue;let w=new Date(x.ts).getTime();if(w>=r){if(l++,a.add(x.sessionId??ms(p,".jsonl")),s===void 0||w<=s)d=x.ts,s=w;if(c===void 0||w>c)L=x.ts,c=w;ks(e,x,w)}}catch{i.count++}}catch{i.count++}let o=e.map((p)=>({timestamp:p.ts,command:p.command,reason:p.reason,relativeTime:zt(new Date(p.ts))}));return{totalBlocked:l,sessionCount:a.size,recentEntries:o,oldestEntry:d,newestEntry:L,unreadable:i.count}}function ks(n,t,r){let e=n.findIndex((a)=>r>new Date(a.ts).getTime());if(e===-1){if(n.length<3)n.push(t);return}if(n.splice(e,0,t),n.length>3)n.pop()}import{dirname as qs}from"node:path";function Pe(n,t,r,e,a){let l;try{if(g(e)===null)return{path:n,exists:!1,valid:!1,ruleCount:0};l=a2(e),l.errors.push(...l2(n,t,{userConfigDir:r},a))}catch(d){if(!(d instanceof Z))throw d;l={errors:[d.message],ruleNames:new Set}}return{path:n,exists:!0,valid:l.errors.length===0,ruleCount:l.ruleNames.size,...l.errors.length>0?{errors:l.errors}:{}}}function js(n,t){return{source:t,name:n.name,command:n.command,subcommand:n.subcommand,blockArgs:[...n.block_args],reason:n.reason}}function Ie(n,t){let r=t?.userConfigPath??E(),e=t?.projectConfigPath??_(n),a=qs(r),l=v2({cwd:n,userConfigPath:r,projectConfigPath:e,userConfigDir:a}),d=P({cwd:n,userConfigPath:r,projectConfigPath:e,userConfigDir:a}),s=new Map(l.rulebooks.flatMap((L)=>L.rules.map((c)=>[c,L.source])));return{userConfig:Pe(r,R2({userConfigPath:r}),a,d.userConfigTarget,d.userScope),projectConfig:Pe(e,K2(e),a,d.projectConfigTarget,d.projectScope),effectiveRules:l.rules.map((L)=>js(L,s.get(L.name)??"project")),shadowedRules:[]}}var Fs=[{flag:m.level,description:"Safety level preset: standard, strict, or paranoid",defaultBehavior:"standard"},{flag:m.strict,description:"Legacy; equivalent to safety.overrides.fail_closed",defaultBehavior:"permissive"},{flag:m.paranoid,description:"Legacy; equivalent to safety.overrides.paranoid_rm and paranoid_interpreters",defaultBehavior:"off"},{flag:m.paranoidRm,description:"Legacy; equivalent to safety.overrides.paranoid_rm",defaultBehavior:"off"},{flag:m.paranoidInterpreters,description:"Legacy; equivalent to safety.overrides.paranoid_interpreters",defaultBehavior:"off"},{flag:m.worktree,description:"Allow local git discards in linked worktrees",defaultBehavior:"off"},{flag:m.debug,description:"Print diagnostic messages to stderr",defaultBehavior:"off"},{flag:m.auditScope,description:"Command decisions recorded: all, or blocked (privacy-minimizing, denials only)",defaultBehavior:"all"}];function Ne(){return[...Fs.map((n)=>({name:n.flag.name,value:nr(n.flag),isSet:tr(n.flag),legacyName:n.flag.legacyName,legacyValue:n.flag.legacyName?process.env[n.flag.legacyName]:void 0,legacyIsSet:n.flag.legacyName?process.env[n.flag.legacyName]!==void 0:void 0,description:n.description,defaultBehavior:n.defaultBehavior})),{name:"CC_SAFETY_NET_HOME",value:process.env.CC_SAFETY_NET_HOME,isSet:process.env.CC_SAFETY_NET_HOME!==void 0,description:"Override user-scope config/cache directory",defaultBehavior:"~/.cc-safety-net"}]}var na={error:0,warning:1,info:2},zs=["policy","config","audit"];function Bs(n){return n.map((t)=>{if(t==="ownership")return"is not owned by the current user";if(t==="permissions")return"has unsafe permissions";if(t==="symlink")return"is a symbolic link";return"is not a directory"}).join(" and ")}var Js=[{derive:(n)=>n.hooks.length>0&&n.hooks.every((t)=>!t.configured)?[{checkId:"integration.none-configured",severity:"error",title:"No integration configured",detail:"CC Safety Net is not connected to any supported coding-agent integration.",fixHint:"Run `cc-safety-net install` and configure at least one integration."}]:[]},{derive:(n)=>n.hooks.filter((t)=>t.inspectionStatus==="failed").map((t)=>{let r=o2(t.platform);return{checkId:"integration.inspection-failed",severity:"error",title:`${r} inspection failed`,detail:`Doctor could not verify the ${r} integration configuration.`,fixHint:`Correct the reported ${r} configuration error, then run \`cc-safety-net doctor\` again.`,integration:t.platform}})},{derive:(n)=>n.userConfig.exists&&!n.userConfig.valid?[{checkId:"config.user-invalid",severity:"error",title:"User configuration is invalid",detail:"Doctor could not load a valid user rules configuration.",fixHint:"Run `cc-safety-net rule verify`, correct the reported error, then rerun doctor.",path:n.userConfig.path}]:[]},{derive:(n)=>n.projectConfig.exists&&!n.projectConfig.valid?[{checkId:"config.project-invalid",severity:"error",title:"Project configuration is invalid",detail:"Doctor could not load a valid project rules configuration.",fixHint:"Run `cc-safety-net rule verify`, correct the reported error, then rerun doctor.",path:n.projectConfig.path}]:[]},{derive:(n)=>n.configState.state==="degraded"?[{checkId:"config.runtime-degraded",severity:"warning",title:"Runtime is enforcing a fallback configuration",detail:`The rejected candidate configuration is not active: ${n.configState.reason}`,fixHint:"Correct the named source, run `cc-safety-net rule sync` for a rule source, then rerun doctor."}]:[]},{derive:(n)=>{let t=n.environment.find((r)=>r.name==="CC_SAFETY_NET_AUDIT_SCOPE");return Nt(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."}]:[]}},...zs.map((n)=>({derive:(t)=>t.posture.directories.filter((r)=>r.kind===n&&r.status==="unsafe").map((r)=>({checkId:`posture.${n}-directory-unsafe`,severity:"error",title:`${n[0]?.toUpperCase()}${n.slice(1)} directory is unsafe`,detail:`The ${n} directory ${Bs(r.issues)}.`,fixHint:"Ensure this is a real directory owned by the current user with no group or other write access, then rerun doctor.",...r.path?{path:r.path}:{}}))})),{derive:(n)=>{let t=[...n.effectiveSafety.weakenedRuleOverrides].sort();return t.length>0?[{checkId:"posture.rule-overrides-weaken-preset",severity:"warning",title:"Rule overrides weaken the selected preset",detail:`Explicit overrides disable rules the resolved preset would enable: ${t.join(", ")}.`,fixHint:`Remove these \`off\` overrides or set them to \`on\`: ${t.join(", ")}.`}]:[]}}];function ta(n){return Js.flatMap((t,r)=>t.derive(n).map((e,a)=>({finding:e,catalogOrder:r,occurrence:a}))).sort((t,r)=>na[t.finding.severity]-na[r.finding.severity]||t.catalogOrder-r.catalogOrder||t.occurrence-r.occurrence).map((t)=>t.finding)}function N(){return Boolean(process.stdout.isTTY&&!process.env.NO_COLOR)}var Zs=(n)=>N()?`\x1B[32m${n}\x1B[0m`:n,Qs=(n)=>N()?`\x1B[33m${n}\x1B[0m`:n,Xs=(n)=>N()?`\x1B[34m${n}\x1B[0m`:n,Ys=(n)=>N()?`\x1B[35m${n}\x1B[0m`:n,Ss=(n)=>N()?`\x1B[36m${n}\x1B[0m`:n,Hs=(n)=>N()?`\x1B[31m${n}\x1B[0m`:n,As=(n)=>N()?`\x1B[2m${n}\x1B[0m`:n,Ws=(n)=>N()?`\x1B[1m${n}\x1B[0m`:n,b={green:Zs,yellow:Qs,blue:Xs,magenta:Ys,cyan:Ss,red:Hs,dim:As,bold:Ws},Rs="\x1B[0m",Ks=[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 Ms(n){let t=n;return()=>{return t=(t*1664525+1013904223)%4294967296,t/4294967296}}function Vs(n){let t=[...Ks],r=Ms(n);for(let e=t.length-1;e>0;e--){let a=Math.floor(r()*(e+1)),l=t[e];t[e]=t[a],t[a]=l}return t}function Gs(n,t=0){if(!N())return"";let r=Vs(t);return`\x1B[38;5;${r[n%r.length]}m`}function ra(n,t,r=0){if(!N())return`"${n}"`;return`${Gs(t,r)}"${n}"${Rs}`}var Cs=new RegExp("\x1B\\[[0-9;]*m","g"),ir=(n)=>n.replace(Cs,"").length;function m2(n){let t=(n.headers??n.rows[0]??[]).map((d,s)=>{let L=Math.max(...n.rows.map((c)=>ir(c[s]??"")));return Math.max(ir(d),L)}),r=(d,s)=>d+" ".repeat(Math.max(0,s-ir(d))),e=(d,s)=>s[0]+t.map((L)=>d.repeat(L+2)).join(s[1])+s[2],a=(d)=>`│ ${d.map((s,L)=>r(s,t[L]??0)).join(" │ ")} │`,l=n.headers?[` ${a(n.headers)}`,` ${e("─",["├","┼","┤"])}`]:[];return[` ${e("─",["┌","┬","┐"])}`,...l,...n.rows.map((d)=>` ${a(d)}`),` ${e("─",["└","┴","┘"])}`].join(`
7
+ `)}function ea(n){let t=[];t.push("Hook Integration"),t.push(Us(n));let r=[],e=[];for(let a of n){let l=o2(a.platform);if(a.errors&&a.errors.length>0)for(let d of a.errors)if(a.configured)r.push({platform:l,message:d});else e.push({platform:l,message:d})}for(let a of r)t.push(` Warning (${a.platform}): ${a.message}`);for(let a of e)t.push(b.red(` Error (${a.platform}): ${a.message}`));return t.join(`
8
+ `)}function Us(n){let t=["Platform","Discovery","Configuration","Inspection"],r=n.map((e)=>{let a=o2(e.platform);if(e.inspectionStatus==="not-inspected"){let L=b.dim("Not inspected");return[a,L,L,L]}let l=e.detected?b.green("Detected"):e.inspectionStatus==="failed"?b.red("Unknown"):b.dim("Not detected"),d=e.configured?b.green("Configured"):e.detected?b.yellow("Not configured"):e.inspectionStatus==="failed"?b.red("Unknown"):b.dim("Not applicable"),s=e.inspectionStatus==="verified"?b.green("Verified"):e.inspectionStatus==="failed"?b.red("Failed"):b.dim("Not applicable");return[a,l,d,s]});return m2({headers:t,rows:r})}function aa(n){let r=["Guard Engine Verification",` Synthetic self-test: ${n.failed>0?b.red(`${n.passed}/${n.total} FAIL`):b.green(`${n.passed}/${n.total} passed`)}`],e=n.results.filter((a)=>!a.passed);if(e.length>0){r.push(""),r.push(b.red(" Failures:"));for(let a of e)r.push(b.red(` • ${a.description}`)),r.push(b.red(` expected ${a.expected}, got ${a.actual}`))}return r.join(`
9
+ `)}function Os(n){if(n.length===0)return" (no custom rules)";let t=["Source","Name","Command","Block Args"],r=n.map((e)=>[e.source,e.name,e.subcommand?`${e.command} ${e.subcommand}`:e.command,e.blockArgs.join(", ")]);return m2({headers:t,rows:r})}function la(n){let t=[];if(t.push("Configuration"),t.push(Ts(n.userConfig,n.projectConfig)),t.push(""),n.effectiveRules.length>0)t.push(` Effective rules (${n.effectiveRules.length} total):`),t.push(Os(n.effectiveRules));else t.push(" Effective rules: (none - using built-in rules only)");for(let r of n.shadowedRules)t.push(""),t.push(` Note: Project rule "${r.name}" shadows user rule with same name`);return t.join(`
10
+ `)}function Ts(n,t){let r=["Scope","Status"],e=(l)=>{if(!l.exists)return b.dim("N/A");if(!l.valid)return b.red(`Invalid (${l.errors?.[0]??"unknown error"})`);return b.green("Configured")},a=[["User",e(n)],["Project",e(t)]];return m2({headers:r,rows:a})}function da(n){let t=[];return t.push("Environment"),t.push(_s(n)),t.join(`
11
11
  `)}function sa(n){let t=["Effective Safety",` Selected preset: ${n.effectiveSafety.selectedPreset}`,` Effective: ${n.effectiveSafety.level}`],r=[["fail_closed","fail_closed"],["paranoid_rm","paranoid_rm"],["paranoid_interpreters","paranoid_interpreters"]];for(let[e,a]of r){let l=n.effectiveSafety.capabilities[e],d=l.enabled?b.green("ON"):b.dim("OFF"),s=l.sources.length>0?` (${l.sources.join(", ")})`:"";t.push(` ${a}: ${d} via ${l.source}${s}`)}t.push(` Stored rule customizations: ${n.effectiveSafety.ruleCounts.stored}`),t.push(` Effective rule customizations: ${n.effectiveSafety.ruleCounts.effective}`);for(let[e,a]of Object.entries(n.effectiveSafety.ruleOverrides))t.push(` ${e}: ${a}`);return t.join(`
12
- `)}function ca(n){let t=["Findings"];if(n.length===0)return t.push(" No findings from inspected doctor facts."),t.join(`
12
+ `)}function La(n){let t=["Findings"];if(n.length===0)return t.push(" No findings from inspected doctor facts."),t.join(`
13
13
  `);for(let r of n){let e=`[${r.severity.toUpperCase()}] ${r.checkId}: ${z(r.title)}`,a=r.severity==="error"?b.red:r.severity==="warning"?b.yellow:b.blue;if(t.push(` ${a(e)}`),t.push(` ${z(r.detail)}`),r.path)t.push(` Path: ${z(r.path)}`);if(r.fixHint)t.push(` Fix: ${z(r.fixHint)}`)}return t.join(`
14
- `)}function Ts(n){let t=["Variable","Status","Legacy"],r=n.map((e)=>{let a=e.isSet?b.green("✓"):b.dim("✗"),l=e.legacyName&&e.legacyIsSet?`${e.legacyName} ${b.green("✓")}`:e.legacyName??"";return[e.name,a,l]});return m2({headers:t,rows:r})}function La(n){let t=[];if(n.totalBlocked===0)t.push("Recent Activity"),t.push(" No blocked commands in the last 7 days"),t.push(" Tip: This is normal for new installations");else t.push(`Recent Activity · last 7 days (${n.totalBlocked} blocked / ${n.sessionCount} sessions)`),t.push(Es(n.recentEntries));if(n.unreadable>0)t.push(` Warning: ${n.unreadable} audit log ${n.unreadable===1?"source":"sources"} could not be read; this summary is incomplete`);return t.join(`
15
- `)}function Es(n){let t=["Time","Command"],r=n.map((e)=>{let a=z(e.command.replace(/\r\n|\r|\n/g," ↵ ").replace(/\t/g," ")),l=a.length>40?`${a.slice(0,37)}...`:a;return[e.relativeTime,l]});return m2({headers:t,rows:r})}function ia(n){let t=[];if(t.push("Update Check"),n.latestVersion===null&&!n.error)return t.push(Gn([["Status",b.dim("Skipped")],["Installed",n.currentVersion]])),t.join(`
16
- `);if(n.error)return t.push(Gn([["Status",`${b.yellow("⚠")} Error`],["Installed",n.currentVersion],["Error",b.dim(n.error)]])),t.join(`
17
- `);if(n.updateAvailable)return t.push(Gn([["Status",`${b.yellow("⚠")} Update Available`],["Current",n.currentVersion],["Latest",b.green(n.latestVersion??"")]])),t.push(""),t.push(" Run: bunx cc-safety-net@latest doctor"),t.push(" Or: npx cc-safety-net@latest doctor"),t.join(`
18
- `);return t.push(Gn([["Status",`${b.green("✓")} Up to date`],["Version",n.currentVersion]])),t.join(`
19
- `)}function Gn(n){return m2({rows:n})}function pa(n){let t=[];return t.push("System Info"),t.push(_s(n)),t.join(`
20
- `)}function _s(n){let t=["Component","Version"],r=(l)=>{if(l===null)return b.dim("not found");return l},a=[{label:"cc-safety-net",value:n.version},{label:"Claude Code",value:n.claudeCodeVersion},{label:"Amp Code",value:n.ampVersion},{label:"Antigravity CLI",value:n.antigravityCliVersion},{label:"Codex",value:n.codexCliVersion},{label:"Cursor",value:n.cursorVersion},{label:"Gemini CLI",value:n.geminiCliVersion},{label:"GitHub Copilot CLI",value:n.copilotCliVersion},{label:"Hermes Agent",value:n.hermesAgentVersion},{label:"Kimi Code",value:n.kimiCodeVersion},{label:"OpenClaw",value:n.openClawVersion},{label:"OpenCode",value:n.openCodeVersion},{label:"Pi",value:n.piCliVersion},{label:"Node.js",value:n.nodeVersion},{label:"npm",value:n.npmVersion},{label:"Bun",value:n.bunVersion},{label:"Platform",value:n.platform}].map((l)=>[l.label,r(l.value)]);return m2({headers:t,rows:a})}function ua(n){if(n.findings.length===0)return b.green(`
14
+ `)}function _s(n){let t=["Variable","Status","Legacy"],r=n.map((e)=>{let a=e.isSet?b.green("✓"):b.dim("✗"),l=e.legacyName&&e.legacyIsSet?`${e.legacyName} ${b.green("✓")}`:e.legacyName??"";return[e.name,a,l]});return m2({headers:t,rows:r})}function ca(n){let t=[];if(n.totalBlocked===0)t.push("Recent Activity"),t.push(" No blocked commands in the last 7 days"),t.push(" Tip: This is normal for new installations");else t.push(`Recent Activity · last 7 days (${n.totalBlocked} blocked / ${n.sessionCount} sessions)`),t.push(Es(n.recentEntries));if(n.unreadable>0)t.push(` Warning: ${n.unreadable} audit log ${n.unreadable===1?"source":"sources"} could not be read; this summary is incomplete`);return t.join(`
15
+ `)}function Es(n){let t=["Time","Command"],r=n.map((e)=>{let a=z(e.command.replace(/\r\n|\r|\n/g," ↵ ").replace(/\t/g," ")),l=a.length>40?`${a.slice(0,37)}...`:a;return[e.relativeTime,l]});return m2({headers:t,rows:r})}function ia(n){let t=[];if(t.push("Update Check"),n.latestVersion===null&&!n.error)return t.push(Un([["Status",b.dim("Skipped")],["Installed",n.currentVersion]])),t.join(`
16
+ `);if(n.error)return t.push(Un([["Status",`${b.yellow("⚠")} Error`],["Installed",n.currentVersion],["Error",b.dim(n.error)]])),t.join(`
17
+ `);if(n.updateAvailable)return t.push(Un([["Status",`${b.yellow("⚠")} Update Available`],["Current",n.currentVersion],["Latest",b.green(n.latestVersion??"")]])),t.push(""),t.push(" Run: bunx cc-safety-net@latest doctor"),t.push(" Or: npx cc-safety-net@latest doctor"),t.join(`
18
+ `);return t.push(Un([["Status",`${b.green("✓")} Up to date`],["Version",n.currentVersion]])),t.join(`
19
+ `)}function Un(n){return m2({rows:n})}function pa(n){let t=[];return t.push("System Info"),t.push(Ps(n)),t.join(`
20
+ `)}function Ps(n){let t=["Component","Version"],r=(l)=>{if(l===null)return b.dim("not found");return l},a=[{label:"cc-safety-net",value:n.version},{label:"Claude Code",value:n.claudeCodeVersion},{label:"Amp Code",value:n.ampVersion},{label:"Antigravity CLI",value:n.antigravityCliVersion},{label:"Codex",value:n.codexCliVersion},{label:"Cursor",value:n.cursorVersion},{label:"Gemini CLI",value:n.geminiCliVersion},{label:"GitHub Copilot CLI",value:n.copilotCliVersion},{label:"Hermes Agent",value:n.hermesAgentVersion},{label:"Kimi Code",value:n.kimiCodeVersion},{label:"OpenClaw",value:n.openClawVersion},{label:"OpenCode",value:n.openCodeVersion},{label:"Pi",value:n.piCliVersion},{label:"Node.js",value:n.nodeVersion},{label:"npm",value:n.npmVersion},{label:"Bun",value:n.bunVersion},{label:"Platform",value:n.platform}].map((l)=>[l.label,r(l.value)]);return m2({headers:t,rows:a})}function ua(n){if(n.findings.length===0)return b.green(`
21
21
  No findings from inspected doctor facts.`);let t={error:n.findings.filter((l)=>l.severity==="error").length,warning:n.findings.filter((l)=>l.severity==="warning").length,info:n.findings.filter((l)=>l.severity==="info").length},r=["error","warning","info"].filter((l)=>t[l]>0).map((l)=>`${t[l]} ${l}`),e=n.findings.length===1?"finding":"findings",a=`
22
- ${n.findings.length} ${e}: ${r.join(", ")}.`;if(t.error>0)return b.red(a);if(t.warning>0)return b.yellow(a);return b.blue(a)}import{lstatSync as Ps}from"node:fs";import{dirname as sr}from"node:path";function cr(n,t){try{let r=Ps(t);if(r.isSymbolicLink())return{kind:n,path:t,status:"unsafe",issues:["symlink"]};if(!r.isDirectory())return{kind:n,path:t,status:"unsafe",issues:["not-directory"]};if(process.platform==="win32"||typeof process.getuid!=="function")return{kind:n,path:t,status:"unknown",issues:[]};let e=[...r.uid!==process.getuid()?["ownership"]:[],...(r.mode&18)!==0?["permissions"]:[]];return{kind:n,path:t,status:e.length>0?"unsafe":"safe",issues:e}}catch(r){if(typeof r==="object"&&r!==null&&"code"in r&&r.code==="ENOENT")return{kind:n,path:t,status:"not-applicable",issues:[]};return{kind:n,path:t,status:"unknown",issues:[]}}}function oa(n){let t=s2();return{directories:[cr("policy",sr(sr(n))),cr("config",sr(n)),...t?[cr("audit",t)]:[{kind:"audit",status:"unknown",issues:[]}]]}}import{spawn as Ns}from"node:child_process";import{existsSync as va}from"node:fs";import{delimiter as Is,extname as nc,join as tc}from"node:path";import{stripVTControlCharacters as ba}from"node:util";var ya="2.0.3",rc=5000,ec="_CC_SAFETY_NET_TEST_SPAWN_PLATFORM";function j(){return ya}function Lr(n,t){let r=n[t];if(r)return r;let e=Object.keys(n).find((a)=>a.toLowerCase()===t.toLowerCase()&&!!n[a]);return e?n[e]:r}function ac(n){return(Lr(n,"PATHEXT")||".COM;.EXE;.BAT;.CMD").split(";").filter((t)=>t.length>0)}function lc(n,t){let r=nc(n)?[n]:[...ac(t).map((e)=>`${n}${e}`),n];if(n.includes("/")||n.includes("\\"))return r.find((e)=>va(e))??n;return(Lr(t,"PATH")??"").split(Is).flatMap((e)=>r.map((a)=>tc(e,a))).find((e)=>va(e))??n}function fa(n){if(!/[\s"&|<>^]/.test(n))return n;return`"${n.replace(/"/g,'""')}"`}function f2(n,t){let[r,...e]=n,a=t[ec]==="win32"?"win32":process.platform;if(!r||a!=="win32")return{cmd:r??"",args:e};let l=lc(r,t);if(!/\.(?:bat|cmd)$/i.test(l))return{cmd:l,args:e};return{cmd:Lr(t,"COMSPEC")??"cmd.exe",args:["/d","/c",["call",fa(l),...e.map(fa)].join(" ")]}}var wn=async(n,t=rc)=>{let r=await dc(n,{timeoutMs:t});if(r.code!==0)return null;return ba(r.stdout).trim()||ba(r.stderr).trim()||null};function dc(n,t){let[r,...e]=n;if(!r)return Promise.resolve({code:null,stdout:"",stderr:""});return new Promise((a)=>{try{let l=f2([r,...e],process.env),d=Ns(l.cmd,l.args,{stdio:["ignore","pipe","pipe"]}),s=!1,c="",L="";d.stdout.on("data",(v)=>{c+=v.toString()}),d.stderr.on("data",(v)=>{L+=v.toString()});let i=(v)=>{if(s)return;s=!0,clearTimeout(u),a(v)},u=setTimeout(()=>{d.kill(),i({code:null,stdout:c,stderr:L})},t.timeoutMs);d.on("close",(v)=>{i({code:v,stdout:c,stderr:L})}),d.on("error",()=>{i({code:null,stdout:c,stderr:L})})}catch{a({code:null,stdout:"",stderr:""})}})}function Q(n){if(!n)return null;let t=/Claude Code\s+(\d+\.\d+\.\d+)/i.exec(n);if(t)return t[1]??null;let r=/v?(\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)/i.exec(n);if(r)return r[1]??null;return n.split(`
23
- `)[0]?.trim()||null}async function xn(n=wn){let[t,r,e,a,l,d,s,c,L,i,u,v,p,f,o,y,x]=await Promise.all([n(["claude","--version"]),n(["agy","--version"]),n(["opencode","--version"]),n(["codex","--version"]),n(["codex","plugin","list"]),n(["gemini","--version"]),n(["copilot","--binary-version"]),n(["hermes","--version"]),n(["kimi","--version"]),n(["openclaw","--version"]),n(["pi","--version"]),n(["cursor","--version"]),n(["amp","--version"]),n(["amp","plugins","list"],30000),n(["node","--version"]),n(["npm","--version"]),n(["bun","--version"])]);return{version:ya,claudeCodeVersion:Q(t),antigravityCliVersion:Q(r),openCodeVersion:Q(e),codexCliVersion:Q(a),codexPluginListOutput:l,geminiCliVersion:Q(d),copilotCliVersion:Q(s),hermesAgentVersion:Q(c),kimiCodeVersion:Q(L),openClawVersion:Q(i),piCliVersion:Q(u),cursorVersion:Q(v),ampVersion:Q(p),ampPluginListOutput:f,nodeVersion:Q(o),npmVersion:Q(y),bunVersion:Q(x),platform:`${process.platform} ${process.arch}`}}function ir(n,t){if(t==="dev")return!1;let r=n.split(".").map(Number),e=t.split(".").map(Number),[a=0,l=0,d=0]=r,[s=0,c=0,L=0]=e;if(a!==s)return a>s;if(l!==c)return l>c;return d>L}async function E2(){let n=j(),t=new AbortController,r=setTimeout(()=>t.abort(),3000);try{let e=await fetch("https://registry.npmjs.org/cc-safety-net/latest",{signal:t.signal});if(!e.ok)return{currentVersion:n,latestVersion:null,updateAvailable:!1,error:`npm registry returned ${e.status}`};let a=await e.json(),l=ir(a.version,n);return{currentVersion:n,latestVersion:a.version,updateAvailable:l}}catch(e){return{currentVersion:n,latestVersion:null,updateAvailable:!1,error:e instanceof Error?e.message:"Network error"}}finally{clearTimeout(r)}}import*as ka from"node:readline";var $a=(n)=>`\x1B[${n}B`,sc=(n)=>`\x1B[${n}A`;var ha=["░","▒","▓","╱","╲","┃","━","┏","┓","┗","┛","╋"];function cc(n){return new Promise((t)=>setTimeout(t,n))}function Lc(n,t,r){if(!r)return t(n);if(r.aborted)return Promise.resolve();return new Promise((e,a)=>{let l=()=>r.removeEventListener("abort",d),d=()=>{l(),e()};r.addEventListener("abort",d,{once:!0}),t(n).then(()=>{l(),e()},(s)=>{l(),a(s)})})}function $n(n,t){return n&&n>0?n:t}function Cn(n){return Math.max(0,Math.min(1,n))}function _2(n){return Math.max(0,Math.min(255,Math.round(n)))}function pr(n){return n<=0.0031308?12.92*n:1.055*n**0.4166666666666667-0.055}function ic(n,t,r){let e=r*Math.PI/180,a=t*Math.cos(e),l=t*Math.sin(e),d=(n+0.3963377774*a+0.2158037573*l)**3,s=(n-0.1055613458*a-0.0638541728*l)**3,c=(n-0.0894841775*a-1.291485548*l)**3;return{blue:_2(pr(Cn(-0.0041960863*d-0.7034186147*s+1.707614701*c))*255),green:_2(pr(Cn(-1.2684380046*d+2.6097574011*s-0.3413193965*c))*255),red:_2(pr(Cn(4.0767416621*d-3.3077115913*s+0.2309699292*c))*255)}}function ur(n,t){let r=(t*n*180/Math.PI%360+360)%360;return ic(0.72,0.15,r)}function ga(n,t=0.1){let r=ur(t,n);return`\x1B[38;2;${r.red};${r.green};${r.blue}m`}function pc(n,t){return{blue:_2(n.blue+(255-n.blue)*t),green:_2(n.green+(255-n.green)*t),red:_2(n.red+(255-n.red)*t)}}function Da(n,t,r){let e=Math.imul(n+2654435769,2246822507)^Math.imul(t+3266489909,668265263)^Math.imul(r+374761393,2654435761),a=e^e>>>15,l=Math.imul(a,739982445),d=l^l>>>12,s=Math.imul(d,695872825);return((s^s>>>15)>>>0)/4294967296}function uc(n,t,r){let e=Math.floor(Da(n,t,r)*ha.length);return ha[e]??"░"}function wa(n){let t=Cn(n);return t*t*t*(t*(t*6-15)+10)}function oc(n){if(n.length===0)return"";let t=[],r=!1,e="";for(let a of n){let l=`${a.red};${a.green};${a.blue}`;if(a.bold!==r)t.push(a.bold?"\x1B[1m":"\x1B[22m"),r=a.bold;if(l!==e)t.push(`\x1B[38;2;${l}m`),e=l;t.push(a.character)}return`${t.join("")}\x1B[22m\x1B[39m`}function vc(n,t,r,e,a){return n.map((l,d)=>({...ur(r,e+t+d/a),bold:!1,character:l}))}function bc(n,t,r,e,a,l,d,s){let c=Math.max(1,e*0.75),L=Math.min(1,r/c),i=a*wa(L),u=Math.max(0,(r-c)/Math.max(1,e-c)),v=(1-wa(r/e))*s*2,p=0.35*Math.max(0,1-u*2),f=L>=1,o=Math.min(n.length,Math.ceil(i+2+1));return n.slice(0,o).map((y,x)=>{let w=ur(l,d+t+x/s+v),h=x+Da(t,x,7919)*2-1;if(h>i+2)return{...w,bold:!1,character:" "};let J=i-h,Z2=0.8*Math.exp(-(J*J)/12.5),an=Math.min(0.9,Z2+p),Dt=!f&&h>i-4;return{...pc(w,an),bold:an>0.3,character:Dt?uc(t,x,r):y}})}function xa(n){return`\x1B[?2026h${n.map((t,r)=>`\x1B8${r>0?$a(r):""}${oc(t)}`).join("")}\x1B[?2026l`}async function or(n,t={}){if(!n)return;let r=t.output??process.stdout,e=t.sleep??cc,a=$n(t.frequency,0.1),l=t.seed??0,d=$n(t.speed,40),s=$n(t.spread,3),c=$n(t.frameRate,60),L=Math.max(1,Math.floor($n(t.duration,12))),i=n.split(`
24
- `).map((o)=>Array.from(o)),u=Math.max(...i.map((o)=>o.length)),v=1000*L*i.filter((o)=>o.length>0).length/d,p=u>0?Math.max(1,Math.ceil(v/(1000/c))):0,f=p>0?v/p:0;r.write(`\x1B[?25l${i.length>1?`${`
25
- `.repeat(i.length-1)}${sc(i.length-1)}`:""}\x1B7`);try{for(let o=1;o<=p;o+=1){if(t.signal?.aborted)break;r.write(xa(i.map((y,x)=>bc(y,x,o,p,u,a,l,s)))),await Lc(f,e,t.signal)}}finally{if(r.write(xa(i.map((o,y)=>vc(o,y,a,l,s)))),r.write("\x1B8"),i.length>1)r.write($a(i.length-1));r.write(`
22
+ ${n.findings.length} ${e}: ${r.join(", ")}.`;if(t.error>0)return b.red(a);if(t.warning>0)return b.yellow(a);return b.blue(a)}import{lstatSync as Is}from"node:fs";import{dirname as pr}from"node:path";function ur(n,t){try{let r=Is(t);if(r.isSymbolicLink())return{kind:n,path:t,status:"unsafe",issues:["symlink"]};if(!r.isDirectory())return{kind:n,path:t,status:"unsafe",issues:["not-directory"]};if(process.platform==="win32"||typeof process.getuid!=="function")return{kind:n,path:t,status:"unknown",issues:[]};let e=[...r.uid!==process.getuid()?["ownership"]:[],...(r.mode&18)!==0?["permissions"]:[]];return{kind:n,path:t,status:e.length>0?"unsafe":"safe",issues:e}}catch(r){if(typeof r==="object"&&r!==null&&"code"in r&&r.code==="ENOENT")return{kind:n,path:t,status:"not-applicable",issues:[]};return{kind:n,path:t,status:"unknown",issues:[]}}}function va(n){let t=s2();return{directories:[ur("policy",pr(pr(n))),ur("config",pr(n)),...t?[ur("audit",t)]:[{kind:"audit",status:"unknown",issues:[]}]]}}import{spawn as Ns}from"node:child_process";import{existsSync as oa}from"node:fs";import{delimiter as nL,extname as tL,join as rL}from"node:path";import{stripVTControlCharacters as ba}from"node:util";var ya="2.0.5",eL=5000,aL="_CC_SAFETY_NET_TEST_SPAWN_PLATFORM";function j(){return ya}function vr(n,t){let r=n[t];if(r)return r;let e=Object.keys(n).find((a)=>a.toLowerCase()===t.toLowerCase()&&!!n[a]);return e?n[e]:r}function lL(n){return(vr(n,"PATHEXT")||".COM;.EXE;.BAT;.CMD").split(";").filter((t)=>t.length>0)}function dL(n,t){let r=tL(n)?[n]:[...lL(t).map((e)=>`${n}${e}`),n];if(n.includes("/")||n.includes("\\"))return r.find((e)=>oa(e))??n;return(vr(t,"PATH")??"").split(nL).flatMap((e)=>r.map((a)=>rL(e,a))).find((e)=>oa(e))??n}function fa(n){if(!/[\s"&|<>^]/.test(n))return n;return`"${n.replace(/"/g,'""')}"`}function f2(n,t){let[r,...e]=n,a=t[aL]==="win32"?"win32":process.platform;if(!r||a!=="win32")return{cmd:r??"",args:e};let l=dL(r,t);if(!/\.(?:bat|cmd)$/i.test(l))return{cmd:l,args:e};return{cmd:vr(t,"COMSPEC")??"cmd.exe",args:["/d","/c",["call",fa(l),...e.map(fa)].join(" ")]}}var _2=async(n,t=eL)=>{let r=await sL(n,{timeoutMs:t});if(r.code!==0)return null;return ba(r.stdout).trim()||ba(r.stderr).trim()||null};function sL(n,t){let[r,...e]=n;if(!r)return Promise.resolve({code:null,stdout:"",stderr:""});return new Promise((a)=>{try{let l=f2([r,...e],process.env),d=Ns(l.cmd,l.args,{stdio:["ignore","pipe","pipe"]}),s=!1,L="",c="";d.stdout.on("data",(o)=>{L+=o.toString()}),d.stderr.on("data",(o)=>{c+=o.toString()});let i=(o)=>{if(s)return;s=!0,clearTimeout(u),a(o)},u=setTimeout(()=>{d.kill(),i({code:null,stdout:L,stderr:c})},t.timeoutMs);d.on("close",(o)=>{i({code:o,stdout:L,stderr:c})}),d.on("error",()=>{i({code:null,stdout:L,stderr:c})})}catch{a({code:null,stdout:"",stderr:""})}})}function Q(n){if(!n)return null;let t=/Claude Code\s+(\d+\.\d+\.\d+)/i.exec(n);if(t)return t[1]??null;let r=/v?(\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)/i.exec(n);if(r)return r[1]??null;return n.split(`
23
+ `)[0]?.trim()||null}async function xn(n=_2){let[t,r,e,a,l,d,s,L,c,i,u,o,p,f,v,y,x]=await Promise.all([n(["claude","--version"]),n(["agy","--version"]),n(["opencode","--version"]),n(["codex","--version"]),n(["codex","plugin","list"]),n(["gemini","--version"]),n(["copilot","--binary-version"]),n(["hermes","--version"]),n(["kimi","--version"]),n(["openclaw","--version"]),n(["pi","--version"]),n(["cursor","--version"]),n(["amp","--version"]),n(["amp","plugins","list"],30000),n(["node","--version"]),n(["npm","--version"]),n(["bun","--version"])]);return{version:ya,claudeCodeVersion:Q(t),antigravityCliVersion:Q(r),openCodeVersion:Q(e),codexCliVersion:Q(a),codexPluginListOutput:l,geminiCliVersion:Q(d),copilotCliVersion:Q(s),hermesAgentVersion:Q(L),kimiCodeVersion:Q(c),openClawVersion:Q(i),piCliVersion:Q(u),cursorVersion:Q(o),ampVersion:Q(p),ampPluginListOutput:f,nodeVersion:Q(v),npmVersion:Q(y),bunVersion:Q(x),platform:`${process.platform} ${process.arch}`}}function or(n,t){if(t==="dev")return!1;let r=n.split(".").map(Number),e=t.split(".").map(Number),[a=0,l=0,d=0]=r,[s=0,L=0,c=0]=e;if(a!==s)return a>s;if(l!==L)return l>L;return d>c}async function E2(){let n=j(),t=new AbortController,r=setTimeout(()=>t.abort(),3000);try{let e=await fetch("https://registry.npmjs.org/cc-safety-net/latest",{signal:t.signal});if(!e.ok)return{currentVersion:n,latestVersion:null,updateAvailable:!1,error:`npm registry returned ${e.status}`};let a=await e.json(),l=or(a.version,n);return{currentVersion:n,latestVersion:a.version,updateAvailable:l}}catch(e){return{currentVersion:n,latestVersion:null,updateAvailable:!1,error:e instanceof Error?e.message:"Network error"}}finally{clearTimeout(r)}}import*as ka from"node:readline";var $a=(n)=>`\x1B[${n}B`,LL=(n)=>`\x1B[${n}A`;var ha=["░","▒","▓","╱","╲","┃","━","┏","┓","┗","┛","╋"];function cL(n){return new Promise((t)=>setTimeout(t,n))}function iL(n,t,r){if(!r)return t(n);if(r.aborted)return Promise.resolve();return new Promise((e,a)=>{let l=()=>r.removeEventListener("abort",d),d=()=>{l(),e()};r.addEventListener("abort",d,{once:!0}),t(n).then(()=>{l(),e()},(s)=>{l(),a(s)})})}function $n(n,t){return n&&n>0?n:t}function On(n){return Math.max(0,Math.min(1,n))}function P2(n){return Math.max(0,Math.min(255,Math.round(n)))}function br(n){return n<=0.0031308?12.92*n:1.055*n**0.4166666666666667-0.055}function pL(n,t,r){let e=r*Math.PI/180,a=t*Math.cos(e),l=t*Math.sin(e),d=(n+0.3963377774*a+0.2158037573*l)**3,s=(n-0.1055613458*a-0.0638541728*l)**3,L=(n-0.0894841775*a-1.291485548*l)**3;return{blue:P2(br(On(-0.0041960863*d-0.7034186147*s+1.707614701*L))*255),green:P2(br(On(-1.2684380046*d+2.6097574011*s-0.3413193965*L))*255),red:P2(br(On(4.0767416621*d-3.3077115913*s+0.2309699292*L))*255)}}function fr(n,t){let r=(t*n*180/Math.PI%360+360)%360;return pL(0.72,0.15,r)}function ga(n,t=0.1){let r=fr(t,n);return`\x1B[38;2;${r.red};${r.green};${r.blue}m`}function uL(n,t){return{blue:P2(n.blue+(255-n.blue)*t),green:P2(n.green+(255-n.green)*t),red:P2(n.red+(255-n.red)*t)}}function Da(n,t,r){let e=Math.imul(n+2654435769,2246822507)^Math.imul(t+3266489909,668265263)^Math.imul(r+374761393,2654435761),a=e^e>>>15,l=Math.imul(a,739982445),d=l^l>>>12,s=Math.imul(d,695872825);return((s^s>>>15)>>>0)/4294967296}function vL(n,t,r){let e=Math.floor(Da(n,t,r)*ha.length);return ha[e]??"░"}function wa(n){let t=On(n);return t*t*t*(t*(t*6-15)+10)}function oL(n){if(n.length===0)return"";let t=[],r=!1,e="";for(let a of n){let l=`${a.red};${a.green};${a.blue}`;if(a.bold!==r)t.push(a.bold?"\x1B[1m":"\x1B[22m"),r=a.bold;if(l!==e)t.push(`\x1B[38;2;${l}m`),e=l;t.push(a.character)}return`${t.join("")}\x1B[22m\x1B[39m`}function bL(n,t,r,e,a){return n.map((l,d)=>({...fr(r,e+t+d/a),bold:!1,character:l}))}function fL(n,t,r,e,a,l,d,s){let L=Math.max(1,e*0.75),c=Math.min(1,r/L),i=a*wa(c),u=Math.max(0,(r-L)/Math.max(1,e-L)),o=(1-wa(r/e))*s*2,p=0.35*Math.max(0,1-u*2),f=c>=1,v=Math.min(n.length,Math.ceil(i+2+1));return n.slice(0,v).map((y,x)=>{let w=fr(l,d+t+x/s+o),h=x+Da(t,x,7919)*2-1;if(h>i+2)return{...w,bold:!1,character:" "};let J=i-h,Z2=0.8*Math.exp(-(J*J)/12.5),ln=Math.min(0.9,Z2+p),jt=!f&&h>i-4;return{...uL(w,ln),bold:ln>0.3,character:jt?vL(t,x,r):y}})}function xa(n){return`\x1B[?2026h${n.map((t,r)=>`\x1B8${r>0?$a(r):""}${oL(t)}`).join("")}\x1B[?2026l`}async function yr(n,t={}){if(!n)return;let r=t.output??process.stdout,e=t.sleep??cL,a=$n(t.frequency,0.1),l=t.seed??0,d=$n(t.speed,40),s=$n(t.spread,3),L=$n(t.frameRate,60),c=Math.max(1,Math.floor($n(t.duration,12))),i=n.split(`
24
+ `).map((v)=>Array.from(v)),u=Math.max(...i.map((v)=>v.length)),o=1000*c*i.filter((v)=>v.length>0).length/d,p=u>0?Math.max(1,Math.ceil(o/(1000/L))):0,f=p>0?o/p:0;r.write(`\x1B[?25l${i.length>1?`${`
25
+ `.repeat(i.length-1)}${LL(i.length-1)}`:""}\x1B7`);try{for(let v=1;v<=p;v+=1){if(t.signal?.aborted)break;r.write(xa(i.map((y,x)=>fL(y,x,v,p,u,a,l,s)))),await iL(f,e,t.signal)}}finally{if(r.write(xa(i.map((v,y)=>bL(v,y,a,l,s)))),r.write("\x1B8"),i.length>1)r.write($a(i.length-1));r.write(`
26
26
  \x1B[0m\x1B[?25h`)}}var ma=["┏━┛┏━┛ ┏━┛┏━┃┏━┛┏━┛━┏┛┃ ┃ ┏━ ┏━┛━┏┛","┃ ┃ ━━┃┏━┃┏━┛┏━┛ ┃ ━┏┛ ┃ ┃┏━┛ ┃ ","━━┛━━┛ ━━┛┛ ┛┛ ━━┛ ┛ ┛ ┛ ┛━━┛ ┛ "].join(`
27
- `);function fc(n){return Boolean(n.isTTY)}async function Un(n={}){let t=n.output??process.stdout;if(!fc(t))return;let r=n.input??process.stdin,e={duration:n.duration,frequency:n.frequency,output:t,seed:n.seed??Math.random()*8192,sleep:n.sleep,speed:n.speed,spread:n.spread};if(!r.isTTY||typeof r.setRawMode!=="function"){await or(ma,e);return}let a=new AbortController,l=r.readableFlowing===!0,d=r.isRaw===!0,s=!1,c=(L,i)=>{if(i.ctrl&&i.name==="c")s=!0;if(s||i.name==="return"||i.name==="enter")a.abort()};ka.emitKeypressEvents(r),r.on("keypress",c),r.setRawMode(!0),r.resume();try{await or(ma,{...e,signal:a.signal})}finally{if(r.off("keypress",c),r.setRawMode(d),!l)r.pause()}if(!s)return;if(n.onInterrupt){n.onInterrupt();return}process.kill(process.pid,"SIGINT")}var qa="\r\x1B[2K",yc="\x1B[?25l",hc="\x1B[39m",wc="\x1B[?25h",xc=100,$c=0.55,gc=80,ja=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function Dc(n){return new Promise((t)=>setTimeout(t,n))}async function vr(n,t={}){let r=t.output??process.stdout;if(!r.isTTY)return n;let e=t.sleep??Dc,a=!1,l=n.then((s)=>{return a=!0,s},(s)=>{throw a=!0,s});if(await Promise.race([l.then(()=>!0),e(xc).then(()=>!1)]))return l;r.write(yc);try{for(let s=0;!a;s+=1)r.write(`${qa}${ga(s*$c)}${ja[s%ja.length]}${hc} ${t.loadingMessage??"Loading…"}`),await Promise.race([l,e(gc)]);return await l}finally{r.write(`${qa}${wc}`)}}async function On(n,t,r,e={}){let a=t();if(n)await r();if(n&&a.ready)await vr(a.ready,e);return a.finish()}import{homedir as XL}from"node:os";import{stripVTControlCharacters as mc}from"node:util";var Tn="amp plugins list",kc=/^\s*[✓✗]\s+cc-safety-net(?:\.ts)?\s+\(User Plugins\)\s+(\S+)\s*$/;function Fa(n){if(!n.ampPluginListOutput)return{platform:"amp",status:"n/a"};let t=mc(n.ampPluginListOutput).split(`
28
- `).map((r)=>kc.exec(r)?.[1]).find((r)=>r!==void 0);if(!t)return{platform:"amp",status:"n/a"};if(t!=="active")return{platform:"amp",status:"disabled",method:Tn,configPath:Tn,errors:[`Amp personal plugin cc-safety-net is ${t}; run "plugins: reload" in Amp or reinstall with install --amp`]};return{platform:"amp",status:"configured",method:Tn,configPath:Tn}}import{existsSync as jc,readFileSync as Fc}from"node:fs";import{join as qc}from"node:path";function gn(n){return qc(n,".gemini","config","hooks.json")}var zc=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*(?:--agy-cli|-ac)(\s|["']|$)/;function Bc(n){if(!n||typeof n!=="object"||Array.isArray(n))return[];return Object.values(n).flatMap((t)=>{if(!t||typeof t!=="object"||Array.isArray(t))return[];let r=t,e=r.PreToolUse;if(!Array.isArray(e))return[];return e.flatMap((a)=>{if(!a||typeof a!=="object"||Array.isArray(a))return[];let l=a.hooks;if(!Array.isArray(l))return[];return l.flatMap((d)=>{if(!d||typeof d!=="object"||Array.isArray(d))return[];let s=d.command;if(typeof s!=="string"||!zc.test(s))return[];return[{command:s,enabled:r.enabled!==!1}]})})})}function za(n){let t=gn(n.homeDir);if(!jc(t))return{platform:"antigravity-cli",status:"n/a",configPath:t};let r;try{r=Bc(JSON.parse(Fc(t,"utf-8")))}catch(e){return{platform:"antigravity-cli",status:"n/a",configPath:t,errors:[`Failed to parse Antigravity hooks config ${t}: ${e instanceof Error?e.message:String(e)}`]}}if(r.some((e)=>e.enabled))return{platform:"antigravity-cli",status:"configured",method:"hook config",configPath:t};if(r.length>0)return{platform:"antigravity-cli",status:"disabled",method:"hook config",configPath:t};return{platform:"antigravity-cli",status:"n/a",configPath:t}}import{join as Ba}from"node:path";import{existsSync as Jc,lstatSync as Zc,readFileSync as Qc}from"node:fs";function n2(n,t=(r)=>r){if(!Jc(n))return{kind:"missing"};try{return{kind:"ok",value:JSON.parse(t(Qc(n,"utf-8")))}}catch{return{kind:"unreadable"}}}function S(n){try{return Zc(n)}catch{return}}function En(n,t){let r=S(t);if(!r)return{platform:n,status:"n/a",configPath:t};if(!r.isSymbolicLink()&&r.isDirectory())return;return{platform:n,status:"n/a",configPath:t,errors:[`${t} is a symlink or not a directory; move or remove it before installing`]}}function $(n,t){return typeof n==="object"&&n!==null?n[t]:void 0}var br="cc-safety-net@cc-marketplace";function Ja(n){return Ba(n,".claude","plugins","installed_plugins.json")}function Za(n,t){let r=$($(n,"plugins"),t);return Array.isArray(r)&&r.length>0}function _n(n,t){let r=n2(Ja(n));return r.kind==="ok"&&Za(r.value,t)}function fr(n){let t=Ja(n),r=n2(t);if(r.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(r.kind==="missing")return{platform:"claude-code",status:"n/a"};if(!Za(r.value,br))return{platform:"claude-code",status:"n/a"};let e=Ba(n,".claude","settings.json"),a=n2(e);if(a.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(!(a.kind==="ok"&&$($(a.value,"enabledPlugins"),br)===!0))return{platform:"claude-code",status:"disabled",method:"plugin config",configPath:e,errors:[`${br} is installed but not enabled in Claude Code`]};return{platform:"claude-code",status:"configured",method:"plugin config",configPath:t}}function Qa(n){return fr(n.homeDir)}function Xa(n){if(!n.codexPluginListOutput)return{platform:"codex",status:"n/a"};let t=n.codexPluginListOutput.split(`
29
- `).find((r)=>r.includes("https://github.com/kenryu42/cc-safety-net.git"));if(!t)return{platform:"codex",status:"n/a"};if(!t.includes("installed, enabled"))return{platform:"codex",status:"disabled",method:"codex plugin list",configPath:"codex plugin list",errors:["Codex plugin line for https://github.com/kenryu42/cc-safety-net.git must contain installed, enabled."]};return{platform:"codex",status:"configured",method:"codex plugin list",configPath:"codex plugin list"}}import{existsSync as In,readdirSync as Xc,readFileSync as Yc}from"node:fs";import{join as V}from"node:path";var t2="cc-safety-net@cc-marketplace",Pn=["cc-marketplace","cc-safety-net"],Ya=["_direct","copilot-safety-net"],Sa=["cc-marketplace","safety-net"],Ha="safety-net@cc-marketplace";function Nn(n,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(^|[^a-z0-9-])${r}([^a-z0-9-]|$)`,"m").test(n??"")}function Aa(n){return Nn(n,"cc-safety-net@cc-marketplace")}function Wa(n){return Nn(n,"cc-marketplace")}function Ra(n){return Nn(n,"copilot-safety-net")}function Va(n){return Nn(n,"safety-net@cc-marketplace")}function R(n){let t="",r=0,e=!1,a=!1,l=-1;while(r<n.length){let d=n[r],s=n[r+1];if(a){t+=d,a=!1,r++;continue}if(d==='"'&&!e){e=!0,l=-1,t+=d,r++;continue}if(d==='"'&&e){e=!1,t+=d,r++;continue}if(d==="\\"&&e){a=!0,t+=d,r++;continue}if(e){t+=d,r++;continue}if(d==="/"&&s==="/"){while(r<n.length&&n[r]!==`
30
- `)r++;continue}if(d==="/"&&s==="*"){r+=2;while(r<n.length-1){if(n[r]==="*"&&n[r+1]==="/"){r+=2;break}r++}continue}if(d===","){l=t.length,t+=d,r++;continue}if(d==="}"||d==="]"){if(l!==-1){let c=t.slice(l+1);if(/^\s*$/.test(c))t=t.slice(0,l)+c}l=-1,t+=d,r++;continue}if(!/\s/.test(d))l=-1;t+=d,r++}return t}function yr(n){if(!n?.includes("cc-safety-net"))return!1;return/(^|\s)hook\s+(?:[^\s]+\s+)*(--copilot-cli|-cp)(\s|$)/.test(n)}function Ma(n,t){if(!n)return null;let r=n.match(/(\d+)\.(\d+)\.(\d+)/);if(!r)return null;let e=[Number(r[1]),Number(r[2]),Number(r[3])];for(let a=0;a<t.length;a++){let l=e[a]??0,d=t[a]??0;if(l!==d)return l>d}return!0}function Sc(n){return Ma(n,[0,0,422])}function Hc(n){return Ma(n,[1,0,8])}function Dn(n){return process.env.COPILOT_HOME||V(n,".copilot")}function wr(n){return(n.hooks?.preToolUse??[]).some((r)=>{if(r.type!=="command")return!1;return yr(r.command)||yr(r.bash)||yr(r.powershell)})}function xr(n,t){try{return JSON.parse(R(Yc(n,"utf-8")))}catch(r){t?.push(`Failed to parse ${n}: ${r instanceof Error?r.message:String(r)}`);return}}function Ga(n,t){try{return Xc(n).filter((r)=>r.endsWith(".json")).sort((r,e)=>r.localeCompare(e))}catch(r){return t?.push(`Failed to read ${n}: ${r instanceof Error?r.message:String(r)}`),[]}}function Ac(n,t){if(!In(n))return[];let r=[];for(let e of Ga(n,t)){let a=V(n,e),l=xr(a,t);if(l&&wr(l))r.push(a)}return r}function hr(n,t){if(!In(n))return;let r=xr(n,t);if(!r)return;return{path:n,config:r}}function Ka(n,t,r,e){if(t){n.push(`GitHub Copilot CLI ${t} does not support ${r}; requires ${e}+`);return}n.push(`GitHub Copilot CLI version unavailable; skipping ${r} because it requires ${e}+`)}function Wc(n){let t=[n.localSettings,n.repoSettings,n.userConfig];for(let r of t){if(r?.config.disableAllHooks===!0)return r.path;if(r?.config.disableAllHooks===!1)return}return}function Rc(n,t,r,e){let a=Dn(n),l=V(t,".github","hooks"),d=V(a,"hooks"),s=V(t,".github","copilot"),c=Hc(r),L=c===!0?e:void 0,i={userConfig:hr(V(a,"config.json"),L),repoSettings:hr(V(s,"settings.json"),L),localSettings:hr(V(s,"settings.local.json"),L)};if(c!==!1){let w=Wc(i);if(w){if(c===null)e.push(`GitHub Copilot CLI version unavailable; treating disableAllHooks in ${w} as active`);return{activeConfigPaths:[],disabledBy:w}}}let u=Ac(l,e),v=Sc(r),p=v===!0?e:void 0,f=In(d)?Ga(d,p):[],o=[];for(let w of f){let h=V(d,w),J=xr(h,p);if(J&&wr(J))o.push(h)}if(v!==!0&&o.length>0)Ka(e,r,`user hook files in ${d}`,"0.0.422"),o.length=0;let y=[],x=[i.localSettings,i.repoSettings,i.userConfig];for(let w of x){if(!w)continue;if(!wr(w.config))continue;if(c===!0){y.push(w.path);continue}Ka(e,r,"inline hook definitions in Copilot config files","1.0.8");break}return{activeConfigPaths:[...y.filter((w)=>w.endsWith("settings.local.json")),...y.filter((w)=>w.endsWith("settings.json")),...u,...y.filter((w)=>w.endsWith("config.json")),...o]}}function Ca(n){let t=[],r=Rc(n.homeDir,n.cwd,n.copilotCliVersion,t);if(r.disabledBy)return{platform:"copilot-cli",status:"disabled",method:"hook config",configPath:r.disabledBy,configPaths:[r.disabledBy],errors:t.length>0?t:void 0};let e=Dn(n.homeDir),a=V(e,"installed-plugins",...Pn),l=In(a),d=V(e,"settings.json"),s=n2(d,R);if(l&&s.kind==="unreadable")return{platform:"copilot-cli",status:"not-inspected"};if(l&&s.kind==="ok"&&$($(s.value,"enabledPlugins"),t2)===!1)return{platform:"copilot-cli",status:"disabled",method:"plugin config",configPath:d,errors:[`${t2} is installed but not enabled in Copilot CLI`]};if(l||r.activeConfigPaths.length>0){let c=l,L=r.activeConfigPaths[0];return{platform:"copilot-cli",status:"configured",method:c?"plugin config":"hook config",configPath:L??(c?a:void 0),configPaths:r.activeConfigPaths.length>0?r.activeConfigPaths:void 0,errors:t.length>0?t:void 0}}return{platform:"copilot-cli",status:"n/a",errors:t.length>0?t:void 0}}import{existsSync as _c,readFileSync as Pc}from"node:fs";import{existsSync as Ua,mkdirSync as Mc,readFileSync as Gc}from"node:fs";import{dirname as Cc,join as Uc}from"node:path";import{renameSync as Vc,writeFileSync as Kc}from"node:fs";function B(n,t){let r=`${n}.${process.pid}.tmp`;Kc(r,t),Vc(r,n)}var mn="npx -y cc-safety-net hook --cursor",Oa=30;function tt(n){return Uc(n,".cursor","hooks.json")}function k2(n){return typeof n==="object"&&n!==null&&!Array.isArray(n)}function $r(){return{command:mn,timeout:Oa,failClosed:!0}}function nt(n){return k2(n)&&n.command===mn}function Oc(n){return Object.keys(n).length===3&&n.command===mn&&n.timeout===Oa&&n.failClosed===!0}function Tc(n){try{return JSON.parse(Gc(n,"utf-8"))}catch(t){if(t instanceof SyntaxError)throw Error(`Failed to parse Cursor hooks config ${n}: ${t.message}`);throw t}}function Ta(n){let t=Tc(n);if(!k2(t))throw Error(`Cursor hooks config ${n} must be a JSON object`);if(t.version!==1)throw Error(`Cursor hooks config ${n} must set "version": 1`);if(t.hooks!==void 0&&!k2(t.hooks))throw Error(`Cursor hooks config ${n} "hooks" must be an object`);let r=k2(t.hooks)?t.hooks.preToolUse:void 0;if(r!==void 0&&!Array.isArray(r))throw Error(`Cursor hooks config ${n} "hooks.preToolUse" must be an array`);return t}function Ea(n){let t=k2(n.hooks)?n.hooks.preToolUse:void 0;return Array.isArray(t)?t:[]}function Ec(n){if(!n.some(nt))return[...n,$r()];return n.reduce((t,r)=>{if(!nt(r))return t.result.push(r),t;if(!t.inserted)t.result.push($r()),t.inserted=!0;return t},{result:[],inserted:!1}).result}function _a(n,t,r){let e=k2(t.hooks)?t.hooks:{},a={...t,hooks:{...e,preToolUse:r}};B(n,`${JSON.stringify(a,null,2)}
31
- `)}function Pa(n){let t=tt(n);if(!Ua(t))return Mc(Cc(t),{recursive:!0}),B(t,`${JSON.stringify({version:1,hooks:{preToolUse:[$r()]}},null,2)}
32
- `),{path:t,alreadyInstalled:!1};let r=Ta(t),e=Ea(r),a=e.filter(nt);if(k2(r.hooks)&&Array.isArray(r.hooks.preToolUse)&&a.length===1&&a[0]!==void 0&&Oc(a[0]))return{path:t,alreadyInstalled:!0};return _a(t,r,Ec(e)),{path:t,alreadyInstalled:!1}}function Na(n){let t=tt(n);if(!Ua(t))return{path:t,alreadyInstalled:!1};let r=Ta(t),e=Ea(r),a=e.filter((l)=>!nt(l));if(a.length===e.length)return{path:t,alreadyInstalled:!1};return _a(t,r,a),{path:t,alreadyInstalled:!0}}function Nc(n){if(!n||typeof n!=="object"||Array.isArray(n))return[];let t=n.hooks;if(!t||typeof t!=="object"||Array.isArray(t))return[];let r=t.preToolUse;if(!Array.isArray(r))return[];return r.filter((e)=>!!e&&typeof e==="object"&&!Array.isArray(e)&&e.command===mn)}function Ic(n){let t=[];if(n.length>1)t.push("Multiple managed cc-safety-net hooks found; reinstall to collapse duplicates");let r=n[0];if(r&&r.failClosed!==!0)t.push('Managed hook is missing "failClosed": true; reinstall to repair');if(r&&r.timeout!==30)t.push('Managed hook "timeout" is not 30; reinstall to repair');return t}function Ia(n){let t=tt(n.homeDir);if(!_c(t))return{platform:"cursor",status:"n/a",configPath:t};let r;try{r=JSON.parse(Pc(t,"utf-8"))}catch(l){return{platform:"cursor",status:"n/a",configPath:t,errors:[`Failed to parse Cursor hooks config ${t}: ${l instanceof Error?l.message:String(l)}`]}}let e=Nc(r);if(e.length===0)return{platform:"cursor",status:"n/a",configPath:t};let a=Ic(e);return{platform:"cursor",status:"configured",method:"hook config",configPath:t,errors:a.length>0?a:void 0}}import{existsSync as nL}from"node:fs";import{join as gr}from"node:path";var Dr="gemini-safety-net";function mr(n){let t=gr(n,".gemini","extensions"),r=gr(t,Dr);if(!nL(r))return{platform:"gemini-cli",status:"n/a"};let e=gr(t,"extension-enablement.json"),a=n2(e);if(a.kind==="unreadable")return{platform:"gemini-cli",status:"not-inspected"};let l=a.kind==="ok"?$($(a.value,Dr),"overrides"):void 0;if(Array.isArray(l)&&l.some((s)=>typeof s==="string"&&s.startsWith("!")))return{platform:"gemini-cli",status:"disabled",method:"extension config",configPath:e,errors:[`${Dr} is disabled in Gemini CLI`]};return{platform:"gemini-cli",status:"configured",method:"extension config",configPath:r}}function n0(n){return mr(n.homeDir)}import{readFileSync as L0}from"node:fs";import{join as i0}from"node:path";var K="cc-safety-net",t0="# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent";function r0(n){return`# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent
27
+ `);function yL(n){return Boolean(n.isTTY)}async function gn(n={}){let t=n.output??process.stdout;if(!yL(t))return;let r=n.input??process.stdin,e={duration:n.duration,frequency:n.frequency,output:t,seed:n.seed??Math.random()*8192,sleep:n.sleep,speed:n.speed,spread:n.spread};if(!r.isTTY||typeof r.setRawMode!=="function"){await yr(ma,e);return}let a=new AbortController,l=r.readableFlowing===!0,d=r.isRaw===!0,s=!1,L=(c,i)=>{if(i.ctrl&&i.name==="c")s=!0;if(s||i.name==="return"||i.name==="enter")a.abort()};ka.emitKeypressEvents(r),r.on("keypress",L),r.setRawMode(!0),r.resume();try{await yr(ma,{...e,signal:a.signal})}finally{if(r.off("keypress",L),r.setRawMode(d),!l)r.pause()}if(!s)return;if(n.onInterrupt){n.onInterrupt();return}process.kill(process.pid,"SIGINT")}var qa="\r\x1B[2K",hL="\x1B[?25l",wL="\x1B[39m",xL="\x1B[?25h",$L=100,gL=0.55,DL=80,ja=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function mL(n){return new Promise((t)=>setTimeout(t,n))}async function Tn(n,t={}){let r=t.output??process.stdout;if(!r.isTTY)return n;let e=t.sleep??mL,a=!1,l=n.then((s)=>{return a=!0,s},(s)=>{throw a=!0,s});if(await Promise.race([l.then(()=>!0),e($L).then(()=>!1)]))return l;r.write(hL);try{for(let s=0;!a;s+=1)r.write(`${qa}${ga(s*gL)}${ja[s%ja.length]}${wL} ${t.loadingMessage??"Loading…"}`),await Promise.race([l,e(DL)]);return await l}finally{r.write(`${qa}${xL}`)}}async function Dn(n,t,r,e={}){let a=t();if(n)await r();if(n&&a.ready)await Tn(a.ready,e);return a.finish()}import{homedir as Yc}from"node:os";import{stripVTControlCharacters as kL}from"node:util";var _n="amp plugins list",qL=/^\s*[✓✗]\s+cc-safety-net(?:\.ts)?\s+\(User Plugins\)\s+(\S+)\s*$/;function Fa(n){if(!n.ampPluginListOutput)return{platform:"amp",status:"n/a"};let t=kL(n.ampPluginListOutput).split(`
28
+ `).map((r)=>qL.exec(r)?.[1]).find((r)=>r!==void 0);if(!t)return{platform:"amp",status:"n/a"};if(t!=="active")return{platform:"amp",status:"disabled",method:_n,configPath:_n,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:_n,configPath:_n}}import{existsSync as FL,readFileSync as zL}from"node:fs";import{join as jL}from"node:path";function mn(n){return jL(n,".gemini","config","hooks.json")}var BL=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*(?:--agy-cli|-ac)(\s|["']|$)/;function JL(n){if(!n||typeof n!=="object"||Array.isArray(n))return[];return Object.values(n).flatMap((t)=>{if(!t||typeof t!=="object"||Array.isArray(t))return[];let r=t,e=r.PreToolUse;if(!Array.isArray(e))return[];return e.flatMap((a)=>{if(!a||typeof a!=="object"||Array.isArray(a))return[];let l=a.hooks;if(!Array.isArray(l))return[];return l.flatMap((d)=>{if(!d||typeof d!=="object"||Array.isArray(d))return[];let s=d.command;if(typeof s!=="string"||!BL.test(s))return[];return[{command:s,enabled:r.enabled!==!1}]})})})}function za(n){let t=mn(n.homeDir);if(!FL(t))return{platform:"antigravity-cli",status:"n/a",configPath:t};let r;try{r=JL(JSON.parse(zL(t,"utf-8")))}catch(e){return{platform:"antigravity-cli",status:"n/a",configPath:t,errors:[`Failed to parse Antigravity hooks config ${t}: ${e instanceof Error?e.message:String(e)}`]}}if(r.some((e)=>e.enabled))return{platform:"antigravity-cli",status:"configured",method:"hook config",configPath:t};if(r.length>0)return{platform:"antigravity-cli",status:"disabled",method:"hook config",configPath:t};return{platform:"antigravity-cli",status:"n/a",configPath:t}}import{join as Ba}from"node:path";import{existsSync as ZL,lstatSync as QL,readFileSync as XL}from"node:fs";function n2(n,t=(r)=>r){if(!ZL(n))return{kind:"missing"};try{return{kind:"ok",value:JSON.parse(t(XL(n,"utf-8")))}}catch{return{kind:"unreadable"}}}function S(n){try{return QL(n)}catch{return}}function En(n,t){let r=S(t);if(!r)return{platform:n,status:"n/a",configPath:t};if(!r.isSymbolicLink()&&r.isDirectory())return;return{platform:n,status:"n/a",configPath:t,errors:[`${t} is a symlink or not a directory; move or remove it before installing`]}}function $(n,t){return typeof n==="object"&&n!==null?n[t]:void 0}var hr="cc-safety-net@cc-marketplace";function Ja(n){return Ba(n,".claude","plugins","installed_plugins.json")}function Za(n,t){let r=$($(n,"plugins"),t);return Array.isArray(r)&&r.length>0}function Pn(n,t){let r=n2(Ja(n));return r.kind==="ok"&&Za(r.value,t)}function wr(n){let t=Ja(n),r=n2(t);if(r.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(r.kind==="missing")return{platform:"claude-code",status:"n/a"};if(!Za(r.value,hr))return{platform:"claude-code",status:"n/a"};let e=Ba(n,".claude","settings.json"),a=n2(e);if(a.kind==="unreadable")return{platform:"claude-code",status:"not-inspected"};if(!(a.kind==="ok"&&$($(a.value,"enabledPlugins"),hr)===!0))return{platform:"claude-code",status:"disabled",method:"plugin config",configPath:e,errors:[`${hr} is installed but not enabled in Claude Code`]};return{platform:"claude-code",status:"configured",method:"plugin config",configPath:t}}function Qa(n){return wr(n.homeDir)}function Xa(n){if(!n.codexPluginListOutput)return{platform:"codex",status:"n/a"};let t=n.codexPluginListOutput.split(`
29
+ `).find((r)=>r.includes("https://github.com/kenryu42/cc-safety-net.git"));if(!t)return{platform:"codex",status:"n/a"};if(!t.includes("installed, enabled"))return{platform:"codex",status:"disabled",method:"codex plugin list",configPath:"codex plugin list",errors:["Codex plugin line for https://github.com/kenryu42/cc-safety-net.git must contain installed, enabled."]};return{platform:"codex",status:"configured",method:"codex plugin list",configPath:"codex plugin list"}}import{existsSync as nt,readdirSync as YL,readFileSync as SL}from"node:fs";import{join as K}from"node:path";var t2="cc-safety-net@cc-marketplace",In=["cc-marketplace","cc-safety-net"],Ya=["_direct","copilot-safety-net"],Sa=["cc-marketplace","safety-net"],Ha="safety-net@cc-marketplace";function Nn(n,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(^|[^a-z0-9-])${r}([^a-z0-9-]|$)`,"m").test(n??"")}function Aa(n){return Nn(n,"cc-safety-net@cc-marketplace")}function Wa(n){return Nn(n,"cc-marketplace")}function Ra(n){return Nn(n,"copilot-safety-net")}function Ka(n){return Nn(n,"safety-net@cc-marketplace")}function R(n){let t="",r=0,e=!1,a=!1,l=-1;while(r<n.length){let d=n[r],s=n[r+1];if(a){t+=d,a=!1,r++;continue}if(d==='"'&&!e){e=!0,l=-1,t+=d,r++;continue}if(d==='"'&&e){e=!1,t+=d,r++;continue}if(d==="\\"&&e){a=!0,t+=d,r++;continue}if(e){t+=d,r++;continue}if(d==="/"&&s==="/"){while(r<n.length&&n[r]!==`
30
+ `)r++;continue}if(d==="/"&&s==="*"){r+=2;while(r<n.length-1){if(n[r]==="*"&&n[r+1]==="/"){r+=2;break}r++}continue}if(d===","){l=t.length,t+=d,r++;continue}if(d==="}"||d==="]"){if(l!==-1){let L=t.slice(l+1);if(/^\s*$/.test(L))t=t.slice(0,l)+L}l=-1,t+=d,r++;continue}if(!/\s/.test(d))l=-1;t+=d,r++}return t}function xr(n){if(!n?.includes("cc-safety-net"))return!1;return/(^|\s)hook\s+(?:[^\s]+\s+)*(--copilot-cli|-cp)(\s|$)/.test(n)}function Va(n,t){if(!n)return null;let r=n.match(/(\d+)\.(\d+)\.(\d+)/);if(!r)return null;let e=[Number(r[1]),Number(r[2]),Number(r[3])];for(let a=0;a<t.length;a++){let l=e[a]??0,d=t[a]??0;if(l!==d)return l>d}return!0}function HL(n){return Va(n,[0,0,422])}function AL(n){return Va(n,[1,0,8])}function kn(n){return process.env.COPILOT_HOME||K(n,".copilot")}function gr(n){return(n.hooks?.preToolUse??[]).some((r)=>{if(r.type!=="command")return!1;return xr(r.command)||xr(r.bash)||xr(r.powershell)})}function Dr(n,t){try{return JSON.parse(R(SL(n,"utf-8")))}catch(r){t?.push(`Failed to parse ${n}: ${r instanceof Error?r.message:String(r)}`);return}}function Ga(n,t){try{return YL(n).filter((r)=>r.endsWith(".json")).sort((r,e)=>r.localeCompare(e))}catch(r){return t?.push(`Failed to read ${n}: ${r instanceof Error?r.message:String(r)}`),[]}}function WL(n,t){if(!nt(n))return[];let r=[];for(let e of Ga(n,t)){let a=K(n,e),l=Dr(a,t);if(l&&gr(l))r.push(a)}return r}function $r(n,t){if(!nt(n))return;let r=Dr(n,t);if(!r)return;return{path:n,config:r}}function Ma(n,t,r,e){if(t){n.push(`GitHub Copilot CLI ${t} does not support ${r}; requires ${e}+`);return}n.push(`GitHub Copilot CLI version unavailable; skipping ${r} because it requires ${e}+`)}function RL(n){let t=[n.localSettings,n.repoSettings,n.userConfig];for(let r of t){if(r?.config.disableAllHooks===!0)return r.path;if(r?.config.disableAllHooks===!1)return}return}function KL(n,t,r,e){let a=kn(n),l=K(t,".github","hooks"),d=K(a,"hooks"),s=K(t,".github","copilot"),L=AL(r),c=L===!0?e:void 0,i={userConfig:$r(K(a,"config.json"),c),repoSettings:$r(K(s,"settings.json"),c),localSettings:$r(K(s,"settings.local.json"),c)};if(L!==!1){let w=RL(i);if(w){if(L===null)e.push(`GitHub Copilot CLI version unavailable; treating disableAllHooks in ${w} as active`);return{activeConfigPaths:[],disabledBy:w}}}let u=WL(l,e),o=HL(r),p=o===!0?e:void 0,f=nt(d)?Ga(d,p):[],v=[];for(let w of f){let h=K(d,w),J=Dr(h,p);if(J&&gr(J))v.push(h)}if(o!==!0&&v.length>0)Ma(e,r,`user hook files in ${d}`,"0.0.422"),v.length=0;let y=[],x=[i.localSettings,i.repoSettings,i.userConfig];for(let w of x){if(!w)continue;if(!gr(w.config))continue;if(L===!0){y.push(w.path);continue}Ma(e,r,"inline hook definitions in Copilot config files","1.0.8");break}return{activeConfigPaths:[...y.filter((w)=>w.endsWith("settings.local.json")),...y.filter((w)=>w.endsWith("settings.json")),...u,...y.filter((w)=>w.endsWith("config.json")),...v]}}function Ca(n){let t=[],r=KL(n.homeDir,n.cwd,n.copilotCliVersion,t);if(r.disabledBy)return{platform:"copilot-cli",status:"disabled",method:"hook config",configPath:r.disabledBy,configPaths:[r.disabledBy],errors:t.length>0?t:void 0};let e=kn(n.homeDir),a=K(e,"installed-plugins",...In),l=nt(a),d=K(e,"settings.json"),s=n2(d,R);if(l&&s.kind==="unreadable")return{platform:"copilot-cli",status:"not-inspected"};if(l&&s.kind==="ok"&&$($(s.value,"enabledPlugins"),t2)===!1)return{platform:"copilot-cli",status:"disabled",method:"plugin config",configPath:d,errors:[`${t2} is installed but not enabled in Copilot CLI`]};if(l||r.activeConfigPaths.length>0){let L=l,c=r.activeConfigPaths[0];return{platform:"copilot-cli",status:"configured",method:L?"plugin config":"hook config",configPath:c??(L?a:void 0),configPaths:r.activeConfigPaths.length>0?r.activeConfigPaths:void 0,errors:t.length>0?t:void 0}}return{platform:"copilot-cli",status:"n/a",errors:t.length>0?t:void 0}}import{existsSync as PL,readFileSync as IL}from"node:fs";import{existsSync as Ua,mkdirSync as GL,readFileSync as CL}from"node:fs";import{dirname as UL,join as OL}from"node:path";import{renameSync as ML,writeFileSync as VL}from"node:fs";function B(n,t){let r=`${n}.${process.pid}.tmp`;VL(r,t),ML(r,n)}var qn="npx -y cc-safety-net hook --cursor",Oa=30;function rt(n){return OL(n,".cursor","hooks.json")}function k2(n){return typeof n==="object"&&n!==null&&!Array.isArray(n)}function mr(){return{command:qn,timeout:Oa,failClosed:!0}}function tt(n){return k2(n)&&n.command===qn}function TL(n){return Object.keys(n).length===3&&n.command===qn&&n.timeout===Oa&&n.failClosed===!0}function _L(n){try{return JSON.parse(CL(n,"utf-8"))}catch(t){if(t instanceof SyntaxError)throw Error(`Failed to parse Cursor hooks config ${n}: ${t.message}`);throw t}}function Ta(n){let t=_L(n);if(!k2(t))throw Error(`Cursor hooks config ${n} must be a JSON object`);if(t.version!==1)throw Error(`Cursor hooks config ${n} must set "version": 1`);if(t.hooks!==void 0&&!k2(t.hooks))throw Error(`Cursor hooks config ${n} "hooks" must be an object`);let r=k2(t.hooks)?t.hooks.preToolUse:void 0;if(r!==void 0&&!Array.isArray(r))throw Error(`Cursor hooks config ${n} "hooks.preToolUse" must be an array`);return t}function _a(n){let t=k2(n.hooks)?n.hooks.preToolUse:void 0;return Array.isArray(t)?t:[]}function EL(n){if(!n.some(tt))return[...n,mr()];return n.reduce((t,r)=>{if(!tt(r))return t.result.push(r),t;if(!t.inserted)t.result.push(mr()),t.inserted=!0;return t},{result:[],inserted:!1}).result}function Ea(n,t,r){let e=k2(t.hooks)?t.hooks:{},a={...t,hooks:{...e,preToolUse:r}};B(n,`${JSON.stringify(a,null,2)}
31
+ `)}function Pa(n){let t=rt(n);if(!Ua(t))return GL(UL(t),{recursive:!0}),B(t,`${JSON.stringify({version:1,hooks:{preToolUse:[mr()]}},null,2)}
32
+ `),{path:t,alreadyInstalled:!1};let r=Ta(t),e=_a(r),a=e.filter(tt);if(k2(r.hooks)&&Array.isArray(r.hooks.preToolUse)&&a.length===1&&a[0]!==void 0&&TL(a[0]))return{path:t,alreadyInstalled:!0};return Ea(t,r,EL(e)),{path:t,alreadyInstalled:!1}}function Ia(n){let t=rt(n);if(!Ua(t))return{path:t,alreadyInstalled:!1};let r=Ta(t),e=_a(r),a=e.filter((l)=>!tt(l));if(a.length===e.length)return{path:t,alreadyInstalled:!1};return Ea(t,r,a),{path:t,alreadyInstalled:!0}}function NL(n){if(!n||typeof n!=="object"||Array.isArray(n))return[];let t=n.hooks;if(!t||typeof t!=="object"||Array.isArray(t))return[];let r=t.preToolUse;if(!Array.isArray(r))return[];return r.filter((e)=>!!e&&typeof e==="object"&&!Array.isArray(e)&&e.command===qn)}function nc(n){let t=[];if(n.length>1)t.push("Multiple managed cc-safety-net hooks found; reinstall to collapse duplicates");let r=n[0];if(r&&r.failClosed!==!0)t.push('Managed hook is missing "failClosed": true; reinstall to repair');if(r&&r.timeout!==30)t.push('Managed hook "timeout" is not 30; reinstall to repair');return t}function Na(n){let t=rt(n.homeDir);if(!PL(t))return{platform:"cursor",status:"n/a",configPath:t};let r;try{r=JSON.parse(IL(t,"utf-8"))}catch(l){return{platform:"cursor",status:"n/a",configPath:t,errors:[`Failed to parse Cursor hooks config ${t}: ${l instanceof Error?l.message:String(l)}`]}}let e=NL(r);if(e.length===0)return{platform:"cursor",status:"n/a",configPath:t};let a=nc(e);return{platform:"cursor",status:"configured",method:"hook config",configPath:t,errors:a.length>0?a:void 0}}import{existsSync as tc}from"node:fs";import{join as kr}from"node:path";var qr="gemini-safety-net";function jr(n){let t=kr(n,".gemini","extensions"),r=kr(t,qr);if(!tc(r))return{platform:"gemini-cli",status:"n/a"};let e=kr(t,"extension-enablement.json"),a=n2(e);if(a.kind==="unreadable")return{platform:"gemini-cli",status:"not-inspected"};let l=a.kind==="ok"?$($(a.value,qr),"overrides"):void 0;if(Array.isArray(l)&&l.some((s)=>typeof s==="string"&&s.startsWith("!")))return{platform:"gemini-cli",status:"disabled",method:"extension config",configPath:e,errors:[`${qr} is disabled in Gemini CLI`]};return{platform:"gemini-cli",status:"configured",method:"extension config",configPath:r}}function n0(n){return jr(n.homeDir)}import{readFileSync as c0}from"node:fs";import{join as i0}from"node:path";var M="cc-safety-net",t0="# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent";function r0(n){return`# cc-safety-net managed Hermes Agent plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --hermes-agent
33
33
  # version: ${n}
34
- `}function tL(n){return`${r0(n)}name: cc-safety-net
34
+ `}function rc(n){return`${r0(n)}name: cc-safety-net
35
35
  version: "${n}"
36
36
  description: "Block destructive commands and secret-file access before Hermes runs a tool."
37
37
  author: "cc-safety-net"
38
38
  provides_hooks:
39
39
  - pre_tool_call
40
- `}function rL(n){return`${r0(n)}"""CC Safety Net guard for Hermes Agent.
40
+ `}function ec(n){return`${r0(n)}"""CC Safety Net guard for Hermes Agent.
41
41
 
42
42
  Registers pre_tool_call and forwards the tool call to the packaged CC Safety Net
43
43
  adapter (cc-safety-net hook --hermes-agent) over JSON stdin. The adapter prints nothing
@@ -169,82 +169,83 @@ def _pre_tool_call(tool_name="", args=None, session_id="", task_id="", **_):
169
169
 
170
170
  def register(ctx):
171
171
  ctx.register_hook("pre_tool_call", _pre_tool_call)
172
- `}function kn(n){return[{name:"__init__.py",content:rL(n)},{name:"plugin.yaml",content:tL(n)}]}import{mkdirSync as eL,readdirSync as aL,readFileSync as lL,rmSync as kr}from"node:fs";import{join as q2}from"node:path";var dL="__pycache__";function qr(n){let t=process.env.HERMES_HOME?.trim();return t?t:q2(n,".hermes")}function jr(n){return q2(qr(n),"plugins",K)}function Fr(n){return n.startsWith(t0)}function zr(n,t){let r=jr(n),e=S(r);if(e&&(e.isSymbolicLink()||!e.isDirectory()))throw Error(`Refusing to ${t} ${r}: not a regular directory. Move or remove it and rerun ${t==="install"?"install":"uninstall"} --hermes-agent.`);return r}function e0(n,t){let r=S(n);if(!r)return;if(r.isSymbolicLink()||!r.isFile())throw Error(`Refusing to ${t} ${n}: not a regular file. Move or remove it.`);let e=lL(n,"utf-8");if(!Fr(e))throw Error(`Refusing to ${t} unmanaged file at ${n}. Move or remove it.`);return e}function a0(n){let t=zr(n,"install"),r=kn(j());if(r.map((a)=>e0(q2(t,a.name),"overwrite")).every((a,l)=>a===r[l]?.content))return{path:t,alreadyInstalled:!0};return eL(t,{recursive:!0}),r.forEach((a)=>{B(q2(t,a.name),a.content)}),{path:t,alreadyInstalled:!1}}function Br(n){let t=zr(n,"remove");if(!S(t))return[];return kn(j()).filter((r)=>e0(q2(t,r.name),"remove")!==void 0)}function l0(n){let t=zr(n,"remove");if(!S(t))return{path:t,alreadyInstalled:!1};let r=Br(n);if(r.forEach((e)=>{kr(q2(t,e.name))}),kr(q2(t,dL),{recursive:!0,force:!0}),aL(t).length===0)kr(t,{recursive:!0});return{path:t,alreadyInstalled:r.length>0}}var rt="hermes-agent",d0=/^([^\s#][^:]*):/,sL=/^\s+([A-Za-z_][\w-]*):/,s0=/^\s+-\s*(.*)$/;function cL(n){return n.trim().replace(/^(["'])(.*)\1$/,"$2")}function LL(n){let t=n.split(/\r?\n/),r=t.findIndex((l)=>d0.exec(l)?.[1]?.trim()==="plugins");if(r===-1)return[];let e=t.slice(r+1),a=e.findIndex((l)=>d0.test(l));return a===-1?e:e.slice(0,a)}function c0(n,t){let r=LL(n),e=r.findIndex((d)=>sL.exec(d)?.[1]===t);if(e===-1)return[];let a=r.slice(e+1),l=a.findIndex((d)=>!s0.test(d));return(l===-1?a:a.slice(0,l)).map((d)=>cL(s0.exec(d)?.[1]??""))}function iL(n){try{return L0(i0(qr(n),"config.yaml"),"utf-8")}catch{return}}function Jr(n){let t=iL(n)??"";return c0(t,"enabled").includes(K)&&!c0(t,"disabled").includes(K)}function p0(n){return/^# version:\s*(.+)$/m.exec(n)?.[1]?.trim()}function pL(n,t){let r=S(n);if(!r)return{error:`${t.name} is missing from ${n}; run install --hermes-agent`};if(r.isSymbolicLink()||!r.isFile())return{error:`${n} is a symlink or not a regular file; move or remove it`};try{let e=L0(n,"utf-8");if(!Fr(e))return{error:`Unmanaged ${t.name} occupies ${n}; move or remove it`};if(p0(e)===j()&&e!==t.content)return{error:`Modified ${t.name} occupies ${n}; run install --hermes-agent to restore it`};return{content:e}}catch(e){return{error:`Failed to read ${n}: ${e instanceof Error?e.message:String(e)}`}}}function u0(n){let t=jr(n.homeDir),r=En(rt,t);if(r)return r;let e=kn(j()).map((s)=>pL(i0(t,s.name),s)),a=e.flatMap((s)=>("error"in s)?[s.error]:[]);if(a.length>0)return{platform:rt,status:"n/a",configPath:t,errors:a};let l=e.some((s)=>("content"in s)&&p0(s.content)!==j()),d=l?["Installed Hermes Agent plugin is outdated; run install --hermes-agent to update"]:[];if(!Jr(n.homeDir))return{platform:rt,status:"disabled",method:"plugin directory",configPath:t,errors:[`${K} is not enabled in Hermes; run \`hermes plugins enable ${K}\``,...d]};return{platform:rt,status:"configured",method:"plugin directory",configPath:t,errors:l?d:void 0}}import{existsSync as uL,readFileSync as oL}from"node:fs";import{join as o0}from"node:path";var vL=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*--kimi-code(\s|["']|$)/;function bL(n){return o0(process.env.KIMI_CODE_HOME||o0(n,".kimi-code"),"config.toml")}function qn(n){let t=bL(n.homeDir);if(!uL(t))return{platform:"kimi-code",status:"n/a",configPath:t};try{if(!vL.test(oL(t,"utf-8")))return{platform:"kimi-code",status:"n/a",configPath:t}}catch(r){return{platform:"kimi-code",status:"n/a",configPath:t,errors:[`Failed to read ${t}: ${r instanceof Error?r.message:String(r)}`]}}return{platform:"kimi-code",status:"configured",method:"hook config",configPath:t}}import{readFileSync as D0}from"node:fs";import{join as Fn}from"node:path";var q="cc-safety-net",M="index.js",P2="openclaw.plugin.json",N2="package.json";var et="// cc-safety-net managed OpenClaw plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --openclaw";import{existsSync as hL,lstatSync as wL,readdirSync as xL,readFileSync as $L}from"node:fs";import{dirname as f0,join as j2}from"node:path";import{fileURLToPath as gL}from"node:url";import{spawn as fL}from"node:child_process";function yL(n){return n.join(" ")}function Zr(n,t,r){return[`Failed to run ${yL(n)}${t===null?"":` (exit ${t})`}.`,r.trim()].filter(Boolean).join(`
173
- `)}function Qr(n){let t={stdout:"",stderr:""};return n.stdout.setEncoding("utf-8"),n.stderr.setEncoding("utf-8"),n.stdout.on("data",(r)=>{t.stdout+=r}),n.stderr.on("data",(r)=>{t.stderr+=r}),t}function r2(n,t){return new Promise((r,e)=>{let a=f2([...n],process.env),l=fL(a.cmd,a.args,{stdio:["ignore","pipe","pipe"]}),d=Qr(l),s=()=>[d.stdout,d.stderr].filter(Boolean).join(`
174
- `),c=t?.timeoutMs??120000,L=setTimeout(()=>{l.kill(),e(Error(Zr(n,null,`Timed out after ${c}ms.
175
- ${s()}`.trim())))},c);l.on("error",(i)=>{clearTimeout(L),e(Error(Zr(n,null,`${i.message}
176
- ${s()}`.trim())))}),l.on("close",(i)=>{if(clearTimeout(L),i!==0){e(Error(Zr(n,i,s())));return}r(t?.stdoutOnly?d.stdout:s())})})}async function Xr(n){for(let t of n)await r2(t)}async function v0(n){for(let t of n)try{await r2(t)}catch(r){console.warn(r instanceof Error?r.message:String(r))}}var b0=j2("openclaw",q),DL=[M,P2,N2];function y0(n){let t=process.env.OPENCLAW_STATE_DIR?.trim();if(t)return t;let r=process.env.OPENCLAW_CONFIG_PATH?.trim();return r?f0(r):j2(n,".openclaw")}function h0(n){let t=process.env.OPENCLAW_CONFIG_PATH?.trim();return t?t:j2(y0(n),"openclaw.json")}function Yr(n){return j2(y0(n),"extensions",q)}function mL(n){let t=xL(n);if(t.length===0)return!0;if(t.some((a)=>!DL.includes(a)))return!1;let r=j2(n,M),e=S(r);return e!==void 0&&!e.isSymbolicLink()&&e.isFile()&&$L(r,"utf-8").startsWith(et)}function Sr(n){let t=Yr(n),r=S(t);if(!r)return;if(!r.isSymbolicLink()&&r.isDirectory()&&mL(t))return;throw Error(`Refusing to modify ${t}: it does not hold a cc-safety-net managed OpenClaw plugin. Move or remove it, then run the command again.`)}function w0(){let n=f0(gL(import.meta.url));return[j2(n,"..",b0),j2(n,"..","..","..","dist",b0)]}function Hr(n=w0()){return n.find((t)=>hL(t)&&wL(t).isDirectory())}function kL(n=w0()){let t=Hr(n);if(!t)throw Error("Packaged OpenClaw plugin directory not found. Reinstall cc-safety-net and try again.");return t}function x0(n=kL()){return[["openclaw","plugins","install",n,"--force"],["openclaw","plugins","enable",q]]}function qL(n){let t=(()=>{try{return JSON.parse(n)}catch{return}})(),r=$($(t,"plugin"),"status");return typeof r==="string"?r:void 0}async function $0(){let n=qL(await r2(["openclaw","plugins","inspect",q,"--runtime","--json"],{stdoutOnly:!0}));if(n==="loaded")return;throw Error(`${n===void 0?`The ${q} plugin's load state could not be verified: OpenClaw's runtime inspect report was unreadable.`:`OpenClaw reports the ${q} plugin with status "${n}".`} Run \`openclaw plugins inspect ${q} --runtime\` for details.`)}var at="openclaw",jn=`run \`openclaw plugins enable ${q}\``;function I2(n,t){let r=Fn(n,t),e=S(r);if(!e)return{error:`${t} is missing from ${r}; run install --openclaw`};if(e.isSymbolicLink()||!e.isFile())return{error:`${r} is a symlink or not a regular file; move or remove it`};try{return{content:D0(r,"utf-8")}}catch(a){return{error:`Failed to read ${r}: ${a instanceof Error?a.message:String(a)}`}}}function m0(n){try{return JSON.parse(R(n))}catch{return}}function jL(n){let t=I2(n,P2);if("error"in t)return t.error;if($(m0(t.content),"id")===q)return;return`${Fn(n,P2)} is not a valid ${q} manifest; run install --openclaw`}function FL(n){let t=I2(n,N2);if("error"in t)return t.error;let r=$($(m0(t.content),"openclaw"),"extensions");if(Array.isArray(r)&&r.includes(`./${M}`))return;return`${Fn(n,N2)} does not point OpenClaw at ${M}; run install --openclaw`}function g0(n){return Array.isArray(n)?n.filter((t)=>typeof t==="string"):[]}function zL(n){let t=h0(n);if(!S(t))return`${q} is not enabled; ${jn}`;let r=(()=>{try{return JSON.parse(R(D0(t,"utf-8")))}catch{return}})();if(r===void 0)return`Failed to read ${t}; fix it, then ${jn}`;let e=$(r,"plugins");if($(e,"enabled")===!1)return`plugins.enabled is false in ${t}; no OpenClaw plugin loads`;let a=$($($(e,"entries"),q),"enabled");if(g0($(e,"deny")).includes(q)||a===!1)return`${q} is disabled in ${t}; ${jn}`;let l=g0($(e,"allow"));if(l.length>0&&!l.includes(q))return`plugins.allow in ${t} does not list ${q}; add it, then ${jn}`;if(l.includes(q)||a===!0)return;return`${q} is not enabled; ${jn}`}function k0(n){return/^\/\/ version:\s*(.+)$/m.exec(n)?.[1]?.trim()}function BL(n,t,r){if(r===void 0)return[];let e=I2(r,M);if("error"in e||k0(e.content)!==t)return[];return[M,P2,N2].flatMap((a)=>{let l=I2(n,a),d=I2(r,a);if("error"in l||"error"in d||l.content===d.content)return[];return[`Modified ${a} occupies ${Fn(n,a)}; run install --openclaw to restore it`]})}function q0(n){let t=Yr(n.homeDir),r=En(at,t);if(r)return r;let e=I2(t,M),l=["error"in e?e.error:e.content.startsWith(et)?void 0:`Unmanaged ${M} occupies ${Fn(t,M)}; move or remove it`,jL(t),FL(t)].filter((i)=>i!==void 0),d="content"in e?k0(e.content):void 0,s=l.length>0?l:BL(t,d,Hr());if(s.length>0)return{platform:at,status:"n/a",configPath:t,errors:s};let c=d===j()?[]:["Installed OpenClaw plugin is outdated; run install --openclaw to update"],L=zL(n.homeDir);if(L)return{platform:at,status:"disabled",method:"plugin directory",configPath:t,errors:[L,...c]};return{platform:at,status:"configured",method:"plugin directory",configPath:t,errors:c.length>0?c:void 0}}import{existsSync as JL,readFileSync as ZL}from"node:fs";import{join as j0}from"node:path";function F0(n){let t=[],r=j0(n.homeDir,".config","opencode"),e=["opencode.json","opencode.jsonc"];for(let a of e){let l=j0(r,a);if(JL(l))try{let d=ZL(l,"utf-8"),s=R(d);if((JSON.parse(s).plugin??[]).some((u)=>u.includes("cc-safety-net")))return{platform:"opencode",status:"configured",method:"plugin array",configPath:l,errors:t.length>0?t:void 0}}catch(d){t.push(`Failed to parse ${a}: ${d instanceof Error?d.message:String(d)}`)}}return{platform:"opencode",status:"n/a",errors:t.length>0?t:void 0}}import{join as QL}from"node:path";function Ar(n){return QL(n,".pi","agent","settings.json")}function Wr(n){if(typeof n!=="string")return!1;return n==="npm:cc-safety-net"||n.startsWith("npm:cc-safety-net@")}function z0(n){let t=Ar(n.homeDir),r=n2(t);if(r.kind==="unreadable")return{platform:"pi",status:"not-inspected"};if(r.kind==="missing")return{platform:"pi",status:"n/a"};let e=$(r.value,"packages");if(!Array.isArray(e))return{platform:"pi",status:"n/a"};let a=e.find((s)=>Wr(typeof s==="string"?s:$(s,"source")));if(a===void 0)return{platform:"pi",status:"n/a"};let l=$(a,"extensions");if(Array.isArray(l)&&l.some((s)=>typeof s==="string"&&s.startsWith("-")))return{platform:"pi",status:"disabled",method:"package config",configPath:t,errors:["npm:cc-safety-net is installed but its extension is disabled in Pi settings"]};return{platform:"pi",status:"configured",method:"package config",configPath:t}}var YL={amp:Fa,"antigravity-cli":za,"claude-code":Qa,codex:Xa,"copilot-cli":Ca,cursor:Ia,"gemini-cli":n0,"hermes-agent":u0,"kimi-code":qn,openclaw:q0,opencode:F0,pi:z0};function nn(n,t){let r={...t,cwd:n,homeDir:t?.homeDir??XL()};return j1.map((e)=>SL(YL[e](r)))}function SL(n){if(n.status==="not-inspected")return{platform:n.platform,detected:!1,configured:!1,inspectionStatus:"not-inspected"};return{platform:n.platform,detected:n.status!=="n/a",configured:n.status==="configured",inspectionStatus:n.status!=="n/a"?"verified":n.errors&&n.errors.length>0?"failed":"not-applicable",method:n.method,configPath:n.configPath,configPaths:n.configPaths,errors:n.errors}}import{tmpdir as HL}from"node:os";import{join as AL}from"node:path";var WL=Object.freeze([{command:"git reset --hard",description:"git reset --hard",expectBlocked:!0},{command:"rm -rf /",description:"rm -rf /",expectBlocked:!0},{command:"rm -rf ./node_modules",description:"rm in cwd (safe)",expectBlocked:!1}]),RL=Object.freeze({state:"ready",diagnostics:Object.freeze([]),ruleMetadata:Object.freeze({}),policy:Object.freeze({rules:Object.freeze([]),transparentWrappers:Object.freeze([]),safety:Object.freeze({}),worktreeMode:!1,destructiveCommandProtectionEnabled:!0,destructiveCommandRuleOverrides:Object.freeze({}),destructiveCommandAllowPaths:Object.freeze([]),secretProtection:Object.freeze({enabled:!0,disabledRules:Object.freeze([]),denyPaths:Object.freeze([])})})}),VL={strict:!1,paranoidRm:!1,paranoidInterpreters:!1,worktreeMode:!1,effectiveLevel:"standard",capabilities:{fail_closed:{enabled:!1,source:"preset",sources:[]},paranoid_rm:{enabled:!1,source:"preset",sources:[]},paranoid_interpreters:{enabled:!1,source:"preset",sources:[]}},sources:{failClosed:[],paranoidRm:[],paranoidInterpreters:[],worktreeMode:[]}};function B0(){let n=AL(HL(),"cc-safety-net-self-test"),t=WL.map((r)=>{let e=Wn(K2("self-test",{command:r.command},{kind:"command",shell:"auto"},{configCwd:n,executionCwd:n},r.command),{guard:{dependencies:{loadPolicySnapshot:()=>RL,getModes:()=>VL,findPolicyMutation:()=>null}},audit:{agent:"self-test",getSessionId:()=>{return}}}),a=r.expectBlocked?"blocked":"allowed",l=e.decision.kind==="deny"?"blocked":"allowed";return{command:r.command,description:r.description,expected:a,actual:l,passed:a===l,reason:e.decision.kind==="deny"?e.decision.reason:void 0,ruleId:e.decision.kind==="deny"?e.decision.ruleId:void 0}});return{passed:t.filter((r)=>r.passed).length,failed:t.filter((r)=>!r.passed).length,total:t.length,results:t}}function Rr(n){let t=F({label:"doctor",booleans:{json:["--json"],skipUpdateCheck:["--skip-update-check"]}},n);if(e2(t.errors))return null;return{json:t.flags.json,skipUpdateCheck:t.flags.skipUpdateCheck}}async function J0(n={}){let t=await On(!n.json,()=>{let r=KL(n);return{ready:r,finish:()=>r}},()=>Un(),{loadingMessage:"Checking system status…"});if(n.json)console.log(JSON.stringify(t,null,2));else GL(t);return ML(t.hooks,t.engineSelfTest,{userConfig:t.userConfig,projectConfig:t.projectConfig})?1:0}async function KL(n){let t=n.cwd??process.cwd(),r=await xn(),e=nn(t,{ampPluginListOutput:r.ampPluginListOutput,codexPluginListOutput:r.codexPluginListOutput,copilotCliVersion:r.copilotCliVersion}),a=N1(t),l=I1(),d=W({cwd:t}),s=d.policy,c=d2(s),L=g2(s,c.capabilities),i=Mn(7),u=n.skipUpdateCheck?{currentVersion:j(),latestVersion:null,updateAvailable:!1}:await E2(),v={hooks:e,engineSelfTest:B0(),userConfig:a.userConfig,projectConfig:a.projectConfig,configState:bn(d),effectiveRules:a.effectiveRules,shadowedRules:a.shadowedRules,environment:l,effectiveSafety:{selectedPreset:s.safety.level??"standard",level:c.effectiveLevel,capabilities:c.capabilities,ruleOverrides:s.destructiveCommandRuleOverrides,weakenedRuleOverrides:Object.entries(L).filter(([,p])=>p.source==="rule_override"&&p.override==="off"&&p.inheritedEnabled&&p.changesInherited).map(([p])=>p),ruleCounts:{stored:Object.keys(s.destructiveCommandRuleOverrides).length,effective:Object.values(L).filter((p)=>p.changesInherited).length}},posture:oa(a.userConfig.path),activity:i,update:u,system:r};return{...v,findings:ta(v)}}function ML(n,t,r){return n.length>0&&n.every((e)=>!e.configured)||n.some((e)=>e.inspectionStatus==="failed")||t.failed>0||r.userConfig.exists&&!r.userConfig.valid||r.projectConfig.exists&&!r.projectConfig.valid}function GL(n){console.log(),console.log(ea(n.hooks)),console.log(),console.log(aa(n.engineSelfTest)),console.log(),console.log(la(n)),console.log(),console.log(da(n.environment)),console.log(),console.log(sa(n)),console.log(),console.log(ca(n.findings)),console.log(),console.log(La(n.activity)),console.log(),console.log(pa(n.system)),console.log(),console.log(ia(n.update)),console.log(ua(n))}import{existsSync as CL}from"node:fs";var UL=/^[A-Za-z0-9_@%+=:,./-]+$/,Z0="Usage: cc-safety-net explain [--json] [--cwd <path>] <command>";function Vr(n){let t=F({label:"explain",booleans:{json:["--json"]},values:{cwd:["--cwd"]},positionals:"tail"},n);if(e2(t.errors))return console.error(Z0),console.error("Pass -- before a command that starts with dashes."),null;if(t.values.cwd!==void 0&&!CL(t.values.cwd))return console.error(`Error: --cwd path does not exist: ${t.values.cwd}`),null;let r=t.positionals.length===1?t.positionals[0]:t.positionals.map((e)=>UL.test(e)?e:`'${e.replaceAll("'","'\\''")}'`).join(" ");if(!r)return console.error("Error: No command provided"),console.error(Z0),null;return{json:t.flags.json,cwd:t.values.cwd,command:r}}function Q0(n){if(n)return{dh:"=",dv:"|",dtl:"+",dtr:"+",dbl:"+",dbr:"+",h:"-",v:"|",tl:"+",tr:"+",bl:"+",br:"+",sh:"="};return{dh:"═",dv:"║",dtl:"╔",dtr:"╗",dbl:"╚",dbr:"╝",h:"─",v:"│",tl:"┌",tr:"┐",bl:"└",br:"┘",sh:"━"}}function X0(n,t){let e=t-18;return[`${n.dtl}${n.dh.repeat(t)}${n.dtr}`,`${n.dv} Command Analysis${" ".repeat(e)}${n.dv}`,`${n.dbl}${n.dh.repeat(t)}${n.dbr}`]}function Kr(n){return JSON.stringify(n)}function Y0(n,t=0){return`[${n.map((e,a)=>ra(e,a,t)).join(",")}]`}function lt(n,t,r=70){let e=n.split(" "),a=[],l="";for(let d of e)if(l&&l.length+d.length+1>r)a.push(l),l=d;else l=l?`${l} ${d}`:d;if(l)a.push(l);return a.map((d,s)=>s===0?d:`${t}${d}`)}function S0(n,t,r){let e=[];switch(n.type){case"parse":return null;case"env-strip":{e.push(""),e.push(`STEP ${t} ${r.h} Strip environment variables`);let a=Object.keys(n.envVars);return e.push(` Removed: ${a.map((l)=>`${l}=<redacted>`).join(", ")}`),e.push(` Tokens: ${Kr(n.output)}`),{lines:e,incrementStep:!0}}case"leading-tokens-stripped":return e.push(""),e.push(`STEP ${t} ${r.h} Strip wrappers`),e.push(` Removed: ${n.removed.join(", ")}`),e.push(` Tokens: ${Kr(n.output)}`),{lines:e,incrementStep:!0};case"shell-wrapper":return e.push(""),e.push(`STEP ${t} ${r.h} Detect shell wrapper`),e.push(` Wrapper: ${n.wrapper} -c`),e.push(` Inner: ${n.innerCommand}`),{lines:e,incrementStep:!0};case"interpreter":{if(e.push(""),e.push(`STEP ${t} ${r.h} Detect interpreter`),e.push(` Interpreter: ${n.interpreter}`),e.push(` Code: ${n.codeArg}`),n.paranoidBlocked)e.push(" Result: ✗ BLOCKED (paranoid mode)");return{lines:e,incrementStep:!0}}case"busybox":return e.push(""),e.push(`STEP ${t} ${r.h} Busybox wrapper`),e.push(` Subcommand: ${n.subcommand}`),{lines:e,incrementStep:!0};case"transparent-wrapper":return e.push(""),e.push(`STEP ${t} ${r.h} Transparent wrapper`),e.push(` Wrapper: ${n.wrapper}`),e.push(` Tokens: ${Kr(n.output)}`),{lines:e,incrementStep:!0};case"recurse":return{lines:[],incrementStep:!1};case"rule-check":{e.push(""),e.push(`STEP ${t} ${r.h} Match rules`);let a=`${n.ruleModule}:${n.ruleFunction}()`;if(e.push(` Rule: ${a}`),n.matched)e.push(" Result: MATCHED");else e.push(" Result: No match");return{lines:e,incrementStep:!0}}case"worktree-relaxation":return e.push(""),e.push(`STEP ${t} ${r.h} Worktree relaxation`),e.push(` Mode: ${m.worktree.name}`),e.push(` Git cwd: ${n.gitCwd}`),e.push(" Result: Allowed local discard in linked worktree"),{lines:e,incrementStep:!0};case"tmpdir-check":return null;case"fallback-scan":{if(n.embeddedCommandFound)return e.push(""),e.push(`STEP ${t} ${r.h} Fallback scan`),e.push(` Found: ${n.embeddedCommandFound}`),{lines:e,incrementStep:!0};return null}case"custom-rules-check":{if(n.rulesChecked){if(e.push(""),e.push(`STEP ${t} ${r.h} Custom rules`),n.matched)e.push(" Result: MATCHED");else e.push(" Result: No match");return{lines:e,incrementStep:!0}}return null}case"cwd-change":return null;case"dangerous-text":{if(n.matched)return e.push(""),e.push(`STEP ${t} ${r.h} Dangerous text check`),e.push(` Token: ${n.token}`),e.push(" Result: MATCHED"),{lines:e,incrementStep:!0};return null}case"strict-unparseable":return e.push(""),e.push(`STEP ${t} ${r.h} Strict mode check`),e.push(` Command: ${n.rawCommand}`),e.push(" Result: ✗ UNPARSEABLE"),{lines:e,incrementStep:!0};case"segment-skipped":return null;case"error":return e.push(""),e.push(`ERROR: ${n.message}`),{lines:e,incrementStep:!1};default:return null}}function Mr(n,t){let r=Q0(t?.asciiOnly??!1),e=58,a=[],l=1;a.push(...X0(r,58)),a.push("");let d=n.trace.steps.find((p)=>p.type==="error");if(d&&d.type==="error"){a.push("ERROR"),a.push(` ${d.message}`),a.push(""),a.push("RESULT"),a.push(` Status: ${n.result==="blocked"?b.red("BLOCKED"):b.green("ALLOWED")}`),a.push(""),a.push("CONFIG");let p=n.configSource??"none";return a.push(` Path: ${p}`),a.join(`
177
- `)}let s=n.trace.steps.find((p)=>p.type==="parse");if(s&&s.type==="parse"){a.push("INPUT"),a.push(` ${s.input}`),a.push(""),a.push(`STEP ${l} ${r.h} Split shell commands`),l++;for(let p=0;p<s.segments.length;p++){let f=s.segments[p];if(f){let o=Math.random();a.push(` Segment ${p+1}: ${Y0(f,o)}`)}}}let c=n.trace.segments,L=c.length>1;for(let p of c){if(L){a.push("");let x="";if(s&&s.type==="parse"){let mt=s.segments[p.index];if(mt)x=mt.join(" ")}let w=54,h=x,J=` Segment ${p.index+1}: `,Z2=" ";if(x){if(J.length+x.length+Z2.length>w){let Q3=w-J.length-Z2.length;h=`${x.substring(0,Q3-1)}…`}}let an=x?`${J}${h}${Z2}`:` Segment ${p.index+1} `,Dt=x?`${J}${b.cyan(h)}${Z2}`:an,we=58-an.length,xe=Math.floor(we/2),Z3=we-xe;a.push(`${r.sh.repeat(xe)}${Dt}${r.sh.repeat(Z3)}`)}if(p.steps.find((x)=>x.type==="segment-skipped")){a.push(""),a.push(" (skipped — prior segment blocked)");continue}let o=!1,y=!1;for(let x of p.steps){let w=S0(x,l,r);if(w){if(y=!0,x.type==="recurse"){a.push("");let h=" RECURSING ",J=58-h.length-4;a.push(` ${r.tl}${r.h}${h}${r.h.repeat(J)}`),a.push(` ${r.v}`),o=!0;continue}for(let h of w.lines)if(o)a.push(` ${r.v} ${h}`);else a.push(h);if(w.incrementStep)l++}}if(o)a.push(` ${r.v}`),a.push(` ${r.bl}${r.h.repeat(56)}`),o=!1;if(!y)a.push(""),a.push(` ${b.green("✓")} Allowed (no matching rules)`)}if(a.push(""),a.push("RESULT"),n.result==="blocked"){if(a.push(` Status: ${b.red("BLOCKED")}`),n.customRule){if(a.push(` Rule: ${n.customRule.id}`),n.customRule.rulebook)a.push(` Rulebook: ${n.customRule.rulebook.name} ${n.customRule.rulebook.version}`);if(n.customRule.source)a.push(` Source: ${n.customRule.source}`);if(n.customRule.override)a.push(` Override: reason ${n.customRule.override.reason}`)}if(n.reason){let p=lt(n.reason," ");a.push(` Reason: ${p[0]}`);for(let f=1;f<p.length;f++)a.push(p[f]??"")}}else a.push(` Status: ${b.green("ALLOWED")}`);a.push(""),a.push("CONFIG");let i=n.configSource??"none",u=n.configValid?"":" (invalid)";a.push(` Path: ${i}${u}`),a.push(` Safety preset: ${n.selectedPreset??"standard"}`),a.push(` Effective capabilities: ${n.effectiveLevel}`);let v=Object.entries(n.destructiveCommandRuleOverrides??{});if(a.push(` Rule customizations: ${v.length}`),n.ruleActivation)a.push(` Rule activation: ${n.ruleActivation.id} — ${n.ruleActivation.enabled?"on":"off"} via ${n.ruleActivation.source}`);return a.join(`
178
- `)}function Gr(n){return JSON.stringify(n,null,2)}var H0="2.0.3",G=" ",F2="cc-safety-net";function A0(n){return n.argument?`${n.flags} ${n.argument}`:n.flags}function OL(n){return Math.max(...n.map((t)=>A0(t).length))}function TL(n){return Math.max(...n.map((t)=>t.usage.length))}function EL(n){return Math.max(...n.map((t)=>`${F2} ${t.usage}`.length))}function _L(n,t){let r=`${F2} ${n.usage}`;return`${G}${r.padEnd(t+2)}${n.description}`}function i2(n,t){return`${G}${n.padEnd(Math.max(40,n.length+2))}${t}`}function dt(n,t=console.log){let r=[];if(r.push(`${F2} ${n.name}`),r.push(""),r.push(`${G}${n.description}`),r.push(""),r.push("USAGE:"),r.push(`${G}${F2} ${n.usage}`),r.push(""),n.subcommands&&n.subcommands.length>0){r.push("SUBCOMMANDS:");let e=TL(n.subcommands);for(let a of n.subcommands)r.push(`${G}${a.usage.padEnd(e+2)}${a.description}`);r.push("")}if(n.options.length>0){r.push("OPTIONS:");let e=OL(n.options);for(let a of n.options){let l=A0(a),d=a.default?`${a.description} (default: ${a.default})`:a.description;r.push(`${G}${l.padEnd(e+2)}${d}`)}r.push("")}if(n.examples&&n.examples.length>0){r.push("EXAMPLES:");for(let e of n.examples)r.push(`${G}${e}`)}t(r.join(`
179
- `))}function Cr(){let n=_1(),t=EL(n),r=[];r.push(`${F2} v${H0}`),r.push(""),r.push("Blocks destructive commands and secret access."),r.push(""),r.push("COMMANDS:");for(let e of n)r.push(_L(e,t));r.push(""),r.push("GLOBAL OPTIONS:"),r.push(`${G}-h, --help Show help (use with command for command-specific help)`),r.push(`${G}-V, --version Show version`),r.push(""),r.push("HELP:"),r.push(`${G}${F2} help <command> Show help for a specific command`),r.push(`${G}${F2} <command> --help Show help for a specific command`),r.push(""),r.push("ENVIRONMENT VARIABLES:"),r.push(i2(`${m.level.name}=standard|strict|paranoid`,"Set session safety level")),r.push(i2(`${m.worktree.name}=1`,"Allow local git discards in linked worktrees")),r.push(i2(`${m.debug.name}=1`,"Print diagnostic messages to stderr")),r.push(i2(`${m.auditScope.name}=all|blocked`,"Record all command decisions, or denials only")),r.push(i2("CC_SAFETY_NET_HOME","Override rule config home directory")),r.push(""),r.push("LEGACY ENVIRONMENT VARIABLES (STILL SUPPORTED):"),r.push(i2(`${m.strict.name}=1`,"Force safety.overrides.fail_closed on")),r.push(i2(`${m.paranoid.name}=1`,"Force paranoid_rm and paranoid_interpreters on")),r.push(i2(`${m.paranoidRm.name}=1`,"Force safety.overrides.paranoid_rm on")),r.push(i2(`${m.paranoidInterpreters.name}=1`,"Force safety.overrides.paranoid_interpreters on")),r.push(""),r.push("Documentation: https://ccsafetynet.com/docs"),console.log(r.join(`
180
- `))}function W0(){console.log(H0)}function zn(n,t=console.log){let r=Kn(n);if(!r)return!1;if(r.hidden||r.name.toLowerCase()!==n.toLowerCase())return!1;return dt(r,t),!0}import{existsSync as se,readFileSync as Vl}from"node:fs";import{homedir as Ei}from"node:os";import{join as le}from"node:path";import*as y2 from"node:readline";function PL(n){return n==="install"?"Install":"Uninstall"}function NL(n){return n==="install"?"Installing":"Uninstalling"}function IL(n){return n==="install"?"into":"from"}function K0(n){return n?.available===!0}function ni(n,t){let r=new Set(t);return n.filter((e)=>r.has(e.target)).map((e)=>e.target)}function R0(n,t,r){if(n.length===0||n.every((e)=>!e.available))return t;return Array.from({length:n.length},(e,a)=>a+1).map((e)=>(t+e*r+n.length)%n.length).find((e)=>K0(n[e]))}function ti(n,t,r){if(r.ctrl&&r.name==="c")return"interrupt";if(r.name==="escape"||t==="q")return"abort";if(n==="install"&&(t==="u"||t==="U"))return"update";if(r.name==="up"||t==="k")return"up";if(r.name==="down"||t==="j")return"down";if(r.name==="space"||t===" ")return"toggle";if(r.name==="return"||r.name==="enter")return"confirm";return null}function ri(n){return{cursor:n.findIndex((t)=>t.available),selected:[]}}function ei(n,t,r){if(r==="confirm"||r==="update"||r==="abort"||r==="interrupt")return{state:n,done:r};if(r==="up")return{state:{...n,cursor:R0(t,n.cursor,-1)}};if(r==="down")return{state:{...n,cursor:R0(t,n.cursor,1)}};let e=t[n.cursor];if(!K0(e))return{state:n};let a=n.selected.includes(e.target)?n.selected.filter((l)=>l!==e.target):ni(t,[...n.selected,e.target]);return{state:{...n,selected:a}}}var M0="◉",G0="◯",C0=">",U0=" ";function ai(n,t,r,e={}){let a=e.color!==!1,l=a?b.dim:(c)=>c,d=a?b.green:(c)=>c,s=a?b.bold:(c)=>c;return["",`${PL(n)} CC Safety Net ${IL(n)}:`,"",...t.map((c,L)=>{let i=r.selected.includes(c.target),u=L===r.cursor,v=i?M0:G0,p=u?C0:U0,f=c.available?"":` (${c.unavailableReason??"not installed"})`,o=`${v} ${c.label}${f}`,y=!c.available?l(o):i?d(o):u?s(o):o;return`${p} ${y}`}),"",n==="install"?"Space: select Enter: confirm u: update installed Up/Down: move q/Esc: cancel":t.some((c)=>c.available)?"Space: select Enter: confirm Up/Down: move q/Esc: cancel":`No selectable integrations found for ${n}. q/Esc: close`].join(`
181
- `)}var V0=["global-hook","plugin"];function li(n,t,r={}){let e=r.color!==!1?b.bold:(l)=>l;return["","Install the Kimi Code integration as:","",...[`Global hook — ${t?"already installed; selecting it reports the current state":"write the hook into ~/.kimi-code/config.toml now"}`,"Native Kimi plugin — print the steps to run inside Kimi Code"].map((l,d)=>{let s=d===n,c=`${s?M0:G0} ${l}`;return`${s?C0:U0} ${s?e(c):c}`}),"","Enter: confirm Up/Down: move q/Esc: cancel"].join(`
172
+ `}function jn(n){return[{name:"__init__.py",content:ec(n)},{name:"plugin.yaml",content:rc(n)}]}import{mkdirSync as ac,readdirSync as lc,readFileSync as dc,rmSync as Fr}from"node:fs";import{join as q2}from"node:path";var sc="__pycache__";function zr(n){let t=process.env.HERMES_HOME?.trim();return t?t:q2(n,".hermes")}function Br(n){return q2(zr(n),"plugins",M)}function Jr(n){return n.startsWith(t0)}function Zr(n,t){let r=Br(n),e=S(r);if(e&&(e.isSymbolicLink()||!e.isDirectory()))throw Error(`Refusing to ${t} ${r}: not a regular directory. Move or remove it and rerun ${t==="install"?"install":"uninstall"} --hermes-agent.`);return r}function e0(n,t){let r=S(n);if(!r)return;if(r.isSymbolicLink()||!r.isFile())throw Error(`Refusing to ${t} ${n}: not a regular file. Move or remove it.`);let e=dc(n,"utf-8");if(!Jr(e))throw Error(`Refusing to ${t} unmanaged file at ${n}. Move or remove it.`);return e}function a0(n){let t=Zr(n,"install"),r=jn(j());if(r.map((a)=>e0(q2(t,a.name),"overwrite")).every((a,l)=>a===r[l]?.content))return{path:t,alreadyInstalled:!0};return ac(t,{recursive:!0}),r.forEach((a)=>{B(q2(t,a.name),a.content)}),{path:t,alreadyInstalled:!1}}function Qr(n){let t=Zr(n,"remove");if(!S(t))return[];return jn(j()).filter((r)=>e0(q2(t,r.name),"remove")!==void 0)}function l0(n){let t=Zr(n,"remove");if(!S(t))return{path:t,alreadyInstalled:!1};let r=Qr(n);if(r.forEach((e)=>{Fr(q2(t,e.name))}),Fr(q2(t,sc),{recursive:!0,force:!0}),lc(t).length===0)Fr(t,{recursive:!0});return{path:t,alreadyInstalled:r.length>0}}var et="hermes-agent",d0=/^([^\s#][^:]*):/,Lc=/^\s+([A-Za-z_][\w-]*):/,s0=/^\s+-\s*(.*)$/;function cc(n){return n.trim().replace(/^(["'])(.*)\1$/,"$2")}function ic(n){let t=n.split(/\r?\n/),r=t.findIndex((l)=>d0.exec(l)?.[1]?.trim()==="plugins");if(r===-1)return[];let e=t.slice(r+1),a=e.findIndex((l)=>d0.test(l));return a===-1?e:e.slice(0,a)}function L0(n,t){let r=ic(n),e=r.findIndex((d)=>Lc.exec(d)?.[1]===t);if(e===-1)return[];let a=r.slice(e+1),l=a.findIndex((d)=>!s0.test(d));return(l===-1?a:a.slice(0,l)).map((d)=>cc(s0.exec(d)?.[1]??""))}function pc(n){try{return c0(i0(zr(n),"config.yaml"),"utf-8")}catch{return}}function Xr(n){let t=pc(n)??"";return L0(t,"enabled").includes(M)&&!L0(t,"disabled").includes(M)}function p0(n){return/^# version:\s*(.+)$/m.exec(n)?.[1]?.trim()}function uc(n,t){let r=S(n);if(!r)return{error:`${t.name} is missing from ${n}; run install --hermes-agent`};if(r.isSymbolicLink()||!r.isFile())return{error:`${n} is a symlink or not a regular file; move or remove it`};try{let e=c0(n,"utf-8");if(!Jr(e))return{error:`Unmanaged ${t.name} occupies ${n}; move or remove it`};if(p0(e)===j()&&e!==t.content)return{error:`Modified ${t.name} occupies ${n}; run install --hermes-agent to restore it`};return{content:e}}catch(e){return{error:`Failed to read ${n}: ${e instanceof Error?e.message:String(e)}`}}}function u0(n){let t=Br(n.homeDir),r=En(et,t);if(r)return r;let e=jn(j()).map((s)=>uc(i0(t,s.name),s)),a=e.flatMap((s)=>("error"in s)?[s.error]:[]);if(a.length>0)return{platform:et,status:"n/a",configPath:t,errors:a};let l=e.some((s)=>("content"in s)&&p0(s.content)!==j()),d=l?["Installed Hermes Agent plugin is outdated; run install --hermes-agent to update"]:[];if(!Xr(n.homeDir))return{platform:et,status:"disabled",method:"plugin directory",configPath:t,errors:[`${M} is not enabled in Hermes; run \`hermes plugins enable ${M}\``,...d]};return{platform:et,status:"configured",method:"plugin directory",configPath:t,errors:l?d:void 0}}import{existsSync as vc,readFileSync as oc}from"node:fs";import{join as v0}from"node:path";var bc=/cc-safety-net\s+hook\s+(?:[^\s]+\s+)*--kimi-code(\s|["']|$)/;function fc(n){return v0(process.env.KIMI_CODE_HOME||v0(n,".kimi-code"),"config.toml")}function Fn(n){let t=fc(n.homeDir);if(!vc(t))return{platform:"kimi-code",status:"n/a",configPath:t};try{if(!bc.test(oc(t,"utf-8")))return{platform:"kimi-code",status:"n/a",configPath:t}}catch(r){return{platform:"kimi-code",status:"n/a",configPath:t,errors:[`Failed to read ${t}: ${r instanceof Error?r.message:String(r)}`]}}return{platform:"kimi-code",status:"configured",method:"hook config",configPath:t}}import{readFileSync as D0}from"node:fs";import{join as Bn}from"node:path";var q="cc-safety-net",V="index.js",I2="openclaw.plugin.json",N2="package.json";var at="// cc-safety-net managed OpenClaw plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --openclaw";import{existsSync as wc,lstatSync as xc,readdirSync as $c,readFileSync as gc}from"node:fs";import{dirname as f0,join as j2}from"node:path";import{fileURLToPath as Dc}from"node:url";import{spawn as yc}from"node:child_process";function hc(n){return n.join(" ")}function Yr(n,t,r){return[`Failed to run ${hc(n)}${t===null?"":` (exit ${t})`}.`,r.trim()].filter(Boolean).join(`
173
+ `)}function Sr(n){let t={stdout:"",stderr:""};return n.stdout.setEncoding("utf-8"),n.stderr.setEncoding("utf-8"),n.stdout.on("data",(r)=>{t.stdout+=r}),n.stderr.on("data",(r)=>{t.stderr+=r}),t}function r2(n,t){return new Promise((r,e)=>{let a=f2([...n],process.env),l=yc(a.cmd,a.args,{stdio:["ignore","pipe","pipe"]}),d=Sr(l),s=()=>[d.stdout,d.stderr].filter(Boolean).join(`
174
+ `),L=t?.timeoutMs??120000,c=setTimeout(()=>{l.kill(),e(Error(Yr(n,null,`Timed out after ${L}ms.
175
+ ${s()}`.trim())))},L);l.on("error",(i)=>{clearTimeout(c),e(Error(Yr(n,null,`${i.message}
176
+ ${s()}`.trim())))}),l.on("close",(i)=>{if(clearTimeout(c),i!==0){e(Error(Yr(n,i,s())));return}r(t?.stdoutOnly?d.stdout:s())})})}async function Hr(n){for(let t of n)await r2(t)}async function o0(n){for(let t of n)try{await r2(t)}catch(r){console.warn(r instanceof Error?r.message:String(r))}}var b0=j2("openclaw",q),mc=[V,I2,N2];function y0(n){let t=process.env.OPENCLAW_STATE_DIR?.trim();if(t)return t;let r=process.env.OPENCLAW_CONFIG_PATH?.trim();return r?f0(r):j2(n,".openclaw")}function h0(n){let t=process.env.OPENCLAW_CONFIG_PATH?.trim();return t?t:j2(y0(n),"openclaw.json")}function Ar(n){return j2(y0(n),"extensions",q)}function kc(n){let t=$c(n);if(t.length===0)return!0;if(t.some((a)=>!mc.includes(a)))return!1;let r=j2(n,V),e=S(r);return e!==void 0&&!e.isSymbolicLink()&&e.isFile()&&gc(r,"utf-8").startsWith(at)}function Wr(n){let t=Ar(n),r=S(t);if(!r)return;if(!r.isSymbolicLink()&&r.isDirectory()&&kc(t))return;throw Error(`Refusing to modify ${t}: it does not hold a cc-safety-net managed OpenClaw plugin. Move or remove it, then run the command again.`)}function w0(){let n=f0(Dc(import.meta.url));return[j2(n,"..",b0),j2(n,"..","..","..","dist",b0)]}function Rr(n=w0()){return n.find((t)=>wc(t)&&xc(t).isDirectory())}function qc(n=w0()){let t=Rr(n);if(!t)throw Error("Packaged OpenClaw plugin directory not found. Reinstall cc-safety-net and try again.");return t}function x0(n=qc()){return[["openclaw","plugins","install",n,"--force"],["openclaw","plugins","enable",q]]}function jc(n){let t=(()=>{try{return JSON.parse(n)}catch{return}})(),r=$($(t,"plugin"),"status");return typeof r==="string"?r:void 0}async function $0(){let n=jc(await r2(["openclaw","plugins","inspect",q,"--runtime","--json"],{stdoutOnly:!0}));if(n==="loaded")return;throw Error(`${n===void 0?`The ${q} plugin's load state could not be verified: OpenClaw's runtime inspect report was unreadable.`:`OpenClaw reports the ${q} plugin with status "${n}".`} Run \`openclaw plugins inspect ${q} --runtime\` for details.`)}var lt="openclaw",zn=`run \`openclaw plugins enable ${q}\``;function nn(n,t){let r=Bn(n,t),e=S(r);if(!e)return{error:`${t} is missing from ${r}; run install --openclaw`};if(e.isSymbolicLink()||!e.isFile())return{error:`${r} is a symlink or not a regular file; move or remove it`};try{return{content:D0(r,"utf-8")}}catch(a){return{error:`Failed to read ${r}: ${a instanceof Error?a.message:String(a)}`}}}function m0(n){try{return JSON.parse(R(n))}catch{return}}function Fc(n){let t=nn(n,I2);if("error"in t)return t.error;if($(m0(t.content),"id")===q)return;return`${Bn(n,I2)} is not a valid ${q} manifest; run install --openclaw`}function zc(n){let t=nn(n,N2);if("error"in t)return t.error;let r=$($(m0(t.content),"openclaw"),"extensions");if(Array.isArray(r)&&r.includes(`./${V}`))return;return`${Bn(n,N2)} does not point OpenClaw at ${V}; run install --openclaw`}function g0(n){return Array.isArray(n)?n.filter((t)=>typeof t==="string"):[]}function Bc(n){let t=h0(n);if(!S(t))return`${q} is not enabled; ${zn}`;let r=(()=>{try{return JSON.parse(R(D0(t,"utf-8")))}catch{return}})();if(r===void 0)return`Failed to read ${t}; fix it, then ${zn}`;let e=$(r,"plugins");if($(e,"enabled")===!1)return`plugins.enabled is false in ${t}; no OpenClaw plugin loads`;let a=$($($(e,"entries"),q),"enabled");if(g0($(e,"deny")).includes(q)||a===!1)return`${q} is disabled in ${t}; ${zn}`;let l=g0($(e,"allow"));if(l.length>0&&!l.includes(q))return`plugins.allow in ${t} does not list ${q}; add it, then ${zn}`;if(l.includes(q)||a===!0)return;return`${q} is not enabled; ${zn}`}function k0(n){return/^\/\/ version:\s*(.+)$/m.exec(n)?.[1]?.trim()}function Jc(n,t,r){if(r===void 0)return[];let e=nn(r,V);if("error"in e||k0(e.content)!==t)return[];return[V,I2,N2].flatMap((a)=>{let l=nn(n,a),d=nn(r,a);if("error"in l||"error"in d||l.content===d.content)return[];return[`Modified ${a} occupies ${Bn(n,a)}; run install --openclaw to restore it`]})}function q0(n){let t=Ar(n.homeDir),r=En(lt,t);if(r)return r;let e=nn(t,V),l=["error"in e?e.error:e.content.startsWith(at)?void 0:`Unmanaged ${V} occupies ${Bn(t,V)}; move or remove it`,Fc(t),zc(t)].filter((i)=>i!==void 0),d="content"in e?k0(e.content):void 0,s=l.length>0?l:Jc(t,d,Rr());if(s.length>0)return{platform:lt,status:"n/a",configPath:t,errors:s};let L=d===j()?[]:["Installed OpenClaw plugin is outdated; run install --openclaw to update"],c=Bc(n.homeDir);if(c)return{platform:lt,status:"disabled",method:"plugin directory",configPath:t,errors:[c,...L]};return{platform:lt,status:"configured",method:"plugin directory",configPath:t,errors:L.length>0?L:void 0}}import{existsSync as Zc,readFileSync as Qc}from"node:fs";import{join as j0}from"node:path";function F0(n){let t=[],r=j0(n.homeDir,".config","opencode"),e=["opencode.json","opencode.jsonc"];for(let a of e){let l=j0(r,a);if(Zc(l))try{let d=Qc(l,"utf-8"),s=R(d);if((JSON.parse(s).plugin??[]).some((u)=>u.includes("cc-safety-net")))return{platform:"opencode",status:"configured",method:"plugin array",configPath:l,errors:t.length>0?t:void 0}}catch(d){t.push(`Failed to parse ${a}: ${d instanceof Error?d.message:String(d)}`)}}return{platform:"opencode",status:"n/a",errors:t.length>0?t:void 0}}import{join as Xc}from"node:path";function Kr(n){return Xc(n,".pi","agent","settings.json")}function Mr(n){if(typeof n!=="string")return!1;return n==="npm:cc-safety-net"||n.startsWith("npm:cc-safety-net@")}function z0(n){let t=Kr(n.homeDir),r=n2(t);if(r.kind==="unreadable")return{platform:"pi",status:"not-inspected"};if(r.kind==="missing")return{platform:"pi",status:"n/a"};let e=$(r.value,"packages");if(!Array.isArray(e))return{platform:"pi",status:"n/a"};let a=e.find((s)=>Mr(typeof s==="string"?s:$(s,"source")));if(a===void 0)return{platform:"pi",status:"n/a"};let l=$(a,"extensions");if(Array.isArray(l)&&l.some((s)=>typeof s==="string"&&s.startsWith("-")))return{platform:"pi",status:"disabled",method:"package config",configPath:t,errors:["npm:cc-safety-net is installed but its extension is disabled in Pi settings"]};return{platform:"pi",status:"configured",method:"package config",configPath:t}}var Sc={amp:Fa,"antigravity-cli":za,"claude-code":Qa,codex:Xa,"copilot-cli":Ca,cursor:Na,"gemini-cli":n0,"hermes-agent":u0,"kimi-code":Fn,openclaw:q0,opencode:F0,pi:z0};function tn(n,t){let r={...t,cwd:n,homeDir:t?.homeDir??Yc()};return je.map((e)=>Hc(Sc[e](r)))}function Hc(n){if(n.status==="not-inspected")return{platform:n.platform,detected:!1,configured:!1,inspectionStatus:"not-inspected"};return{platform:n.platform,detected:n.status!=="n/a",configured:n.status==="configured",inspectionStatus:n.status!=="n/a"?"verified":n.errors&&n.errors.length>0?"failed":"not-applicable",method:n.method,configPath:n.configPath,configPaths:n.configPaths,errors:n.errors}}import{tmpdir as Ac}from"node:os";import{join as Wc}from"node:path";var Rc=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}]),Kc=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([])})})}),Mc={strict:!1,paranoidRm:!1,paranoidInterpreters:!1,worktreeMode:!1,effectiveLevel:"standard",capabilities:{fail_closed:{enabled:!1,source:"preset",sources:[]},paranoid_rm:{enabled:!1,source:"preset",sources:[]},paranoid_interpreters:{enabled:!1,source:"preset",sources:[]}},sources:{failClosed:[],paranoidRm:[],paranoidInterpreters:[],worktreeMode:[]}};function B0(){let n=Wc(Ac(),"cc-safety-net-self-test"),t=Rc.map((r)=>{let e=Kn(M2("self-test",{command:r.command},{kind:"command",shell:"auto"},{configCwd:n,executionCwd:n},r.command),{guard:{dependencies:{loadPolicySnapshot:()=>Kc,getModes:()=>Mc,findPolicyMutation:()=>null}},audit:{agent:"self-test",getSessionId:()=>{return}}}),a=r.expectBlocked?"blocked":"allowed",l=e.decision.kind==="deny"?"blocked":"allowed";return{command:r.command,description:r.description,expected:a,actual:l,passed:a===l,reason:e.decision.kind==="deny"?e.decision.reason:void 0,ruleId:e.decision.kind==="deny"?e.decision.ruleId:void 0}});return{passed:t.filter((r)=>r.passed).length,failed:t.filter((r)=>!r.passed).length,total:t.length,results:t}}function Vr(n){let t=F({label:"doctor",booleans:{json:["--json"],skipUpdateCheck:["--skip-update-check"]}},n);if(e2(t.errors))return null;return{json:t.flags.json,skipUpdateCheck:t.flags.skipUpdateCheck}}async function J0(n={}){let t=await Dn(!n.json,()=>{let r=Vc(n);return{ready:r,finish:()=>r}},()=>gn(),{loadingMessage:"Checking system status…"});if(n.json)console.log(JSON.stringify(t,null,2));else Cc(t);return Gc(t.hooks,t.engineSelfTest,{userConfig:t.userConfig,projectConfig:t.projectConfig})?1:0}async function Vc(n){let t=n.cwd??process.cwd(),r=await xn(),e=tn(t,{ampPluginListOutput:r.ampPluginListOutput,codexPluginListOutput:r.codexPluginListOutput,copilotCliVersion:r.copilotCliVersion}),a=Ie(t),l=Ne(),d=W({cwd:t}),s=d.policy,L=d2(s),c=g2(s,L.capabilities),i=Cn(7),u=n.skipUpdateCheck?{currentVersion:j(),latestVersion:null,updateAvailable:!1}:await E2(),o={hooks:e,engineSelfTest:B0(),userConfig:a.userConfig,projectConfig:a.projectConfig,configState:fn(d),effectiveRules:a.effectiveRules,shadowedRules:a.shadowedRules,environment:l,effectiveSafety:{selectedPreset:s.safety.level??"standard",level:L.effectiveLevel,capabilities:L.capabilities,ruleOverrides:s.destructiveCommandRuleOverrides,weakenedRuleOverrides:Object.entries(c).filter(([,p])=>p.source==="rule_override"&&p.override==="off"&&p.inheritedEnabled&&p.changesInherited).map(([p])=>p),ruleCounts:{stored:Object.keys(s.destructiveCommandRuleOverrides).length,effective:Object.values(c).filter((p)=>p.changesInherited).length}},posture:va(a.userConfig.path),activity:i,update:u,system:r};return{...o,findings:ta(o)}}function Gc(n,t,r){return n.length>0&&n.every((e)=>!e.configured)||n.some((e)=>e.inspectionStatus==="failed")||t.failed>0||r.userConfig.exists&&!r.userConfig.valid||r.projectConfig.exists&&!r.projectConfig.valid}function Cc(n){console.log(),console.log(ea(n.hooks)),console.log(),console.log(aa(n.engineSelfTest)),console.log(),console.log(la(n)),console.log(),console.log(da(n.environment)),console.log(),console.log(sa(n)),console.log(),console.log(La(n.findings)),console.log(),console.log(ca(n.activity)),console.log(),console.log(pa(n.system)),console.log(),console.log(ia(n.update)),console.log(ua(n))}import{existsSync as Uc}from"node:fs";var Oc=/^[A-Za-z0-9_@%+=:,./-]+$/,Z0="Usage: cc-safety-net explain [--json] [--cwd <path>] <command>";function Gr(n){let t=F({label:"explain",booleans:{json:["--json"]},values:{cwd:["--cwd"]},positionals:"tail"},n);if(e2(t.errors))return console.error(Z0),console.error("Pass -- before a command that starts with dashes."),null;if(t.values.cwd!==void 0&&!Uc(t.values.cwd))return console.error(`Error: --cwd path does not exist: ${t.values.cwd}`),null;let r=t.positionals.length===1?t.positionals[0]:t.positionals.map((e)=>Oc.test(e)?e:`'${e.replaceAll("'","'\\''")}'`).join(" ");if(!r)return console.error("Error: No command provided"),console.error(Z0),null;return{json:t.flags.json,cwd:t.values.cwd,command:r}}function Q0(n){if(n)return{dh:"=",dv:"|",dtl:"+",dtr:"+",dbl:"+",dbr:"+",h:"-",v:"|",tl:"+",tr:"+",bl:"+",br:"+",sh:"="};return{dh:"═",dv:"║",dtl:"╔",dtr:"╗",dbl:"╚",dbr:"╝",h:"─",v:"│",tl:"┌",tr:"┐",bl:"└",br:"┘",sh:"━"}}function X0(n,t){let e=t-18;return[`${n.dtl}${n.dh.repeat(t)}${n.dtr}`,`${n.dv} Command Analysis${" ".repeat(e)}${n.dv}`,`${n.dbl}${n.dh.repeat(t)}${n.dbr}`]}function Cr(n){return JSON.stringify(n)}function Y0(n,t=0){return`[${n.map((e,a)=>ra(e,a,t)).join(",")}]`}function dt(n,t,r=70){let e=n.split(" "),a=[],l="";for(let d of e)if(l&&l.length+d.length+1>r)a.push(l),l=d;else l=l?`${l} ${d}`:d;if(l)a.push(l);return a.map((d,s)=>s===0?d:`${t}${d}`)}function S0(n,t,r){let e=[];switch(n.type){case"parse":return null;case"env-strip":{e.push(""),e.push(`STEP ${t} ${r.h} Strip environment variables`);let a=Object.keys(n.envVars);return e.push(` Removed: ${a.map((l)=>`${l}=<redacted>`).join(", ")}`),e.push(` Tokens: ${Cr(n.output)}`),{lines:e,incrementStep:!0}}case"leading-tokens-stripped":return e.push(""),e.push(`STEP ${t} ${r.h} Strip wrappers`),e.push(` Removed: ${n.removed.join(", ")}`),e.push(` Tokens: ${Cr(n.output)}`),{lines:e,incrementStep:!0};case"shell-wrapper":return e.push(""),e.push(`STEP ${t} ${r.h} Detect shell wrapper`),e.push(` Wrapper: ${n.wrapper} -c`),e.push(` Inner: ${n.innerCommand}`),{lines:e,incrementStep:!0};case"interpreter":{if(e.push(""),e.push(`STEP ${t} ${r.h} Detect interpreter`),e.push(` Interpreter: ${n.interpreter}`),e.push(` Code: ${n.codeArg}`),n.paranoidBlocked)e.push(" Result: ✗ BLOCKED (paranoid mode)");return{lines:e,incrementStep:!0}}case"busybox":return e.push(""),e.push(`STEP ${t} ${r.h} Busybox wrapper`),e.push(` Subcommand: ${n.subcommand}`),{lines:e,incrementStep:!0};case"transparent-wrapper":return e.push(""),e.push(`STEP ${t} ${r.h} Transparent wrapper`),e.push(` Wrapper: ${n.wrapper}`),e.push(` Tokens: ${Cr(n.output)}`),{lines:e,incrementStep:!0};case"recurse":return{lines:[],incrementStep:!1};case"rule-check":{e.push(""),e.push(`STEP ${t} ${r.h} Match rules`);let a=`${n.ruleModule}:${n.ruleFunction}()`;if(e.push(` Rule: ${a}`),n.matched)e.push(" Result: MATCHED");else e.push(" Result: No match");return{lines:e,incrementStep:!0}}case"worktree-relaxation":return e.push(""),e.push(`STEP ${t} ${r.h} Worktree relaxation`),e.push(` Mode: ${m.worktree.name}`),e.push(` Git cwd: ${n.gitCwd}`),e.push(" Result: Allowed local discard in linked worktree"),{lines:e,incrementStep:!0};case"tmpdir-check":return null;case"fallback-scan":{if(n.embeddedCommandFound)return e.push(""),e.push(`STEP ${t} ${r.h} Fallback scan`),e.push(` Found: ${n.embeddedCommandFound}`),{lines:e,incrementStep:!0};return null}case"custom-rules-check":{if(n.rulesChecked){if(e.push(""),e.push(`STEP ${t} ${r.h} Custom rules`),n.matched)e.push(" Result: MATCHED");else e.push(" Result: No match");return{lines:e,incrementStep:!0}}return null}case"cwd-change":return null;case"dangerous-text":{if(n.matched)return e.push(""),e.push(`STEP ${t} ${r.h} Dangerous text check`),e.push(` Token: ${n.token}`),e.push(" Result: MATCHED"),{lines:e,incrementStep:!0};return null}case"strict-unparseable":return e.push(""),e.push(`STEP ${t} ${r.h} Strict mode check`),e.push(` Command: ${n.rawCommand}`),e.push(" Result: ✗ UNPARSEABLE"),{lines:e,incrementStep:!0};case"segment-skipped":return null;case"error":return e.push(""),e.push(`ERROR: ${n.message}`),{lines:e,incrementStep:!1};default:return null}}function Ur(n,t){let r=Q0(t?.asciiOnly??!1),e=58,a=[],l=1;a.push(...X0(r,58)),a.push("");let d=n.trace.steps.find((p)=>p.type==="error");if(d&&d.type==="error"){a.push("ERROR"),a.push(` ${d.message}`),a.push(""),a.push("RESULT"),a.push(` Status: ${n.result==="blocked"?b.red("BLOCKED"):b.green("ALLOWED")}`),a.push(""),a.push("CONFIG");let p=n.configSource??"none";return a.push(` Path: ${p}`),a.join(`
177
+ `)}let s=n.trace.steps.find((p)=>p.type==="parse");if(s&&s.type==="parse"){a.push("INPUT"),a.push(` ${s.input}`),a.push(""),a.push(`STEP ${l} ${r.h} Split shell commands`),l++;for(let p=0;p<s.segments.length;p++){let f=s.segments[p];if(f){let v=Math.random();a.push(` Segment ${p+1}: ${Y0(f,v)}`)}}}let L=n.trace.segments,c=L.length>1;for(let p of L){if(c){a.push("");let x="";if(s&&s.type==="parse"){let Ft=s.segments[p.index];if(Ft)x=Ft.join(" ")}let w=54,h=x,J=` Segment ${p.index+1}: `,Z2=" ";if(x){if(J.length+x.length+Z2.length>w){let X3=w-J.length-Z2.length;h=`${x.substring(0,X3-1)}…`}}let ln=x?`${J}${h}${Z2}`:` Segment ${p.index+1} `,jt=x?`${J}${b.cyan(h)}${Z2}`:ln,w1=58-ln.length,x1=Math.floor(w1/2),Q3=w1-x1;a.push(`${r.sh.repeat(x1)}${jt}${r.sh.repeat(Q3)}`)}if(p.steps.find((x)=>x.type==="segment-skipped")){a.push(""),a.push(" (skipped — prior segment blocked)");continue}let v=!1,y=!1;for(let x of p.steps){let w=S0(x,l,r);if(w){if(y=!0,x.type==="recurse"){a.push("");let h=" RECURSING ",J=58-h.length-4;a.push(` ${r.tl}${r.h}${h}${r.h.repeat(J)}`),a.push(` ${r.v}`),v=!0;continue}for(let h of w.lines)if(v)a.push(` ${r.v} ${h}`);else a.push(h);if(w.incrementStep)l++}}if(v)a.push(` ${r.v}`),a.push(` ${r.bl}${r.h.repeat(56)}`),v=!1;if(!y)a.push(""),a.push(` ${b.green("✓")} Allowed (no matching rules)`)}if(a.push(""),a.push("RESULT"),n.result==="blocked"){if(a.push(` Status: ${b.red("BLOCKED")}`),n.customRule){if(a.push(` Rule: ${n.customRule.id}`),n.customRule.rulebook)a.push(` Rulebook: ${n.customRule.rulebook.name} ${n.customRule.rulebook.version}`);if(n.customRule.source)a.push(` Source: ${n.customRule.source}`);if(n.customRule.override)a.push(` Override: reason ${n.customRule.override.reason}`)}if(n.reason){let p=dt(n.reason," ");a.push(` Reason: ${p[0]}`);for(let f=1;f<p.length;f++)a.push(p[f]??"")}}else a.push(` Status: ${b.green("ALLOWED")}`);a.push(""),a.push("CONFIG");let i=n.configSource??"none",u=n.configValid?"":" (invalid)";a.push(` Path: ${i}${u}`),a.push(` Safety preset: ${n.selectedPreset??"standard"}`),a.push(` Effective capabilities: ${n.effectiveLevel}`);let o=Object.entries(n.destructiveCommandRuleOverrides??{});if(a.push(` Rule customizations: ${o.length}`),n.ruleActivation)a.push(` Rule activation: ${n.ruleActivation.id} — ${n.ruleActivation.enabled?"on":"off"} via ${n.ruleActivation.source}`);return a.join(`
178
+ `)}function Or(n){return JSON.stringify(n,null,2)}var H0="2.0.5",G=" ",F2="cc-safety-net";function A0(n){return n.argument?`${n.flags} ${n.argument}`:n.flags}function Tc(n){return Math.max(...n.map((t)=>A0(t).length))}function _c(n){return Math.max(...n.map((t)=>t.usage.length))}function Ec(n){return Math.max(...n.map((t)=>`${F2} ${t.usage}`.length))}function Pc(n,t){let r=`${F2} ${n.usage}`;return`${G}${r.padEnd(t+2)}${n.description}`}function i2(n,t){return`${G}${n.padEnd(Math.max(40,n.length+2))}${t}`}function st(n,t=console.log){let r=[];if(r.push(`${F2} ${n.name}`),r.push(""),r.push(`${G}${n.description}`),r.push(""),r.push("USAGE:"),r.push(`${G}${F2} ${n.usage}`),r.push(""),n.subcommands&&n.subcommands.length>0){r.push("SUBCOMMANDS:");let e=_c(n.subcommands);for(let a of n.subcommands)r.push(`${G}${a.usage.padEnd(e+2)}${a.description}`);r.push("")}if(n.options.length>0){r.push("OPTIONS:");let e=Tc(n.options);for(let a of n.options){let l=A0(a),d=a.default?`${a.description} (default: ${a.default})`:a.description;r.push(`${G}${l.padEnd(e+2)}${d}`)}r.push("")}if(n.examples&&n.examples.length>0){r.push("EXAMPLES:");for(let e of n.examples)r.push(`${G}${e}`)}t(r.join(`
179
+ `))}function Tr(){let n=Ee(),t=Ec(n),r=[];r.push(`${F2} v${H0}`),r.push(""),r.push("Blocks destructive commands and secret access."),r.push(""),r.push("COMMANDS:");for(let e of n)r.push(Pc(e,t));r.push(""),r.push("GLOBAL OPTIONS:"),r.push(`${G}-h, --help Show help (use with command for command-specific help)`),r.push(`${G}-V, --version Show version`),r.push(""),r.push("HELP:"),r.push(`${G}${F2} help <command> Show help for a specific command`),r.push(`${G}${F2} <command> --help Show help for a specific command`),r.push(""),r.push("ENVIRONMENT VARIABLES:"),r.push(i2(`${m.level.name}=standard|strict|paranoid`,"Set session safety level")),r.push(i2(`${m.worktree.name}=1`,"Allow local git discards in linked worktrees")),r.push(i2(`${m.debug.name}=1`,"Print diagnostic messages to stderr")),r.push(i2(`${m.auditScope.name}=all|blocked`,"Record all command decisions, or denials only")),r.push(i2("CC_SAFETY_NET_HOME","Override rule config home directory")),r.push(""),r.push("LEGACY ENVIRONMENT VARIABLES (STILL SUPPORTED):"),r.push(i2(`${m.strict.name}=1`,"Force safety.overrides.fail_closed on")),r.push(i2(`${m.paranoid.name}=1`,"Force paranoid_rm and paranoid_interpreters on")),r.push(i2(`${m.paranoidRm.name}=1`,"Force safety.overrides.paranoid_rm on")),r.push(i2(`${m.paranoidInterpreters.name}=1`,"Force safety.overrides.paranoid_interpreters on")),r.push(""),r.push("Documentation: https://ccsafetynet.com/docs"),console.log(r.join(`
180
+ `))}function W0(){console.log(H0)}function Jn(n,t=console.log){let r=Gn(n);if(!r)return!1;if(r.hidden||r.name.toLowerCase()!==n.toLowerCase())return!1;return st(r,t),!0}import{existsSync as c1,readFileSync as Ml}from"node:fs";import{homedir as Ei}from"node:os";import{join as s1}from"node:path";import*as y2 from"node:readline";function Ic(n){return n==="install"?"Install":"Uninstall"}function Nc(n){return n==="install"?"Installing":"Uninstalling"}function ni(n){return n==="install"?"into":"from"}function M0(n){return n?.available===!0}function ti(n,t){let r=new Set(t);return n.filter((e)=>r.has(e.target)).map((e)=>e.target)}function R0(n,t,r){if(n.length===0||n.every((e)=>!e.available))return t;return Array.from({length:n.length},(e,a)=>a+1).map((e)=>(t+e*r+n.length)%n.length).find((e)=>M0(n[e]))}function ri(n,t,r){if(r.ctrl&&r.name==="c")return"interrupt";if(r.name==="escape"||t==="q")return"abort";if(n==="install"&&(t==="u"||t==="U"))return"update";if(r.name==="up"||t==="k")return"up";if(r.name==="down"||t==="j")return"down";if(r.name==="space"||t===" ")return"toggle";if(r.name==="return"||r.name==="enter")return"confirm";return null}function ei(n){return{cursor:n.findIndex((t)=>t.available),selected:[]}}function ai(n,t,r){if(r==="confirm"||r==="update"||r==="abort"||r==="interrupt")return{state:n,done:r};if(r==="up")return{state:{...n,cursor:R0(t,n.cursor,-1)}};if(r==="down")return{state:{...n,cursor:R0(t,n.cursor,1)}};let e=t[n.cursor];if(!M0(e))return{state:n};let a=n.selected.includes(e.target)?n.selected.filter((l)=>l!==e.target):ti(t,[...n.selected,e.target]);return{state:{...n,selected:a}}}var V0="◉",G0="◯",C0=">",U0=" ";function li(n,t,r,e={}){let a=e.color!==!1,l=a?b.dim:(L)=>L,d=a?b.green:(L)=>L,s=a?b.bold:(L)=>L;return["",`${Ic(n)} CC Safety Net ${ni(n)}:`,"",...t.map((L,c)=>{let i=r.selected.includes(L.target),u=c===r.cursor,o=i?V0:G0,p=u?C0:U0,f=L.available?"":` (${L.unavailableReason??"not installed"})`,v=`${o} ${L.label}${f}`,y=!L.available?l(v):i?d(v):u?s(v):v;return`${p} ${y}`}),"",n==="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 ${n}. q/Esc: close`].join(`
181
+ `)}var K0=["global-hook","plugin"];function di(n,t,r={}){let e=r.color!==!1?b.bold:(l)=>l;return["","Install the Kimi Code integration as:","",...[`Global hook — ${t?"already installed; selecting it reports the current state":"write the hook into ~/.kimi-code/config.toml now"}`,"Native Kimi plugin — print the steps to run inside Kimi Code"].map((l,d)=>{let s=d===n,L=`${s?V0:G0} ${l}`;return`${s?C0:U0} ${s?e(L):L}`}),"","Enter: confirm Up/Down: move q/Esc: cancel"].join(`
182
182
  `)}function O0(n){let{input:t,output:r}=n;y2.emitKeypressEvents(t);let e=t.isRaw===!0;t.setRawMode(!0),t.resume();let a=0,l=()=>{if(a===0)return;y2.moveCursor(r,0,-a),y2.cursorTo(r,0),y2.clearScreenDown(r)},d=()=>{l();let s=n.render();r.write(`${s}
183
183
  `),a=s.split(`
184
- `).length};return new Promise((s)=>{let c=(i)=>{t.off("keypress",L),t.setRawMode(e),t.pause(),l(),s(i)};function L(i,u){n.onKey(i,u,{finish:c,draw:d})}t.on("keypress",L),d()})}function T0(n={}){let t=0;return O0({input:n.input??process.stdin,output:n.output??process.stdout,render:()=>li(t,n.globalHookInstalled===!0),onKey:(r,e,a)=>{if(e.ctrl&&e.name==="c"){a.finish(null),(n.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(e.name==="escape"||r==="q")return a.finish(null);if(e.name==="return"||e.name==="enter")return a.finish(V0[t]);if(e.name==="up"||e.name==="down"||r==="k"||r==="j")t=(t+1)%V0.length,a.draw()}})}function Ur(n=process.stdin,t=process.stdout){return Boolean(n.isTTY&&t.isTTY&&typeof n.setRawMode==="function")}function E0(n,t,r={}){let e=r.output??process.stdout,a=ri(t);return O0({input:r.input??process.stdin,output:e,render:()=>ai(n,t,a),onKey:(l,d,s)=>{let c=ti(n,l,d);if(!c)return;let L=ei(a,t,c);if(a=L.state,L.done==="interrupt"){s.finish(null),(r.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(L.done==="abort")return s.finish(null);if(L.done==="update")return s.finish("update");if(L.done==="confirm"){if(a.selected.length===0){e.write("\x07"),s.draw();return}s.finish([...a.selected]),e.write(`${NL(n)} selected integrations...
185
- `);return}s.draw()}})}import{existsSync as P0,lstatSync as N0,mkdtempSync as si,readFileSync as Lt,rmSync as I0}from"node:fs";import{tmpdir as ci}from"node:os";import{dirname as Li,join as z2}from"node:path";import{fileURLToPath as ii}from"node:url";var Or="// cc-safety-net managed Amp plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --amp";import{spawn as di}from"node:child_process";var Tr=(n,t)=>{let r=f2([...n],process.env);return new Promise((e)=>{let a=di(r.cmd,r.args,{cwd:t,stdio:["ignore","pipe","pipe"]}),l=Qr(a),d=!1,s=setTimeout(()=>{d=!0,a.kill()},120000);a.on("error",(c)=>{clearTimeout(s),e({status:null,errorCode:c.code,stdout:l.stdout,stderr:[c.message,l.stderr].filter(Boolean).join(`
186
- `)})}),a.on("close",(c)=>{clearTimeout(s),e({status:d?null:c,errorCode:d?"ETIMEDOUT":void 0,stdout:l.stdout,stderr:l.stderr})})})};var _0=z2("amp","cc-safety-net.ts"),p2="cc-safety-net.ts";function pi(n){return z2(n,".config","amp","plugins",p2)}function ui(){let n=Li(ii(import.meta.url));return[z2(n,"..",_0),z2(n,"..","..","..","dist",_0)]}function oi(n=ui()){let t=n.find((r)=>P0(r)&&N0(r).isFile());if(!t)throw Error("Packaged Amp plugin artifact not found. Reinstall cc-safety-net and try again.");return t}function nl(n){try{return N0(n)}catch{return}}function tl(n){try{return JSON.parse(n)}catch{return}}function rl(n){return n.subarray(0,Buffer.byteLength(Or)).toString("utf-8")===Or}async function Bn(n,t,r){let e=await n(t,r);if(e.status===0)return e;throw Error([`Failed to run ${t.join(" ")}${e.status===null?"":` (exit ${e.status})`}.`,[e.stdout,e.stderr].filter(Boolean).join(`
184
+ `).length};return new Promise((s)=>{let L=(i)=>{t.off("keypress",c),t.setRawMode(e),t.pause(),l(),s(i)};function c(i,u){n.onKey(i,u,{finish:L,draw:d})}t.on("keypress",c),d()})}function T0(n={}){let t=0;return O0({input:n.input??process.stdin,output:n.output??process.stdout,render:()=>di(t,n.globalHookInstalled===!0),onKey:(r,e,a)=>{if(e.ctrl&&e.name==="c"){a.finish(null),(n.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(e.name==="escape"||r==="q")return a.finish(null);if(e.name==="return"||e.name==="enter")return a.finish(K0[t]);if(e.name==="up"||e.name==="down"||r==="k"||r==="j")t=(t+1)%K0.length,a.draw()}})}function _r(n=process.stdin,t=process.stdout){return Boolean(n.isTTY&&t.isTTY&&typeof n.setRawMode==="function")}function _0(n,t,r={}){let e=r.output??process.stdout,a=ei(t);return O0({input:r.input??process.stdin,output:e,render:()=>li(n,t,a),onKey:(l,d,s)=>{let L=ri(n,l,d);if(!L)return;let c=ai(a,t,L);if(a=c.state,c.done==="interrupt"){s.finish(null),(r.onInterrupt??(()=>process.kill(process.pid,"SIGINT")))();return}if(c.done==="abort")return s.finish(null);if(c.done==="update")return s.finish("update");if(c.done==="confirm"){if(a.selected.length===0){e.write("\x07"),s.draw();return}s.finish([...a.selected]),e.write(`${Nc(n)} selected integrations...
185
+ `);return}s.draw()}})}import{existsSync as P0,lstatSync as I0,mkdtempSync as Li,readFileSync as it,rmSync as N0}from"node:fs";import{tmpdir as ci}from"node:os";import{dirname as ii,join as z2}from"node:path";import{fileURLToPath as pi}from"node:url";var Er="// cc-safety-net managed Amp plugin. Do not edit. Reinstall with: npx -y cc-safety-net install --amp";import{spawn as si}from"node:child_process";var Pr=(n,t)=>{let r=f2([...n],process.env);return new Promise((e)=>{let a=si(r.cmd,r.args,{cwd:t,stdio:["ignore","pipe","pipe"]}),l=Sr(a),d=!1,s=setTimeout(()=>{d=!0,a.kill()},120000);a.on("error",(L)=>{clearTimeout(s),e({status:null,errorCode:L.code,stdout:l.stdout,stderr:[L.message,l.stderr].filter(Boolean).join(`
186
+ `)})}),a.on("close",(L)=>{clearTimeout(s),e({status:d?null:L,errorCode:d?"ETIMEDOUT":void 0,stdout:l.stdout,stderr:l.stderr})})})};var E0=z2("amp","cc-safety-net.ts"),p2="cc-safety-net.ts";function ui(n){return z2(n,".config","amp","plugins",p2)}function vi(){let n=ii(pi(import.meta.url));return[z2(n,"..",E0),z2(n,"..","..","..","dist",E0)]}function oi(n=vi()){let t=n.find((r)=>P0(r)&&I0(r).isFile());if(!t)throw Error("Packaged Amp plugin artifact not found. Reinstall cc-safety-net and try again.");return t}function nl(n){try{return I0(n)}catch{return}}function tl(n){try{return JSON.parse(n)}catch{return}}function rl(n){return n.subarray(0,Buffer.byteLength(Er)).toString("utf-8")===Er}async function Zn(n,t,r){let e=await n(t,r);if(e.status===0)return e;throw Error([`Failed to run ${t.join(" ")}${e.status===null?"":` (exit ${e.status})`}.`,[e.stdout,e.stderr].filter(Boolean).join(`
187
187
  `).trim()].filter(Boolean).join(`
188
188
  `))}async function el(n){let t=await n(["amp","plugins","repositories","--json"]);if(t.status===null)throw Error(`${t.errorCode==="ENOENT"?'Amp CLI not found. Install the amp CLI, sign in with "amp login", and rerun install --amp.':`amp plugins repositories --json did not finish (${t.errorCode??"terminated"}). Check that the amp CLI responds and rerun install --amp.`}
189
189
  ${t.stderr}`.trim());if(t.status!==0)throw Error(`Failed to run amp plugins repositories --json (exit ${t.status}). Sign in with "amp login" and rerun install --amp.
190
190
  ${[t.stdout,t.stderr].filter(Boolean).join(`
191
- `)}`.trim());let r=tl(t.stdout),e=(Array.isArray(r)?r:[]).filter((a)=>$(a,"scope")==="user"&&$(a,"exists")===!0&&$(a,"viewerCanWrite")===!0).map((a)=>$(a,"cloneRef")).find((a)=>typeof a==="string"&&a.length>0);if(!e)throw Error('Your Amp account has no writable Personal Plugins repository. Sign in with "amp login", open Amp once to create it, and rerun install --amp.');return e}async function al(n,t){let r=si(z2(ci(),"cc-safety-net-amp-"));try{return await Bn(n,["amp","clone","user-plugins",r]),await t(r)}finally{I0(r,{recursive:!0,force:!0})}}function ll(n,t){let r=z2(n,p2),e=nl(r);if(!e)return;if(e.isSymbolicLink()||!e.isFile())throw Error(`Refusing to ${t} ${p2} in your Amp personal plugins repository: not a regular file. Remove it there and rerun install --amp.`);let a=Lt(r);if(rl(a))return a;throw Error(`Refusing to ${t} unmanaged file ${p2} in your Amp personal plugins repository. Remove it there and rerun install --amp.`)}async function dl(n,t,r,e){if(await Bn(n,r,t),(await Bn(n,["git","status","--porcelain"],t)).stdout.trim()==="")return!1;return await Bn(n,["git","-c","commit.gpgsign=false","-c","user.name=cc-safety-net","-c","user.email=cc-safety-net@localhost","commit","-m",e],t),await Bn(n,["git","push","origin","HEAD"],t),!0}function st(n,t){let r=pi(n),e=nl(r);if(!e)return;if(!e.isSymbolicLink()&&e.isFile()&&rl(Lt(r))){I0(r);return}if(t==="keep")return;throw Error(`Local Amp plugin ${r} is not a managed copy and masks the personal plugin. Remove it and rerun install --amp.`)}function vi(){let n=vn();if(!P0(n))return"";let t=tl(Lt(n,"utf-8"));if(!t||typeof t!=="object"||Array.isArray(t))return"";return`;globalThis.__CC_SAFETY_NET_EMBEDDED_POLICY__ = ${JSON.stringify(ct(t))};
192
- `}async function sl(n,t=oi(),r=Tr){let e=Buffer.concat([Lt(t),Buffer.from(vi(),"utf-8")]),a=await el(r);return al(r,async(l)=>{let d=`${a}/${p2}`;if(ll(l,"overwrite")?.equals(e))return st(n,"fail"),{path:d,alreadyInstalled:!0};B(z2(l,p2),e);let s=await dl(r,l,["git","add",p2],`chore: update cc-safety-net plugin to v${j()}`);return st(n,"fail"),{path:d,alreadyInstalled:!s}})}async function cl(n,t=Tr){let r=await el(t);return al(t,async(e)=>{let a=`${r}/${p2}`;if(!ll(e,"remove"))return st(n,"keep"),{path:a,alreadyInstalled:!1};return await dl(t,e,["git","rm",p2],`chore: remove cc-safety-net plugin v${j()}`),st(n,"keep"),{path:a,alreadyInstalled:!0}})}import{existsSync as Ll,mkdirSync as bi,readFileSync as fi}from"node:fs";import{dirname as yi}from"node:path";var Er="npx -y cc-safety-net hook --agy-cli",h2="cc-safety-net";function pt(){return{PreToolUse:[{hooks:[{type:"command",command:Er,timeout:30}]}]}}function il(n){try{let t=JSON.parse(fi(n,"utf-8"));if(!t||typeof t!=="object"||Array.isArray(t))throw Error("Antigravity hooks config must be a JSON object");return t}catch(t){if(t instanceof SyntaxError)throw Error(`Failed to parse Antigravity hooks config ${n}: ${t.message}`);throw t}}function pl(n){let t=n[h2];if(t===void 0)return n[h2]=pt(),n[h2];if(!t||typeof t!=="object"||Array.isArray(t))throw Error(`Antigravity hooks config entry "${h2}" must be an object`);if(!Array.isArray(t.PreToolUse))t.PreToolUse=[];return t}function ul(n){if(!Array.isArray(n.PreToolUse))return!1;return n.PreToolUse.some((t)=>Array.isArray(t.hooks)&&t.hooks.some((r)=>r.command===Er))}function hi(n){return Object.values(n).some((t)=>t.enabled!==!1&&ul(t))}function wi(n){if(n[h2]===void 0)return!1;let t=pl(n);if(t.enabled!==!1||!ul(t))return!1;return t.enabled=!0,!0}function xi(n){if(n[h2]===void 0){n[h2]=pt();return}let t=pl(n);t.PreToolUse??=[],t.enabled=!0,t.PreToolUse.push(pt().PreToolUse?.[0]??{hooks:[]})}function $i(n){let t=!1;for(let r of Object.values(n)){if(!Array.isArray(r.PreToolUse))continue;r.PreToolUse=r.PreToolUse.flatMap((e)=>{if(!Array.isArray(e.hooks))return[e];let a=e.hooks.filter((l)=>l.command!==Er);if(a.length!==e.hooks.length)t=!0;return a.length===0?[]:[{...e,hooks:a}]})}return t}function it(n,t){B(n,`${JSON.stringify(t,null,2)}
193
- `)}function ol(n){let t=gn(n);if(bi(yi(t),{recursive:!0}),!Ll(t))return it(t,{[h2]:pt()}),{path:t,alreadyInstalled:!1};let r=il(t);if(hi(r))return{path:t,alreadyInstalled:!0};if(wi(r))return it(t,r),{path:t,alreadyInstalled:!1};return xi(r),it(t,r),{path:t,alreadyInstalled:!1}}function vl(n){let t=gn(n);if(!Ll(t))return{path:t,alreadyInstalled:!1};let r=il(t);if(!$i(r))return{path:t,alreadyInstalled:!1};return it(t,r),{path:t,alreadyInstalled:!0}}import{spawn as gi,spawnSync as Di}from"node:child_process";var C=L2.map((n)=>({target:n.id,flag:n.flag,label:n.installLabel,probeCommand:n.probeCommand})),bl=new Map(C.map((n)=>[n.flag,n.target]));function _r(n){let t=new Set(n);return C.map((r)=>r.target).filter((r)=>t.has(r))}async function fl(n,t){for(let r of n)await t(r)}var yl=5000;function mi(n){let t=f2([...n],process.env),r=Di(t.cmd,t.args,{env:process.env,stdio:"ignore",timeout:yl});return!r.error&&r.status===0}function Nr(n){return new Promise((t)=>{let r=f2([...n],process.env),e=gi(r.cmd,r.args,{env:process.env,stdio:"ignore"}),a=!1,l=(s)=>{if(a)return;a=!0,clearTimeout(d),t(s)},d=setTimeout(()=>{e.kill(),l(!1)},yl);e.on("error",()=>l(!1)),e.on("close",(s)=>l(s===0))})}function ki(n=mi,t={}){let r=new Set(t.configuredTargets??[]);if(t.async)return Promise.all(C.map(async(a)=>({target:a.target,flag:a.flag,label:a.label,...Pr(t.action,await n(a.probeCommand),r.has(a.target))})));let e=n;return C.map((a)=>({target:a.target,flag:a.flag,label:a.label,...Pr(t.action,e(a.probeCommand),r.has(a.target))}))}function hl(n=Nr,t={}){return ki(n,{...t,async:!0})}function wl(n,t){let r=new Set(t.configuredTargets??[]);return n.map((e)=>({...e,...Pr(t.action,e.available,r.has(e.target))}))}function Pr(n,t,r){if(n==="uninstall")return r?{available:!0}:{available:!1,unavailableReason:"not installed"};if(n==="install"&&r)return{available:!1,unavailableReason:"already installed"};if(!t)return{available:!1,unavailableReason:"CLI not installed"};return{available:!0}}import{existsSync as xl,readdirSync as qi,rmSync as ji}from"node:fs";import{join as tn}from"node:path";function Ir(n,t=process.platform){let r=tn(process.env.npm_config_cache||(t==="win32"?tn(process.env.LOCALAPPDATA||tn(n,"AppData","Local"),"npm-cache"):tn(n,".npm")),"_npx");if(!xl(r))return;qi(r).filter((e)=>xl(tn(r,e,"node_modules","cc-safety-net"))).forEach((e)=>{ji(tn(r,e),{recursive:!0,force:!0})})}import{existsSync as ml,mkdirSync as zi,readFileSync as kl}from"node:fs";import{dirname as Bi,join as Dl}from"node:path";function $l(n){return n!==void 0&&/\s/.test(n)}function Fi(n,t,r){let e=t+1,a=!1;while(e<n.length){let l=n[e];if(a){a=!1,e++;continue}if(l==="\\"){a=!0,e++;continue}if(l==='"')return e+1;e++}throw Error(r)}function ut(n,t,r){let e=n[t],a=e==="["?"]":"}",l=0,d=t;while(d<n.length){let s=r.skipComment?.(n,d)??d;if(s!==d){d=s;continue}if(n[d]==='"'){d=Fi(n,d,r.stringError);continue}if(n[d]===e)l++;if(n[d]===a){if(l--,l===0)return d}d++}throw Error(r.bracketError)}function gl(n,t){let r=n.lastIndexOf(`
194
- `,t)+1;return/^[ \t]*/.exec(n.slice(r))?.[0]??""}function ot(n,t){let{start:r,end:e,end:a}=t;while($l(n[a]))a++;if(n[a]===","){if(e=a+1,n[e]===`
191
+ `)}`.trim());let r=tl(t.stdout),e=(Array.isArray(r)?r:[]).filter((a)=>$(a,"scope")==="user"&&$(a,"exists")===!0&&$(a,"viewerCanWrite")===!0).map((a)=>$(a,"cloneRef")).find((a)=>typeof a==="string"&&a.length>0);if(!e)throw Error('Your Amp account has no writable Personal Plugins repository. Sign in with "amp login", open Amp once to create it, and rerun install --amp.');return e}async function al(n,t){let r=Li(z2(ci(),"cc-safety-net-amp-"));try{return await Zn(n,["amp","clone","user-plugins",r]),await t(r)}finally{N0(r,{recursive:!0,force:!0})}}function ll(n,t){let r=z2(n,p2),e=nl(r);if(!e)return;if(e.isSymbolicLink()||!e.isFile())throw Error(`Refusing to ${t} ${p2} in your Amp personal plugins repository: not a regular file. Remove it there and rerun install --amp.`);let a=it(r);if(rl(a))return a;throw Error(`Refusing to ${t} unmanaged file ${p2} in your Amp personal plugins repository. Remove it there and rerun install --amp.`)}async function dl(n,t,r,e){if(await Zn(n,r,t),(await Zn(n,["git","status","--porcelain"],t)).stdout.trim()==="")return!1;return await Zn(n,["git","-c","commit.gpgsign=false","-c","user.name=cc-safety-net","-c","user.email=cc-safety-net@localhost","commit","-m",e],t),await Zn(n,["git","push","origin","HEAD"],t),!0}function Lt(n,t){let r=ui(n),e=nl(r);if(!e)return;if(!e.isSymbolicLink()&&e.isFile()&&rl(it(r))){N0(r);return}if(t==="keep")return;throw Error(`Local Amp plugin ${r} is not a managed copy and masks the personal plugin. Remove it and rerun install --amp.`)}function bi(){let n=bn();if(!P0(n))return"";let t=tl(it(n,"utf-8"));if(!t||typeof t!=="object"||Array.isArray(t))return"";return`;globalThis.__CC_SAFETY_NET_EMBEDDED_POLICY__ = ${JSON.stringify(ct(t))};
192
+ `}async function sl(n,t=oi(),r=Pr){let e=Buffer.concat([it(t),Buffer.from(bi(),"utf-8")]),a=await el(r);return al(r,async(l)=>{let d=`${a}/${p2}`;if(ll(l,"overwrite")?.equals(e))return Lt(n,"fail"),{path:d,alreadyInstalled:!0};B(z2(l,p2),e);let s=await dl(r,l,["git","add",p2],`chore: update cc-safety-net plugin to v${j()}`);return Lt(n,"fail"),{path:d,alreadyInstalled:!s}})}async function Ll(n,t=Pr){let r=await el(t);return al(t,async(e)=>{let a=`${r}/${p2}`;if(!ll(e,"remove"))return Lt(n,"keep"),{path:a,alreadyInstalled:!1};return await dl(t,e,["git","rm",p2],`chore: remove cc-safety-net plugin v${j()}`),Lt(n,"keep"),{path:a,alreadyInstalled:!0}})}import{existsSync as cl,mkdirSync as fi,readFileSync as yi}from"node:fs";import{dirname as hi}from"node:path";var Ir="npx -y cc-safety-net hook --agy-cli",h2="cc-safety-net";function ut(){return{PreToolUse:[{hooks:[{type:"command",command:Ir,timeout:30}]}]}}function il(n){try{let t=JSON.parse(yi(n,"utf-8"));if(!t||typeof t!=="object"||Array.isArray(t))throw Error("Antigravity hooks config must be a JSON object");return t}catch(t){if(t instanceof SyntaxError)throw Error(`Failed to parse Antigravity hooks config ${n}: ${t.message}`);throw t}}function pl(n){let t=n[h2];if(t===void 0)return n[h2]=ut(),n[h2];if(!t||typeof t!=="object"||Array.isArray(t))throw Error(`Antigravity hooks config entry "${h2}" must be an object`);if(!Array.isArray(t.PreToolUse))t.PreToolUse=[];return t}function ul(n){if(!Array.isArray(n.PreToolUse))return!1;return n.PreToolUse.some((t)=>Array.isArray(t.hooks)&&t.hooks.some((r)=>r.command===Ir))}function wi(n){return Object.values(n).some((t)=>t.enabled!==!1&&ul(t))}function xi(n){if(n[h2]===void 0)return!1;let t=pl(n);if(t.enabled!==!1||!ul(t))return!1;return t.enabled=!0,!0}function $i(n){if(n[h2]===void 0){n[h2]=ut();return}let t=pl(n);t.PreToolUse??=[],t.enabled=!0,t.PreToolUse.push(ut().PreToolUse?.[0]??{hooks:[]})}function gi(n){let t=!1;for(let r of Object.values(n)){if(!Array.isArray(r.PreToolUse))continue;r.PreToolUse=r.PreToolUse.flatMap((e)=>{if(!Array.isArray(e.hooks))return[e];let a=e.hooks.filter((l)=>l.command!==Ir);if(a.length!==e.hooks.length)t=!0;return a.length===0?[]:[{...e,hooks:a}]})}return t}function pt(n,t){B(n,`${JSON.stringify(t,null,2)}
193
+ `)}function vl(n){let t=mn(n);if(fi(hi(t),{recursive:!0}),!cl(t))return pt(t,{[h2]:ut()}),{path:t,alreadyInstalled:!1};let r=il(t);if(wi(r))return{path:t,alreadyInstalled:!0};if(xi(r))return pt(t,r),{path:t,alreadyInstalled:!1};return $i(r),pt(t,r),{path:t,alreadyInstalled:!1}}function ol(n){let t=mn(n);if(!cl(t))return{path:t,alreadyInstalled:!1};let r=il(t);if(!gi(r))return{path:t,alreadyInstalled:!1};return pt(t,r),{path:t,alreadyInstalled:!0}}import{spawn as Di,spawnSync as mi}from"node:child_process";var C=c2.map((n)=>({target:n.id,flag:n.flag,label:n.installLabel,probeCommand:n.probeCommand})),bl=new Map(C.map((n)=>[n.flag,n.target]));function Nr(n){let t=new Set(n);return C.map((r)=>r.target).filter((r)=>t.has(r))}async function fl(n,t){for(let r of n)await t(r)}var yl=5000;function ki(n){let t=f2([...n],process.env),r=mi(t.cmd,t.args,{env:process.env,stdio:"ignore",timeout:yl});return!r.error&&r.status===0}function t1(n){return new Promise((t)=>{let r=f2([...n],process.env),e=Di(r.cmd,r.args,{env:process.env,stdio:"ignore"}),a=!1,l=(s)=>{if(a)return;a=!0,clearTimeout(d),t(s)},d=setTimeout(()=>{e.kill(),l(!1)},yl);e.on("error",()=>l(!1)),e.on("close",(s)=>l(s===0))})}function qi(n=ki,t={}){let r=new Set(t.configuredTargets??[]);if(t.async)return Promise.all(C.map(async(a)=>({target:a.target,flag:a.flag,label:a.label,...n1(t.action,await n(a.probeCommand),r.has(a.target))})));let e=n;return C.map((a)=>({target:a.target,flag:a.flag,label:a.label,...n1(t.action,e(a.probeCommand),r.has(a.target))}))}function hl(n=t1,t={}){return qi(n,{...t,async:!0})}function wl(n,t){let r=new Set(t.configuredTargets??[]);return n.map((e)=>({...e,...n1(t.action,e.available,r.has(e.target))}))}function n1(n,t,r){if(n==="uninstall")return r?{available:!0}:{available:!1,unavailableReason:"not installed"};if(n==="install"&&r)return{available:!1,unavailableReason:"already installed"};if(!t)return{available:!1,unavailableReason:"CLI not installed"};return{available:!0}}import{existsSync as xl,readdirSync as ji,rmSync as Fi}from"node:fs";import{join as rn}from"node:path";function vt(n,t=process.platform){let r=rn(process.env.npm_config_cache||(t==="win32"?rn(process.env.LOCALAPPDATA||rn(n,"AppData","Local"),"npm-cache"):rn(n,".npm")),"_npx");if(!xl(r))return;ji(r).filter((e)=>xl(rn(r,e,"node_modules","cc-safety-net"))).forEach((e)=>{Fi(rn(r,e),{recursive:!0,force:!0})})}import{existsSync as ml,mkdirSync as Bi,readFileSync as kl}from"node:fs";import{dirname as Ji,join as Dl}from"node:path";function $l(n){return n!==void 0&&/\s/.test(n)}function zi(n,t,r){let e=t+1,a=!1;while(e<n.length){let l=n[e];if(a){a=!1,e++;continue}if(l==="\\"){a=!0,e++;continue}if(l==='"')return e+1;e++}throw Error(r)}function ot(n,t,r){let e=n[t],a=e==="["?"]":"}",l=0,d=t;while(d<n.length){let s=r.skipComment?.(n,d)??d;if(s!==d){d=s;continue}if(n[d]==='"'){d=zi(n,d,r.stringError);continue}if(n[d]===e)l++;if(n[d]===a){if(l--,l===0)return d}d++}throw Error(r.bracketError)}function gl(n,t){let r=n.lastIndexOf(`
194
+ `,t)+1;return/^[ \t]*/.exec(n.slice(r))?.[0]??""}function bt(n,t){let{start:r,end:e,end:a}=t;while($l(n[a]))a++;if(n[a]===","){if(e=a+1,n[e]===`
195
195
  `)e++;return`${n.slice(0,r)}${n.slice(e)}`}a=t.start-1;while($l(n[a]))a--;if(n[a]===","){r=a;let l=n.lastIndexOf(`
196
- `,r-1);if(l!==-1&&/^\s*$/.test(n.slice(l+1,r)))r=l}return`${n.slice(0,r)}${n.slice(e)}`}var Jn="npx -y cc-safety-net hook --kimi-code",ne=`[[hooks]]
196
+ `,r-1);if(l!==-1&&/^\s*$/.test(n.slice(l+1,r)))r=l}return`${n.slice(0,r)}${n.slice(e)}`}var Qn="npx -y cc-safety-net hook --kimi-code",r1=`[[hooks]]
197
197
  event = "PreToolUse"
198
- command = "${Jn}"`,te=`{ event = "PreToolUse", command = "${Jn}" }`;function ql(n){return Dl(process.env.KIMI_CODE_HOME??Dl(n,".kimi-code"),"config.toml")}function Ji(n){return n.split(`
198
+ command = "${Qn}"`,e1=`{ event = "PreToolUse", command = "${Qn}" }`;function ql(n){return Dl(process.env.KIMI_CODE_HOME??Dl(n,".kimi-code"),"config.toml")}function Zi(n){return n.split(`
199
199
  `).reduce((r,e)=>{if(/^\s*\[/.test(e))return r.activeTable=!0,r.lines.push(e),r;if(!r.activeTable&&/^\s*hooks\s*=\s*\[\s*]\s*(?:#.*)?$/.test(e))return r;return r.lines.push(e),r},{activeTable:!1,lines:[]}).lines.join(`
200
- `)}function Zi(n,t){if(n[t]!=="#")return t;let r=n.indexOf(`
201
- `,t+1);return r===-1?n.length:r+1}function Qi(n,t){return ut(n,t,{skipComment:Zi,stringError:"Unterminated string in Kimi Code config",bracketError:"Unmatched hooks array in Kimi Code config"})}function jl(n){let t=!1,r=0;while(r<n.length){let e=n.indexOf(`
202
- `,r),a=e===-1?n.length:e,l=n.slice(r,a);if(/^\s*\[/.test(l))t=!0;if(!t){let d=/^(\s*)hooks\s*=\s*\[/.exec(l);if(d){let s=r+d[0].lastIndexOf("[");return{start:s,end:Qi(n,s)}}}r=e===-1?n.length:e+1}return}function Xi(n,t){let r=n.slice(0,t.end).trimEnd(),e=gl(n,t.end),a=e===""?" ":`${e} `,l=!r.endsWith("[")&&!r.endsWith(",");return`${r}${l?",":""}
203
- ${a}${te}${n.slice(t.end)}`}function Yi(n){let t=jl(n);if(t&&n.slice(t.start+1,t.end).trim())return Xi(n,t);let r=Ji(n).trimEnd();if(r==="")return`${ne}
200
+ `)}function Qi(n,t){if(n[t]!=="#")return t;let r=n.indexOf(`
201
+ `,t+1);return r===-1?n.length:r+1}function Xi(n,t){return ot(n,t,{skipComment:Qi,stringError:"Unterminated string in Kimi Code config",bracketError:"Unmatched hooks array in Kimi Code config"})}function jl(n){let t=!1,r=0;while(r<n.length){let e=n.indexOf(`
202
+ `,r),a=e===-1?n.length:e,l=n.slice(r,a);if(/^\s*\[/.test(l))t=!0;if(!t){let d=/^(\s*)hooks\s*=\s*\[/.exec(l);if(d){let s=r+d[0].lastIndexOf("[");return{start:s,end:Xi(n,s)}}}r=e===-1?n.length:e+1}return}function Yi(n,t){let r=n.slice(0,t.end).trimEnd(),e=gl(n,t.end),a=e===""?" ":`${e} `,l=!r.endsWith("[")&&!r.endsWith(",");return`${r}${l?",":""}
203
+ ${a}${e1}${n.slice(t.end)}`}function Si(n){let t=jl(n);if(t&&n.slice(t.start+1,t.end).trim())return Yi(n,t);let r=Zi(n).trimEnd();if(r==="")return`${r1}
204
204
  `;return`${r}
205
205
 
206
- ${ne}
207
- `}function Si(n){return n.split(/(?=^\s*\[)/m).filter((r)=>!/^\s*\[\[hooks]]\s*$/m.test(r)||!r.includes(Jn)).join("").trimEnd()}function Hi(n,t){let r=n.indexOf(te,t.start);if(r===-1||r>t.end)return n;return ot(n,{start:r,end:r+te.length})}function Fl(n){let t=ql(n);if(zi(Bi(t),{recursive:!0}),!ml(t))return B(t,`${ne}
208
- `),{path:t,alreadyInstalled:!1};let r=kl(t,"utf-8");if(r.includes(Jn))return{path:t,alreadyInstalled:!0};return B(t,Yi(r)),{path:t,alreadyInstalled:!1}}function zl(n){let t=ql(n);if(!ml(t))return{path:t,alreadyInstalled:!1};let r=kl(t,"utf-8");if(!r.includes(Jn))return{path:t,alreadyInstalled:!1};let e=jl(r),a=e?Hi(r,e):`${Si(r)}
209
- `;return B(t,a),{path:t,alreadyInstalled:!0}}import{existsSync as Bl,readFileSync as Ai,rmSync as Wi}from"node:fs";import{join as re}from"node:path";var ee="cc-safety-net",Ri=`${ee}@latest`,Zl=["opencode.json","opencode.jsonc"];function Vi(n){return re(n,".config","opencode",Zl[0])}function Ki(n){return Zl.map((t)=>re(n,".config","opencode",t))}function Mi(n){return re(n,".cache","opencode","packages",Ri)}function ae(n){Wi(Mi(n),{recursive:!0,force:!0})}function vt(n,t){if(n[t]==="/"&&n[t+1]==="/"){let r=n.indexOf(`
210
- `,t+2);return r===-1?n.length:r+1}if(n[t]==="/"&&n[t+1]==="*"){let r=n.indexOf("*/",t+2);return r===-1?n.length:r+2}return t}function Jl(n,t){let r=t;while(r<n.length){if(/\s/.test(n[r]??"")){r++;continue}let e=vt(n,r);if(e===r)return r;r=e}return r}function Ql(n,t){let r=t+1,e=!1;while(r<n.length){if(e){e=!1,r++;continue}if(n[r]==="\\"){e=!0,r++;continue}if(n[r]==='"')return r+1;r++}throw Error("Unterminated string in OpenCode config")}function Xl(n,t,r){return JSON.parse(n.slice(t,r))}function Gi(n,t){return ut(n,t,{skipComment:vt,stringError:"Unterminated string in OpenCode config",bracketError:"Unmatched plugin array in OpenCode config"})}function Ci(n){let t=0,r=0;while(r<n.length){let e=vt(n,r);if(e!==r){r=e;continue}if(n[r]==='"'){let a=Ql(n,r);if(t===1&&Xl(n,r,a)==="plugin"){let l=Jl(n,a),d=Jl(n,l+1);if(n[l]===":"&&n[d]==="[")return{start:d,end:Gi(n,d)}}r=a;continue}if(n[r]==="{"||n[r]==="[")t++;if(n[r]==="}"||n[r]==="]")t--;r++}return}function Ui(n,t){let r=[],e=t.start+1;while(e<t.end){let a=vt(n,e);if(a!==e){e=a;continue}if(n[e]==='"'){let l=Ql(n,e),d=Xl(n,e,l);if(typeof d==="string"&&d.includes(ee))r.push({start:e,end:l});e=l;continue}e++}return r}function Yl(n,t){try{return JSON.parse(R(n))}catch(r){if(r instanceof SyntaxError)throw Error(`Failed to parse OpenCode config ${t}: ${r.message}`);throw r}}function Oi(n){if(!n||typeof n!=="object"||Array.isArray(n))return!1;let t=n.plugin;if(!Array.isArray(t))return!1;return t.some((r)=>typeof r==="string"&&r.includes(ee))}function Ti(n,t){let r=Ci(n);if(!r)throw Error(`Failed to locate OpenCode plugin array in ${t}`);let e=[...Ui(n,r)].reverse().reduce(ot,n);return Yl(e,t),e}function Sl(n){ae(n);let t=Ki(n),r=t.find((a)=>Bl(a)),e=[];for(let a of t){if(!Bl(a))continue;try{let l=Ai(a,"utf-8");if(!Oi(Yl(l,a)))continue;return B(a,Ti(l,a)),{path:a,alreadyInstalled:!0}}catch(l){e.push(l instanceof Error?l.message:String(l))}}if(e.length>0)throw Error(e.join(`
211
- `));return{path:r??Vi(n),alreadyInstalled:!1}}var de="safety-net@cc-marketplace",Hl=new Set(["claude-code","codex","copilot-cli","gemini-cli","hermes-agent","openclaw","opencode","pi"]);function ce(n){return/^\s*safety-net@cc-marketplace[^a-z0-9-][^\n]*installed,/m.test(n??"")}function Kl(n){return/^\s*cc-safety-net[^a-z0-9-][^\n]*installed,/m.test(n??"")}function _i(n){return/^Marketplace `cc-marketplace`\s*$/m.test(n??"")}var Ml={"claude-code":{installCommands:(n)=>{let t=_n(n,"cc-safety-net@cc-marketplace");return{commands:[...t?[["claude","plugin","marketplace","update","cc-marketplace"],["claude","plugin","update","cc-safety-net@cc-marketplace"]]:[["claude","plugin","marketplace","add","kenryu42/cc-marketplace"],["claude","plugin","marketplace","update","cc-marketplace"],["claude","plugin","install","cc-safety-net@cc-marketplace"]],...fr(n).status==="disabled"?[["claude","plugin","enable","cc-safety-net@cc-marketplace"]]:[]],cleanupCommands:_n(n,de)?[["claude","plugin","uninstall",de]]:[],update:t}},uninstallCommands:[["claude","plugin","uninstall","cc-safety-net@cc-marketplace"],["claude","plugin","marketplace","remove","cc-marketplace"]]},codex:{installCommands:async()=>{let n=await r2(["codex","plugin","list"]),t=Kl(n);return{commands:[t||_i(n)?["codex","plugin","marketplace","upgrade","cc-marketplace"]:["codex","plugin","marketplace","add","kenryu42/cc-marketplace"],["codex","plugin","add","cc-safety-net@cc-marketplace"]],cleanupCommands:ce(n)?[["codex","plugin","remove","safety-net@cc-marketplace"]]:[],update:t}},uninstallCommands:[["codex","plugin","remove","cc-safety-net@cc-marketplace"],["codex","plugin","marketplace","remove","cc-marketplace"]],postInstallMessage:"Start Codex, open `/hooks`, select the cc-safety-net PreToolUse hook, and press `t` to trust it."},"copilot-cli":{installCommands:async()=>{let n=await r2(["copilot","plugin","list"]),t=[...Ra(n)?[["copilot","plugin","uninstall","copilot-safety-net"]]:[],...Va(n)?[["copilot","plugin","uninstall",Ha]]:[]];if(Aa(n))return{commands:[["copilot","plugin","marketplace","update","cc-marketplace"],["copilot","plugin","update",t2]],cleanupCommands:t,update:!0};return{commands:[Wa(await r2(["copilot","plugin","marketplace","list"]))?["copilot","plugin","marketplace","update","cc-marketplace"]:["copilot","plugin","marketplace","add","kenryu42/cc-marketplace"],["copilot","plugin","install",t2]],cleanupCommands:t}},uninstallCommands:[["copilot","plugin","uninstall","cc-safety-net@cc-marketplace"],["copilot","plugin","marketplace","remove","cc-marketplace"]]},"gemini-cli":{installCommands:(n)=>{let t=mr(n);if(t.status==="configured")return{commands:[["gemini","extensions","update","gemini-safety-net"]],update:!0};if(t.status==="disabled")return{commands:[["gemini","extensions","update","gemini-safety-net"],["gemini","extensions","enable","gemini-safety-net"]],update:!0};return{commands:[["gemini","extensions","install","https://github.com/kenryu42/gemini-safety-net","--consent"]]}},uninstallCommands:[["gemini","extensions","uninstall","gemini-safety-net"]]},openclaw:{beforeInstall:Sr,installCommands:()=>({commands:x0()}),uninstallCommands:[["openclaw","plugins","uninstall",q,"--force"]],postInstallMessage:["Restart the OpenClaw Gateway to apply the change.","If plugins.allow is set in openclaw.json, it must also list cc-safety-net."].join(`
212
- `)},opencode:{beforeInstall:ae,installCommands:[["opencode","plugin","-g","-f","cc-safety-net@latest"]]},pi:{installCommands:[["pi","install","npm:cc-safety-net"]],uninstallCommands:[["pi","uninstall","npm:cc-safety-net"]]}};function Le(){return process.env.HOME??Ei()}function Gl(n,t=(r)=>r){try{let r=JSON.parse(t(Vl(n,"utf-8")));if(!r||typeof r!=="object"||Array.isArray(r))throw Error(`Settings file ${n} must be a JSON object`);return r}catch(r){if(r instanceof SyntaxError)throw Error(`Failed to parse ${n}: ${r.message}`);throw r}}function Pi(n){let t=le(Dn(n),"settings.json");if(!se(t))return;let r=Gl(t,R),e=r.enabledPlugins;if(!e||typeof e!=="object"||Array.isArray(e))return;if(e[t2]!==!1)return;let a=Vl(t,"utf-8"),l=a.replace(new RegExp(`("${t2}"\\s*:\\s*)false`),"$1true");return e[t2]=!0,B(t,l!==a?l:`${JSON.stringify(r,null,2)}
213
- `),`Enabled ${t2} plugin in ${t}`}function Ni(n){let t=Ar(n);if(!se(t))return;let r=Gl(t);if(!Array.isArray(r.packages))return;let e=r.packages.find((a)=>!!a&&typeof a==="object"&&!Array.isArray(a)&&Wr(a.source)&&("extensions"in a));if(!e)return;return delete e.extensions,B(t,`${JSON.stringify(r,null,2)}
214
- `),`Enabled npm:cc-safety-net extensions in ${t}`}function Al(n,t){let r=F({label:t,booleans:Object.fromEntries(C.map((l)=>[l.target,[l.flag]]))},n),e=r.errors[0];if(e)throw Error(e);let a=C.filter((l)=>r.flags[l.target]).map((l)=>l.target);if(a.length!==1)throw Error(`Choose exactly one ${t} target: ${[...bl.keys()].join(", ")}`);return a[0]}async function Cl(n=Le()){let[t,r,e]=await Promise.all([wn(["amp","plugins","list"],30000),wn(["codex","plugin","list"],30000),wn(["copilot","--binary-version"])]);return{codexPluginListOutput:r,hooks:nn(process.cwd(),{homeDir:n,ampPluginListOutput:t,codexPluginListOutput:r,copilotCliVersion:e})}}async function Ii(n){let t=await Cl();return t.hooks.filter((r)=>n==="install"?r.configured:r.detected||r.inspectionStatus==="not-inspected").filter((r)=>r.platform!=="codex"||!ce(t.codexPluginListOutput)||Kl(t.codexPluginListOutput)).map((r)=>r.platform)}function n5(n,t,r){if(t.length>0)return{finish:async()=>[Al(t,n)]};if(!r.selectTargets&&!Ur(r.input,r.output))return{finish:async()=>[Al(t,n)]};let e=r.detectConfiguredTargets??(()=>Ii(n)),a=Promise.all([hl(r.probeTargets),e()]);return{ready:a,finish:async()=>{let[l,d]=await a,s=wl(l,{action:n,configuredTargets:d}),c=r.selectTargets?await r.selectTargets(n,Rl(n,s)):await E0(n,Rl(n,s),{input:r.input,output:r.output});if(c==="update")return c;if(!c||c.length===0)return null;return _r(c)}}}async function B2(n,t,r=!1){let e=Ml[n];e.beforeInstall?.(t);let a=typeof e.installCommands==="function"?await e.installCommands(t):{commands:e.installCommands};return await Xr(a.commands),await v0(a.cleanupCommands??[]),[`${a.update||r?"Updated":"Installed"} ${b2(n)} integration`,e.postInstallMessage].filter(Boolean).join(`
215
- `)}async function rn(n){let t=Ml[n];if(!t.uninstallCommands)throw Error(`${b2(n)} uninstall is not supported`);return await Xr(t.uninstallCommands),`Uninstalled ${b2(n)} integration`}function t5(n){let t=Sl(n);return t.alreadyInstalled?`Uninstalled OpenCode plugin from ${t.path}`:`OpenCode plugin not installed in ${t.path}`}var r5={"antigravity-cli":{install:ol,uninstall:vl},cursor:{install:Pa,uninstall:Na},"kimi-code":{install:Fl,uninstall:zl}};function en(n,t,r,e=!1){if(n==="install")Ir(r);let a=r5[t][n](r),l=b2(t),d=n!=="install"?"Uninstalled":e?"Updated":"Installed";return n==="install"&&a.alreadyInstalled?e?`${l} hook up to date in ${a.path}`:`${l} hook already installed in ${a.path}`:n==="uninstall"&&!a.alreadyInstalled?`${l} hook not installed in ${a.path}`:`${d} ${l} hook ${n==="install"?"in":"from"} ${a.path}`}var e5={amp:{install:sl,uninstall:cl,restartNote:'Amp personal plugins apply to every Amp session, including Orb threads. Restart Amp or run "plugins: reload" to apply the change.'},"hermes-agent":{install:a0,uninstall:l0,afterInstall:async(n)=>{let t=Jr(n);return await r2(["hermes","plugins","enable",K,"--no-allow-tool-override"]),!t},beforeUninstall:async(n)=>{Br(n);try{await r2(["hermes","plugins","disable",K])}catch(t){console.warn(`${t instanceof Error?t.message:String(t)}
216
- Removing the plugin files anyway; ${K} may still be listed in the Hermes config.`)}},restartNote:"Restart Hermes to apply the change."}};async function bt(n,t,r,e=!1){let a=e5[t];if(n==="uninstall")await a.beforeUninstall?.(r);let l=n==="install"?await a.install(r):await a.uninstall(r),d=n==="install"&&await a.afterInstall?.(r),s=b2(t),c=!d&&(n==="install"&&l.alreadyInstalled||n==="uninstall"&&!l.alreadyInstalled);return[c?n==="install"?`${s} plugin ${e?"up to date":"already installed"} at ${l.path}`:`${s} plugin not installed at ${l.path}`:`${n!=="install"?"Uninstalled":e?"Updated":"Installed"} ${s} plugin ${n==="install"?"at":"from"} ${l.path}`,c?void 0:a.restartNote].filter(Boolean).join(`
217
- `)}var a5={amp:{install:(n,t)=>bt("install","amp",n,t),uninstall:(n)=>bt("uninstall","amp",n)},"antigravity-cli":{install:(n,t)=>en("install","antigravity-cli",n,t),uninstall:(n)=>en("uninstall","antigravity-cli",n)},"claude-code":{install:(n,t)=>B2("claude-code",n,t),uninstall:()=>rn("claude-code")},codex:{install:(n,t)=>B2("codex",n,t),uninstall:()=>rn("codex")},"copilot-cli":{install:async(n,t)=>[await B2("copilot-cli",n,t),Pi(n)].filter(Boolean).join(`
218
- `),uninstall:()=>rn("copilot-cli")},cursor:{install:(n,t)=>en("install","cursor",n,t),uninstall:(n)=>en("uninstall","cursor",n)},"gemini-cli":{install:(n,t)=>B2("gemini-cli",n,t),uninstall:()=>rn("gemini-cli")},"hermes-agent":{install:(n,t)=>{return Ir(n),bt("install","hermes-agent",n,t)},uninstall:(n)=>bt("uninstall","hermes-agent",n)},"kimi-code":{install:(n,t)=>en("install","kimi-code",n,t),uninstall:(n)=>en("uninstall","kimi-code",n)},openclaw:{install:async(n,t)=>{let r=await B2("openclaw",n,t);return await $0(),r},uninstall:(n)=>{return Sr(n),rn("openclaw")}},opencode:{install:(n,t)=>B2("opencode",n,t),uninstall:(n)=>t5(n)},pi:{install:async(n,t)=>[await B2("pi",n,t),Ni(n)].filter(Boolean).join(`
219
- `),uninstall:()=>rn("pi")}},Wl=["Install CC Safety Net as a native Kimi Code plugin:",""," 1. Start Kimi Code and run: /plugins install https://github.com/kenryu42/cc-safety-net"," Confirm the trust prompt; it defaults to cancel."," 2. Run /reload, or start a new session.","","Note: Kimi Code hooks are fail-open. When the hook process cannot start, crashes, or times","out, Kimi Code allows the tool call."].join(`
220
- `);function l5(n){if(qn({homeDir:n,cwd:process.cwd()}).status!=="configured")return Wl;return[Wl,"",b.red(["CAUTION: the global Kimi Code hook is installed and will run alongside the plugin.","After the plugin is active, remove it with: cc-safety-net uninstall --kimi-code"].join(`
206
+ ${r1}
207
+ `}function Hi(n){return n.split(/(?=^\s*\[)/m).filter((r)=>!/^\s*\[\[hooks]]\s*$/m.test(r)||!r.includes(Qn)).join("").trimEnd()}function Ai(n,t){let r=n.indexOf(e1,t.start);if(r===-1||r>t.end)return n;return bt(n,{start:r,end:r+e1.length})}function Fl(n){let t=ql(n);if(Bi(Ji(t),{recursive:!0}),!ml(t))return B(t,`${r1}
208
+ `),{path:t,alreadyInstalled:!1};let r=kl(t,"utf-8");if(r.includes(Qn))return{path:t,alreadyInstalled:!0};return B(t,Si(r)),{path:t,alreadyInstalled:!1}}function zl(n){let t=ql(n);if(!ml(t))return{path:t,alreadyInstalled:!1};let r=kl(t,"utf-8");if(!r.includes(Qn))return{path:t,alreadyInstalled:!1};let e=jl(r),a=e?Ai(r,e):`${Hi(r)}
209
+ `;return B(t,a),{path:t,alreadyInstalled:!0}}import{existsSync as Bl,readFileSync as Wi,rmSync as Ri}from"node:fs";import{join as a1}from"node:path";var l1="cc-safety-net",Ki=`${l1}@latest`,Zl=["opencode.json","opencode.jsonc"];function Mi(n){return a1(n,".config","opencode",Zl[0])}function Vi(n){return Zl.map((t)=>a1(n,".config","opencode",t))}function Gi(n){return a1(n,".cache","opencode","packages",Ki)}function d1(n){Ri(Gi(n),{recursive:!0,force:!0})}function ft(n,t){if(n[t]==="/"&&n[t+1]==="/"){let r=n.indexOf(`
210
+ `,t+2);return r===-1?n.length:r+1}if(n[t]==="/"&&n[t+1]==="*"){let r=n.indexOf("*/",t+2);return r===-1?n.length:r+2}return t}function Jl(n,t){let r=t;while(r<n.length){if(/\s/.test(n[r]??"")){r++;continue}let e=ft(n,r);if(e===r)return r;r=e}return r}function Ql(n,t){let r=t+1,e=!1;while(r<n.length){if(e){e=!1,r++;continue}if(n[r]==="\\"){e=!0,r++;continue}if(n[r]==='"')return r+1;r++}throw Error("Unterminated string in OpenCode config")}function Xl(n,t,r){return JSON.parse(n.slice(t,r))}function Ci(n,t){return ot(n,t,{skipComment:ft,stringError:"Unterminated string in OpenCode config",bracketError:"Unmatched plugin array in OpenCode config"})}function Ui(n){let t=0,r=0;while(r<n.length){let e=ft(n,r);if(e!==r){r=e;continue}if(n[r]==='"'){let a=Ql(n,r);if(t===1&&Xl(n,r,a)==="plugin"){let l=Jl(n,a),d=Jl(n,l+1);if(n[l]===":"&&n[d]==="[")return{start:d,end:Ci(n,d)}}r=a;continue}if(n[r]==="{"||n[r]==="[")t++;if(n[r]==="}"||n[r]==="]")t--;r++}return}function Oi(n,t){let r=[],e=t.start+1;while(e<t.end){let a=ft(n,e);if(a!==e){e=a;continue}if(n[e]==='"'){let l=Ql(n,e),d=Xl(n,e,l);if(typeof d==="string"&&d.includes(l1))r.push({start:e,end:l});e=l;continue}e++}return r}function Yl(n,t){try{return JSON.parse(R(n))}catch(r){if(r instanceof SyntaxError)throw Error(`Failed to parse OpenCode config ${t}: ${r.message}`);throw r}}function Ti(n){if(!n||typeof n!=="object"||Array.isArray(n))return!1;let t=n.plugin;if(!Array.isArray(t))return!1;return t.some((r)=>typeof r==="string"&&r.includes(l1))}function _i(n,t){let r=Ui(n);if(!r)throw Error(`Failed to locate OpenCode plugin array in ${t}`);let e=[...Oi(n,r)].reverse().reduce(bt,n);return Yl(e,t),e}function Sl(n){d1(n);let t=Vi(n),r=t.find((a)=>Bl(a)),e=[];for(let a of t){if(!Bl(a))continue;try{let l=Wi(a,"utf-8");if(!Ti(Yl(l,a)))continue;return B(a,_i(l,a)),{path:a,alreadyInstalled:!0}}catch(l){e.push(l instanceof Error?l.message:String(l))}}if(e.length>0)throw Error(e.join(`
211
+ `));return{path:r??Mi(n),alreadyInstalled:!1}}var L1="safety-net@cc-marketplace",Hl=new Set(["claude-code","codex","copilot-cli","gemini-cli","hermes-agent","openclaw","opencode","pi"]),Al=new Set(["antigravity-cli","cursor","hermes-agent","kimi-code"]);function i1(n){return/^\s*safety-net@cc-marketplace[^a-z0-9-][^\n]*installed,/m.test(n??"")}function Vl(n){return/^\s*cc-safety-net[^a-z0-9-][^\n]*installed,/m.test(n??"")}function Pi(n){return/^Marketplace `cc-marketplace`\s*$/m.test(n??"")}var Gl={"claude-code":{installCommands:(n)=>{let t=Pn(n,"cc-safety-net@cc-marketplace");return{commands:[...t?[["claude","plugin","marketplace","update","cc-marketplace"],["claude","plugin","update","cc-safety-net@cc-marketplace"]]:[["claude","plugin","marketplace","add","kenryu42/cc-marketplace"],["claude","plugin","marketplace","update","cc-marketplace"],["claude","plugin","install","cc-safety-net@cc-marketplace"]],...wr(n).status==="disabled"?[["claude","plugin","enable","cc-safety-net@cc-marketplace"]]:[]],cleanupCommands:Pn(n,L1)?[["claude","plugin","uninstall",L1]]:[],update:t}},uninstallCommands:[["claude","plugin","uninstall","cc-safety-net@cc-marketplace"],["claude","plugin","marketplace","remove","cc-marketplace"]]},codex:{installCommands:async(n,t)=>{let r=t??await r2(["codex","plugin","list"]),e=Vl(r);return{commands:[e||Pi(r)?["codex","plugin","marketplace","upgrade","cc-marketplace"]:["codex","plugin","marketplace","add","kenryu42/cc-marketplace"],["codex","plugin","add","cc-safety-net@cc-marketplace"]],cleanupCommands:i1(r)?[["codex","plugin","remove","safety-net@cc-marketplace"]]:[],update:e}},uninstallCommands:[["codex","plugin","remove","cc-safety-net@cc-marketplace"],["codex","plugin","marketplace","remove","cc-marketplace"]],postInstallMessage:"Start Codex, open `/hooks`, select the cc-safety-net PreToolUse hook, and press `t` to trust it."},"copilot-cli":{installCommands:async()=>{let n=await r2(["copilot","plugin","list"]),t=[...Ra(n)?[["copilot","plugin","uninstall","copilot-safety-net"]]:[],...Ka(n)?[["copilot","plugin","uninstall",Ha]]:[]];if(Aa(n))return{commands:[["copilot","plugin","marketplace","update","cc-marketplace"],["copilot","plugin","update",t2]],cleanupCommands:t,update:!0};return{commands:[Wa(await r2(["copilot","plugin","marketplace","list"]))?["copilot","plugin","marketplace","update","cc-marketplace"]:["copilot","plugin","marketplace","add","kenryu42/cc-marketplace"],["copilot","plugin","install",t2]],cleanupCommands:t}},uninstallCommands:[["copilot","plugin","uninstall","cc-safety-net@cc-marketplace"],["copilot","plugin","marketplace","remove","cc-marketplace"]]},"gemini-cli":{installCommands:(n)=>{let t=jr(n);if(t.status==="configured")return{commands:[["gemini","extensions","update","gemini-safety-net"]],update:!0};if(t.status==="disabled")return{commands:[["gemini","extensions","update","gemini-safety-net"],["gemini","extensions","enable","gemini-safety-net"]],update:!0};return{commands:[["gemini","extensions","install","https://github.com/kenryu42/gemini-safety-net","--consent"]]}},uninstallCommands:[["gemini","extensions","uninstall","gemini-safety-net"]]},openclaw:{beforeInstall:Wr,installCommands:()=>({commands:x0()}),uninstallCommands:[["openclaw","plugins","uninstall",q,"--force"]],postInstallMessage:["Restart the OpenClaw Gateway to apply the change.","If plugins.allow is set in openclaw.json, it must also list cc-safety-net."].join(`
212
+ `)},opencode:{beforeInstall:d1,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 wt(){return process.env.HOME??Ei()}function Cl(n,t=(r)=>r){try{let r=JSON.parse(t(Ml(n,"utf-8")));if(!r||typeof r!=="object"||Array.isArray(r))throw Error(`Settings file ${n} must be a JSON object`);return r}catch(r){if(r instanceof SyntaxError)throw Error(`Failed to parse ${n}: ${r.message}`);throw r}}function Ii(n){let t=s1(kn(n),"settings.json");if(!c1(t))return;let r=Cl(t,R),e=r.enabledPlugins;if(!e||typeof e!=="object"||Array.isArray(e))return;if(e[t2]!==!1)return;let a=Ml(t,"utf-8"),l=a.replace(new RegExp(`("${t2}"\\s*:\\s*)false`),"$1true");return e[t2]=!0,B(t,l!==a?l:`${JSON.stringify(r,null,2)}
213
+ `),`Enabled ${t2} plugin in ${t}`}function Ni(n){let t=Kr(n);if(!c1(t))return;let r=Cl(t);if(!Array.isArray(r.packages))return;let e=r.packages.find((a)=>!!a&&typeof a==="object"&&!Array.isArray(a)&&Mr(a.source)&&("extensions"in a));if(!e)return;return delete e.extensions,B(t,`${JSON.stringify(r,null,2)}
214
+ `),`Enabled npm:cc-safety-net extensions in ${t}`}function Wl(n,t){let r=F({label:t,booleans:Object.fromEntries(C.map((l)=>[l.target,[l.flag]]))},n),e=r.errors[0];if(e)throw Error(e);let a=C.filter((l)=>r.flags[l.target]).map((l)=>l.target);if(a.length!==1)throw Error(`Choose exactly one ${t} target: ${[...bl.keys()].join(", ")}`);return a[0]}async function Ul(n=wt(),t=_2){let[r,e,a]=await Promise.all([t(["amp","plugins","list"],30000),t(["codex","plugin","list"],30000),t(["copilot","--binary-version"])]);return{codexPluginListOutput:e,hooks:tn(process.cwd(),{homeDir:n,ampPluginListOutput:r,codexPluginListOutput:e,copilotCliVersion:a})}}async function n5(n,t=_2){let r=await Ul(wt(),t);return r.hooks.filter((e)=>n==="install"?e.configured:e.detected||e.inspectionStatus==="not-inspected").filter((e)=>e.platform!=="codex"||!i1(r.codexPluginListOutput)||Vl(r.codexPluginListOutput)).map((e)=>e.platform)}function t5(n,t,r){if(t.length>0)return{finish:async()=>[Wl(t,n)]};if(!r.selectTargets&&!_r(r.input,r.output))return{finish:async()=>[Wl(t,n)]};let e=r.detectConfiguredTargets??(()=>n5(n,r.fetchVersion)),a=Promise.all([hl(r.probeTargets),e()]);return{ready:a,finish:async()=>{let[l,d]=await a,s=wl(l,{action:n,configuredTargets:d}),L=r.selectTargets?await r.selectTargets(n,Kl(n,s)):await _0(n,Kl(n,s),{input:r.input,output:r.output});if(L==="update")return L;if(!L||L.length===0)return null;return Nr(L)}}}async function B2(n,t,r=!1,e){let a=Gl[n];a.beforeInstall?.(t);let l=typeof a.installCommands==="function"?await a.installCommands(t,e):{commands:a.installCommands};return await Hr(l.commands),await o0(l.cleanupCommands??[]),[`${l.update||r?"Updated":"Installed"} ${b2(n)} integration`,a.postInstallMessage].filter(Boolean).join(`
215
+ `)}async function en(n){let t=Gl[n];if(!t.uninstallCommands)throw Error(`${b2(n)} uninstall is not supported`);return await Hr(t.uninstallCommands),`Uninstalled ${b2(n)} integration`}function r5(n){let t=Sl(n);return t.alreadyInstalled?`Uninstalled OpenCode plugin from ${t.path}`:`OpenCode plugin not installed in ${t.path}`}var e5={"antigravity-cli":{install:vl,uninstall:ol},cursor:{install:Pa,uninstall:Ia},"kimi-code":{install:Fl,uninstall:zl}};function an(n,t,r,e=!1){if(n==="install"&&!e)vt(r);let a=e5[t][n](r),l=b2(t),d=n!=="install"?"Uninstalled":e?"Updated":"Installed";return n==="install"&&a.alreadyInstalled?e?`${l} hook up to date in ${a.path}`:`${l} hook already installed in ${a.path}`:n==="uninstall"&&!a.alreadyInstalled?`${l} hook not installed in ${a.path}`:`${d} ${l} hook ${n==="install"?"in":"from"} ${a.path}`}var a5={amp:{install:sl,uninstall:Ll,restartNote:'Amp personal plugins apply to every Amp session, including Orb threads. Restart Amp or run "plugins: reload" to apply the change.'},"hermes-agent":{install:a0,uninstall:l0,afterInstall:async(n)=>{let t=Xr(n);return await r2(["hermes","plugins","enable",M,"--no-allow-tool-override"]),!t},beforeUninstall:async(n)=>{Qr(n);try{await r2(["hermes","plugins","disable",M])}catch(t){console.warn(`${t instanceof Error?t.message:String(t)}
216
+ Removing the plugin files anyway; ${M} may still be listed in the Hermes config.`)}},restartNote:"Restart Hermes to apply the change."}};async function yt(n,t,r,e=!1){let a=a5[t];if(n==="uninstall")await a.beforeUninstall?.(r);let l=n==="install"?await a.install(r):await a.uninstall(r),d=n==="install"&&await a.afterInstall?.(r),s=b2(t),L=!d&&(n==="install"&&l.alreadyInstalled||n==="uninstall"&&!l.alreadyInstalled);return[L?n==="install"?`${s} plugin ${e?"up to date":"already installed"} at ${l.path}`:`${s} plugin not installed at ${l.path}`:`${n!=="install"?"Uninstalled":e?"Updated":"Installed"} ${s} plugin ${n==="install"?"at":"from"} ${l.path}`,L?void 0:a.restartNote].filter(Boolean).join(`
217
+ `)}var l5={amp:{install:(n,t)=>yt("install","amp",n,t),uninstall:(n)=>yt("uninstall","amp",n)},"antigravity-cli":{install:(n,t)=>an("install","antigravity-cli",n,t),uninstall:(n)=>an("uninstall","antigravity-cli",n)},"claude-code":{install:(n,t)=>B2("claude-code",n,t),uninstall:()=>en("claude-code")},codex:{install:(n,t,r)=>B2("codex",n,t,r),uninstall:()=>en("codex")},"copilot-cli":{install:async(n,t)=>[await B2("copilot-cli",n,t),Ii(n)].filter(Boolean).join(`
218
+ `),uninstall:()=>en("copilot-cli")},cursor:{install:(n,t)=>an("install","cursor",n,t),uninstall:(n)=>an("uninstall","cursor",n)},"gemini-cli":{install:(n,t)=>B2("gemini-cli",n,t),uninstall:()=>en("gemini-cli")},"hermes-agent":{install:(n,t)=>{if(!t)vt(n);return yt("install","hermes-agent",n,t)},uninstall:(n)=>yt("uninstall","hermes-agent",n)},"kimi-code":{install:(n,t)=>an("install","kimi-code",n,t),uninstall:(n)=>an("uninstall","kimi-code",n)},openclaw:{install:async(n,t)=>{let r=await B2("openclaw",n,t);return await $0(),r},uninstall:(n)=>{return Wr(n),en("openclaw")}},opencode:{install:(n,t)=>B2("opencode",n,t),uninstall:(n)=>r5(n)},pi:{install:async(n,t)=>[await B2("pi",n,t),Ni(n)].filter(Boolean).join(`
219
+ `),uninstall:()=>en("pi")}},Rl=["Install CC Safety Net as a native Kimi Code plugin:",""," 1. Start Kimi Code and run: /plugins install https://github.com/kenryu42/cc-safety-net"," Confirm the trust prompt; it defaults to cancel."," 2. Run /reload, or start a new session.","","Note: Kimi Code hooks are fail-open. When the hook process cannot start, crashes, or times","out, Kimi Code allows the tool call."].join(`
220
+ `);function d5(n){if(Fn({homeDir:n,cwd:process.cwd()}).status!=="configured")return Rl;return[Rl,"",b.red(["CAUTION: the global Kimi Code hook is installed and will run alongside the plugin.","After the plugin is active, remove it with: cc-safety-net uninstall --kimi-code"].join(`
221
221
  `))].join(`
222
- `)}function Rl(n,t){return t.map((r)=>n==="install"&&r.target==="kimi-code"&&r.unavailableReason==="already installed"?{...r,available:!0,unavailableReason:void 0,label:`${r.label} (global hook installed)`}:r)}function d5(n,t){if(n.selectKimiInstallMethod)return n.selectKimiInstallMethod();if(!Ur(n.input,n.output))return Promise.resolve("global-hook");return T0({input:n.input,output:n.output,globalHookInstalled:qn({homeDir:t,cwd:process.cwd()}).status==="configured"})}async function Ul(n,t,r,e=!1){return a5[t][n](r,e)}function s5(n){let t=F({label:"update"},n).errors[0];if(t)throw Error(t)}async function c5(n){let t=await Cl(n),r=le(Dn(n),"installed-plugins");return _r([...t.hooks.filter((e)=>e.platform!=="copilot-cli"&&e.detected).map((e)=>e.platform),...[Pn,Sa,Ya].flatMap((e)=>se(le(r,...e))?["copilot-cli"]:[]),..._n(n,de)?["claude-code"]:[],...ce(t.codexPluginListOutput)?["codex"]:[]])}async function L5(){let n=Le(),t=await c5(n);if(t.length===0)return console.log("No installed integrations found. Run `cc-safety-net install` to set one up."),0;let r=new Set(t),e=new Map(await Promise.all(C.filter((l)=>r.has(l.target)&&Hl.has(l.target)).map(async(l)=>[l.target,await Nr(l.probeCommand)]))),a=[];for(let l of t){if(Hl.has(l)&&!e.get(l)){console.log(`${b2(l)} not found; skipped`);continue}try{console.log(await Ul("install",l,n,!0))}catch(d){console.error(pe(d)),a.push(l)}}return a.length>0?1:0}function ie(n){return Promise.resolve().then(()=>s5(n)).then(L5).catch((t)=>{return console.error(pe(t)),1})}async function Zn(n,t,r={}){try{let e=await On(!0,()=>n5(n,t,r),()=>Un({input:r.input??process.stdin,output:r.output??process.stdout}),{loadingMessage:n==="install"?"Checking available integrations…":"Checking installed integrations…",output:r.output??process.stdout});if(!e)return(r.output??process.stdout).write(`Cancelled: nothing was ${n}ed.
223
- `),0;if(e==="update")return(r.runUpdate??(()=>ie([])))();let a=Le(),l=r.output??process.stdout;return await fl(e,async(d)=>{if(d==="kimi-code"&&n==="install"){let c=await d5(r,a);if(c===null){l.write(`Cancelled: Kimi Code integration was not installed.
224
- `);return}if(c==="plugin"){l.write(`${l5(a)}
225
- `);return}}let s=await vr(Ul(n,d,a),{loadingMessage:`${n==="install"?"Installing":"Uninstalling"} ${b2(d)} integration…`,output:l});l.write(`${s}
226
- `)}),0}catch(e){return console.error(pe(e)),1}}function pe(n){let t=n instanceof Error?n.message:String(n),r=typeof n==="object"&&n!==null&&"code"in n?n.code:null;if(r==="EACCES"||r==="EPERM")return`${t}
222
+ `)}function Kl(n,t){return t.map((r)=>n==="install"&&r.target==="kimi-code"&&r.unavailableReason==="already installed"?{...r,available:!0,unavailableReason:void 0,label:`${r.label} (global hook installed)`}:r)}function s5(n,t){if(n.selectKimiInstallMethod)return n.selectKimiInstallMethod();if(!_r(n.input,n.output))return Promise.resolve("global-hook");return T0({input:n.input,output:n.output,globalHookInstalled:Fn({homeDir:t,cwd:process.cwd()}).status==="configured"})}async function Ol(n,t,r,e=!1,a){return l5[t][n](r,e,a)}function L5(n){let t=F({label:"update"},n).errors[0];if(t)throw Error(t)}async function c5(n,t=_2){let r=await Ul(n,t),e=s1(kn(n),"installed-plugins");return{targets:Nr([...r.hooks.filter((l)=>l.platform!=="copilot-cli"&&l.detected).map((l)=>l.platform),...[In,Sa,Ya].flatMap((l)=>c1(s1(e,...l))?["copilot-cli"]:[]),...Pn(n,L1)?["claude-code"]:[],...i1(r.codexPluginListOutput)?["codex"]:[]]),codexPluginListOutput:r.codexPluginListOutput}}async function i5(n){let t=wt(),r=n.output??process.stdout,e=c5(t,n.fetchVersion??_2).then(async(s)=>{let L=new Set(s.targets);return{targets:s.targets,codexPluginListOutput:s.codexPluginListOutput,available:new Map(await Promise.all(C.filter((c)=>L.has(c.target)&&Hl.has(c.target)).map(async(c)=>[c.target,await t1(c.probeCommand)])))}}),a=await Dn(n.showBanner??!0,()=>({ready:e,finish:()=>e}),()=>gn({input:n.input??process.stdin,output:r}),{loadingMessage:"Checking installed integrations…",output:r});if(a.targets.length===0)return r.write("No installed integrations found. Run `cc-safety-net install` to set one up.\n"),0;let l=a.targets.some((s)=>Al.has(s))?await Promise.resolve().then(()=>{return vt(t),null}).catch((s)=>ht(s)):null,d=await Tn(Promise.all(a.targets.map((s)=>{if(Hl.has(s)&&!a.available.get(s))return Promise.resolve({message:`${b2(s)} not found; skipped`,failed:!1});if(l!==null&&Al.has(s))return Promise.resolve({message:l,failed:!0});return Ol("install",s,t,!0,a.codexPluginListOutput).then((L)=>({message:L,failed:!1}),(L)=>({message:ht(L),failed:!0}))})),{loadingMessage:`Updating ${a.targets.length} integration${a.targets.length===1?"":"s"}…`,output:r});return d.forEach((s)=>{s.failed?console.error(s.message):r.write(`${s.message}
223
+ `)}),d.some((s)=>s.failed)?1:0}function p1(n,t={}){return Promise.resolve().then(()=>L5(n)).then(()=>i5(t)).catch((r)=>{return console.error(ht(r)),1})}async function Xn(n,t,r={}){try{let e=await Dn(!0,()=>t5(n,t,r),()=>gn({input:r.input??process.stdin,output:r.output??process.stdout}),{loadingMessage:n==="install"?"Checking available integrations…":"Checking installed integrations…",output:r.output??process.stdout});if(!e)return(r.output??process.stdout).write(`Cancelled: nothing was ${n}ed.
224
+ `),0;if(e==="update")return(r.runUpdate??(()=>p1([],{fetchVersion:r.fetchVersion,input:r.input,output:r.output,showBanner:!1})))();let a=wt(),l=r.output??process.stdout;return await fl(e,async(d)=>{if(d==="kimi-code"&&n==="install"){let L=await s5(r,a);if(L===null){l.write(`Cancelled: Kimi Code integration was not installed.
225
+ `);return}if(L==="plugin"){l.write(`${d5(a)}
226
+ `);return}}let s=await Tn(Ol(n,d,a),{loadingMessage:`${n==="install"?"Installing":"Uninstalling"} ${b2(d)} integration…`,output:l});l.write(`${s}
227
+ `)}),0}catch(e){return console.error(ht(e)),1}}function ht(n){let t=n instanceof Error?n.message:String(n),r=typeof n==="object"&&n!==null&&"code"in n?n.code:null;if(r==="EACCES"||r==="EPERM")return`${t}
227
228
  Check file permissions for the target config file and parent directory.`;if(r==="ENOENT")return`${t}
228
229
  Check that the target config path and parent directory exist.`;if(r==="ENOTDIR")return`${t}
229
- Check that every parent path component is a directory.`;return t}import{join as O5}from"node:path";var Ol="# Custom Rules Reference\n\nAgent reference for generating CC Safety Net rulebook configuration.\n\n## Config Locations\n\n| Scope | Config path | Rulebook path | Cache path | Priority |\n|-------|-------------|---------------|------------|----------|\n| User | `~/.cc-safety-net/rules/rule.json` | `~/.cc-safety-net/rules/<rulebook-name>/rulebook.json` | `~/.cc-safety-net/cache/rulebooks/` | First |\n| Project | `.cc-safety-net/rules/rule.json` | `.cc-safety-net/rules/<rulebook-name>/rulebook.json` | `.cc-safety-net/cache/rulebooks/` | Second |\n| GitHub source | Listed in a local `rule.json` | `.cc-safety-net/rules/<rulebook-name>/rulebook.json` in the source repository | Consumer local cache | Source order |\n\nUser scope is evaluated before project scope; within a scope, sources apply in `rules` array order. A duplicate active rulebook name keeps the first claim and ignores the later rulebook with a warning, so a user-scoped name shadows a project-scoped one.\n\nUse `cc-safety-net rule init` to create an inert local config. Use `--global` for user scope. Use `cc-safety-net rule init --example` to also create an inactive example rulebook. `CC_SAFETY_NET_HOME` overrides the `~/.cc-safety-net` user root.\n\nLegacy inline `.safety-net.json` and `~/.cc-safety-net/config.json` files are not loaded at runtime. Convert them with `cc-safety-net rule migrate`.\n\n## rule.json Schema\n\n```json\n{\n \"version\": 1,\n \"rules\": [\"project-rules\", \"owner/repo#main/team-rules\"],\n \"overrides\": {\n \"project-rules/block-docker-system-prune\": {\n \"reason\": \"Use targeted Docker cleanup commands.\"\n },\n \"team-rules/block-npm-global\": \"off\"\n },\n \"transparent_wrappers\": [\"rtk\"]\n}\n```\n\n- `version`: Required. Must be `1`.\n- `$schema`: Optional. `cc-safety-net rule verify` inserts it into a valid `rule.json` that lacks it.\n- `rules`: Optional array of rulebook source strings. Missing `rules` is treated as `[]`.\n- `overrides`: Optional object keyed by `<rulebook-name>/<rule-name>`.\n- `overrides` values are either `\"off\"` to disable a rule or an object with a required `reason` (replacement block reason) and an optional `intent` (one of `hard_stop`, `use_alternative`, `scope_down`, `manual_only`, `stop_and_explain`).\n- A project override cannot target a user-scoped rule: only that override is ignored, the user rule keeps its configured state, and `rule sync`/`rule verify` report the diagnostic as a failure.\n- `transparent_wrappers`: Optional array of command names that transparently execute a visible child command.\n- Transparent wrappers have no built-in defaults. Configure only wrappers you intentionally trust, such as `\"rtk\"`.\n- Use `cc-safety-net rule wrapper add rtk` to configure RTK without manually editing `rule.json`.\n\n## Rulebook Sources\n\n- Local sources are bare rulebook names such as `project-rules`; the rulebook file is `.cc-safety-net/rules/project-rules/rulebook.json`.\n- GitHub sources use `owner/repo#ref/<rulebook-name>`.\n- GitHub refs must be one path segment, such as a tag, SHA, or branch name without `/`.\n- The GitHub source name, the repository directory name, and the rulebook `name` must match exactly.\n- Rulebook source strings must be unique in a config.\n\n## rulebook.json Schema\n\n```json\n{\n \"rulebook_version\": 1,\n \"name\": \"project-rules\",\n \"version\": \"1.0.0\",\n \"description\": \"Project-specific CC Safety Net rules.\",\n \"author\": \"project\",\n \"allowed_commands\": [\"docker\"],\n \"rules\": [\n {\n \"name\": \"block-docker-system-prune\",\n \"command\": \"docker\",\n \"subcommand\": \"system\",\n \"block_args\": [\"prune\"],\n \"reason\": \"Use targeted cleanup instead.\"\n }\n ],\n \"tests\": [\n {\n \"command\": \"docker system prune\",\n \"expect\": \"blocked\",\n \"rule\": \"block-docker-system-prune\"\n },\n {\n \"command\": \"docker ps\",\n \"expect\": \"allowed\"\n }\n ]\n}\n```\n\n### Rulebook Fields\n\n| Field | Required | Constraints |\n|-------|----------|-------------|\n| `rulebook_version` | Yes | Must be `1` |\n| `name` | Yes | `^[a-zA-Z][a-zA-Z0-9_-]{0,63}$` |\n| `version` | Yes | Non-empty string |\n| `description` | No | Free text; not type-checked at runtime |\n| `author` | No | Free text; not type-checked at runtime |\n| `allowed_commands` | Yes | Unique command names matching `^[a-zA-Z][a-zA-Z0-9_-]*$` |\n| `rules` | Yes | Array of rule objects |\n| `tests` | No | Array of fixtures |\n\n### Rule Fields\n\n| Field | Required | Constraints |\n|-------|----------|-------------|\n| `name` | Yes | Unique within the rulebook (case-insensitive); same pattern as rulebook `name` |\n| `command` | Yes | Must be listed in `allowed_commands`; basename only, not path |\n| `subcommand` | No | Same pattern as `command`; omit to match any subcommand |\n| `intent` | No | One of `hard_stop`, `use_alternative`, `scope_down`, `manual_only`, `stop_and_explain` |\n| `block_args` | Yes | Non-empty array of non-empty strings |\n| `reason` | Yes | Non-empty string, max 256 chars |\n\n### Test Fixture Fields\n\n| Field | Required | Constraints |\n|-------|----------|-------------|\n| `command` | Yes | Non-empty shell command string |\n| `expect` | Yes | `\"blocked\"` or `\"allowed\"` |\n| `rule` | Required for blocked fixtures | Rule name expected to block the command |\n\nFixtures are optional documentation of intended behavior. Fixtures are shape-validated only; CC Safety Net does not execute them.\n\n## Matching Behavior\n\n- **Command**: Normalized to lowercase basename with any trailing `.exe` removed (`/usr/bin/git` → `git`).\n- **Subcommand**: The first command token after recognized Git and Docker global options and their values; `--` ends option parsing. An unrecognized option without `=` may consume the following token as its value.\n- **Arguments**: Each `block_args` value is compared literally against every command token, including expanded short options. The command is blocked if **any** item matches.\n- **Short options**: Expanded (`-Ap` matches `-A`).\n- **Long options**: Exact match (`--all-files` does not match `--all`).\n- **Execution order**: Built-in rules first, then custom rulebooks. Custom rules only add restrictions.\n- **Transparent wrappers**: A configured wrapper such as `rtk` lets `rtk git commit` be analyzed as `git commit` only when `git` is protected by built-in analyzers or active custom rules. `rtk -- git commit` is also supported.\n\n## Workflow\n\n1. Run `cc-safety-net rule init` or create `rule.json` manually.\n2. Optionally run `cc-safety-net rule init --example` to create an inactive example rulebook.\n3. Use `cc-safety-net rule wrapper add rtk` for trusted transparent wrappers.\n4. Run `cc-safety-net rule add <source>` after creating or choosing a rulebook source; it adds the source and syncs it.\n5. Run `cc-safety-net rule sync` after manual `rule.json` changes or local rulebook edits.\n6. Run `cc-safety-net rule verify` to validate config, lock/cache state, local rulebooks, and shareable GitHub-source rulebook directories in the current repository (it does not fetch remote content).\n7. Run `cc-safety-net rule list` to inspect active rulebooks and transparent wrappers.\n\nAn edited or invalid local rulebook keeps its last synced, digest-verified cached version enforced until `cc-safety-net rule sync` validates the edit. A missing lock entry or cache, a cache digest mismatch, or an invalid cached rulebook makes that source inactive; a missing lockfile or an unreadable or invalid `rule.json` makes every source in its scope inactive. Inactive sources stop applying their rules while other custom rules and all built-in protections stay active. Repair the reported condition, then run `cc-safety-net rule sync`. Run `cc-safety-net status` to see degraded sources.\n";function Qn(n,t){if(!n.ok){o5(n);return}v5(n),console.log(t),console.log("Rule config synced."),console.log(""),i5(n.entries)}function i5(n){if(n.length===0){console.log("Active rulebooks: (none)");return}console.log(`Active rulebooks (${n.length}):`);for(let t of n)console.log(` - ${t.name} ${t.version} (${p5(t.ruleCount??0)})`),console.log(` Source: ${Mt(t)}`)}function p5(n){return`${n} ${n===1?"rule":"rules"}`}function El(n,t){J2("Active sources",n.rulebooks,(r)=>[`[${r.source}] ${r.name} ${r.version}`,` Source: ${t[r.source].get(r.spec)??r.spec}`]),J2("Active rules",n.rules,(r)=>[`[${u5(n,r.name)}] ${r.name}`,` Command: ${r.subcommand?`${r.command} ${r.subcommand}`:r.command}`,` Block args: ${r.block_args.join(", ")}`,` Reason: ${r.reason}`]),J2("Disabled rules",Tl(n,"off"),(r)=>[r.key]),J2("Reason overrides",Tl(n,"reason"),(r)=>[r.key,` Reason: ${r.value.reason}`]),J2("Transparent wrappers",n.transparent_wrappers,(r)=>[r]),J2("Issues",n.errors,(r)=>[r]),J2("Warnings",n.warnings,(r)=>[r])}function J2(n,t,r){if(t.length===0){console.log(`${n}: (none)`);return}console.log(`${n} (${t.length}):`);for(let e of t){let[a,...l]=r(e);console.log(` - ${a}`);for(let d of l)console.log(` ${d}`)}}function u5(n,t){return n.rulebooks.find((r)=>r.rules.includes(t))?.source??"project"}function Tl(n,t){return Object.entries({...n.userConfig?.overrides??{},...n.projectConfig?.overrides??{}}).filter((r)=>{if(t==="off")return r[1]==="off";return!!r[1]&&typeof r[1]==="object"}).map(([r,e])=>({key:r,value:e}))}function o5(n){for(let t of n.errors)console.error(t)}function v5(n){if(!n.warnings||n.warnings.length===0)return;for(let t of n.warnings)console.warn(t)}import{dirname as _l,join as ft}from"node:path";var b5=".safety-net.json",f5="~/.cc-safety-net/config.json";async function Il(n){return[await Pl({legacyPath:Nl({cwd:n.cwd}),configPath:E(n.cwd),defaultRulebookName:"project-rules",migratedFrom:b5,cleanup:n.cleanup,syncOptions:{cwd:n.cwd}}),await Pl({legacyPath:Ln(),configPath:_(),defaultRulebookName:"user-rules",migratedFrom:f5,cleanup:n.cleanup,syncOptions:{cwd:n.cwd,global:!0}})].every((r)=>r)?0:1}async function Pl(n){let t=U(n.syncOptions),r=D(t.filesystemScope,n.legacyPath),e=g(r);if(e===null)return console.log(`No legacy config found at ${n.legacyPath}`),!0;let a=h5(e);if(!a.ok){for(let v of a.errors)console.error(v);return!1}let l=O(t.configTarget);if(l.errors.length>0){for(let v of l.errors)console.error(v);return!1}let d=l.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},s=w5(_l(n.configPath),d.rules,n.defaultRulebookName,n.migratedFrom,t.filesystemScope),c=ft(_l(n.configPath),s,"rulebook.json"),L=D(t.filesystemScope,c),i=[ue(t.configTarget),ue(L),ue(t.lockTarget)],u=await y5(n,t.configTarget,L,s,a.config.rules,d.rules.includes(s)?d.rules:[...d.rules,s],d.overrides??{},d.transparent_wrappers??[]);if(!u.ok){g5(i);for(let v of u.errors)console.error(v);return!1}if(!n.cleanup)return console.log(`Migrated legacy config at ${n.legacyPath}. Legacy file is no longer used.`),!0;if(!$5(t.configTarget,L,s,n.migratedFrom,a.config.rules))return console.error(`Migration cleanup verification failed for ${n.legacyPath}`),!1;return sn(r),console.log(`Deleted legacy config at ${n.legacyPath}`),!0}async function y5(n,t,r,e,a,l,d,s){try{return T(t,{version:1,rules:l,overrides:d,transparent_wrappers:s}),T(r,x5(e,n.migratedFrom,a)),await W2(n.syncOptions)}catch(c){return{ok:!1,errors:[c instanceof Error?c.message:String(c)]}}}function h5(n){try{let t=JSON.parse(n),r=Bt(t);if(r.errors.length>0)return{ok:!1,errors:r.errors};return{ok:!0,config:{version:1,rules:t.rules??[]}}}catch{return{ok:!1,errors:["Invalid JSON"]}}}function w5(n,t,r,e,a){let l=t.find((d)=>D5(D(a,ft(n,d,"rulebook.json")))===e);if(l)return l;if(g(D(a,ft(n,r,"rulebook.json")))===null)return r;for(let d=2;;d++){let s=`${r}-${d}`;if(g(D(a,ft(n,s,"rulebook.json")))===null)return s}}function x5(n,t,r){return{rulebook_version:1,name:n,version:"1.0.0",description:"Migrated CC Safety Net rules.",author:"project",migrated_from:t,allowed_commands:[...new Set(r.map((e)=>e.command))],rules:r,tests:r.map((e)=>({command:[e.command,e.subcommand,e.block_args[0]].filter(Boolean).join(" "),expect:"blocked",rule:e.name}))}}function $5(n,t,r,e,a){if(!O(n).config?.rules.includes(r))return!1;try{let d=g(t);if(d===null)return!1;let s=JSON.parse(d);return s.migrated_from===e&&JSON.stringify(s.rules)===JSON.stringify(a)}catch{return!1}}function ue(n){return{target:n,content:g(n)}}function g5(n){for(let t of n){if(t.content===null){sn(t.target);continue}w2(t.target,t.content)}}function D5(n){let t=g(n);if(t===null)return null;try{let r=JSON.parse(t);return typeof r.migrated_from==="string"?r.migrated_from:null}catch{return null}}import{mkdir as m5,readFile as k5,writeFile as q5}from"node:fs/promises";import{dirname as j5,join as F5}from"node:path";var z5=86400000,B5=604800000;async function t3(n=Date.now()){if(process.env.CC_SAFETY_NET_NO_UPDATE_CHECK)return null;let t=Ut();if(!t)return null;let r=F5(t,".cc-safety-net","update-check.json"),e=await J5(r,n);if(!e.lastCheck||n-e.lastCheck>z5){let d=await E2();if(e.lastCheck=n,d.latestVersion)e.latestVersion=d.latestVersion;if(!await n3(r,e))return null;if(d.error)return null}let a=e.latestVersion,l=j();if(!a||!ir(a,l))return null;if(e.notifiedVersion===a&&e.notifiedAt!==void 0&&n-e.notifiedAt<B5)return null;if(e.notifiedVersion=a,e.notifiedAt=n,!await n3(r,e))return null;return`UPDATE_AVAILABLE: cc-safety-net v${a} is available (running v${l}). Ask the user once whether to run \`npx -y cc-safety-net@latest update\`; continue the current task either way and do not raise this again.`}async function J5(n,t){let r=await k5(n,"utf8").then((l)=>JSON.parse(l)).catch(()=>{return});if(!r||typeof r!=="object"||Array.isArray(r))return{};let e=r,a=(l)=>typeof l==="number"&&Number.isFinite(l)&&l<=t?l:void 0;return{lastCheck:a(e.lastCheck),latestVersion:typeof e.latestVersion==="string"?e.latestVersion:void 0,notifiedVersion:typeof e.notifiedVersion==="string"?e.notifiedVersion:void 0,notifiedAt:a(e.notifiedAt)}}async function n3(n,t){return m5(j5(n),{recursive:!0,mode:448}).then(()=>q5(n,JSON.stringify(t),{mode:384})).then(()=>!0).catch(()=>!1)}import{dirname as Z5,join as Q5,resolve as oe}from"node:path";var e3="CC Safety Net Config",X5="═".repeat(e3.length),Y5="https://raw.githubusercontent.com/kenryu42/cc-safety-net/main/assets/cc-safety-net.schema.json",S5=new Set(["rule.json","rule.lock","cache"]);function a3(n={}){try{return H5(n)}catch(t){if(t instanceof Z)return console.error(t.message),1;throw t}}function H5(n){let t=n.cwd??process.cwd(),r=n.userConfigPath??_(),e=n.projectConfigPath??E(t),a=n.legacyUserConfigPath??Ln(),l=n.legacyProjectConfigPath??Se(t),d=oe(t,Kt),s=Z5(r),c=P({cwd:t,userConfigPath:r,projectConfigPath:e}),L=P({cwd:t}),i=D(c.userScope,r),u=D(c.projectScope,e),v=n.legacyUserConfigPath?dn(n.legacyUserConfigPath,"user policy"):D(L.userScope,a),p=n.legacyProjectConfigPath?dn(n.legacyProjectConfigPath,"project policy"):D(L.projectScope,l),f=!1,o=!1,y=[],x=[],w=A5(D(L.projectScope,d));if(R5(),g(i)!==null){let h=a2(i);if(h.errors.push(...l2(r,R2({userConfigDir:s}),{userConfigDir:s},c.userScope)),y.push({scope:"User",path:r,result:h,schema:"rules",sourceDisplayMap:x2(r,c.userScope),target:i}),h.errors.length>0)f=!0}if(g(v)!==null)if(o=!0,g(i)!==null)x.push(yt("user","cleanup"));else{let h=Jt(v);if(y.push({scope:"User",path:a,result:h,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:v}),x.push(yt("user",h.errors.length>0?"fix-or-delete":"migrate")),h.errors.length>0)f=!0}if(g(u)!==null){let h=a2(u);if(h.errors.push(...l2(e,V2(e),{userConfigDir:s},c.projectScope)),y.push({scope:"Project",path:oe(e),result:h,schema:"rules",sourceDisplayMap:x2(e,c.projectScope),target:u}),h.errors.length>0)f=!0;if(g(p)!==null)o=!0,x.push(yt("project","cleanup"))}else if(g(p)!==null){o=!0,f=!0;let h=Jt(p);y.push({scope:"Project",path:oe(l),result:h,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:p}),x.push(yt("project",h.errors.length>0?"fix-or-delete":"migrate"))}if(w?.result.errors.length)f=!0;if(y.length===0&&!w)return console.log(`
230
- No config files found. Using built-in rules only.`),0;for(let h of y)if(h.inactive)K5(h.scope,h.path,h.result,h.sourceDisplayMap);else if(h.result.errors.length>0)M5(h.scope,h.path,h.result.errors);else{if(h.schema==="rules"&&U5(h.target))console.log(`
231
- Added $schema to ${h.scope.toLowerCase()} config.`);V5(h.scope,h.path,h.result,h.schema,h.sourceDisplayMap)}for(let h of x)console.error(`
232
- ${b.red(h)}`);if(w)if(w.result.errors.length>0)C5(w.path,w.result.errors);else G5(w.path,w.result);if(f)return console.error(`
233
- Config validation failed.`),1;return console.log(o?`
230
+ Check that every parent path component is a directory.`;return t}import{join as T5}from"node:path";var Tl="# 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 Yn(n,t){if(!n.ok){o5(n);return}b5(n),console.log(t),console.log("Rule config synced."),console.log(""),p5(n.entries)}function p5(n){if(n.length===0){console.log("Active rulebooks: (none)");return}console.log(`Active rulebooks (${n.length}):`);for(let t of n)console.log(` - ${t.name} ${t.version} (${u5(t.ruleCount??0)})`),console.log(` Source: ${Ot(t)}`)}function u5(n){return`${n} ${n===1?"rule":"rules"}`}function El(n,t){J2("Active sources",n.rulebooks,(r)=>[`[${r.source}] ${r.name} ${r.version}`,` Source: ${t[r.source].get(r.spec)??r.spec}`]),J2("Active rules",n.rules,(r)=>[`[${v5(n,r.name)}] ${r.name}`,` Command: ${r.subcommand?`${r.command} ${r.subcommand}`:r.command}`,` Block args: ${r.block_args.join(", ")}`,` Reason: ${r.reason}`]),J2("Disabled rules",_l(n,"off"),(r)=>[r.key]),J2("Reason overrides",_l(n,"reason"),(r)=>[r.key,` Reason: ${r.value.reason}`]),J2("Transparent wrappers",n.transparent_wrappers,(r)=>[r]),J2("Issues",n.errors,(r)=>[r]),J2("Warnings",n.warnings,(r)=>[r])}function J2(n,t,r){if(t.length===0){console.log(`${n}: (none)`);return}console.log(`${n} (${t.length}):`);for(let e of t){let[a,...l]=r(e);console.log(` - ${a}`);for(let d of l)console.log(` ${d}`)}}function v5(n,t){return n.rulebooks.find((r)=>r.rules.includes(t))?.source??"project"}function _l(n,t){return Object.entries({...n.userConfig?.overrides??{},...n.projectConfig?.overrides??{}}).filter((r)=>{if(t==="off")return r[1]==="off";return!!r[1]&&typeof r[1]==="object"}).map(([r,e])=>({key:r,value:e}))}function o5(n){for(let t of n.errors)console.error(t)}function b5(n){if(!n.warnings||n.warnings.length===0)return;for(let t of n.warnings)console.warn(t)}import{dirname as Pl,join as xt}from"node:path";var f5=".safety-net.json",y5="~/.cc-safety-net/config.json";async function n3(n){return[await Il({legacyPath:Nl({cwd:n.cwd}),configPath:_(n.cwd),defaultRulebookName:"project-rules",migratedFrom:f5,cleanup:n.cleanup,syncOptions:{cwd:n.cwd}}),await Il({legacyPath:pn(),configPath:E(),defaultRulebookName:"user-rules",migratedFrom:y5,cleanup:n.cleanup,syncOptions:{cwd:n.cwd,global:!0}})].every((r)=>r)?0:1}async function Il(n){let t=U(n.syncOptions),r=D(t.filesystemScope,n.legacyPath),e=g(r);if(e===null)return console.log(`No legacy config found at ${n.legacyPath}`),!0;let a=w5(e);if(!a.ok){for(let o of a.errors)console.error(o);return!1}let l=O(t.configTarget);if(l.errors.length>0){for(let o of l.errors)console.error(o);return!1}let d=l.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},s=x5(Pl(n.configPath),d.rules,n.defaultRulebookName,n.migratedFrom,t.filesystemScope),L=xt(Pl(n.configPath),s,"rulebook.json"),c=D(t.filesystemScope,L),i=[u1(t.configTarget),u1(c),u1(t.lockTarget)],u=await h5(n,t.configTarget,c,s,a.config.rules,d.rules.includes(s)?d.rules:[...d.rules,s],d.overrides??{},d.transparent_wrappers??[]);if(!u.ok){D5(i);for(let o of u.errors)console.error(o);return!1}if(!n.cleanup)return console.log(`Migrated legacy config at ${n.legacyPath}. Legacy file is no longer used.`),!0;if(!g5(t.configTarget,c,s,n.migratedFrom,a.config.rules))return console.error(`Migration cleanup verification failed for ${n.legacyPath}`),!1;return Ln(r),console.log(`Deleted legacy config at ${n.legacyPath}`),!0}async function h5(n,t,r,e,a,l,d,s){try{return T(t,{version:1,rules:l,overrides:d,transparent_wrappers:s}),T(r,$5(e,n.migratedFrom,a)),await W2(n.syncOptions)}catch(L){return{ok:!1,errors:[L instanceof Error?L.message:String(L)]}}}function w5(n){try{let t=JSON.parse(n),r=Xt(t);if(r.errors.length>0)return{ok:!1,errors:r.errors};return{ok:!0,config:{version:1,rules:t.rules??[]}}}catch{return{ok:!1,errors:["Invalid JSON"]}}}function x5(n,t,r,e,a){let l=t.find((d)=>m5(D(a,xt(n,d,"rulebook.json")))===e);if(l)return l;if(g(D(a,xt(n,r,"rulebook.json")))===null)return r;for(let d=2;;d++){let s=`${r}-${d}`;if(g(D(a,xt(n,s,"rulebook.json")))===null)return s}}function $5(n,t,r){return{rulebook_version:1,name:n,version:"1.0.0",description:"Migrated CC Safety Net rules.",author:"project",migrated_from:t,allowed_commands:[...new Set(r.map((e)=>e.command))],rules:r,tests:r.map((e)=>({command:[e.command,e.subcommand,e.block_args[0]].filter(Boolean).join(" "),expect:"blocked",rule:e.name}))}}function g5(n,t,r,e,a){if(!O(n).config?.rules.includes(r))return!1;try{let d=g(t);if(d===null)return!1;let s=JSON.parse(d);return s.migrated_from===e&&JSON.stringify(s.rules)===JSON.stringify(a)}catch{return!1}}function u1(n){return{target:n,content:g(n)}}function D5(n){for(let t of n){if(t.content===null){Ln(t.target);continue}w2(t.target,t.content)}}function m5(n){let t=g(n);if(t===null)return null;try{let r=JSON.parse(t);return typeof r.migrated_from==="string"?r.migrated_from:null}catch{return null}}import{mkdir as k5,readFile as q5,writeFile as j5}from"node:fs/promises";import{dirname as F5,join as z5}from"node:path";var B5=86400000,J5=604800000;async function r3(n=Date.now()){if(process.env.CC_SAFETY_NET_NO_UPDATE_CHECK)return null;let t=Et();if(!t)return null;let r=z5(t,".cc-safety-net","update-check.json"),e=await Z5(r,n);if(!e.lastCheck||n-e.lastCheck>B5){let d=await E2();if(e.lastCheck=n,d.latestVersion)e.latestVersion=d.latestVersion;if(!await t3(r,e))return null;if(d.error)return null}let a=e.latestVersion,l=j();if(!a||!or(a,l))return null;if(e.notifiedVersion===a&&e.notifiedAt!==void 0&&n-e.notifiedAt<J5)return null;if(e.notifiedVersion=a,e.notifiedAt=n,!await t3(r,e))return null;return`UPDATE_AVAILABLE: cc-safety-net v${a} is available (running v${l}). Ask the user once whether to run \`npx -y cc-safety-net@latest update\`; continue the current task either way and do not raise this again.`}async function Z5(n,t){let r=await q5(n,"utf8").then((l)=>JSON.parse(l)).catch(()=>{return});if(!r||typeof r!=="object"||Array.isArray(r))return{};let e=r,a=(l)=>typeof l==="number"&&Number.isFinite(l)&&l<=t?l:void 0;return{lastCheck:a(e.lastCheck),latestVersion:typeof e.latestVersion==="string"?e.latestVersion:void 0,notifiedVersion:typeof e.notifiedVersion==="string"?e.notifiedVersion:void 0,notifiedAt:a(e.notifiedAt)}}async function t3(n,t){return k5(F5(n),{recursive:!0,mode:448}).then(()=>j5(n,JSON.stringify(t),{mode:384})).then(()=>!0).catch(()=>!1)}import{dirname as Q5,join as X5,resolve as v1}from"node:path";var a3="CC Safety Net Config",Y5="═".repeat(a3.length),S5="https://raw.githubusercontent.com/kenryu42/cc-safety-net/main/assets/cc-safety-net.schema.json",H5=new Set(["rule.json","rule.lock","cache"]);function l3(n={}){try{return A5(n)}catch(t){if(t instanceof Z)return console.error(t.message),1;throw t}}function A5(n){let t=n.cwd??process.cwd(),r=n.userConfigPath??E(),e=n.projectConfigPath??_(t),a=n.legacyUserConfigPath??pn(),l=n.legacyProjectConfigPath??S1(t),d=v1(t,Ut),s=Q5(r),L=P({cwd:t,userConfigPath:r,projectConfigPath:e}),c=P({cwd:t}),i=D(L.userScope,r),u=D(L.projectScope,e),o=n.legacyUserConfigPath?sn(n.legacyUserConfigPath,"user policy"):D(c.userScope,a),p=n.legacyProjectConfigPath?sn(n.legacyProjectConfigPath,"project policy"):D(c.projectScope,l),f=!1,v=!1,y=[],x=[],w=W5(D(c.projectScope,d));if(K5(),g(i)!==null){let h=a2(i);if(h.errors.push(...l2(r,R2({userConfigDir:s}),{userConfigDir:s},L.userScope)),y.push({scope:"User",path:r,result:h,schema:"rules",sourceDisplayMap:x2(r,L.userScope),target:i}),h.errors.length>0)f=!0}if(g(o)!==null)if(v=!0,g(i)!==null)x.push($t("user","cleanup"));else{let h=Yt(o);if(y.push({scope:"User",path:a,result:h,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:o}),x.push($t("user",h.errors.length>0?"fix-or-delete":"migrate")),h.errors.length>0)f=!0}if(g(u)!==null){let h=a2(u);if(h.errors.push(...l2(e,K2(e),{userConfigDir:s},L.projectScope)),y.push({scope:"Project",path:v1(e),result:h,schema:"rules",sourceDisplayMap:x2(e,L.projectScope),target:u}),h.errors.length>0)f=!0;if(g(p)!==null)v=!0,x.push($t("project","cleanup"))}else if(g(p)!==null){v=!0,f=!0;let h=Yt(p);y.push({scope:"Project",path:v1(l),result:h,schema:"legacy",sourceDisplayMap:new Map,inactive:!0,target:p}),x.push($t("project",h.errors.length>0?"fix-or-delete":"migrate"))}if(w?.result.errors.length)f=!0;if(y.length===0&&!w)return console.log(`
231
+ No config files found. Using built-in rules only.`),0;for(let h of y)if(h.inactive)V5(h.scope,h.path,h.result,h.sourceDisplayMap);else if(h.result.errors.length>0)G5(h.scope,h.path,h.result.errors);else{if(h.schema==="rules"&&O5(h.target))console.log(`
232
+ Added $schema to ${h.scope.toLowerCase()} config.`);M5(h.scope,h.path,h.result,h.schema,h.sourceDisplayMap)}for(let h of x)console.error(`
233
+ ${b.red(h)}`);if(w)if(w.result.errors.length>0)U5(w.path,w.result.errors);else C5(w.path,w.result);if(f)return console.error(`
234
+ Config validation failed.`),1;return console.log(v?`
234
235
  Configs valid with warnings.`:`
235
- All configs valid.`),0}function yt(n,t){let r=`legacy ${n} config`;if(t==="cleanup")return`Warning: Legacy ${n} config is no longer needed. Run \`npx -y cc-safety-net rule migrate --cleanup\` to clean it up safely.`;if(t==="migrate")return`Warning: Legacy ${n} config is ignored by CC Safety Net. Run \`npx -y cc-safety-net rule migrate\`.`;return`Warning: Legacy ${n} config is no longer supported. Fix or delete the ${r}, then run \`npx -y cc-safety-net rule migrate\`.`}function A5(n){if(A2(n)===null)return null;let t=W5(n);if(t.ruleNames.size===0&&t.errors.length===0)return null;return{path:n.path,result:t}}function W5(n){let t=[],r=new Set,e=(A2(n)??[]).filter((a)=>!S5.has(a.name)).sort((a,l)=>a.name.localeCompare(l.name));if(e.length===0)return{errors:t,ruleNames:r};for(let a of e){if(!cn.test(a.name)){t.push(`rulebook directory names must match ${cn}: ${a.name}`);continue}if(a.kind!=="directory"){t.push(`${a.name} must be a rulebook directory`);continue}let l=D(n.scope,Q5(n.path,a.name,"rulebook.json")),d=g(l);if(d===null){t.push(`${a.name}/rulebook.json is required`);continue}try{let s;try{s=JSON.parse(d)}catch{t.push(`${a.name}/rulebook.json: invalid JSON`);continue}let c=r3(s);if(c.name!==a.name){t.push(`rulebook name "${c.name}" must match folder "${a.name}"`);continue}r.add(a.name)}catch(s){t.push(s instanceof Error?`${a.name}/rulebook.json: ${s.message}`:`${a.name}/rulebook.json: ${String(s)}`)}}return{errors:t,ruleNames:r}}function R5(){console.log(e3),console.log(X5)}function V5(n,t,r,e,a){if(console.log(`
236
- ✓ ${n} config: ${t}`),console.log(` Schema: ${e==="rules"?"rulebook sources":"legacy inline rules"}`),r.ruleNames.size>0){console.log(` ${e==="rules"?"Sources":"Rules"}:`);let l=1;for(let d of r.ruleNames)console.log(` ${l}. ${a.get(d)??d}`),l++}else console.log(` ${e==="rules"?"Sources":"Rules"}: (none)`)}function K5(n,t,r,e){if(console.error(`
237
- ✗ Legacy ${n.toLowerCase()} config: ${t}`),console.error(" Schema: legacy inline rules"),console.error(" Status: ignored by CC Safety Net"),r.errors.length>0){console.error(" Errors:");let a=1;for(let l of r.errors)for(let d of l.split("; "))console.error(` ${a}. ${d}`),a++;return}if(r.ruleNames.size>0){console.error(" Rules:");let a=1;for(let l of r.ruleNames)console.error(` ${a}. ${e.get(l)??l}`),a++;return}console.error(" Rules: (none)")}function M5(n,t,r){l3(`${n} config`,t,r)}function G5(n,t){console.log(`
238
- ✓ GitHub source rules: ${n}`),console.log(" Rulebooks:");let r=1;for(let e of t.ruleNames)console.log(` ${r}. ${e}`),r++}function C5(n,t){l3("GitHub source rules",n,t)}function l3(n,t,r){console.error(`
239
- ✗ ${n}: ${t}`),console.error(" Errors:");let e=1;for(let a of r)for(let l of a.split("; "))console.error(` ${e}. ${l}`),e++}function U5(n){try{let t=g(n);if(t===null)return!1;let r=JSON.parse(t);if(r.$schema)return!1;return w2(n,JSON.stringify({$schema:Y5,...r},null,2)),!0}catch(t){if(t instanceof Z)throw t;return!1}}var d3=new Set(["init","add","remove","update","sync","list","wrapper","migrate","doc","verify"]),T5=new Set(["add","remove","list"]);async function c3(n){try{return await E5(n)}catch(t){if(t instanceof Z)return console.error(t.message),1;throw t}}async function E5(n){let t=P5(n),r=t.help?_5(t.positionals):null;if(r)return dt(r),0;if(t.errors.length>0){for(let d of t.errors)console.error(d);return 1}let e=t.positionals[0];if(!e)return dt(T2,console.error),1;let a=t.positionals[1],l={global:t.global,check:t.check};if(e==="init"){let d=U(l),s=d.configDir;n8(d.configTarget),s3(D(d.filesystemScope,Hn({...l,cacheConfigDir:s})));let c=O5(s,"example-rules","rulebook.json"),L=D(d.filesystemScope,c);if(t.example&&g(L)===null)Ct(L,"example-rules");let i=await W2(l);return Qn(i,"Rule config initialized."),i.ok?0:1}if(e==="add"){if(!a)return console.error("rule add requires a source"),1;let d=await Wt(a,l);return Qn(d,`Added rulebook source: ${a}`),d.ok?0:1}if(e==="remove"){if(!a)return console.error("rule remove requires a source"),1;let d=await Vt(a,{...l,deleteSource:t.deleteSource});return Qn(d,`Removed rulebook source: ${a}`),d.ok?0:1}if(e==="update"||e==="sync"){let d=await W2({...l,only:e==="update"?a:void 0});return Qn(d,t.check?"Rule config checked.":"Rule config synced."),d.ok?0:1}if(e==="list"){let d=o2(),s=P({});return El(d,{user:x2(d.userConfigPath,s.userScope),project:x2(d.projectConfigPath,s.projectScope)}),d.errors.length>0?1:0}if(e==="wrapper")return t8(t);if(e==="migrate")return Il({cleanup:t.cleanup,cwd:process.cwd()});if(e==="doc"){console.log(Ol);let d=await t3();if(d)console.error(d);return 0}if(e==="verify")return a3();return 1}function _5(n){if(n.length===0)return T2;let t=T2.subcommands.filter((e)=>e.usage.split(" ")[0]===n[0]);if(t.length===0)return null;if(n.length===1&&t.length>1)return{name:`rule ${n[0]}`,description:`Subcommands of rule ${n[0]}`,usage:`rule ${n[0]} <subcommand>`,subcommands:t,options:[]};let r=n.length===1?t[0]:t.find((e)=>e.usage.split(" ")[1]===n[1]);if(!r)return null;return{name:`rule ${n[0]}`,description:r.description,usage:`rule ${r.usage}`,options:[]}}function P5(n){let t=F({label:"rule",booleans:{global:["-g","--global"],check:["--check"],cleanup:["--cleanup"],deleteSource:["--delete-source"],example:["--example"]},positionals:"list"},n),r={...t.flags,help:t.help,positionals:t.positionals,errors:t.errors};return N5(r),r}function N5(n){let[t]=n.positionals;if(t&&!d3.has(t))n.errors.push(`Unknown rule subcommand: ${t}`);if(n.deleteSource&&t!=="remove")if(t&&d3.has(t))n.errors.push(`Unknown option for rule ${t}: --delete-source`);else n.errors.push("--delete-source is only valid with 'rule remove'");if(n.cleanup&&t!=="migrate")n.errors.push(ht(t,"--cleanup"));if(n.example&&t!=="init")n.errors.push(ht(t,"--example"));if(t==="migrate"){if(n.global)n.errors.push(ht(t,"--global"));if(n.check)n.errors.push(ht(t,"--check"));if(n.positionals.length>1)n.errors.push(`Unexpected rule migrate argument: ${n.positionals[1]}`)}else if(t==="wrapper")I5(n);else if(n.positionals.length>2)n.errors.push(`Unexpected rule argument: ${n.positionals[2]}`);if(t==="list"&&n.global)n.errors.push("Unknown option for rule list: --global")}function ht(n,t){return n?`Unknown option for rule ${n}: ${t}`:`Unknown option for rule: ${t}`}function I5(n){let t=n.positionals[1],r=n.positionals[2];if(!t){n.errors.push("rule wrapper requires add, remove, or list");return}if(!T5.has(t)){n.errors.push(`Unknown rule wrapper action: ${t}`);return}if(t==="list"){if(r)n.errors.push(`Unexpected rule wrapper argument: ${r}`);return}if(!r){n.errors.push(`rule wrapper ${t} requires a command`);return}if(n.positionals.length>3)n.errors.push(`Unexpected rule wrapper argument: ${n.positionals[3]}`)}function n8(n){if(g(n)===null){Gt(n);return}let t=O(n);if(!t.config)return;T(n,{version:1,rules:t.config.rules,overrides:t.config.overrides??{},transparent_wrappers:t.config.transparent_wrappers??[]})}async function t8(n){let t=n.positionals[1],r=n.positionals[2],e=U({global:n.global}).configTarget;if(t==="list"){let s=O(e);if(s.errors.length>0){for(let c of s.errors)console.error(c);return 1}return r8(s.config?.transparent_wrappers??[]),0}if(!r||!Ot.test(r))return console.error("transparent wrapper must match command pattern"),1;if(Tt(r))return console.error(`reserved command "${r}" cannot be a wrapper`),1;let a=O(e);if(a.errors.length>0){for(let s of a.errors)console.error(s);return 1}let l=a.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},d=t==="add"?[...new Set([...l.transparent_wrappers??[],r])]:(l.transparent_wrappers??[]).filter((s)=>s!==r);return T(e,{version:1,rules:l.rules,overrides:l.overrides??{},transparent_wrappers:d}),console.log(t==="add"?`Added transparent wrapper: ${r}`:`Removed transparent wrapper: ${r}`),0}function r8(n){if(n.length===0){console.log("Transparent wrappers: (none)");return}console.log(`Transparent wrappers (${n.length}):`);for(let t of n)console.log(` - ${t}`)}import{homedir as L3}from"node:os";import{existsSync as e8,readFileSync as a8}from"node:fs";import{homedir as l8}from"node:os";import{join as d8}from"node:path";async function s8(){if(process.stdin.isTTY)return null;return(await tr(process.stdin).catch(()=>null))?.trim()||null}function c8(){if(process.env.CLAUDE_SETTINGS_PATH)return process.env.CLAUDE_SETTINGS_PATH;return d8(l8(),".claude","settings.json")}function ve(){let n=c8();if(!e8(n))return!1;try{let t=a8(n,"utf-8"),r=JSON.parse(t);if(!r.enabledPlugins)return!1;let e="cc-safety-net@cc-marketplace";if(!(e in r.enabledPlugins))return!1;return r.enabledPlugins[e]===!0}catch(t){if(on(m.debug))console.error(`CC Safety Net debug: failed to read Claude settings: ${n}: ${t instanceof Error?t.message:String(t)}`);return!1}}async function be(){let n=ve(),t;if(!n)t="\uD83D\uDEE1️ CC Safety Net ❌";else{let e=W({cwd:process.cwd()}),a=e.policy,l=d2(a),d=Object.values(g2(a,l.capabilities)).some((c)=>c.changesInherited);t=`\uD83D\uDEE1️ CC Safety Net ${{standard:"✅",strict:"\uD83D\uDD12",paranoid:"\uD83D\uDC41️",custom:"\uD83D\uDD27"}[d?"custom":l.effectiveLevel]}${l.worktreeMode?"\uD83C\uDF33":""}${e.state==="degraded"?"⚠️":""}`}let r=await s8();if(r&&!r.startsWith("{"))console.log(`${r} | ${t}`);else console.log(t)}function i3(){let n=W({cwd:process.cwd()}),t=n.policy,r=d2(t),e=!!process.env.NO_COLOR||!process.stdout.isTTY,a=Math.min(process.stdout.columns||80,100),l=e?"ok":"✔",d=e?"OFF":"✘",s=(p,f)=>{let o=` ${p.padEnd(13)}${f}`;return(o.length>a?`${o.slice(0,a-1)}…`:o).replaceAll(d,b.red(d))},c=Object.values(g2(t,r.capabilities)).some((p)=>p.changesInherited),L=vn(),i={ready:b.green,degraded:b.yellow}[n.state],u=[...ve()?[]:["plugin cc-safety-net@cc-marketplace is disabled in Claude Code; nothing is enforced in Claude Code until it is re-enabled. Other integrations are not affected."],...n.diagnostics],v=e?"-":"·";console.log([`${e?"":"\uD83D\uDEE1️ "}CC Safety Net — ${i(n.state)}`,"",s("Protection",`destructive ${t.destructiveCommandProtectionEnabled?l:d} secrets ${t.secretProtection.enabled?l:d}`),s("Level",c?`${r.effectiveLevel} (customised)`:r.effectiveLevel),s("Rules",t.rules.length===0?"none active":`${t.rules.length} active`),s("Policy",L.startsWith(L3())?`~${L.slice(L3().length)}`:L),...r.worktreeMode?[s("Worktree","relaxations active")]:[],"",...u.length===0?[" Everything configured is active."]:[" Not active",...u.flatMap((p)=>lt(p," ",a-6).map((f,o)=>o===0?` ${v} ${f}`:f)),""," Full report: cc-safety-net doctor"]].join(`
240
- `))}import{spawn as z3}from"node:child_process";import{randomBytes as w8}from"node:crypto";import{createServer as x8}from"node:http";import{Writable as $8}from"node:stream";import{homedir as L8}from"node:os";var wt=500;function i8(n){let t=n.filter((a)=>a.decision!=="allow"),r=n.filter((a)=>a.decision==="allow"),e=Math.min(t.length,Math.max(wt-r.length,Math.ceil(wt/2)));return[...t.slice(0,e),...r.slice(0,wt-e)]}function p3(n,t=s2()){if(t)$2(t);let r=(o)=>new Date(o.getFullYear(),o.getMonth(),o.getDate()).getTime(),e=r(new Date),a=new Date(e);a.setDate(a.getDate()-(n-1));let l=a.getTime(),d=[],s={count:0};for(let o of t?u2(t,s):[])for(let y of ln(o,s)){if(!y||typeof y.ts!=="string"||typeof y.command!=="string")continue;let x=new Date(y.ts).getTime();if(!Number.isFinite(x))continue;if(x>=l)d.push(y)}d.sort((o,y)=>new Date(y.ts).getTime()-new Date(o.ts).getTime());let c=Array.from({length:n},()=>0),L=Array.from({length:n},()=>0),i={},u={},v={},p=0,f=0;for(let o of d){let y=o.agent||"unknown";i[y]=(i[y]??0)+1;let x=Math.round((e-r(new Date(o.ts)))/86400000),w=n-1-x,h=x>=0&&x<n;if(h)L[w]=(L[w]??0)+1;if(o.decision!=="allow"){if(p++,o.ruleId)u[o.ruleId]=(u[o.ruleId]??0)+1;let J=Q2(o.segment||o.command);if(J)v[J]=(v[J]??0)+1;if(o.failureStage)f++;if(h)c[w]=(c[w]??0)+1}}return{days:n,logsDir:t,homeDir:L8(),totalInWindow:d.length,truncated:d.length>wt,unreadable:s.count,counts:{blocked:p,allowed:d.length-p,agents:i,blockedByDay:c,analyzedByDay:L,rules:u,commands:v,errors:f},entries:i8(d).sort((o,y)=>new Date(y.ts).getTime()-new Date(o.ts).getTime())}}import{spawn as p8}from"node:child_process";import{existsSync as u3,statSync as u8}from"node:fs";import{delimiter as o8,join as v8}from"node:path";var b8=120000,xt="Choose the project folder",f8=`try
241
- return POSIX path of (choose folder with prompt "${xt}")
236
+ All configs valid.`),0}function $t(n,t){let r=`legacy ${n} config`;if(t==="cleanup")return`Warning: Legacy ${n} config is no longer needed. Run \`npx -y cc-safety-net rule migrate --cleanup\` to clean it up safely.`;if(t==="migrate")return`Warning: Legacy ${n} config is ignored by CC Safety Net. Run \`npx -y cc-safety-net rule migrate\`.`;return`Warning: Legacy ${n} config is no longer supported. Fix or delete the ${r}, then run \`npx -y cc-safety-net rule migrate\`.`}function W5(n){if(A2(n)===null)return null;let t=R5(n);if(t.ruleNames.size===0&&t.errors.length===0)return null;return{path:n.path,result:t}}function R5(n){let t=[],r=new Set,e=(A2(n)??[]).filter((a)=>!H5.has(a.name)).sort((a,l)=>a.name.localeCompare(l.name));if(e.length===0)return{errors:t,ruleNames:r};for(let a of e){if(!cn.test(a.name)){t.push(`rulebook directory names must match ${cn}: ${a.name}`);continue}if(a.kind!=="directory"){t.push(`${a.name} must be a rulebook directory`);continue}let l=D(n.scope,X5(n.path,a.name,"rulebook.json")),d=g(l);if(d===null){t.push(`${a.name}/rulebook.json is required`);continue}try{let s;try{s=JSON.parse(d)}catch{t.push(`${a.name}/rulebook.json: invalid JSON`);continue}let L=e3(s);if(L.name!==a.name){t.push(`rulebook name "${L.name}" must match folder "${a.name}"`);continue}r.add(a.name)}catch(s){t.push(s instanceof Error?`${a.name}/rulebook.json: ${s.message}`:`${a.name}/rulebook.json: ${String(s)}`)}}return{errors:t,ruleNames:r}}function K5(){console.log(a3),console.log(Y5)}function M5(n,t,r,e,a){if(console.log(`
237
+ ✓ ${n} config: ${t}`),console.log(` Schema: ${e==="rules"?"rulebook sources":"legacy inline rules"}`),r.ruleNames.size>0){console.log(` ${e==="rules"?"Sources":"Rules"}:`);let l=1;for(let d of r.ruleNames)console.log(` ${l}. ${a.get(d)??d}`),l++}else console.log(` ${e==="rules"?"Sources":"Rules"}: (none)`)}function V5(n,t,r,e){if(console.error(`
238
+ ✗ Legacy ${n.toLowerCase()} config: ${t}`),console.error(" Schema: legacy inline rules"),console.error(" Status: ignored by CC Safety Net"),r.errors.length>0){console.error(" Errors:");let a=1;for(let l of r.errors)for(let d of l.split("; "))console.error(` ${a}. ${d}`),a++;return}if(r.ruleNames.size>0){console.error(" Rules:");let a=1;for(let l of r.ruleNames)console.error(` ${a}. ${e.get(l)??l}`),a++;return}console.error(" Rules: (none)")}function G5(n,t,r){d3(`${n} config`,t,r)}function C5(n,t){console.log(`
239
+ ✓ GitHub source rules: ${n}`),console.log(" Rulebooks:");let r=1;for(let e of t.ruleNames)console.log(` ${r}. ${e}`),r++}function U5(n,t){d3("GitHub source rules",n,t)}function d3(n,t,r){console.error(`
240
+ ✗ ${n}: ${t}`),console.error(" Errors:");let e=1;for(let a of r)for(let l of a.split("; "))console.error(` ${e}. ${l}`),e++}function O5(n){try{let t=g(n);if(t===null)return!1;let r=JSON.parse(t);if(r.$schema)return!1;return w2(n,JSON.stringify({$schema:S5,...r},null,2)),!0}catch(t){if(t instanceof Z)throw t;return!1}}var s3=new Set(["init","add","remove","update","sync","list","wrapper","migrate","doc","verify"]),_5=new Set(["add","remove","list"]);async function c3(n){try{return await E5(n)}catch(t){if(t instanceof Z)return console.error(t.message),1;throw t}}async function E5(n){let t=I5(n),r=t.help?P5(t.positionals):null;if(r)return st(r),0;if(t.errors.length>0){for(let d of t.errors)console.error(d);return 1}let e=t.positionals[0];if(!e)return st(T2,console.error),1;let a=t.positionals[1],l={global:t.global,check:t.check};if(e==="init"){let d=U(l),s=d.configDir;t8(d.configTarget),L3(D(d.filesystemScope,Wn({...l,cacheConfigDir:s})));let L=T5(s,"example-rules","rulebook.json"),c=D(d.filesystemScope,L);if(t.example&&g(c)===null)_t(c,"example-rules");let i=await W2(l);return Yn(i,"Rule config initialized."),i.ok?0:1}if(e==="add"){if(!a)return console.error("rule add requires a source"),1;let d=await Vt(a,l);return Yn(d,`Added rulebook source: ${a}`),d.ok?0:1}if(e==="remove"){if(!a)return console.error("rule remove requires a source"),1;let d=await Ct(a,{...l,deleteSource:t.deleteSource});return Yn(d,`Removed rulebook source: ${a}`),d.ok?0:1}if(e==="update"||e==="sync"){let d=await W2({...l,only:e==="update"?a:void 0});return Yn(d,t.check?"Rule config checked.":"Rule config synced."),d.ok?0:1}if(e==="list"){let d=v2(),s=P({});return El(d,{user:x2(d.userConfigPath,s.userScope),project:x2(d.projectConfigPath,s.projectScope)}),d.errors.length>0?1:0}if(e==="wrapper")return r8(t);if(e==="migrate")return n3({cleanup:t.cleanup,cwd:process.cwd()});if(e==="doc"){console.log(Tl);let d=await r3();if(d)console.error(d);return 0}if(e==="verify")return l3();return 1}function P5(n){if(n.length===0)return T2;let t=T2.subcommands.filter((e)=>e.usage.split(" ")[0]===n[0]);if(t.length===0)return null;if(n.length===1&&t.length>1)return{name:`rule ${n[0]}`,description:`Subcommands of rule ${n[0]}`,usage:`rule ${n[0]} <subcommand>`,subcommands:t,options:[]};let r=n.length===1?t[0]:t.find((e)=>e.usage.split(" ")[1]===n[1]);if(!r)return null;return{name:`rule ${n[0]}`,description:r.description,usage:`rule ${r.usage}`,options:[]}}function I5(n){let t=F({label:"rule",booleans:{global:["-g","--global"],check:["--check"],cleanup:["--cleanup"],deleteSource:["--delete-source"],example:["--example"]},positionals:"list"},n),r={...t.flags,help:t.help,positionals:t.positionals,errors:t.errors};return N5(r),r}function N5(n){let[t]=n.positionals;if(t&&!s3.has(t))n.errors.push(`Unknown rule subcommand: ${t}`);if(n.deleteSource&&t!=="remove")if(t&&s3.has(t))n.errors.push(`Unknown option for rule ${t}: --delete-source`);else n.errors.push("--delete-source is only valid with 'rule remove'");if(n.cleanup&&t!=="migrate")n.errors.push(gt(t,"--cleanup"));if(n.example&&t!=="init")n.errors.push(gt(t,"--example"));if(t==="migrate"){if(n.global)n.errors.push(gt(t,"--global"));if(n.check)n.errors.push(gt(t,"--check"));if(n.positionals.length>1)n.errors.push(`Unexpected rule migrate argument: ${n.positionals[1]}`)}else if(t==="wrapper")n8(n);else if(n.positionals.length>2)n.errors.push(`Unexpected rule argument: ${n.positionals[2]}`);if(t==="list"&&n.global)n.errors.push("Unknown option for rule list: --global")}function gt(n,t){return n?`Unknown option for rule ${n}: ${t}`:`Unknown option for rule: ${t}`}function n8(n){let t=n.positionals[1],r=n.positionals[2];if(!t){n.errors.push("rule wrapper requires add, remove, or list");return}if(!_5.has(t)){n.errors.push(`Unknown rule wrapper action: ${t}`);return}if(t==="list"){if(r)n.errors.push(`Unexpected rule wrapper argument: ${r}`);return}if(!r){n.errors.push(`rule wrapper ${t} requires a command`);return}if(n.positionals.length>3)n.errors.push(`Unexpected rule wrapper argument: ${n.positionals[3]}`)}function t8(n){if(g(n)===null){Tt(n);return}let t=O(n);if(!t.config)return;T(n,{version:1,rules:t.config.rules,overrides:t.config.overrides??{},transparent_wrappers:t.config.transparent_wrappers??[]})}async function r8(n){let t=n.positionals[1],r=n.positionals[2],e=U({global:n.global}).configTarget;if(t==="list"){let s=O(e);if(s.errors.length>0){for(let L of s.errors)console.error(L);return 1}return e8(s.config?.transparent_wrappers??[]),0}if(!r||!Pt.test(r))return console.error("transparent wrapper must match command pattern"),1;if(It(r))return console.error(`reserved command "${r}" cannot be a wrapper`),1;let a=O(e);if(a.errors.length>0){for(let s of a.errors)console.error(s);return 1}let l=a.config??{version:1,rules:[],overrides:{},transparent_wrappers:[]},d=t==="add"?[...new Set([...l.transparent_wrappers??[],r])]:(l.transparent_wrappers??[]).filter((s)=>s!==r);return T(e,{version:1,rules:l.rules,overrides:l.overrides??{},transparent_wrappers:d}),console.log(t==="add"?`Added transparent wrapper: ${r}`:`Removed transparent wrapper: ${r}`),0}function e8(n){if(n.length===0){console.log("Transparent wrappers: (none)");return}console.log(`Transparent wrappers (${n.length}):`);for(let t of n)console.log(` - ${t}`)}import{homedir as i3}from"node:os";import{existsSync as a8,readFileSync as l8}from"node:fs";import{homedir as d8}from"node:os";import{join as s8}from"node:path";async function L8(n){if(n.isTTY)return null;return(await lr(n).catch(()=>null))?.trim()||null}function c8(){if(process.env.CLAUDE_SETTINGS_PATH)return process.env.CLAUDE_SETTINGS_PATH;return s8(d8(),".claude","settings.json")}function o1(){let n=c8();if(!a8(n))return!1;try{let t=l8(n,"utf-8"),r=JSON.parse(t);if(!r.enabledPlugins)return!1;let e="cc-safety-net@cc-marketplace";if(!(e in r.enabledPlugins))return!1;return r.enabledPlugins[e]===!0}catch(t){if(on(m.debug))console.error(`CC Safety Net debug: failed to read Claude settings: ${n}: ${t instanceof Error?t.message:String(t)}`);return!1}}async function b1(n=process.stdin){let t=o1(),r;if(!t)r="\uD83D\uDEE1️ CC Safety Net ❌";else{let a=W({cwd:process.cwd()}),l=a.policy,d=d2(l),s=Object.values(g2(l,d.capabilities)).some((c)=>c.changesInherited);r=`\uD83D\uDEE1️ CC Safety Net ${{standard:"✅",strict:"\uD83D\uDD12",paranoid:"\uD83D\uDC41️",custom:"\uD83D\uDD27"}[s?"custom":d.effectiveLevel]}${d.worktreeMode?"\uD83C\uDF33":""}${a.state==="degraded"?"⚠️":""}`}let e=await L8(n);if(e&&!e.startsWith("{"))console.log(`${e} | ${r}`);else console.log(r)}function p3(){let n=W({cwd:process.cwd()}),t=n.policy,r=d2(t),e=!!process.env.NO_COLOR||!process.stdout.isTTY,a=Math.min(process.stdout.columns||80,100),l=e?"ok":"✔",d=e?"OFF":"✘",s=(p,f)=>{let v=` ${p.padEnd(13)}${f}`;return(v.length>a?`${v.slice(0,a-1)}…`:v).replaceAll(d,b.red(d))},L=Object.values(g2(t,r.capabilities)).some((p)=>p.changesInherited),c=bn(),i={ready:b.green,degraded:b.yellow}[n.state],u=[...o1()?[]:["plugin cc-safety-net@cc-marketplace is disabled in Claude Code; nothing is enforced in Claude Code until it is re-enabled. Other integrations are not affected."],...n.diagnostics],o=e?"-":"·";console.log([`${e?"":"\uD83D\uDEE1️ "}CC Safety Net — ${i(n.state)}`,"",s("Protection",`destructive ${t.destructiveCommandProtectionEnabled?l:d} secrets ${t.secretProtection.enabled?l:d}`),s("Level",L?`${r.effectiveLevel} (customised)`:r.effectiveLevel),s("Rules",t.rules.length===0?"none active":`${t.rules.length} active`),s("Policy",c.startsWith(i3())?`~${c.slice(i3().length)}`:c),...r.worktreeMode?[s("Worktree","relaxations active")]:[],"",...u.length===0?[" Everything configured is active."]:[" Not active",...u.flatMap((p)=>dt(p," ",a-6).map((f,v)=>v===0?` ${o} ${f}`:f)),""," Full report: cc-safety-net doctor"]].join(`
241
+ `))}import{spawn as B3}from"node:child_process";import{randomBytes as x8}from"node:crypto";import{createServer as $8}from"node:http";import{Writable as g8}from"node:stream";import{homedir as i8}from"node:os";var Dt=500;function p8(n){let t=n.filter((a)=>a.decision!=="allow"),r=n.filter((a)=>a.decision==="allow"),e=Math.min(t.length,Math.max(Dt-r.length,Math.ceil(Dt/2)));return[...t.slice(0,e),...r.slice(0,Dt-e)]}function u3(n,t=s2()){if(t)$2(t);let r=(v)=>new Date(v.getFullYear(),v.getMonth(),v.getDate()).getTime(),e=r(new Date),a=new Date(e);a.setDate(a.getDate()-(n-1));let l=a.getTime(),d=[],s={count:0};for(let v of t?u2(t,s):[])for(let y of dn(v,s)){if(!y||typeof y.ts!=="string"||typeof y.command!=="string")continue;let x=new Date(y.ts).getTime();if(!Number.isFinite(x))continue;if(x>=l)d.push(y)}d.sort((v,y)=>new Date(y.ts).getTime()-new Date(v.ts).getTime());let L=Array.from({length:n},()=>0),c=Array.from({length:n},()=>0),i={},u={},o={},p=0,f=0;for(let v of d){let y=v.agent||"unknown";i[y]=(i[y]??0)+1;let x=Math.round((e-r(new Date(v.ts)))/86400000),w=n-1-x,h=x>=0&&x<n;if(h)c[w]=(c[w]??0)+1;if(v.decision!=="allow"){if(p++,v.ruleId)u[v.ruleId]=(u[v.ruleId]??0)+1;let J=Q2(v.segment||v.command);if(J)o[J]=(o[J]??0)+1;if(v.failureStage)f++;if(h)L[w]=(L[w]??0)+1}}return{days:n,logsDir:t,homeDir:i8(),totalInWindow:d.length,truncated:d.length>Dt,unreadable:s.count,counts:{blocked:p,allowed:d.length-p,agents:i,blockedByDay:L,analyzedByDay:c,rules:u,commands:o,errors:f},entries:p8(d).sort((v,y)=>new Date(y.ts).getTime()-new Date(v.ts).getTime())}}import{spawn as u8}from"node:child_process";import{existsSync as v3,statSync as v8}from"node:fs";import{delimiter as o8,join as b8}from"node:path";var f8=120000,mt="Choose the project folder",y8=`try
242
+ return POSIX path of (choose folder with prompt "${mt}")
242
243
  on error number -128
243
244
  return ""
244
- end try`,y8=`Add-Type -AssemblyName System.Windows.Forms
245
+ end try`,h8=`Add-Type -AssemblyName System.Windows.Forms
245
246
  $dialog = New-Object System.Windows.Forms.FolderBrowserDialog
246
- $dialog.Description = '${xt}'
247
- if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { [Console]::Out.Write($dialog.SelectedPath) }`,o3=[{binary:"zenity",args:["--file-selection","--directory",`--title=${xt}`]},{binary:"kdialog",args:["--getexistingdirectory",".","--title",xt]}],v3=(n,t)=>(t.PATH??"").split(o8).some((r)=>r.length>0&&u3(v8(r,n)));function b3(n,t){if(n==="darwin"||n==="win32")return!0;if(n!=="linux")return!1;if(!t.DISPLAY&&!t.WAYLAND_DISPLAY)return!1;return o3.some((r)=>v3(r.binary,t))}function h8(n,t){if(n==="darwin")return{cmd:"osascript",args:["-e",f8]};if(n==="win32")return{cmd:"powershell.exe",args:["-NoProfile","-STA","-Command",y8]};let r=o3.find((e)=>v3(e.binary,t));return r?{cmd:r.binary,args:r.args}:null}function f3(n=process.platform,t=process.env){let r=h8(n,t);if(!r)return Promise.resolve({error:"No folder dialog is available on this system"});return new Promise((e)=>{let a=p8(r.cmd,r.args,{env:t,stdio:["ignore","pipe","pipe"]}),l="",d=!1,s=(L)=>{if(d)return;d=!0,clearTimeout(c),e(L)},c=setTimeout(()=>{a.kill(),s({error:"The folder dialog timed out"})},b8);a.stdout.on("data",(L)=>{l+=L.toString()}),a.on("error",()=>s({error:`Could not open the folder dialog (${r.cmd})`})),a.on("close",()=>{let L=l.trim().replace(/\/+$/,"");if(!L)return s({cancelled:!0});if(!u3(L)||!u8(L).isDirectory())return s({error:"That selection is not a folder on disk"});s({path:L})})})}var y3=`<!doctype html>
247
+ $dialog.Description = '${mt}'
248
+ if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { [Console]::Out.Write($dialog.SelectedPath) }`,o3=[{binary:"zenity",args:["--file-selection","--directory",`--title=${mt}`]},{binary:"kdialog",args:["--getexistingdirectory",".","--title",mt]}],b3=(n,t)=>(t.PATH??"").split(o8).some((r)=>r.length>0&&v3(b8(r,n)));function f3(n,t){if(n==="darwin"||n==="win32")return!0;if(n!=="linux")return!1;if(!t.DISPLAY&&!t.WAYLAND_DISPLAY)return!1;return o3.some((r)=>b3(r.binary,t))}function w8(n,t){if(n==="darwin")return{cmd:"osascript",args:["-e",y8]};if(n==="win32")return{cmd:"powershell.exe",args:["-NoProfile","-STA","-Command",h8]};let r=o3.find((e)=>b3(e.binary,t));return r?{cmd:r.binary,args:r.args}:null}function y3(n=process.platform,t=process.env){let r=w8(n,t);if(!r)return Promise.resolve({error:"No folder dialog is available on this system"});return new Promise((e)=>{let a=u8(r.cmd,r.args,{env:t,stdio:["ignore","pipe","pipe"]}),l="",d=!1,s=(c)=>{if(d)return;d=!0,clearTimeout(L),e(c)},L=setTimeout(()=>{a.kill(),s({error:"The folder dialog timed out"})},f8);a.stdout.on("data",(c)=>{l+=c.toString()}),a.on("error",()=>s({error:`Could not open the folder dialog (${r.cmd})`})),a.on("close",()=>{let c=l.trim().replace(/\/+$/,"");if(!c)return s({cancelled:!0});if(!v3(c)||!v8(c).isDirectory())return s({error:"That selection is not a folder on disk"});s({path:c})})})}var h3=`<!doctype html>
248
249
  <html lang="en">
249
250
  <head>
250
251
  <meta charset="utf-8">
@@ -5341,5 +5342,5 @@ load().then((loaded) => {
5341
5342
  </script>
5342
5343
  </body>
5343
5344
  </html>
5344
- `;var h3='<script id="ccsn-data" type="application/json">';function w3(n){return y3.replace(h3,()=>h3+JSON.stringify({token:n}).replaceAll("<","\\u003c"))}var gt="kenryu42/cc-safety-net",g8=`https://github.com/${gt}`,he=1e4,D8=7;async function B3(n,t={}){let r=F({label:"gui",booleans:{noOpen:["--no-open"]}},n),e=t.log??console.log,a=t.error??console.error;if(r.errors.length>0){for(let d of r.errors)a(d);return a("Usage: cc-safety-net gui [--no-open]"),1}let l=await m8(t);if(e(`CC Safety Net policy GUI: ${l.url}`),!r.flags.noOpen)try{await(t.openBrowser??Z8)(l.url)}catch(d){a(`Failed to open browser: ${d instanceof Error?d.message:String(d)}`),a(`Open this URL manually: ${l.url}`)}if(t.keepAlive===!1)return await l.close(),0;return await J8(l),0}async function m8(n={}){let t=n.token??w8(24).toString("base64url"),r=x8((l,d)=>{k8(l,d,t,n)});await new Promise((l,d)=>{r.once("error",d),r.listen(0,"127.0.0.1",()=>{r.off("error",d),l()})});let a=`http://127.0.0.1:${r.address().port}`;return{origin:a,token:t,url:`${a}/?token=${encodeURIComponent(t)}`,close:()=>B8(r)}}async function k8(n,t,r,e){let a=new URL(n.url??"/","http://127.0.0.1");if(n.method==="GET"&&a.pathname==="/favicon.ico"){t.writeHead(204,{"cache-control":"no-store"}),t.end();return}if(!F8(n,a,r)){k(t,403,{error:"Forbidden"});return}if(n.method==="GET"&&a.pathname==="/"){z8(t,w3(r));return}if(n.method==="GET"&&a.pathname==="/api/policy"){let l=D3(e);k(t,200,{...l,configState:bn(W(e)),destructiveCommandRules:pn,secretPatterns:$3,version:j(),preview:l.errors.length>0?null:k3(l.policy)});return}if(n.method==="POST"&&a.pathname==="/api/policy/preview"){let l=await $t(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=m3(l.value);k(t,d.errors.length>0?400:200,d);return}if(n.method==="POST"&&a.pathname==="/api/policy/explain"){let l=await $t(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=l.value;if(d===null||typeof d.command!=="string"){k(t,400,{errors:["command must be a string"]});return}let s=Nt(d.policy);if(s.length>0){k(t,400,{errors:s});return}k(t,200,q8(d.command,d.policy,e));return}if(n.method==="POST"&&a.pathname==="/api/policy"){let l=await $t(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=fe(l.value,e);k(t,d.errors.length>0?400:200,d);return}if(n.method==="POST"&&a.pathname==="/api/reset"){k(t,200,fe(g3,e));return}if(n.method==="POST"&&a.pathname==="/api/repair"){k(t,200,q3(e));return}if(n.method==="GET"&&a.pathname==="/api/activity"){let l=G2(e),d=j8(a.searchParams.get("days"),l);if(d===null){k(t,400,{error:`days must be an integer between 1 and ${l}`});return}k(t,200,p3(d,e.activityLogsDir));return}if(n.method==="POST"&&a.pathname==="/api/rules/choose-directory"){k(t,200,await f3());return}if(n.method==="GET"&&a.pathname==="/api/rules"){let l=o2(e),d=new Map(l.rules.map((s)=>[s.name,s]));k(t,200,{projectPath:e.cwd??process.cwd(),canPickDirectory:b3(process.platform,process.env),rulebooks:l.rulebooks.map((s)=>({source:s.source,spec:s.spec,name:s.name,version:s.version,rules:s.rules.flatMap((c)=>{let L=d.get(c);if(!L)return[];return[{name:L.name,command:L.command,subcommand:L.subcommand,block_args:L.block_args,reason:L.reason}]})})),errors:l.errors,warnings:l.warnings});return}if(n.method==="GET"&&a.pathname==="/api/star/context"){k(t,200,await(e.fetchStarContext??(()=>A8({logsDir:e.activityLogsDir})))());return}if(n.method==="POST"&&a.pathname==="/api/star"){let l=await(e.starRepo??Q8)();k(t,200,l.ok?{ok:!0}:{ok:!1,fallbackUrl:g8});return}if(n.method==="GET"&&a.pathname==="/api/integrations"){k(t,200,await(e.fetchIntegrations??Y8)());return}if(n.method==="GET"&&a.pathname==="/api/health"){k(t,200,await(e.fetchHealth??S8)());return}if(n.method==="POST"&&(a.pathname==="/api/install"||a.pathname==="/api/uninstall")){let l=await $t(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=l.value?.target;if(typeof d!=="string"||!C.some((c)=>c.target===d)){k(t,400,{error:"unknown target"});return}let s=a.pathname==="/api/install"?"install":"uninstall";k(t,200,await(e.runIntegration??H8)(s,d));return}k(t,404,{error:"Not found"})}function q8(n,t,r){let e=ct(t),a=W(r),l=un({rules:a.policy.rules,transparentWrappers:a.policy.transparentWrappers,safety:F3(e.safety),worktreeMode:e.workflow.worktree_mode,destructiveCommandProtectionEnabled:e.destructive_command_protection.enabled,destructiveCommandRuleOverrides:e.destructive_command_protection.overrides,destructiveCommandAllowPaths:e.destructive_command_protection.allow_paths,secretProtection:{enabled:e.secret_protection.enabled,disabledRules:[...j3(e.secret_protection.overrides)],denyPaths:e.secret_protection.deny_paths}});return M2(n,{policySnapshot:l,cwd:r.cwd,userConfigDir:r.userConfigDir})}function j8(n,t){if(n===null)return Math.min(D8,t);let r=Number(n);if(!Number.isInteger(r)||r<1||r>t)return null;return r}function F8(n,t,r){if(t.searchParams.get("token")!==r)return!1;if(n.method!=="POST")return!0;return n.headers["x-cc-safety-net-token"]===r}async function $t(n){let t=[];for await(let r of n)t.push(r);try{return{ok:!0,value:JSON.parse(Buffer.concat(t).toString("utf-8")||"{}")}}catch(r){return{ok:!1,error:`Invalid JSON: ${r instanceof Error?r.message:String(r)}`}}}function z8(n,t){n.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),n.end(t)}function k(n,t,r){n.writeHead(t,{"content-type":"application/json; charset=utf-8","cache-control":"no-store"}),n.end(JSON.stringify(r))}function B8(n){return new Promise((t,r)=>{n.close((e)=>e?r(e):t())})}function J8(n){return new Promise((t)=>{let r=()=>{process.off("SIGINT",e),process.off("SIGTERM",e)},e=()=>{r(),n.close().then(t)};process.once("SIGINT",e),process.once("SIGTERM",e)})}function Z8(n){let t=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",r=process.platform==="win32"?["/c","start","",n]:[n];return new Promise((e,a)=>{let l=z3(t,r,{detached:!0,stdio:"ignore"}),d=(c)=>{l.off("spawn",s),a(c)},s=()=>{l.off("error",d),l.unref(),e()};l.once("error",d),l.once("spawn",s)})}async function Q8(n="gh",t=he){return{ok:await ye(n,["api","-X","PUT",`/user/starred/${gt}`],t)===0}}var X8={amp:"ampVersion","antigravity-cli":"antigravityCliVersion","claude-code":"claudeCodeVersion",codex:"codexCliVersion","copilot-cli":"copilotCliVersion",cursor:"cursorVersion","gemini-cli":"geminiCliVersion","hermes-agent":"hermesAgentVersion","kimi-code":"kimiCodeVersion",openclaw:"openClawVersion",opencode:"openCodeVersion",pi:"piCliVersion"};async function Y8(n={}){let t=await xn(n.fetcher),r=J3(t,n.homeDir);return{targets:L2.map((e)=>{let a=r.find((l)=>l.platform===e.id);return{target:e.id,label:v2(e.id),version:t[X8[e.id]],status:a?.configured?"active":a?.detected?"disabled":a?.inspectionStatus==="not-inspected"?"not-inspected":"not-installed"}}),system:{version:t.version,nodeVersion:t.nodeVersion,platform:t.platform}}}function J3(n,t){return nn(process.cwd(),{homeDir:t,ampPluginListOutput:n.ampPluginListOutput,codexPluginListOutput:n.codexPluginListOutput,copilotCliVersion:n.copilotCliVersion})}async function S8(n={}){let[t,r]=await Promise.all([xn(n.fetcher),(n.checkUpdates??E2)()]);return{hooks:J3(t,n.homeDir).filter((e)=>e.detected).map((e)=>({platform:e.platform,label:v2(e.platform),configured:e.configured})),update:{currentVersion:r.currentVersion,latestVersion:r.latestVersion??null,updateAvailable:r.updateAvailable}}}var x3=Promise.resolve();function H8(n,t,r={}){let e=async()=>{let l=[],d=console.log,s=console.error;console.log=(...c)=>l.push(c.map(String).join(" ")),console.error=console.log;try{return{ok:await Zn(n,[],{selectTargets:async()=>[t],output:new $8({write(L,i,u){u()}}),...r})===0,output:l.join(`
5345
- `)}}finally{console.log=d,console.error=s}},a=x3.then(e);return x3=a.then(()=>{return},()=>{return}),a}async function A8(n={}){let[t,r,e]=await Promise.all([W8(n.command),R8(n.fetchRepo),Promise.resolve(Mn(G2(),n.logsDir).totalBlocked)]);return{starred:t,starCount:r,blockedTotal:e}}async function W8(n="gh",t=he){if(await ye(n,["auth","status"],t)!==0)return null;let r=await ye(n,["api",`/user/starred/${gt}`],t);if(r===0)return!0;if(r===null)return null;return!1}function ye(n,t,r){return new Promise((e)=>{let a=z3(n,t,{stdio:"ignore",windowsHide:!0}),l=!1,d,s=(c)=>{if(l)return;if(l=!0,d)clearTimeout(d);e(c)};a.once("error",()=>s(null)),a.once("close",s),d=setTimeout(()=>{a.kill(),s(null)},r)})}async function R8(n=fetch){try{let t=await n(`https://api.github.com/repos/${gt}`,{headers:{accept:"application/vnd.github+json"},signal:AbortSignal.timeout(he)});if(!t.ok)return null;let r=await t.json();return typeof r.stargazers_count==="number"?r.stargazers_count:null}catch{return null}}function V8(n){if(n[0]!=="help")return!1;let t=n[1];if(!t)Cr(),process.exit(0);if(zn(t))process.exit(0);console.error(`Unknown command: ${t}`),console.error("Run 'cc-safety-net --help' for available commands."),process.exit(1)}var K8={hook:async(n)=>{let t=R1(n);if(t){await t.run();return}console.error("hook requires exactly one integration flag. Try: cc-safety-net hook --kimi-code"),zn("hook",console.error),process.exit(1)},install:async(n)=>{process.exit(await Zn("install",n))},update:async(n)=>{process.exit(await ie(n))},uninstall:async(n)=>{process.exit(await Zn("uninstall",n))},rule:async(n)=>{process.exit(await c3(n))},status:async(n)=>{if(e2(F({label:"status"},n).errors))process.exit(1);i3()},statusline:async(n)=>{let t=F({label:"statusline",booleans:{claudeCode:["-cc","--claude-code"]}},n);if(t.errors.length===0&&t.flags.claudeCode){await be();return}if(e2(t.errors),!t.flags.claudeCode)console.error("statusline requires --claude-code (-cc)");zn("statusline",console.error),process.exit(1)},doctor:async(n)=>{let t=Rr(n);if(!t)process.exit(1);let r=await J0({json:t.json,skipUpdateCheck:t.skipUpdateCheck});process.exit(r)},logs:async(n)=>{process.exit(await L1(n))},gui:async(n)=>{process.exit(await B3(n))},explain:async(n)=>{let t=Vr(n);if(!t)process.exit(1);let r=M2(t.command,{cwd:t.cwd}),e=!!process.env.NO_COLOR||!process.stdout.isTTY;if(t.json)console.log(Gr(r));else console.log(Mr(r,{asciiOnly:e}));process.exit(0)}};async function M8(){let n=process.argv.slice(2),t=F({label:"cc-safety-net",booleans:{version:["-V","--version"]},positionals:"list"},n);if(V8(n))return;let r=n[0],e=r?Kn(r):void 0;if(t.help&&e&&e.name!=="rule")zn(e.name),process.exit(0);if(!r||t.help&&!e)Cr(),process.exit(0);if(t.flags.version)W0(),process.exit(0);if(e){await K8[e.name](n.slice(1));return}let a=V1(r);if(a){await a.run();return}if(r==="--statusline"){await be();return}console.error(r.startsWith("-")?`Unknown option: ${r}`:`Unknown command: ${r}`),console.error("Run 'cc-safety-net --help' for usage."),process.exit(1)}M8().catch((n)=>{console.error("CC Safety Net error:",n),process.exit(1)});
5345
+ `;var w3='<script id="ccsn-data" type="application/json">';function x3(n){return h3.replace(w3,()=>w3+JSON.stringify({token:n}).replaceAll("<","\\u003c"))}var qt="kenryu42/cc-safety-net",D8=`https://github.com/${qt}`,h1=1e4,m8=7;async function J3(n,t={}){let r=F({label:"gui",booleans:{noOpen:["--no-open"]}},n),e=t.log??console.log,a=t.error??console.error;if(r.errors.length>0){for(let d of r.errors)a(d);return a("Usage: cc-safety-net gui [--no-open]"),1}let l=await k8(t);if(e(`CC Safety Net policy GUI: ${l.url}`),!r.flags.noOpen)try{await(t.openBrowser??Q8)(l.url)}catch(d){a(`Failed to open browser: ${d instanceof Error?d.message:String(d)}`),a(`Open this URL manually: ${l.url}`)}if(t.keepAlive===!1)return await l.close(),0;return await Z8(l),0}async function k8(n={}){let t=n.token??x8(24).toString("base64url"),r=$8((l,d)=>{q8(l,d,t,n)});await new Promise((l,d)=>{r.once("error",d),r.listen(0,"127.0.0.1",()=>{r.off("error",d),l()})});let a=`http://127.0.0.1:${r.address().port}`;return{origin:a,token:t,url:`${a}/?token=${encodeURIComponent(t)}`,close:()=>J8(r)}}async function q8(n,t,r,e){let a=new URL(n.url??"/","http://127.0.0.1");if(n.method==="GET"&&a.pathname==="/favicon.ico"){t.writeHead(204,{"cache-control":"no-store"}),t.end();return}if(!z8(n,a,r)){k(t,403,{error:"Forbidden"});return}if(n.method==="GET"&&a.pathname==="/"){B8(t,x3(r));return}if(n.method==="GET"&&a.pathname==="/api/policy"){let l=m3(e);k(t,200,{...l,configState:fn(W(e)),destructiveCommandRules:un,secretPatterns:g3,version:j(),preview:l.errors.length>0?null:q3(l.policy)});return}if(n.method==="POST"&&a.pathname==="/api/policy/preview"){let l=await kt(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=k3(l.value);k(t,d.errors.length>0?400:200,d);return}if(n.method==="POST"&&a.pathname==="/api/policy/explain"){let l=await kt(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=l.value;if(d===null||typeof d.command!=="string"){k(t,400,{errors:["command must be a string"]});return}let s=rr(d.policy);if(s.length>0){k(t,400,{errors:s});return}k(t,200,j8(d.command,d.policy,e));return}if(n.method==="POST"&&a.pathname==="/api/policy"){let l=await kt(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=f1(l.value,e);k(t,d.errors.length>0?400:200,d);return}if(n.method==="POST"&&a.pathname==="/api/reset"){k(t,200,f1(D3,e));return}if(n.method==="POST"&&a.pathname==="/api/repair"){k(t,200,j3(e));return}if(n.method==="GET"&&a.pathname==="/api/activity"){let l=G2(e),d=F8(a.searchParams.get("days"),l);if(d===null){k(t,400,{error:`days must be an integer between 1 and ${l}`});return}k(t,200,u3(d,e.activityLogsDir));return}if(n.method==="POST"&&a.pathname==="/api/rules/choose-directory"){k(t,200,await y3());return}if(n.method==="GET"&&a.pathname==="/api/rules"){let l=v2(e),d=new Map(l.rules.map((s)=>[s.name,s]));k(t,200,{projectPath:e.cwd??process.cwd(),canPickDirectory:f3(process.platform,process.env),rulebooks:l.rulebooks.map((s)=>({source:s.source,spec:s.spec,name:s.name,version:s.version,rules:s.rules.flatMap((L)=>{let c=d.get(L);if(!c)return[];return[{name:c.name,command:c.command,subcommand:c.subcommand,block_args:c.block_args,reason:c.reason}]})})),errors:l.errors,warnings:l.warnings});return}if(n.method==="GET"&&a.pathname==="/api/star/context"){k(t,200,await(e.fetchStarContext??(()=>W8({logsDir:e.activityLogsDir})))());return}if(n.method==="POST"&&a.pathname==="/api/star"){let l=await(e.starRepo??X8)();k(t,200,l.ok?{ok:!0}:{ok:!1,fallbackUrl:D8});return}if(n.method==="GET"&&a.pathname==="/api/integrations"){k(t,200,await(e.fetchIntegrations??S8)());return}if(n.method==="GET"&&a.pathname==="/api/health"){k(t,200,await(e.fetchHealth??H8)());return}if(n.method==="POST"&&(a.pathname==="/api/install"||a.pathname==="/api/uninstall")){let l=await kt(n);if(!l.ok){k(t,400,{errors:[l.error]});return}let d=l.value?.target;if(typeof d!=="string"||!C.some((L)=>L.target===d)){k(t,400,{error:"unknown target"});return}let s=a.pathname==="/api/install"?"install":"uninstall";k(t,200,await(e.runIntegration??A8)(s,d));return}k(t,404,{error:"Not found"})}function j8(n,t,r){let e=ct(t),a=W(r),l=vn({rules:a.policy.rules,transparentWrappers:a.policy.transparentWrappers,safety:z3(e.safety),worktreeMode:e.workflow.worktree_mode,destructiveCommandProtectionEnabled:e.destructive_command_protection.enabled,destructiveCommandRuleOverrides:e.destructive_command_protection.overrides,destructiveCommandAllowPaths:e.destructive_command_protection.allow_paths,secretProtection:{enabled:e.secret_protection.enabled,disabledRules:[...F3(e.secret_protection.overrides)],denyPaths:e.secret_protection.deny_paths}});return V2(n,{policySnapshot:l,cwd:r.cwd,userConfigDir:r.userConfigDir})}function F8(n,t){if(n===null)return Math.min(m8,t);let r=Number(n);if(!Number.isInteger(r)||r<1||r>t)return null;return r}function z8(n,t,r){if(t.searchParams.get("token")!==r)return!1;if(n.method!=="POST")return!0;return n.headers["x-cc-safety-net-token"]===r}async function kt(n){let t=[];for await(let r of n)t.push(r);try{return{ok:!0,value:JSON.parse(Buffer.concat(t).toString("utf-8")||"{}")}}catch(r){return{ok:!1,error:`Invalid JSON: ${r instanceof Error?r.message:String(r)}`}}}function B8(n,t){n.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),n.end(t)}function k(n,t,r){n.writeHead(t,{"content-type":"application/json; charset=utf-8","cache-control":"no-store"}),n.end(JSON.stringify(r))}function J8(n){return new Promise((t,r)=>{n.close((e)=>e?r(e):t())})}function Z8(n){return new Promise((t)=>{let r=()=>{process.off("SIGINT",e),process.off("SIGTERM",e)},e=()=>{r(),n.close().then(t)};process.once("SIGINT",e),process.once("SIGTERM",e)})}function Q8(n){let t=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",r=process.platform==="win32"?["/c","start","",n]:[n];return new Promise((e,a)=>{let l=B3(t,r,{detached:!0,stdio:"ignore"}),d=(L)=>{l.off("spawn",s),a(L)},s=()=>{l.off("error",d),l.unref(),e()};l.once("error",d),l.once("spawn",s)})}async function X8(n="gh",t=h1){return{ok:await y1(n,["api","-X","PUT",`/user/starred/${qt}`],t)===0}}var Y8={amp:"ampVersion","antigravity-cli":"antigravityCliVersion","claude-code":"claudeCodeVersion",codex:"codexCliVersion","copilot-cli":"copilotCliVersion",cursor:"cursorVersion","gemini-cli":"geminiCliVersion","hermes-agent":"hermesAgentVersion","kimi-code":"kimiCodeVersion",openclaw:"openClawVersion",opencode:"openCodeVersion",pi:"piCliVersion"};async function S8(n={}){let t=await xn(n.fetcher),r=Z3(t,n.homeDir);return{targets:c2.map((e)=>{let a=r.find((l)=>l.platform===e.id);return{target:e.id,label:o2(e.id),version:t[Y8[e.id]],status:a?.configured?"active":a?.detected?"disabled":a?.inspectionStatus==="not-inspected"?"not-inspected":"not-installed"}}),system:{version:t.version,nodeVersion:t.nodeVersion,platform:t.platform}}}function Z3(n,t){return tn(process.cwd(),{homeDir:t,ampPluginListOutput:n.ampPluginListOutput,codexPluginListOutput:n.codexPluginListOutput,copilotCliVersion:n.copilotCliVersion})}async function H8(n={}){let[t,r]=await Promise.all([xn(n.fetcher),(n.checkUpdates??E2)()]);return{hooks:Z3(t,n.homeDir).filter((e)=>e.detected).map((e)=>({platform:e.platform,label:o2(e.platform),configured:e.configured})),update:{currentVersion:r.currentVersion,latestVersion:r.latestVersion??null,updateAvailable:r.updateAvailable}}}var $3=Promise.resolve();function A8(n,t,r={}){let e=async()=>{let l=[],d=console.log,s=console.error;console.log=(...L)=>l.push(L.map(String).join(" ")),console.error=console.log;try{return{ok:await Xn(n,[],{selectTargets:async()=>[t],output:new g8({write(c,i,u){u()}}),...r})===0,output:l.join(`
5346
+ `)}}finally{console.log=d,console.error=s}},a=$3.then(e);return $3=a.then(()=>{return},()=>{return}),a}async function W8(n={}){let[t,r,e]=await Promise.all([R8(n.command),K8(n.fetchRepo),Promise.resolve(Cn(G2(),n.logsDir).totalBlocked)]);return{starred:t,starCount:r,blockedTotal:e}}async function R8(n="gh",t=h1){if(await y1(n,["auth","status"],t)!==0)return null;let r=await y1(n,["api",`/user/starred/${qt}`],t);if(r===0)return!0;if(r===null)return null;return!1}function y1(n,t,r){return new Promise((e)=>{let a=B3(n,t,{stdio:"ignore",windowsHide:!0}),l=!1,d,s=(L)=>{if(l)return;if(l=!0,d)clearTimeout(d);e(L)};a.once("error",()=>s(null)),a.once("close",s),d=setTimeout(()=>{a.kill(),s(null)},r)})}async function K8(n=fetch){try{let t=await n(`https://api.github.com/repos/${qt}`,{headers:{accept:"application/vnd.github+json"},signal:AbortSignal.timeout(h1)});if(!t.ok)return null;let r=await t.json();return typeof r.stargazers_count==="number"?r.stargazers_count:null}catch{return null}}function M8(n){if(n[0]!=="help")return!1;let t=n[1];if(!t)Tr(),process.exit(0);if(Jn(t))process.exit(0);console.error(`Unknown command: ${t}`),console.error("Run 'cc-safety-net --help' for available commands."),process.exit(1)}var V8={hook:async(n)=>{let t=Re(n);if(t){await t.run();return}console.error("hook requires exactly one integration flag. Try: cc-safety-net hook --kimi-code"),Jn("hook",console.error),process.exit(1)},install:async(n)=>{process.exit(await Xn("install",n))},update:async(n)=>{process.exit(await p1(n))},uninstall:async(n)=>{process.exit(await Xn("uninstall",n))},rule:async(n)=>{process.exit(await c3(n))},status:async(n)=>{if(e2(F({label:"status"},n).errors))process.exit(1);p3()},statusline:async(n)=>{let t=F({label:"statusline",booleans:{claudeCode:["-cc","--claude-code"]}},n);if(t.errors.length===0&&t.flags.claudeCode){await b1();return}if(e2(t.errors),!t.flags.claudeCode)console.error("statusline requires --claude-code (-cc)");Jn("statusline",console.error),process.exit(1)},doctor:async(n)=>{let t=Vr(n);if(!t)process.exit(1);let r=await J0({json:t.json,skipUpdateCheck:t.skipUpdateCheck});process.exit(r)},logs:async(n)=>{process.exit(await ce(n))},gui:async(n)=>{process.exit(await J3(n))},explain:async(n)=>{let t=Gr(n);if(!t)process.exit(1);let r=V2(t.command,{cwd:t.cwd}),e=!!process.env.NO_COLOR||!process.stdout.isTTY;if(t.json)console.log(Or(r));else console.log(Ur(r,{asciiOnly:e}));process.exit(0)}};async function G8(){let n=process.argv.slice(2),t=F({label:"cc-safety-net",booleans:{version:["-V","--version"]},positionals:"list"},n);if(M8(n))return;let r=n[0],e=r?Gn(r):void 0;if(t.help&&e&&e.name!=="rule")Jn(e.name),process.exit(0);if(!r||t.help&&!e)Tr(),process.exit(0);if(t.flags.version)W0(),process.exit(0);if(e){await V8[e.name](n.slice(1));return}let a=Ke(r);if(a){await a.run();return}if(r==="--statusline"){await b1();return}console.error(r.startsWith("-")?`Unknown option: ${r}`:`Unknown command: ${r}`),console.error("Run 'cc-safety-net --help' for usage."),process.exit(1)}G8().catch((n)=>{console.error("CC Safety Net error:",n),process.exit(1)});