custodex 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,+CAA+C;AAC/C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAwGD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAgE9D;AAID;;;GAGG;AACH,wBAAgB,aAAa,IAAI,aAAa,CAgE7C;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,aAAa,CAuD7C;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,aAAa,CAsD7C;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,aAAa,CA6B/C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG,aAAa,CAkB1D;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA+B1D"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,+CAA+C;AAC/C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAsJD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CA2C9D;AAID;;;GAGG;AACH,wBAAgB,aAAa,IAAI,aAAa,CAmE7C;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,aAAa,CA0D7C;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,aAAa,CAyD7C;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,aAAa,CA6B/C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG,aAAa,CAkB1D;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA+B1D"}
package/dist/install.js CHANGED
@@ -8,6 +8,7 @@ import * as fs from "fs";
8
8
  import * as os from "os";
9
9
  import * as path from "path";
10
10
  import * as https from "https";
11
+ import { fileURLToPath } from "url";
11
12
  // ─── Helpers ────────────────────────────────────────────────────────────────
12
13
  /**
13
14
  * Read a JSON file and return the parsed object, or an empty object if
@@ -94,6 +95,50 @@ function httpsPost(url, body, apiKey) {
94
95
  req.end();
95
96
  });
96
97
  }
98
+ // ─── Fallback hook.js (inlined for Windows path edge cases) ─────────────────
99
+ const FALLBACK_HOOK_JS = `#!/usr/bin/env node
100
+ 'use strict';
101
+ const fs=require('fs'),path=require('path'),os=require('os'),https=require('https'),http=require('http');
102
+ let API_KEY=process.env.CUSTODEX_API_KEY||'',BASE_URL=process.env.CUSTODEX_BASE_URL||'';
103
+ const cfgFile=path.join(os.homedir(),'.custodex','config.json');
104
+ try{if(fs.existsSync(cfgFile)){const c=JSON.parse(fs.readFileSync(cfgFile,'utf8'));if(!API_KEY&&c.apiKey)API_KEY=c.apiKey;if(!BASE_URL&&c.baseUrl)BASE_URL=c.baseUrl.replace(/\\/+$/,'')}}catch(_){}
105
+ if(!API_KEY||!BASE_URL)process.exit(0);
106
+ BASE_URL=BASE_URL.replace(/\\/+$/,'');
107
+ const SD=path.join(os.tmpdir(),'custodex-hooks');
108
+ try{fs.mkdirSync(SD,{recursive:true})}catch(_){}
109
+ let INPUT='';try{INPUT=fs.readFileSync(0,'utf8')}catch(_){}
110
+ let D={};try{D=JSON.parse(INPUT)}catch(_){D={}}
111
+ const gemS=process.env.GEMINI_SESSION_ID||'';
112
+ let IDE=gemS?'gemini':('conversation_id' in D&&!('session_id' in D))?'cursor':'claude';
113
+ const RE=D.hook_event_name||'';
114
+ const EM={SessionStart:'SessionStart',sessionStart:'SessionStart',SubagentStart:'SubagentStart',subagentStart:'SubagentStart',PreToolUse:'PreToolUse',preToolUse:'PreToolUse',beforeShellExecution:'PreToolUse',beforeMCPExecution:'PreToolUse',BeforeTool:'PreToolUse',PostToolUse:'PostToolUse',postToolUse:'PostToolUse',afterShellExecution:'PostToolUse',afterFileEdit:'PostToolUse',AfterTool:'PostToolUse',UserPromptSubmit:'UserPromptSubmit',beforeSubmitPrompt:'UserPromptSubmit',BeforeAgent:'UserPromptSubmit'};
115
+ const EV=EM[RE]||RE;
116
+ let SID=IDE==='gemini'?gemS:IDE==='cursor'?(D.conversation_id||D.session_id||''):(D.session_id||'');
117
+ let TN=RE==='beforeShellExecution'||RE==='afterShellExecution'?'Bash':RE==='afterFileEdit'?'Edit':(D.tool_name||'');
118
+ const CWD=D.cwd||process.env.PWD||process.cwd();
119
+ let SAI=IDE==='cursor'?(D.subagent_id||D.agent_id||''):(D.agent_id||'');
120
+ let SAT=IDE==='cursor'?(D.subagent_type||D.agent_type||''):(D.agent_type||'');
121
+ const UP=String(D.user_prompt||D.prompt||'').slice(0,4096);
122
+ function sf(n){return path.join(SD,n)}
123
+ function rs(n){try{return fs.readFileSync(sf(n),'utf8')}catch(_){return''}}
124
+ function ws(n,v){try{fs.writeFileSync(sf(n),v,'utf8')}catch(_){}}
125
+ function gai(){return SAI?rs('subagent-'+SID+'-'+SAI):rs('agent-'+SID)}
126
+ function sai(id){SAI?ws('subagent-'+SID+'-'+SAI,id):ws('agent-'+SID,id)}
127
+ function t2a(t){if(t==='Write'||t==='Edit')return'file:write';if(t==='Bash'||t==='shell')return'shell:execute';if(t==='Read')return'file:read';if(t==='Agent'||t==='Task')return'agent:spawn';if(t==='Glob'||t==='Grep')return'file:search';if(t==='WebFetch'||t==='WebSearch')return'web:access';if(t.startsWith('mcp__'))return'mcp:call';return'tool:use'}
128
+ function esc(){const ti=D.tool_input;if(ti&&typeof ti==='object'){for(const k of['file_path','command','pattern','description','prompt','url','query','skill']){if(k in ti)return String(ti[k]).slice(0,150)}}return TN}
129
+ function pn(){return path.basename(CWD||'unknown')}
130
+ function hs(m,ep,body){try{const u=new URL(BASE_URL+ep);const bs=JSON.stringify(body);const mod=u.protocol==='https:'?'https':'http';const opt={hostname:u.hostname,port:u.port||(u.protocol==='https:'?443:80),path:u.pathname+u.search,method:m,headers:{'Authorization':'Bearer '+API_KEY,'Content-Type':'application/json','Content-Length':Buffer.byteLength(bs)},timeout:4000};const{execFileSync}=require('child_process');const sc='const m=require("'+mod+'");const r=m.request('+JSON.stringify(opt)+',(s)=>{let d="";s.on("data",(c)=>{d+=c});s.on("end",()=>{process.stdout.write(d)})});r.on("error",()=>process.exit(0));r.on("timeout",()=>{r.destroy();process.exit(0)});r.write('+JSON.stringify(bs)+');r.end();';return execFileSync(process.execPath,['-e',sc],{timeout:5000,stdio:['pipe','pipe','pipe']}).toString('utf8')}catch(_){return''}}
131
+ function hff(m,ep,body){try{const u=new URL(BASE_URL+ep);const bs=JSON.stringify(body);const mod=u.protocol==='https:'?'https':'http';const opt={hostname:u.hostname,port:u.port||(u.protocol==='https:'?443:80),path:u.pathname+u.search,method:m,headers:{'Authorization':'Bearer '+API_KEY,'Content-Type':'application/json','Content-Length':Buffer.byteLength(bs)},timeout:4000};const{spawn}=require('child_process');const sc='const m=require("'+mod+'");const r=m.request('+JSON.stringify(opt)+',(s)=>{s.resume();s.on("end",()=>process.exit(0))});r.on("error",()=>process.exit(0));r.on("timeout",()=>{r.destroy();process.exit(0)});r.write('+JSON.stringify(bs)+');r.end();';const ch=spawn(process.execPath,['-e',sc],{detached:true,stdio:'ignore'});ch.unref()}catch(_){}}
132
+ function deny(r){if(IDE==='claude'){process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:'PreToolUse',permissionDecision:'deny',permissionDecisionReason:'Custodex: '+r}})+'\\n')}else if(IDE==='cursor'){process.stdout.write(JSON.stringify({permission:'deny',user_message:'Custodex: '+r})+'\\n')}else if(IDE==='gemini'){process.exit(2)}process.exit(0)}
133
+ function reg(name,extra){const md=Object.assign({project:pn(),source:'universal-hook',ide:IDE,sessionId:SID},extra||{});const b={name:name,scopes:['read','write','execute'],metadata:md,protocol:'mcp'};const r=hs('POST','/api/agents/register',b);if(r){try{const j=JSON.parse(r);if(j.agentId){sai(j.agentId);return j.agentId}}catch(_){}}return''}
134
+ const RO=new Set(['Read','Glob','Grep','WebSearch']);
135
+ if(EV==='SessionStart'){const a=reg(pn()+'-orchestrator',{role:'orchestrator',autoDiscovered:true});if(a){ws('gen-'+SID,'0');process.stdout.write(JSON.stringify({hookSpecificOutput:{additionalContext:'[Custodex] Orchestrator registered: '+pn()+'-orchestrator (ID: '+a+'). Running on '+IDE+'.'}})+'\\n')}process.exit(0)}
136
+ if(EV==='SubagentStart'){if(IDE==='gemini')process.exit(0);const n=SAT?pn()+'-'+SAT:pn()+'-subagent-'+Date.now();const pa=rs('agent-'+SID);const pg=parseInt(rs('gen-'+SID),10)||0;const cg=pg+1;const b={name:n,scopes:['read','write','execute'],metadata:{project:pn(),source:'universal-hook',ide:IDE,sessionId:SID,role:'subagent',subagentType:SAT,subagentId:SAI},protocol:'mcp',parentAgentId:pa,generation:cg};const r=hs('POST','/api/agents/register',b);if(r){try{const j=JSON.parse(r);if(j.agentId){sai(j.agentId);ws('gen-'+SID+'-'+SAI,String(cg))}}catch(_){}}process.exit(0)}
137
+ if(EV==='UserPromptSubmit'){const ai=gai();if(!ai)process.exit(0);ws('prompt-'+SID,UP);hff('POST','/api/telemetry',{action:'user.prompt',scope:'session:input',decision:'allowed',latencyMs:0,metadata:{agentId:ai,hookEvent:'UserPromptSubmit',ide:IDE,sessionId:SID,userPrompt:UP.slice(0,4096),environment:{os:os.platform(),cwd:CWD}}});process.exit(0)}
138
+ if(EV==='PreToolUse'){if(RO.has(TN))process.exit(0);let ai=gai();if(!ai){const p=pn();ai=SAI?reg(p+'-'+(SAT||'subagent')+'-late',{role:'subagent',lateRegistration:true}):reg(p+'-orchestrator-late',{role:'orchestrator',lateRegistration:true})}const ac=t2a(TN);const sc=esc();const lp=rs('prompt-'+SID).slice(0,2048);const r=hs('POST','/api/verify',{agentId:ai,action:ac,scope:sc,metadata:{toolName:TN,ide:IDE,sessionId:SID,userPrompt:lp,environment:{os:os.platform(),cwd:CWD}}});if(r){try{const j=JSON.parse(r);if(j.decision==='denied')deny(j.reason||j.message||'Policy violation')}catch(_){}}process.exit(0)}
139
+ if(EV==='PostToolUse'){const ai=gai();if(!ai)process.exit(0);let ac=t2a(TN);let tn=TN;if(RE==='afterFileEdit'){ac='file:write';if(D.file_path)tn='Edit('+D.file_path+')'}let dm=0;if(RE==='afterShellExecution')dm=Math.round((D.duration||0)*1000);const sc=esc();let to=D.tool_output||D.output||'';to=typeof to==='object'?JSON.stringify(to).slice(0,2048):String(to).slice(0,2048);const lp=rs('prompt-'+SID).slice(0,2048);hff('POST','/api/telemetry',{action:ac,scope:sc,decision:'allowed',latencyMs:dm,metadata:{agentId:ai,toolName:tn,hookEvent:'PostToolUse',rawEvent:RE,ide:IDE,sessionId:SID,project:pn(),toolOutput:to,userPrompt:lp,environment:{os:os.platform(),cwd:CWD}}});process.exit(0)}
140
+ process.exit(0);
141
+ `;
97
142
  // ─── Shared config ──────────────────────────────────────────────────────────
98
143
  /**
99
144
  * Write ~/.custodex/config.json and install the governance script.
@@ -106,48 +151,34 @@ export function writeSharedConfig(config) {
106
151
  // Write config
107
152
  const configPath = path.join(custodexDir, "config.json");
108
153
  writeJsonFile(configPath, config);
109
- // Copy hook.sh from package hooks/ → ~/.custodex/hook.sh
110
- const hookDst = path.join(custodexDir, "hook.sh");
111
154
  // Compiled output lives in dist/install.js; package root is one level up.
112
- const packageRoot = path.resolve(path.dirname(new URL(import.meta.url).pathname), "..");
155
+ // Use fileURLToPath for correct Windows path handling (no leading / on C:\...)
156
+ const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
157
+ // Copy hook.js (Node.js, cross-platform) → ~/.custodex/hook.js
158
+ const hookJsDst = path.join(custodexDir, "hook.js");
159
+ const hookJsSrc = path.join(packageRoot, "hooks", "hook.js");
160
+ if (fs.existsSync(hookJsSrc)) {
161
+ fs.copyFileSync(hookJsSrc, hookJsDst);
162
+ }
163
+ else {
164
+ // Inline fallback: write a minimal Node.js hook if package source not found
165
+ fs.writeFileSync(hookJsDst, FALLBACK_HOOK_JS, { encoding: "utf8" });
166
+ }
167
+ // Copy hook.sh (bash, Unix only) → ~/.custodex/hook.sh
168
+ const hookDst = path.join(custodexDir, "hook.sh");
113
169
  const hookSrc = path.join(packageRoot, "hooks", "hook.sh");
114
170
  if (fs.existsSync(hookSrc)) {
115
171
  fs.copyFileSync(hookSrc, hookDst);
116
172
  }
117
- else {
118
- // Write a minimal hook if the package hook is missing (e.g. dev environment)
119
- fs.writeFileSync(hookDst, `#!/usr/bin/env bash
120
- # Custodex governance hook
121
- # Reads event JSON from stdin and forwards to the Custodex backend.
122
-
123
- set -euo pipefail
124
-
125
- CUSTODEX_CONFIG="${custodexDir}/config.json"
126
- if [ ! -f "$CUSTODEX_CONFIG" ]; then
127
- exit 0
128
- fi
129
-
130
- API_KEY=$(node -e "const c=require('$CUSTODEX_CONFIG');process.stdout.write(c.apiKey||'')" 2>/dev/null || true)
131
- BASE_URL=$(node -e "const c=require('$CUSTODEX_CONFIG');process.stdout.write(c.baseUrl||'')" 2>/dev/null || true)
132
-
133
- if [ -z "$API_KEY" ] || [ -z "$BASE_URL" ]; then
134
- exit 0
135
- fi
136
-
137
- # Read event payload from stdin (Claude Code / Cursor pass JSON here)
138
- PAYLOAD=$(cat -)
139
-
140
- # Fire-and-forget telemetry — never block the IDE
141
- curl -s -X POST "$BASE_URL/api/telemetry" \\
142
- -H "Authorization: Bearer $API_KEY" \\
143
- -H "Content-Type: application/json" \\
144
- -d "$PAYLOAD" \\
145
- --max-time 3 >/dev/null 2>&1 || true
146
-
147
- exit 0
148
- `, { encoding: "utf8" });
173
+ // Make both executable on Unix
174
+ try {
175
+ fs.chmodSync(hookDst, 0o755);
176
+ }
177
+ catch { /* Windows: no chmod needed */ }
178
+ try {
179
+ fs.chmodSync(hookJsDst, 0o755);
149
180
  }
150
- fs.chmodSync(hookDst, 0o755);
181
+ catch { /* Windows: no chmod needed */ }
151
182
  // Copy OpenCode plugin
152
183
  const pluginDst = path.join(custodexDir, "plugins", "custodex-opencode.ts");
153
184
  const pluginSrc = path.join(packageRoot, "plugins", "custodex-opencode.ts");
@@ -163,7 +194,10 @@ exit 0
163
194
  export function installClaude() {
164
195
  try {
165
196
  const home = os.homedir();
166
- const hookCmd = `${home}/.custodex/hook.sh`;
197
+ const isWindows = process.platform === "win32";
198
+ const hookCmd = isWindows
199
+ ? `node "${path.join(home, ".custodex", "hook.js")}"`
200
+ : `${home}/.custodex/hook.sh`;
167
201
  const settingsPath = path.join(home, ".claude", "settings.json");
168
202
  fs.mkdirSync(path.join(home, ".claude"), { recursive: true });
169
203
  const existing = readJsonFile(settingsPath);
@@ -225,7 +259,10 @@ export function installClaude() {
225
259
  export function installCursor() {
226
260
  try {
227
261
  const home = os.homedir();
228
- const hookCmd = `${home}/.custodex/hook.sh`;
262
+ const isWindows = process.platform === "win32";
263
+ const hookCmd = isWindows
264
+ ? `node "${path.join(home, ".custodex", "hook.js")}"`
265
+ : `${home}/.custodex/hook.sh`;
229
266
  const hooksPath = path.join(home, ".cursor", "hooks.json");
230
267
  fs.mkdirSync(path.join(home, ".cursor"), { recursive: true });
231
268
  const existing = readJsonFile(hooksPath);
@@ -278,7 +315,10 @@ export function installCursor() {
278
315
  export function installGemini() {
279
316
  try {
280
317
  const home = os.homedir();
281
- const hookCmd = `${home}/.custodex/hook.sh`;
318
+ const isWindows = process.platform === "win32";
319
+ const hookCmd = isWindows
320
+ ? `node "${path.join(home, ".custodex", "hook.js")}"`
321
+ : `${home}/.custodex/hook.sh`;
282
322
  const settingsPath = path.join(home, ".gemini", "settings.json");
283
323
  fs.mkdirSync(path.join(home, ".gemini"), { recursive: true });
284
324
  const existing = readJsonFile(settingsPath);
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
package/hooks/hook.js ADDED
@@ -0,0 +1,628 @@
1
+ #!/usr/bin/env node
2
+ // ============================================================
3
+ // Custodex Universal Governance Hook (Node.js)
4
+ // Version: 1.0.0
5
+ //
6
+ // Cross-platform equivalent of hook.sh — zero external dependencies.
7
+ // Only Node.js built-ins: fs, path, os, https, http, crypto
8
+ //
9
+ // Supported IDEs (detected in priority order):
10
+ // 1. Gemini CLI — GEMINI_SESSION_ID env var is set
11
+ // 2. Cursor — input JSON has conversation_id but no session_id
12
+ // 3. Claude Code — input JSON has session_id (default fallback)
13
+ // ============================================================
14
+
15
+ 'use strict';
16
+
17
+ const fs = require('fs');
18
+ const path = require('path');
19
+ const os = require('os');
20
+ const https = require('https');
21
+ const http = require('http');
22
+
23
+ // ─── 1. LOAD CONFIG ─────────────────────────────────────────────────────────
24
+
25
+ let CUSTODEX_API_KEY = process.env.CUSTODEX_API_KEY || '';
26
+ let CUSTODEX_BASE_URL = process.env.CUSTODEX_BASE_URL || '';
27
+ const CUSTODEX_PROJECT_FILTER = process.env.CUSTODEX_PROJECT_FILTER || '';
28
+
29
+ const configFile = path.join(os.homedir(), '.custodex', 'config.json');
30
+ try {
31
+ if (fs.existsSync(configFile)) {
32
+ const cfg = JSON.parse(fs.readFileSync(configFile, 'utf8'));
33
+ if (!CUSTODEX_API_KEY && cfg.apiKey) CUSTODEX_API_KEY = cfg.apiKey;
34
+ if (!CUSTODEX_BASE_URL && cfg.baseUrl) CUSTODEX_BASE_URL = cfg.baseUrl.replace(/\/+$/, '');
35
+ }
36
+ } catch (_) { /* ignore config read errors */ }
37
+
38
+ // Bail out silently if not configured — never break the IDE.
39
+ if (!CUSTODEX_API_KEY || !CUSTODEX_BASE_URL) process.exit(0);
40
+
41
+ CUSTODEX_BASE_URL = CUSTODEX_BASE_URL.replace(/\/+$/, '');
42
+
43
+ // ─── 2. STATE DIRECTORY ─────────────────────────────────────────────────────
44
+
45
+ const STATE_DIR = path.join(os.tmpdir(), 'custodex-hooks');
46
+ try { fs.mkdirSync(STATE_DIR, { recursive: true }); } catch (_) { /* ok */ }
47
+
48
+ // ─── 3. READ STDIN (synchronous) ────────────────────────────────────────────
49
+
50
+ let INPUT = '';
51
+ try {
52
+ INPUT = fs.readFileSync(0, 'utf8');
53
+ } catch (_) { /* empty stdin */ }
54
+
55
+ let inputData = {};
56
+ try { inputData = JSON.parse(INPUT); } catch (_) { inputData = {}; }
57
+
58
+ // ─── 4. IDE DETECTION & FIELD NORMALISATION ─────────────────────────────────
59
+
60
+ const geminiSession = process.env.GEMINI_SESSION_ID || '';
61
+ let IDE;
62
+ if (geminiSession) {
63
+ IDE = 'gemini';
64
+ } else if ('conversation_id' in inputData && !('session_id' in inputData)) {
65
+ IDE = 'cursor';
66
+ } else {
67
+ IDE = 'claude';
68
+ }
69
+
70
+ // Raw event name
71
+ const RAW_EVENT = inputData.hook_event_name || '';
72
+
73
+ // Canonical event mapping
74
+ const EVENT_MAP = {
75
+ SessionStart: 'SessionStart', sessionStart: 'SessionStart',
76
+ SubagentStart: 'SubagentStart', subagentStart: 'SubagentStart',
77
+ PreToolUse: 'PreToolUse', preToolUse: 'PreToolUse',
78
+ beforeShellExecution: 'PreToolUse', beforeMCPExecution: 'PreToolUse',
79
+ BeforeTool: 'PreToolUse',
80
+ PostToolUse: 'PostToolUse', postToolUse: 'PostToolUse',
81
+ afterShellExecution: 'PostToolUse', afterFileEdit: 'PostToolUse',
82
+ AfterTool: 'PostToolUse',
83
+ UserPromptSubmit: 'UserPromptSubmit', beforeSubmitPrompt: 'UserPromptSubmit',
84
+ BeforeAgent: 'UserPromptSubmit',
85
+ };
86
+ const EVENT = EVENT_MAP[RAW_EVENT] || RAW_EVENT;
87
+
88
+ // Session ID
89
+ let SESSION_ID;
90
+ if (IDE === 'gemini') {
91
+ SESSION_ID = geminiSession;
92
+ } else if (IDE === 'cursor') {
93
+ SESSION_ID = inputData.conversation_id || inputData.session_id || '';
94
+ } else {
95
+ SESSION_ID = inputData.session_id || '';
96
+ }
97
+
98
+ // Tool name
99
+ let TOOL_NAME;
100
+ if (RAW_EVENT === 'beforeShellExecution' || RAW_EVENT === 'afterShellExecution') {
101
+ TOOL_NAME = 'Bash';
102
+ } else if (RAW_EVENT === 'afterFileEdit') {
103
+ TOOL_NAME = 'Edit';
104
+ } else {
105
+ TOOL_NAME = inputData.tool_name || '';
106
+ }
107
+
108
+ // CWD
109
+ const CWD = inputData.cwd || process.env.PWD || process.cwd();
110
+
111
+ // Subagent fields
112
+ let SUBAGENT_ID, SUBAGENT_TYPE;
113
+ if (IDE === 'cursor') {
114
+ SUBAGENT_ID = inputData.subagent_id || inputData.agent_id || '';
115
+ SUBAGENT_TYPE = inputData.subagent_type || inputData.agent_type || '';
116
+ } else {
117
+ SUBAGENT_ID = inputData.agent_id || '';
118
+ SUBAGENT_TYPE = inputData.agent_type || '';
119
+ }
120
+
121
+ // User prompt
122
+ const USER_PROMPT = String(inputData.user_prompt || inputData.prompt || '').slice(0, 4096);
123
+
124
+ // Tool output (truncated)
125
+ let TOOL_OUTPUT = inputData.tool_output || inputData.output || '';
126
+ if (typeof TOOL_OUTPUT === 'object') {
127
+ TOOL_OUTPUT = JSON.stringify(TOOL_OUTPUT).slice(0, 2048);
128
+ } else {
129
+ TOOL_OUTPUT = String(TOOL_OUTPUT).slice(0, 2048);
130
+ }
131
+
132
+ // Cursor-specific
133
+ const COMPOSER_MODE = String(inputData.composer_mode || '').toLowerCase();
134
+ const IS_BACKGROUND_AGENT = String(inputData.is_background_agent || '').toLowerCase();
135
+ const TOOL_USE_ID = inputData.tool_use_id || '';
136
+
137
+ // ─── 5. PROJECT FILTER ──────────────────────────────────────────────────────
138
+
139
+ if (CUSTODEX_PROJECT_FILTER && !CWD.includes(CUSTODEX_PROJECT_FILTER)) {
140
+ process.exit(0);
141
+ }
142
+
143
+ // ─── 6. UTILITY FUNCTIONS ───────────────────────────────────────────────────
144
+
145
+ function stateFile(name) {
146
+ return path.join(STATE_DIR, name);
147
+ }
148
+
149
+ function readState(name) {
150
+ try { return fs.readFileSync(stateFile(name), 'utf8'); } catch (_) { return ''; }
151
+ }
152
+
153
+ function writeState(name, value) {
154
+ try { fs.writeFileSync(stateFile(name), value, 'utf8'); } catch (_) { /* ignore */ }
155
+ }
156
+
157
+ function getAgentId() {
158
+ if (SUBAGENT_ID) {
159
+ return readState(`subagent-${SESSION_ID}-${SUBAGENT_ID}`);
160
+ }
161
+ return readState(`agent-${SESSION_ID}`);
162
+ }
163
+
164
+ function saveAgentId(id) {
165
+ if (SUBAGENT_ID) {
166
+ writeState(`subagent-${SESSION_ID}-${SUBAGENT_ID}`, id);
167
+ } else {
168
+ writeState(`agent-${SESSION_ID}`, id);
169
+ }
170
+ }
171
+
172
+ function toolToAction(t) {
173
+ if (t === 'Write' || t === 'Edit') return 'file:write';
174
+ if (t === 'Bash' || t === 'shell') return 'shell:execute';
175
+ if (t === 'Read') return 'file:read';
176
+ if (t === 'Agent' || t === 'Task') return 'agent:spawn';
177
+ if (t === 'Glob' || t === 'Grep') return 'file:search';
178
+ if (t === 'WebFetch' || t === 'WebSearch') return 'web:access';
179
+ if (t.startsWith('mcp__')) return 'mcp:call';
180
+ return 'tool:use';
181
+ }
182
+
183
+ function extractScope() {
184
+ const ti = inputData.tool_input;
185
+ if (ti && typeof ti === 'object') {
186
+ const keys = ['file_path', 'command', 'pattern', 'description', 'prompt', 'url', 'query', 'skill'];
187
+ for (const k of keys) {
188
+ if (k in ti) return String(ti[k]).slice(0, 150);
189
+ }
190
+ }
191
+ return TOOL_NAME;
192
+ }
193
+
194
+ function projectName() {
195
+ return path.basename(CWD || 'unknown');
196
+ }
197
+
198
+ // ─── HTTP helpers ────────────────────────────────────────────────────────────
199
+
200
+ function parseUrl(endpoint) {
201
+ const full = CUSTODEX_BASE_URL + endpoint;
202
+ const u = new URL(full);
203
+ return u;
204
+ }
205
+
206
+ /** Synchronous HTTP request — blocks until response or timeout. */
207
+ function httpSync(method, endpoint, body) {
208
+ try {
209
+ const u = parseUrl(endpoint);
210
+ const bodyStr = JSON.stringify(body);
211
+ const isHttps = u.protocol === 'https:';
212
+ const options = {
213
+ hostname: u.hostname,
214
+ port: u.port || (isHttps ? 443 : 80),
215
+ path: u.pathname + u.search,
216
+ method: method,
217
+ headers: {
218
+ 'Authorization': `Bearer ${CUSTODEX_API_KEY}`,
219
+ 'Content-Type': 'application/json',
220
+ 'Content-Length': Buffer.byteLength(bodyStr),
221
+ },
222
+ timeout: 4000,
223
+ };
224
+
225
+ // Use child_process.execFileSync to perform a synchronous HTTP call
226
+ // by spawning a small inline Node script that writes the response to stdout.
227
+ const { execFileSync } = require('child_process');
228
+ const script = `
229
+ const ${isHttps ? 'https' : 'http'} = require('${isHttps ? 'https' : 'http'}');
230
+ const options = ${JSON.stringify(options)};
231
+ const body = ${JSON.stringify(bodyStr)};
232
+ const req = ${isHttps ? 'https' : 'http'}.request(options, (res) => {
233
+ let data = '';
234
+ res.on('data', (c) => { data += c; });
235
+ res.on('end', () => {
236
+ process.stdout.write(data);
237
+ });
238
+ });
239
+ req.on('error', () => { process.exit(0); });
240
+ req.on('timeout', () => { req.destroy(); process.exit(0); });
241
+ req.write(body);
242
+ req.end();
243
+ `;
244
+ const result = execFileSync(process.execPath, ['-e', script], {
245
+ timeout: 5000,
246
+ stdio: ['pipe', 'pipe', 'pipe'],
247
+ env: process.env,
248
+ });
249
+ return result.toString('utf8');
250
+ } catch (_) {
251
+ return '';
252
+ }
253
+ }
254
+
255
+ /** Fire-and-forget HTTP request — spawns detached child, never blocks. */
256
+ function httpFireAndForget(method, endpoint, body) {
257
+ try {
258
+ const u = parseUrl(endpoint);
259
+ const bodyStr = JSON.stringify(body);
260
+ const isHttps = u.protocol === 'https:';
261
+ const options = {
262
+ hostname: u.hostname,
263
+ port: u.port || (isHttps ? 443 : 80),
264
+ path: u.pathname + u.search,
265
+ method: method,
266
+ headers: {
267
+ 'Authorization': `Bearer ${CUSTODEX_API_KEY}`,
268
+ 'Content-Type': 'application/json',
269
+ 'Content-Length': Buffer.byteLength(bodyStr),
270
+ },
271
+ timeout: 4000,
272
+ };
273
+
274
+ const { spawn } = require('child_process');
275
+ const script = `
276
+ const ${isHttps ? 'https' : 'http'} = require('${isHttps ? 'https' : 'http'}');
277
+ const req = ${isHttps ? 'https' : 'http'}.request(${JSON.stringify(options)}, (res) => {
278
+ res.resume();
279
+ res.on('end', () => process.exit(0));
280
+ });
281
+ req.on('error', () => process.exit(0));
282
+ req.on('timeout', () => { req.destroy(); process.exit(0); });
283
+ req.write(${JSON.stringify(bodyStr)});
284
+ req.end();
285
+ `;
286
+ const child = spawn(process.execPath, ['-e', script], {
287
+ detached: true,
288
+ stdio: 'ignore',
289
+ });
290
+ child.unref();
291
+ } catch (_) { /* fail silently */ }
292
+ }
293
+
294
+ // ─── DENY RESPONSE ──────────────────────────────────────────────────────────
295
+
296
+ function denyResponse(reason) {
297
+ if (IDE === 'claude') {
298
+ const resp = {
299
+ hookSpecificOutput: {
300
+ hookEventName: 'PreToolUse',
301
+ permissionDecision: 'deny',
302
+ permissionDecisionReason: `Custodex: ${reason}`,
303
+ },
304
+ };
305
+ process.stdout.write(JSON.stringify(resp) + '\n');
306
+ } else if (IDE === 'cursor') {
307
+ const resp = {
308
+ permission: 'deny',
309
+ user_message: `Custodex: ${reason}`,
310
+ };
311
+ process.stdout.write(JSON.stringify(resp) + '\n');
312
+ } else if (IDE === 'gemini') {
313
+ process.exit(2);
314
+ }
315
+ process.exit(0);
316
+ }
317
+
318
+ // ─── REGISTER AGENT ─────────────────────────────────────────────────────────
319
+
320
+ function registerAgent(name, extraMeta) {
321
+ const metadata = Object.assign({
322
+ project: projectName(),
323
+ source: 'universal-hook',
324
+ ide: IDE,
325
+ sessionId: SESSION_ID,
326
+ }, extraMeta || {});
327
+
328
+ const body = {
329
+ name: name,
330
+ scopes: ['read', 'write', 'execute'],
331
+ metadata: metadata,
332
+ protocol: 'mcp',
333
+ };
334
+
335
+ const responseStr = httpSync('POST', '/api/agents/register', body);
336
+ if (responseStr) {
337
+ try {
338
+ const resp = JSON.parse(responseStr);
339
+ const agentId = resp.agentId || '';
340
+ if (agentId) {
341
+ saveAgentId(agentId);
342
+ return agentId;
343
+ }
344
+ } catch (_) { /* ignore parse errors */ }
345
+ }
346
+ return '';
347
+ }
348
+
349
+ // ─── 7. EVENT HANDLERS ──────────────────────────────────────────────────────
350
+
351
+ function handleSessionStart() {
352
+ const proj = projectName();
353
+ const agentName = `${proj}-orchestrator`;
354
+
355
+ const extraMeta = { role: 'orchestrator', autoDiscovered: true };
356
+ if (IDE === 'cursor') {
357
+ extraMeta.composerMode = COMPOSER_MODE;
358
+ extraMeta.isBackgroundAgent = IS_BACKGROUND_AGENT;
359
+ }
360
+ if (IDE === 'gemini') {
361
+ extraMeta.geminiSessionId = SESSION_ID;
362
+ }
363
+
364
+ const agentId = registerAgent(agentName, extraMeta);
365
+ if (agentId) {
366
+ writeState(`gen-${SESSION_ID}`, '0');
367
+ const out = {
368
+ hookSpecificOutput: {
369
+ additionalContext: `[Custodex] Orchestrator registered: ${agentName} (ID: ${agentId}). Running on ${IDE}.`,
370
+ },
371
+ };
372
+ process.stdout.write(JSON.stringify(out) + '\n');
373
+ }
374
+ process.exit(0);
375
+ }
376
+
377
+ function handleSubagentStart() {
378
+ if (IDE === 'gemini') process.exit(0);
379
+
380
+ const proj = projectName();
381
+ const agentName = SUBAGENT_TYPE
382
+ ? `${proj}-${SUBAGENT_TYPE}`
383
+ : `${proj}-subagent-${Date.now()}`;
384
+
385
+ const parentAgentId = readState(`agent-${SESSION_ID}`);
386
+ const parentGen = parseInt(readState(`gen-${SESSION_ID}`), 10) || 0;
387
+ const childGen = parentGen + 1;
388
+
389
+ const extraMeta = {
390
+ role: 'subagent',
391
+ subagentType: SUBAGENT_TYPE,
392
+ subagentId: SUBAGENT_ID,
393
+ };
394
+
395
+ if (IDE === 'cursor') {
396
+ const cursorTask = String(inputData.task || '').slice(0, 200);
397
+ if (cursorTask) extraMeta.task = cursorTask;
398
+ }
399
+
400
+ const metadata = Object.assign({
401
+ project: proj,
402
+ source: 'universal-hook',
403
+ ide: IDE,
404
+ sessionId: SESSION_ID,
405
+ }, extraMeta);
406
+
407
+ const body = {
408
+ name: agentName,
409
+ scopes: ['read', 'write', 'execute'],
410
+ metadata: metadata,
411
+ protocol: 'mcp',
412
+ parentAgentId: parentAgentId,
413
+ generation: childGen,
414
+ };
415
+
416
+ const responseStr = httpSync('POST', '/api/agents/register', body);
417
+ if (responseStr) {
418
+ try {
419
+ const resp = JSON.parse(responseStr);
420
+ const newId = resp.agentId || '';
421
+ if (newId) {
422
+ saveAgentId(newId);
423
+ writeState(`gen-${SESSION_ID}-${SUBAGENT_ID}`, String(childGen));
424
+ }
425
+ } catch (_) { /* ignore */ }
426
+ }
427
+ process.exit(0);
428
+ }
429
+
430
+ function handleUserPrompt() {
431
+ const custodexAgentId = getAgentId();
432
+ if (!custodexAgentId) process.exit(0);
433
+
434
+ // Persist prompt for subsequent PreToolUse
435
+ writeState(`prompt-${SESSION_ID}`, USER_PROMPT);
436
+
437
+ let callerType = 'user';
438
+ let callerId = '';
439
+ if (SUBAGENT_ID) {
440
+ callerType = 'agent';
441
+ callerId = readState(`agent-${SESSION_ID}`);
442
+ }
443
+
444
+ const metadata = {
445
+ agentId: custodexAgentId,
446
+ hookEvent: 'UserPromptSubmit',
447
+ ide: IDE,
448
+ sessionId: SESSION_ID,
449
+ userPrompt: USER_PROMPT.slice(0, 4096),
450
+ caller: { type: callerType, id: callerId },
451
+ environment: { os: os.platform(), shell: process.env.SHELL || 'unknown', cwd: CWD },
452
+ };
453
+
454
+ if (SUBAGENT_TYPE) {
455
+ metadata.onBehalfOf = `${projectName()}-${SUBAGENT_TYPE}`;
456
+ }
457
+
458
+ httpFireAndForget('POST', '/api/telemetry', {
459
+ action: 'user.prompt',
460
+ scope: 'session:input',
461
+ decision: 'allowed',
462
+ latencyMs: 0,
463
+ metadata: metadata,
464
+ });
465
+
466
+ process.exit(0);
467
+ }
468
+
469
+ // Read-only tools — skip governance checks for these.
470
+ const READONLY_TOOLS = new Set(['Read', 'Glob', 'Grep', 'WebSearch']);
471
+
472
+ function handlePreToolUse() {
473
+ if (READONLY_TOOLS.has(TOOL_NAME)) process.exit(0);
474
+
475
+ let custodexAgentId = getAgentId();
476
+
477
+ // Late-register if no agent ID recorded yet.
478
+ if (!custodexAgentId) {
479
+ const proj = projectName();
480
+ if (SUBAGENT_ID) {
481
+ const lateName = `${proj}-${SUBAGENT_TYPE || 'subagent'}-late`;
482
+ custodexAgentId = registerAgent(lateName, {
483
+ role: 'subagent', subagentType: SUBAGENT_TYPE, lateRegistration: true,
484
+ });
485
+ } else {
486
+ custodexAgentId = registerAgent(`${proj}-orchestrator-late`, {
487
+ role: 'orchestrator', lateRegistration: true,
488
+ });
489
+ }
490
+ }
491
+
492
+ const action = toolToAction(TOOL_NAME);
493
+ const scope = extractScope();
494
+
495
+ // Read last persisted prompt for context.
496
+ const lastPrompt = readState(`prompt-${SESSION_ID}`).slice(0, 2048);
497
+
498
+ const verifyBody = {
499
+ agentId: custodexAgentId,
500
+ action: action,
501
+ scope: scope,
502
+ metadata: {
503
+ toolName: TOOL_NAME,
504
+ ide: IDE,
505
+ sessionId: SESSION_ID,
506
+ userPrompt: lastPrompt,
507
+ environment: { os: os.platform(), cwd: CWD },
508
+ },
509
+ };
510
+
511
+ const responseStr = httpSync('POST', '/api/verify', verifyBody);
512
+
513
+ if (responseStr) {
514
+ try {
515
+ const resp = JSON.parse(responseStr);
516
+ if (resp.decision === 'denied') {
517
+ const reason = resp.reason || resp.message || 'Policy violation';
518
+ denyResponse(reason);
519
+ // denyResponse calls process.exit — never reaches here.
520
+ }
521
+ } catch (_) { /* parse error — allow by default */ }
522
+ }
523
+
524
+ process.exit(0);
525
+ }
526
+
527
+ function handlePostToolUse() {
528
+ const custodexAgentId = getAgentId();
529
+ if (!custodexAgentId) process.exit(0);
530
+
531
+ let action = toolToAction(TOOL_NAME);
532
+ let toolName = TOOL_NAME;
533
+
534
+ // Cursor afterFileEdit — override action and extract file path.
535
+ if (RAW_EVENT === 'afterFileEdit') {
536
+ action = 'file:write';
537
+ const filePath = inputData.file_path || '';
538
+ if (filePath) toolName = `Edit(${filePath})`;
539
+ }
540
+
541
+ // Cursor afterShellExecution — capture duration.
542
+ let durationMs = 0;
543
+ if (RAW_EVENT === 'afterShellExecution') {
544
+ durationMs = Math.round((inputData.duration || 0) * 1000);
545
+ }
546
+
547
+ const scope = extractScope();
548
+
549
+ // Tool output
550
+ const safeToolOutput = TOOL_OUTPUT.slice(0, 2048);
551
+
552
+ // Last prompt
553
+ const lastPrompt = readState(`prompt-${SESSION_ID}`).slice(0, 2048);
554
+
555
+ let actorName = 'orchestrator';
556
+ if (SUBAGENT_TYPE) actorName = SUBAGENT_TYPE;
557
+
558
+ let callerType = 'user';
559
+ let callerId = '';
560
+ let callerName = '';
561
+ if (SUBAGENT_ID) {
562
+ callerType = 'agent';
563
+ callerId = readState(`agent-${SESSION_ID}`);
564
+ callerName = 'orchestrator';
565
+ }
566
+
567
+ // Tool input summary
568
+ let toolSummary = {};
569
+ const ti = inputData.tool_input;
570
+ if (ti && typeof ti === 'object') {
571
+ const summaryKeys = ['command', 'file_path', 'pattern', 'description', 'prompt', 'url', 'query', 'skill', 'name'];
572
+ for (const k of summaryKeys) {
573
+ if (k in ti) toolSummary[k] = String(ti[k]).slice(0, 200);
574
+ }
575
+ }
576
+
577
+ const metadata = {
578
+ agentId: custodexAgentId,
579
+ toolName: toolName,
580
+ hookEvent: 'PostToolUse',
581
+ rawEvent: RAW_EVENT,
582
+ ide: IDE,
583
+ sessionId: SESSION_ID,
584
+ actor: actorName,
585
+ subagentType: SUBAGENT_TYPE,
586
+ subagentId: SUBAGENT_ID,
587
+ project: projectName(),
588
+ toolInput: toolSummary,
589
+ toolOutput: safeToolOutput,
590
+ userPrompt: lastPrompt,
591
+ caller: {
592
+ type: callerType,
593
+ id: callerId,
594
+ name: callerName,
595
+ directive: lastPrompt,
596
+ },
597
+ environment: {
598
+ os: os.platform(),
599
+ shell: process.env.SHELL || 'unknown',
600
+ cwd: CWD,
601
+ },
602
+ };
603
+
604
+ if (SUBAGENT_TYPE) {
605
+ metadata.onBehalfOf = `${projectName()}-${SUBAGENT_TYPE}`;
606
+ }
607
+
608
+ httpFireAndForget('POST', '/api/telemetry', {
609
+ action: action,
610
+ scope: scope,
611
+ decision: 'allowed',
612
+ latencyMs: durationMs,
613
+ metadata: metadata,
614
+ });
615
+
616
+ process.exit(0);
617
+ }
618
+
619
+ // ─── 8. ROUTE ───────────────────────────────────────────────────────────────
620
+
621
+ switch (EVENT) {
622
+ case 'SessionStart': handleSessionStart(); break;
623
+ case 'SubagentStart': handleSubagentStart(); break;
624
+ case 'PreToolUse': handlePreToolUse(); break;
625
+ case 'PostToolUse': handlePostToolUse(); break;
626
+ case 'UserPromptSubmit': handleUserPrompt(); break;
627
+ default: process.exit(0);
628
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "custodex",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Universal AI agent governance — one command to govern Claude, Cursor, Gemini CLI, and OpenCode",
5
5
  "type": "module",
6
6
  "bin": { "custodex": "dist/index.js" },