cc-safety-net 2.4.1 → 2.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/amp/cc-safety-net/index.ts +42 -45
- package/dist/api.js +1 -1
- package/dist/bin/hook.js +40 -43
- package/dist/chunks/index-26getn55.js +45 -0
- package/dist/chunks/index-p4h81vth.js +2 -0
- package/dist/chunks/index-sp43p448.js +4 -0
- package/dist/cli.js +143 -152
- package/dist/index.d.ts +5 -0
- package/dist/index.js +11 -1
- package/dist/openclaw/cc-safety-net/index.js +42 -45
- package/dist/openclaw/cc-safety-net/openclaw.plugin.json +1 -1
- package/dist/openclaw/cc-safety-net/package.json +1 -1
- package/dist/opencode-v2.d.ts +3 -0
- package/dist/pi/index.js +2 -2
- package/package.json +16 -6
- package/dist/chunks/index-31w7hfwv.js +0 -4
- package/dist/chunks/index-chc1n91k.js +0 -48
- package/dist/chunks/index-n0tze7vr.js +0 -2
package/dist/pi/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{ye,P,be,Xe,c,o,xe,R,V,et,d,p}from"../chunks/index-26getn55.js";import{Q}from"../chunks/index-p4h81vth.js";import{he,D}from"../chunks/index-sp43p448.js";var E="cc-safety-net",x="Operate CC Safety Net: explain blocks, rules, integrations, diagnostics",w="Help me with CC Safety Net.";function f(e){e.registerCommand(E,{description:x,handler:async(n,l)=>{e.sendUserMessage(N(n),l.isIdle()?void 0:{deliverAs:"followUp"})}})}function N(e){return`${Q.slice(Q.indexOf("# CC Safety Net")).trimEnd()}
|
|
2
2
|
|
|
3
3
|
## User request
|
|
4
4
|
|
|
5
|
-
${e.trim()||
|
|
5
|
+
${e.trim()||w}`}function g(e,n={}){return{malformed:!0,denial:P(n),cwd:e}}function T(e,n={}){return(l,t)=>{try{return I(l,t,e,n)}catch(i){return console.error("CC Safety Net error:",i),e.block(P())}}}function I(e,n,l,t){let i=c();if(l.cancelled?.(n))return l.block(P());let r=l.extract(e,n,i.paths);if(!r)return l.allow;let s=()=>l.getSessionId(e,n);if("malformed"in r)return he(i,r.denial,s,{agent:l.agent,toolName:r.denial.toolName,cwd:r.cwd}),l.block(r.denial);let m=(a,y)=>{let C=ye(a,{includeEvidence:y});return C?l.block(C):l.allow};try{let a=D(i,r,{guard:{auditAllowed:xe(i.env),policyOptions:t.policyOptions,dependencies:t.guardDependencies},audit:{agent:l.agent,getSessionId:s}});return m(a,!0)}catch(a){if(!(a instanceof p))throw a;if(R(o.debug,i.env))console.error(`CC Safety Net debug: ${l.debugLabel} analysis failed: ${Xe(a.cause)}`);return m(a.evaluation,l.includeEvidenceOnError(r))}}var b=new Map([["bash","posix"]]),O={agent:"pi",debugLabel:"pi tool_call",extract:(e,n,l)=>k(e,n,l),getSessionId:(e,n)=>n.sessionManager.getSessionId(),allow:void 0,block:(e)=>M(e),includeEvidenceOnError:(e)=>e.route.kind==="command"};function v(e){e.on("tool_call",S)}var S=A();function A(e={}){return T(O,e)}function k(e,n,l){if(!e||typeof e!=="object")return;let t=e;if(t.type!==void 0&&t.type!=="tool_call")return;if(typeof t.toolName!=="string"||t.toolName.trim()==="")return u(n);let i=typeof n.cwd==="string"&&n.cwd.trim()!==""?et(".",[n.cwd],l):void 0;if(!i)return u(n,t.toolName);let r=b.get(t.toolName);if(!t.input||typeof t.input!=="object")return r?u(n,t.toolName):void 0;if(!r)return d(t.toolName,t.input,{kind:V(t.toolName)},{configCwd:i,executionCwd:i},null);let s=t.input.command;if(typeof s!=="string"||s.trim()==="")return u(n,t.toolName);return d(t.toolName,t.input,{kind:"command",shell:r},{configCwd:i,executionCwd:i},s)}function u(e,n){return g(typeof e.cwd==="string"&&e.cwd.trim()?e.cwd:null,{toolName:n})}function M(e){return{block:!0,reason:be(e)}}function _(e){v(e),f(e)}export{_ as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-safety-net",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.3",
|
|
4
4
|
"description": "A coding agent CLI hook - block destructive commands and secret file access",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
"types": "./dist/api.d.ts",
|
|
15
15
|
"import": "./dist/api.js"
|
|
16
16
|
},
|
|
17
|
+
"./opencode/v2": {
|
|
18
|
+
"types": "./dist/opencode-v2.d.ts",
|
|
19
|
+
"import": "./dist/index.js"
|
|
20
|
+
},
|
|
17
21
|
"./package.json": "./package.json"
|
|
18
22
|
},
|
|
19
23
|
"bin": {
|
|
@@ -39,12 +43,10 @@
|
|
|
39
43
|
"knip": "knip-bun --production",
|
|
40
44
|
"check-duplicates": "bunx jscpd src tests --no-tips --exit-code 1 --reporters ai --ignore '**/*.svg' --ignore 'src/gui/frontend/**' --ignore-pattern 'import\\s[\\s\\S]*?from\\s[^;]*;'",
|
|
41
45
|
"test": "bun test",
|
|
42
|
-
"test:e2e": "bun test tests/e2e",
|
|
43
46
|
"test:e2e:stability": "bun test tests/e2e --randomize --rerun-each 3",
|
|
44
47
|
"test:e2e:live": "CC_SAFETY_NET_E2E_LIVE=1 bun test tests/e2e-live",
|
|
45
48
|
"test:coverage": "AGENT=1 bun test tests --path-ignore-patterns 'tests/e2e-live/**' --coverage --coverage-reporter=text --coverage-reporter=lcov",
|
|
46
49
|
"cc-safety-net": "bun run src/entries/bin.ts",
|
|
47
|
-
"ccsn": "bun run src/entries/bin.ts",
|
|
48
50
|
"eval": "claude plugin eval . --ablation with-without --judge-model sonnet --allow-tools \"Bash(npx -y cc-safety-net:*)\" \"Bash(npx cc-safety-net:*)\""
|
|
49
51
|
},
|
|
50
52
|
"author": {
|
|
@@ -63,19 +65,26 @@
|
|
|
63
65
|
"devDependencies": {
|
|
64
66
|
"@ampcode/plugin": "0.0.0-20260724002649-ga3413e7",
|
|
65
67
|
"@biomejs/biome": "2.3.10",
|
|
66
|
-
"@opencode-ai/plugin": "^1.18.
|
|
68
|
+
"@opencode-ai/plugin": "^1.18.29",
|
|
69
|
+
"@opencode/plugin": "2.0.6",
|
|
70
|
+
"@opencode/schema": "2.0.6",
|
|
67
71
|
"@types/bun": "latest",
|
|
72
|
+
"effect": "4.0.0-rc.112",
|
|
68
73
|
"jscpd": "^5.0.14",
|
|
69
74
|
"knip": "^6.32.0",
|
|
70
75
|
"lefthook": "^2.1.10",
|
|
71
76
|
"typescript": "7.0.2"
|
|
72
77
|
},
|
|
73
78
|
"peerDependencies": {
|
|
74
|
-
"@opencode-ai/plugin": "^1.18.
|
|
79
|
+
"@opencode-ai/plugin": "^1.18.29",
|
|
80
|
+
"@opencode/plugin": "^2.0.6"
|
|
75
81
|
},
|
|
76
82
|
"peerDependenciesMeta": {
|
|
77
83
|
"@opencode-ai/plugin": {
|
|
78
84
|
"optional": true
|
|
85
|
+
},
|
|
86
|
+
"@opencode/plugin": {
|
|
87
|
+
"optional": true
|
|
79
88
|
}
|
|
80
89
|
},
|
|
81
90
|
"pi": {
|
|
@@ -84,6 +93,7 @@
|
|
|
84
93
|
]
|
|
85
94
|
},
|
|
86
95
|
"overrides": {
|
|
96
|
+
"@opentelemetry/core": "2.8.0",
|
|
87
97
|
"js-yaml": "^4.3.1",
|
|
88
98
|
"picomatch@^2.3.1": "2.3.2",
|
|
89
99
|
"picomatch@^4.0.1": "^4.0.5",
|
|
@@ -106,5 +116,5 @@
|
|
|
106
116
|
"grok",
|
|
107
117
|
"grok-build"
|
|
108
118
|
],
|
|
109
|
-
"gitHead": "
|
|
119
|
+
"gitHead": "49be587b269b435362c68aeb5ba90c3b0334b3d0"
|
|
110
120
|
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{n,a,K,f,Ne,d,He,b,p,V}from"./index-chc1n91k.js";import{appendFileSync as re,mkdirSync as oe}from"node:fs";import{isAbsolute as ie,join as S}from"node:path";import{lstatSync as D,readdirSync as j,readFileSync as U,rmdirSync as B,statSync as C,unlinkSync as X,utimesSync as z,writeFileSync as Y}from"node:fs";import{join as m}from"node:path";function ne(t,e={}){return He(d(t,e),t.home).policy.audit.retention_days}var A=86400000,Z=".last-prune",J=/^\d{4}-\d{2}$/,Q=/^((\d{4}-\d{2})-\d{2})-.+\.jsonl$/,L=(t)=>Math.floor(t/A);function q(t,e,o=()=>new Date){try{let r=o().getTime();if(!C(e,{throwIfNoEntry:!1})?.isDirectory())return;let i=m(e,Z),u=C(i,{throwIfNoEntry:!1})?.mtimeMs;if(u!==void 0&&L(u)===L(r))return;let c=r-ne(t)*A,s=new Date(r).toISOString().slice(0,7);for(let l of v(e)){if(l.isDirectory()){W(m(e,l.name),c,s);continue}if(l.isFile()&&l.name.endsWith(".jsonl"))ee(m(e,l.name),c)}Y(i,"",{mode:384}),z(i,r/1000,r/1000)}catch{}}function W(t,e,o){for(let r of v(t)){if(!r.isDirectory()||!J.test(r.name))continue;let i=m(t,r.name);for(let u of v(i)){if(!u.isFile())continue;let c=Q.exec(u.name);if(!c||c[2]!==r.name)continue;let s=Date.parse(`${c[1]}T00:00:00.000Z`)+A;if(!Number.isFinite(s)||s>=e)continue;G(m(i,u.name))}if(r.name!==o)O(i)}O(t)}function ee(t,e){try{let o=D(t);if(o.mtimeMs>=e)return;let r=U(t,"utf-8").split(`
|
|
2
|
-
`).filter((i)=>i.trim()).map(te);if(r.length===0)return;if(r.some((i)=>i===void 0||i>=e))return;if(D(t).mtimeMs!==o.mtimeMs)return;G(t)}catch{}}function te(t){try{let e=JSON.parse(t).ts,o=typeof e==="string"?Date.parse(e):Number.NaN;return Number.isFinite(o)?o:void 0}catch{return}}function v(t){try{return j(t,{withFileTypes:!0,encoding:"utf8"})}catch{return[]}}function G(t){try{X(t)}catch{}}function O(t){try{B(t)}catch{}}var ae="2.4.1",ce=1e4,de=2000,ue=256,se=32768;function le(t){let e=t.trim();if(!e)return null;let o=e.replace(/[^A-Za-z0-9_.-]+/g,"_");if(o=o.replace(/^[._-]+|[._-]+$/g,"").slice(0,128),!o||o==="."||o==="..")return null;return o}function me(t){return(t??"").replace(/[^A-Za-z0-9]/g,"-").slice(0,180)||"no-cwd"}function I(t,e,o,r,i,u,c={}){let s=le(e);if(!s)return;let l=M(t);if(!l)return;try{let y=(c.now??(()=>new Date))().toISOString(),_=g(K(o),c.failureStage?Number.POSITIVE_INFINITY:ce),N=g(K(r),de),h=c.toolName?g(K(c.toolName),ue):void 0,E=u===null?void 0:g(K(u),se),w=S(l,me(E?.value??null),y.slice(0,7));oe(w,{recursive:!0,mode:448});let H=S(w,`${y.slice(0,10)}-${s}.jsonl`),P={ts:y,id:(c.createId??Ne)(),v:ae,sessionId:s,decision:c.decision??"deny",agent:c.agent,shape:c.shape,level:c.level,configFallback:c.configFallback,toolName:h?.value,command:_.value,segment:N.value,..._.truncated||N.truncated||h?.truncated||E?.truncated?{truncated:!0}:{},reason:i,ruleId:c.ruleId,intent:c.intent,failureStage:c.failureStage,errorCode:c.errorCode,cwd:E?.value??null};re(H,`${JSON.stringify(P)}
|
|
3
|
-
`,{encoding:"utf-8",mode:384}),q(t,l,c.now)}catch{}}function g(t,e){return{value:t.slice(0,e),truncated:t.length>e}}function Ke(t){let e=t.env.get("CC_SAFETY_NET_AUDIT_HOME");if(t.env.get("NODE_ENV")==="test"&&!e)return null;let o=e||t.home;return o&&ie(o)?o:null}function M(t){let e=Ke(t);return e?S(e,".cc-safety-net","logs"):null}function k(t,e,o,r=!0,i){if(e.decision.kind==="allow"){if(!o||t.route.kind!=="command")return;let s=T(t);return{decision:"allow",command:s,segment:s,reason:"allowed",cwd:t.context.executionCwd,toolName:t.toolName,level:e.level,...e.configFallback?{configFallback:!0}:{}}}let u=e.decision.evidence.find((s)=>s.kind==="command"),c=u?.command??(r?T(t):"");return{decision:"deny",command:c,segment:u?.segment??c,reason:e.decision.reason,cwd:t.context.executionCwd,toolName:t.toolName,level:e.level,...e.configFallback?{configFallback:!0}:{},ruleId:e.decision.ruleId,intent:e.decision.intent,failureStage:i?.stage,errorCode:i?.errorCode}}function T(t){return"command"in t?t.command??"":""}function x(t,e,o,r){if(!e)return;let i;try{i=o()}catch{return}if(typeof i!=="string"||!i.trim())return;I(t,i,e.command,e.segment,e.reason,e.cwd,{decision:e.decision,agent:r.agent,shape:r.shape,level:e.level,configFallback:e.configFallback,toolName:e.toolName,ruleId:e.ruleId,intent:e.intent,failureStage:e.failureStage,errorCode:e.errorCode})}function we(t,e,o,r){let i;try{i=o()}catch{return}if(typeof i!=="string"||!i.trim())return;I(t,i,e.command??"",e.segment??e.command??"",e.reason,r.cwd??null,{decision:"deny",agent:r.agent,shape:r.shape,toolName:r.toolName??e.toolName,ruleId:e.ruleId,intent:e.intent})}function F(t,e,o){try{let r=V(e,{environment:t,...o.guard});return R(t,e,r,o),r}catch(r){if(!(r instanceof p))throw r;throw R(t,e,r.evaluation,o,!(r.cause instanceof f),{stage:r.stage,errorCode:fe(r.cause)}),r}}function R(t,e,o,r,i=!0,u){x(t,k(e,o,r.guard?.auditAllowed??!1,i,u),r.audit.getSessionId,{agent:r.audit.agent,shape:r.audit.shape})}function fe(t){if(t instanceof a)return n[t.kind].errorCode;if(t instanceof f)return"tool-input-limit";if(t instanceof b)return"structural-shell-syntax-limit";return"unexpected-error"}
|
|
4
|
-
export{ne,q,Ke,M,we,F};
|