@pinta-ai/pinta-codex 1.5.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinta-codex",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Generic OTLP forwarder for Codex hook events",
5
5
  "author": {
6
6
  "name": "Pinta AI",
package/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  All notable changes to pinta-codex are documented here.
4
4
 
5
+ ## [1.5.1] - 2026-07-20
6
+
7
+ ### Changed
8
+
9
+ - `@pinta-ai/core` bumped `^0.3.0` → `^0.5.0` (devDependency, bundled
10
+ into `dist/` at build). Pulls in the oversized-flush fix (pinta-manager#180
11
+ follow-up): the retry queue now flushes in 900 KiB chunks instead of one
12
+ unbounded POST, spans are capped at 800 KiB at build time, and a payload
13
+ that alone exceeds the POST budget is dropped with a diagnostic instead of
14
+ poisoning every later flush. No adaptor source change was needed.
15
+
5
16
  ## [1.4.0] - 2026-07-12
6
17
 
7
18
  ### Changed
package/dist/index.js CHANGED
@@ -1,15 +1,24 @@
1
- "use strict";var tt=Object.create;var re=Object.defineProperty;var rt=Object.getOwnPropertyDescriptor;var nt=Object.getOwnPropertyNames;var ot=Object.getPrototypeOf,st=Object.prototype.hasOwnProperty;var f=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var it=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of nt(t))!st.call(e,o)&&o!==r&&re(e,o,{get:()=>t[o],enumerable:!(n=rt(t,o))||n.enumerable});return e};var m=(e,t,r)=>(r=e!=null?tt(ot(e)):{},it(t||!e||!e.__esModule?re(r,"default",{value:e,enumerable:!0}):r,e));var j=f(c=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});c.PATTERNS=c.MAX_BYTES=void 0;c.truncate=at;c.collectMatches=ne;c.resolveOverlaps=oe;c.applyMatches=se;c.redact=ut;c.MAX_BYTES=102400;function at(e){let t=Buffer.from(e,"utf-8");return t.length<=c.MAX_BYTES?e:`${t.subarray(0,c.MAX_BYTES).toString("utf-8")}\u2026[TRUNCATED:${t.length}]`}c.PATTERNS=[{type:"aws_access_key",regex:/AKIA[0-9A-Z]{16}/g},{type:"aws_secret_key",regex:/(?:aws[_-]?secret(?:[_-]?(?:access)?[_-]?key)?)\s*[:=]\s*["']?([A-Za-z0-9/+=]{40})(?![A-Za-z0-9/+=])/gi,captureGroup:1},{type:"gcp_service_account",regex:/\{[\s\S]{0,200}?"type"\s*:\s*"service_account"[\s\S]*?\}/g},{type:"github_token",regex:/gh[pousr]_[A-Za-z0-9]{36,}/g},{type:"gitlab_token",regex:/glpat-[A-Za-z0-9_-]{20}/g},{type:"slack_token",regex:/xox[abrsp]-[0-9A-Za-z-]{10,}/g},{type:"openai_key",regex:/sk-(?:proj-)?[A-Za-z0-9_-]{40,}/g},{type:"anthropic_key",regex:/sk-ant-[A-Za-z0-9_-]{50,}/g},{type:"stripe_key",regex:/(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g},{type:"jwt",regex:/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g},{type:"private_key_block",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g},{type:"bearer_token",regex:/bearer\s+([A-Za-z0-9._~+/=-]{12,})/gi,captureGroup:1},{type:"basic_auth",regex:/basic\s+([A-Za-z0-9+/=]{12,})/gi,captureGroup:1},{type:"db_url_password",regex:/\b(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|redis):\/\/[^:\s/]+:([^@\s]+)@/gi,captureGroup:1},{type:"cli_password_flag",regex:/(?:--password|--pass|--pwd)[=\s]([^\s'"]+)/g,captureGroup:1},{type:"cli_password_short",regex:/\s-p([^\s'"]+)/g,captureGroup:1,requireContext:"bash"},{type:"env_var_secret",regex:/^(?:export\s+)?([A-Z][A-Z0-9_]*(?:KEY|SECRET|TOKEN|PASSWORD|PASSWD|PWD|API_KEY)[A-Z0-9_]*)\s*=\s*["']?([^\s"'\n]+)/gm,captureGroup:2}];function ne(e,t){let r=[];for(let n of c.PATTERNS){if(n.requireContext&&n.requireContext!==t.context)continue;let o=new RegExp(n.regex.source,n.regex.flags),i;for(;(i=o.exec(e))!==null;){let a=n.captureGroup??0,u=i[a];if(u===void 0){i.index===o.lastIndex&&o.lastIndex++;continue}let S=i.index,Qe=i.index+i[0].length,te=S+i[0].indexOf(u),et=te+u.length;r.push({start:S,end:Qe,replaceStart:te,replaceEnd:et,type:n.type}),i.index===o.lastIndex&&o.lastIndex++}}return r}function oe(e){let t=[...e].sort((o,i)=>o.start!==i.start?o.start-i.start:i.end-i.start-(o.end-o.start)),r=[],n=-1;for(let o of t)o.start<n||(r.push(o),n=o.end);return r}function se(e,t){let r=[...t].sort((o,i)=>i.replaceStart-o.replaceStart),n=e;for(let o of r)n=n.slice(0,o.replaceStart)+`[REDACTED:${o.type}]`+n.slice(o.replaceEnd);return n}function ut(e,t={}){if(e.length===0)return e;let r=ne(e,t);if(r.length===0)return e;let n=oe(r);return se(e,n)}});var N=f(p=>{"use strict";var ct=p&&p.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(p,"__esModule",{value:!0});p.ulidToTraceId=ue;p.newSpanId=ce;p.snakeCase=dt;p.toOtlpValue=le;p.attrsFromRecord=ft;p.guardAttrs=pe;p.clientAttrs=de;p.buildPayload=mt;p.mergeBatch=_t;var lt=ct(require("crypto")),ie=j(),pt="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function ue(e){if(e.length!==26)throw new Error(`ulidToTraceId: expected 26 chars, got ${e.length}`);let t=0n;for(let n of e){let o=pt.indexOf(n);if(o<0)throw new Error(`ulidToTraceId: invalid Crockford char "${n}"`);t=t<<5n|BigInt(o)}let r=(1n<<128n)-1n;return t&=r,t.toString(16).padStart(32,"0")}function ce(){return lt.default.randomBytes(8).toString("hex")}function dt(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var ae=new Set;function R(e,t,r){let n=(0,ie.truncate)(t);if((r.skipRedactKeys??ae).has(e))return n;let o=(r.bashContextKeys??ae).has(e)?"bash":void 0;return(0,ie.redact)(n,{context:o})}function le(e,t,r={}){if(t==null)return null;switch(typeof t){case"string":return{stringValue:R(e,t,r)};case"boolean":return{boolValue:t};case"number":return Number.isInteger(t)?{intValue:t}:{doubleValue:t};case"object":try{return{stringValue:R(e,JSON.stringify(t),r)}}catch{return{stringValue:R(e,String(t),r)}}default:return{stringValue:R(e,String(t),r)}}}function ft(e,t,r={}){let n=[];for(let[o,i]of Object.entries(e)){let a=`${t}.${o}`,u=le(a,i,r);u!==null&&n.push({key:a,value:u})}return n}function pe(e){let t=[{key:"pinta.guard.decision",value:{stringValue:e.decision.toLowerCase()}},{key:"pinta.guard.duration_ms",value:{intValue:e.durationMs}}];return e.reason&&t.push({key:"pinta.guard.matched_rule",value:{stringValue:e.reason}}),e.failOpenReason&&t.push({key:"pinta.guard.fail_open_reason",value:{stringValue:e.failOpenReason}}),t}function de(e){return[{key:"pinta.client.rtt_ms",value:Number.isInteger(e.rttMs)?{intValue:e.rttMs}:{doubleValue:e.rttMs}},{key:"pinta.client.op",value:{stringValue:e.op}}]}function mt(e){let t=e.now??Date.now(),r=(BigInt(t)*1000000n).toString(),n=[...e.attributes];e.guard&&n.push(...pe(e.guard));let o=e.clientTiming??(e.guard?.clientRttMs!==void 0?{op:"guard",rttMs:e.guard.clientRttMs}:null);o&&n.push(...de(o));let i={traceId:ue(e.traceId),spanId:ce(),name:e.spanName,kind:e.spanKind??1,startTimeUnixNano:r,endTimeUnixNano:r,attributes:n};return{resourceSpans:[{resource:{attributes:e.resource},scopeSpans:[{scope:e.scope,spans:[i]}]}]}}function _t(e){let t=[];for(let r of e)t.push(...r.resourceSpans);return{resourceSpans:t}}});var me=f(U=>{"use strict";Object.defineProperty(U,"__esModule",{value:!0});U.evaluateGuard=Pt;var gt=1e4,ht="pinta-core";function fe(e,t){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:e,clientRttMs:e,failOpenReason:t}}function yt(e){return new Promise((t,r)=>setTimeout(()=>{let n=new Error("Guard request timed out");n.name="TimeoutError",r(n)},e))}async function Pt(e,t,r={}){if(!t||r.disabled)return null;let n=r.timeoutMs??gt,o=Date.now();try{let i=await Promise.race([fetch(t,{method:"POST",headers:{"content-type":"application/json","user-agent":r.userAgent??ht,"x-pinta-relay-token":r.token??""},body:JSON.stringify({input:e})}),yt(n)]);if(i.status!==200)return fe(Date.now()-o,"error");let a=await i.json(),u=Date.now()-o;return{decision:a.decision,reason:a.reason,userMessage:a.userMessage??null,durationMs:a.durationMs??u,clientRttMs:u}}catch(i){let a=i.name==="TimeoutError"?"timeout":"error";return fe(Date.now()-o,a)}}});var B=f(h=>{"use strict";var _e=h&&h.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(h,"__esModule",{value:!0});h.MemoryRetryQueue=h.DiskRetryQueue=void 0;var l=_e(require("fs")),w=_e(require("path")),A=1e3,Et=50,vt=5,L=class{filePath;lockPath;logPrefix;constructor(t,r){this.filePath=w.default.join(t,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=r}enqueue(t){try{l.default.mkdirSync(w.default.dirname(this.filePath),{recursive:!0});let r=JSON.stringify({savedAt:new Date().toISOString(),payload:t})+`
2
- `;l.default.appendFileSync(this.filePath,r),this.trim()}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue enqueue failed: ${r}
3
- `)}}readAll(){try{let t=l.default.readFileSync(this.filePath,"utf-8"),r=[];for(let n of t.split(`
4
- `))if(n.trim())try{r.push(JSON.parse(n))}catch{}return r}catch{return[]}}rewrite(t){try{if(t.length===0){l.default.existsSync(this.filePath)&&l.default.unlinkSync(this.filePath);return}l.default.mkdirSync(w.default.dirname(this.filePath),{recursive:!0}),l.default.writeFileSync(this.filePath,t.map(r=>JSON.stringify(r)).join(`
1
+ "use strict";var ht=Object.create;var ce=Object.defineProperty;var gt=Object.getOwnPropertyDescriptor;var mt=Object.getOwnPropertyNames;var yt=Object.getPrototypeOf,Pt=Object.prototype.hasOwnProperty;var m=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Et=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of mt(t))!Pt.call(e,o)&&o!==r&&ce(e,o,{get:()=>t[o],enumerable:!(n=gt(t,o))||n.enumerable});return e};var _=(e,t,r)=>(r=e!=null?ht(yt(e)):{},Et(t||!e||!e.__esModule?ce(r,"default",{value:e,enumerable:!0}):r,e));var X=m(p=>{"use strict";Object.defineProperty(p,"__esModule",{value:!0});p.PATTERNS=p.MAX_BYTES=void 0;p.truncateTo=le;p.truncate=vt;p.collectMatches=de;p.resolveOverlaps=pe;p.applyMatches=fe;p.redact=Tt;p.MAX_BYTES=102400;function le(e,t){let r=Buffer.from(e,"utf-8");return r.length<=t?e:`${r.subarray(0,Math.max(0,t)).toString("utf-8")}\u2026[TRUNCATED:${r.length}]`}function vt(e){return le(e,p.MAX_BYTES)}p.PATTERNS=[{type:"aws_access_key",regex:/AKIA[0-9A-Z]{16}/g},{type:"aws_secret_key",regex:/(?:aws[_-]?secret(?:[_-]?(?:access)?[_-]?key)?)\s*[:=]\s*["']?([A-Za-z0-9/+=]{40})(?![A-Za-z0-9/+=])/gi,captureGroup:1},{type:"gcp_service_account",regex:/\{[\s\S]{0,200}?"type"\s*:\s*"service_account"[\s\S]*?\}/g},{type:"github_token",regex:/gh[pousr]_[A-Za-z0-9]{36,}/g},{type:"gitlab_token",regex:/glpat-[A-Za-z0-9_-]{20}/g},{type:"slack_token",regex:/xox[abrsp]-[0-9A-Za-z-]{10,}/g},{type:"openai_key",regex:/sk-(?:proj-)?[A-Za-z0-9_-]{40,}/g},{type:"anthropic_key",regex:/sk-ant-[A-Za-z0-9_-]{50,}/g},{type:"stripe_key",regex:/(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g},{type:"jwt",regex:/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g},{type:"private_key_block",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g},{type:"bearer_token",regex:/bearer\s+([A-Za-z0-9._~+/=-]{12,})/gi,captureGroup:1},{type:"basic_auth",regex:/basic\s+([A-Za-z0-9+/=]{12,})/gi,captureGroup:1},{type:"db_url_password",regex:/\b(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|redis):\/\/[^:\s/]+:([^@\s]+)@/gi,captureGroup:1},{type:"cli_password_flag",regex:/(?:--password|--pass|--pwd)[=\s]([^\s'"]+)/g,captureGroup:1},{type:"cli_password_short",regex:/\s-p([^\s'"]+)/g,captureGroup:1,requireContext:"bash"},{type:"env_var_secret",regex:/^(?:export\s+)?([A-Z][A-Z0-9_]*(?:KEY|SECRET|TOKEN|PASSWORD|PASSWD|PWD|API_KEY)[A-Z0-9_]*)\s*=\s*["']?([^\s"'\n]+)/gm,captureGroup:2}];function de(e,t){let r=[];for(let n of p.PATTERNS){if(n.requireContext&&n.requireContext!==t.context)continue;let o=new RegExp(n.regex.source,n.regex.flags),s;for(;(s=o.exec(e))!==null;){let a=n.captureGroup??0,u=s[a];if(u===void 0){s.index===o.lastIndex&&o.lastIndex++;continue}let c=s.index,g=s.index+s[0].length,x=c+s[0].indexOf(u),_t=x+u.length;r.push({start:c,end:g,replaceStart:x,replaceEnd:_t,type:n.type}),s.index===o.lastIndex&&o.lastIndex++}}return r}function pe(e){let t=[...e].sort((o,s)=>o.start!==s.start?o.start-s.start:s.end-s.start-(o.end-o.start)),r=[],n=-1;for(let o of t)o.start<n||(r.push(o),n=o.end);return r}function fe(e,t){let r=[...t].sort((o,s)=>s.replaceStart-o.replaceStart),n=e;for(let o of r)n=n.slice(0,o.replaceStart)+`[REDACTED:${o.type}]`+n.slice(o.replaceEnd);return n}function Tt(e,t={}){if(e.length===0)return e;let r=de(e,t);if(r.length===0)return e;let n=pe(r);return fe(e,n)}});var G=m(d=>{"use strict";var Ot=d&&d.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(d,"__esModule",{value:!0});d.MAX_SPAN_BYTES=void 0;d.ulidToTraceId=me;d.newSpanId=ye;d.snakeCase=kt;d.toOtlpValue=Pe;d.attrsFromRecord=xt;d.guardAttrs=Ee;d.clientAttrs=ve;d.enforceSpanBudget=Te;d.buildPayload=At;d.mergeBatch=wt;var St=Ot(require("crypto")),Y=X(),bt="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function me(e){if(e.length!==26)throw new Error(`ulidToTraceId: expected 26 chars, got ${e.length}`);let t=0n;for(let n of e){let o=bt.indexOf(n);if(o<0)throw new Error(`ulidToTraceId: invalid Crockford char "${n}"`);t=t<<5n|BigInt(o)}let r=(1n<<128n)-1n;return t&=r,t.toString(16).padStart(32,"0")}function ye(){return St.default.randomBytes(8).toString("hex")}function kt(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var _e=new Set;function N(e,t,r){let n=(0,Y.truncate)(t);if((r.skipRedactKeys??_e).has(e))return n;let o=(r.bashContextKeys??_e).has(e)?"bash":void 0;return(0,Y.redact)(n,{context:o})}function Pe(e,t,r={}){if(t==null)return null;switch(typeof t){case"string":return{stringValue:N(e,t,r)};case"boolean":return{boolValue:t};case"number":return Number.isInteger(t)?{intValue:t}:{doubleValue:t};case"object":try{return{stringValue:N(e,JSON.stringify(t),r)}}catch{return{stringValue:N(e,String(t),r)}}default:return{stringValue:N(e,String(t),r)}}}function xt(e,t,r={}){let n=[];for(let[o,s]of Object.entries(e)){let a=`${t}.${o}`,u=Pe(a,s,r);u!==null&&n.push({key:a,value:u})}return n}function Ee(e){let t=[{key:"pinta.guard.decision",value:{stringValue:e.decision.toLowerCase()}},{key:"pinta.guard.duration_ms",value:{intValue:e.durationMs}}];return e.reason&&t.push({key:"pinta.guard.matched_rule",value:{stringValue:e.reason}}),e.failOpenReason&&t.push({key:"pinta.guard.fail_open_reason",value:{stringValue:e.failOpenReason}}),t}function ve(e){return[{key:"pinta.client.rtt_ms",value:Number.isInteger(e.rttMs)?{intValue:e.rttMs}:{doubleValue:e.rttMs}},{key:"pinta.client.op",value:{stringValue:e.op}}]}d.MAX_SPAN_BYTES=800*1024;function he(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}var ge=1024;function Te(e,t=d.MAX_SPAN_BYTES){let r=he(e);for(let n=0;n<100&&r>t;n++){let o=null,s=0;for(let c of e.attributes){if(!("stringValue"in c.value))continue;let g=Buffer.byteLength(c.value.stringValue,"utf-8");g>s&&(s=g,o=c.value)}if(o===null||s<=ge)break;let a=r-t,u=Math.max(ge,s-a-64);o.stringValue=(0,Y.truncateTo)(o.stringValue,u),r=he(e)}return e}function At(e){let t=e.now??Date.now(),r=(BigInt(t)*1000000n).toString(),n=[...e.attributes];e.guard&&n.push(...Ee(e.guard));let o=e.clientTiming??(e.guard?.clientRttMs!==void 0?{op:"guard",rttMs:e.guard.clientRttMs}:null);o&&n.push(...ve(o));let s={traceId:me(e.traceId),spanId:ye(),name:e.spanName,kind:e.spanKind??1,startTimeUnixNano:r,endTimeUnixNano:r,attributes:n};return Te(s),{resourceSpans:[{resource:{attributes:e.resource},scopeSpans:[{scope:e.scope,spans:[s]}]}]}}function wt(e){let t=[];for(let r of e)t.push(...r.resourceSpans);return{resourceSpans:t}}});var Oe=m(F=>{"use strict";Object.defineProperty(F,"__esModule",{value:!0});F.evaluateGuard=Nt;var Rt=1e4,Mt="pinta-core";function V(e,t){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:e,clientRttMs:e,failOpenReason:t}}var Dt=new Set(["ALLOW","DENY","REVIEW"]);async function Nt(e,t,r={}){if(!t||r.disabled)return null;let n=r.timeoutMs??Rt,o=Date.now(),s=new AbortController,a=setTimeout(()=>s.abort(),n);try{let u=await fetch(t,{method:"POST",headers:{"content-type":"application/json","user-agent":r.userAgent??Mt,"x-pinta-relay-token":r.token??""},body:JSON.stringify({input:e}),signal:s.signal});if(u.status!==200)return V(Date.now()-o,"error");let c=await u.json(),g=c?.durationMs===void 0||typeof c.durationMs=="number"&&Number.isFinite(c.durationMs);if(!c||!Dt.has(c.decision)||!g)return V(Date.now()-o,"error");let x=Date.now()-o;return{decision:c.decision,reason:c.reason??null,userMessage:c.userMessage??null,durationMs:c.durationMs??x,clientRttMs:x}}catch(u){let c=u.name,g=c==="AbortError"||c==="TimeoutError"?"timeout":"error";return V(Date.now()-o,g)}finally{clearTimeout(a)}}});var I=m(A=>{"use strict";var It=A&&A.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(A,"__esModule",{value:!0});A.atomicWriteFileSync=jt;var Se=It(require("fs"));function jt(e,t){let r=`${e}.${process.pid}.tmp`;Se.default.writeFileSync(r,t),Se.default.renameSync(r,e)}});var H=m(P=>{"use strict";var be=P&&P.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(P,"__esModule",{value:!0});P.MemoryRetryQueue=P.DiskRetryQueue=void 0;var f=be(require("fs")),j=be(require("path")),Ct=I(),C=1e3,Bt=50,Ut=5,K=class{filePath;lockPath;logPrefix;constructor(t,r){this.filePath=j.default.join(t,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=r}enqueue(t){try{f.default.mkdirSync(j.default.dirname(this.filePath),{recursive:!0});let r=JSON.stringify({savedAt:new Date().toISOString(),payload:t})+`
2
+ `;f.default.appendFileSync(this.filePath,r),this.trim()}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue enqueue failed: ${r}
3
+ `)}}readAll(){try{let t=f.default.readFileSync(this.filePath,"utf-8"),r=[];for(let n of t.split(`
4
+ `))if(n.trim())try{let o=JSON.parse(n);Array.isArray(o?.payload?.resourceSpans)&&r.push(o)}catch{}return r}catch{return[]}}rewrite(t){try{if(t.length===0){f.default.existsSync(this.filePath)&&f.default.unlinkSync(this.filePath);return}f.default.mkdirSync(j.default.dirname(this.filePath),{recursive:!0}),(0,Ct.atomicWriteFileSync)(this.filePath,t.map(r=>JSON.stringify(r)).join(`
5
5
  `)+`
6
6
  `)}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue rewrite failed: ${r}
7
- `)}}tryAcquireLock(){let t=Date.now();for(l.default.mkdirSync(w.default.dirname(this.lockPath),{recursive:!0});Date.now()-t<Et;)try{let r=l.default.openSync(this.lockPath,"wx");return l.default.writeSync(r,String(process.pid)),l.default.closeSync(r),!0}catch(r){if(r?.code!=="EEXIST")return process.stderr.write(`[${this.logPrefix}] retry-queue lock open failed: ${r}
8
- `),!1;try{let i=l.default.statSync(this.lockPath);if(Date.now()-i.mtimeMs>3e4){l.default.unlinkSync(this.lockPath);continue}}catch{}let n=vt,o=Date.now()+n;for(;Date.now()<o;);}return!1}release(){try{l.default.unlinkSync(this.lockPath)}catch{}}trim(){let t=this.readAll();if(t.length<=A)return;let r=t.length-A;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${r} oldest entries
9
- `),this.rewrite(t.slice(r))}};h.DiskRetryQueue=L;var q=class{entries=[];enqueue(t){this.entries.push(t),this.entries.length>A&&this.entries.splice(0,this.entries.length-A)}drain(){let t=this.entries;return this.entries=[],t}get size(){return this.entries.length}};h.MemoryRetryQueue=q});var Ee=f(_=>{"use strict";Object.defineProperty(_,"__esModule",{value:!0});_.MemoryTransport=_.DiskTransport=void 0;_.parseHeadersEnv=ye;_.envOptionsResolver=Pe;_.postOtlp=x;var ge=B(),he=N(),Ot=5e3;function ye(e){if(!e)return{};if(typeof e=="object")return{...e};let t={};for(let r of e.split(",")){let[n,...o]=r.split("=");n&&o.length>0&&(t[n.trim()]=o.join("=").trim())}return t}function Pe(){let e=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,t=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,r;return e?r=e.replace(/\/+$/,""):t&&(r=t.replace(/\/+$/,"")+"/v1/traces"),r?{endpoint:r,headers:ye(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function x(e,t,r){let n=new AbortController,o=setTimeout(()=>n.abort(),Ot);try{let i=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify(e),signal:n.signal});if(!i.ok){let a="";try{a=(await i.text()).slice(0,200)}catch{}let u=i.status===401||i.status===403?" \u2014 check OTEL_EXPORTER_OTLP_HEADERS (relay token)":i.status===404?" \u2014 check OTEL_EXPORTER_OTLP_TRACES_ENDPOINT path":i.status>=500?" \u2014 collector may be down":"";return process.stderr.write(`[${r}] OTLP POST ${i.status} ${t.endpoint}${u}${a?` body=${a}`:""}
10
- `),!1}return!0}catch(i){return process.stderr.write(`[${r}] OTLP POST failed: ${i.message??String(i)}
11
- `),!1}finally{clearTimeout(o)}}var G=class{queue;logPrefix;resolveOptions;constructor(t){this.queue=new ge.DiskRetryQueue(t.pluginData,t.logPrefix),this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions??Pe}async send(t){let r=this.resolveOptions();if(!r)return;await x(t,r,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(t&&this.queue.tryAcquireLock())try{let r=this.queue.readAll();if(r.length===0)return;let n=(0,he.mergeBatch)(r.map(i=>i.payload));await x(n,t,this.logPrefix)&&this.queue.rewrite([])}finally{this.queue.release()}}};_.DiskTransport=G;var V=class{queue=new ge.MemoryRetryQueue;logPrefix;resolveOptions;constructor(t){this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions}async send(t){let r=this.resolveOptions();if(!r)return;await x(t,r,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(!t)return;let r=this.queue.drain();if(r.length===0)return;let n=(0,he.mergeBatch)(r);if(!await x(n,t,this.logPrefix))for(let i of r)this.queue.enqueue(i)}};_.MemoryTransport=V});var Y=f(P=>{"use strict";var K=P&&P.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(P,"__esModule",{value:!0});P.TraceManager=void 0;P.generateUlid=ve;var F=K(require("fs")),Tt=K(require("path")),St=K(require("crypto")),X="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function ve(){let e=Date.now(),t="",r=e;for(let i=0;i<10;i++)t=X[r&31]+t,r=Math.floor(r/32);let n=St.default.randomBytes(10),o="";for(let i=0;i<10;i++)o+=X[n[i]&31];for(;o.length<16;)o+=X[0];return t+o}var $=class{tracePath;constructor(t){this.tracePath=t}newTrace(){let t=ve();return this.save(t),t}currentTrace(){try{let t=F.default.readFileSync(this.tracePath,"utf-8"),{traceId:r}=JSON.parse(t);if(r)return r}catch{}return this.newTrace()}save(t){F.default.mkdirSync(Tt.default.dirname(this.tracePath),{recursive:!0}),F.default.writeFileSync(this.tracePath,JSON.stringify({traceId:t}))}};P.TraceManager=$});var xe=f(y=>{"use strict";var Oe=y&&y.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(y,"__esModule",{value:!0});y.MemorySessionTraceManager=y.DiskSessionTraceManager=void 0;var H=Oe(require("fs")),xt=Oe(require("path")),Te=Y(),Se=200,Z=class{tracePath;maxSessions;constructor(t,r={}){this.tracePath=t,this.maxSessions=r.maxSessions??Se}read(){try{let t=JSON.parse(H.default.readFileSync(this.tracePath,"utf-8"));if(t&&typeof t=="object"&&!("traceId"in t))return t}catch{}return{}}write(t){try{H.default.mkdirSync(xt.default.dirname(this.tracePath),{recursive:!0});let r=Object.entries(t),n=r.length>this.maxSessions?Object.fromEntries(r.slice(-this.maxSessions)):t;H.default.writeFileSync(this.tracePath,JSON.stringify(n))}catch{}}newTrace(t){let r=t||"default",n=(0,Te.generateUlid)(),o=this.read();return o[r]=n,this.write(o),n}currentTrace(t){let r=t||"default",n=this.read()[r];return n||this.newTrace(r)}};y.DiskSessionTraceManager=Z;var W=class{map=new Map;maxSessions;constructor(t={}){this.maxSessions=t.maxSessions??Se}newTrace(t){let r=t||"default",n=(0,Te.generateUlid)();if(this.map.set(r,n),this.map.size>this.maxSessions){let o=this.map.keys().next().value;o!==void 0&&this.map.delete(o)}return n}currentTrace(t){let r=t||"default";return this.map.get(r)??this.newTrace(r)}};y.MemorySessionTraceManager=W});var Re=f(E=>{"use strict";var z=E&&E.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(E,"__esModule",{value:!0});E.envFilePath=Rt;E.parseEnvFile=be;E.loadEnvFile=wt;var kt=z(require("node:fs")),bt=z(require("node:os")),ke=z(require("node:path"));function Rt(e,t,r){let n=r?process.env[r]:void 0,o=n&&n.length>0?n:ke.default.join(bt.default.homedir(),e);return ke.default.join(o,t)}function be(e){let t={};for(let r of e.split(`
12
- `)){let n=r.trim();if(!n||n.startsWith("#"))continue;let o=n.indexOf("=");if(o<0)continue;let i=n.slice(0,o).trim(),a=n.slice(o+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),i&&(t[i]=a)}return t}function wt(e){let t;try{t=kt.default.readFileSync(e,"utf-8")}catch{return}let r=be(t);for(let[n,o]of Object.entries(r))process.env[n]===void 0&&(process.env[n]=o)}});var T=f(s=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0});s.loadEnvFile=s.parseEnvFile=s.envFilePath=s.MemorySessionTraceManager=s.DiskSessionTraceManager=s.generateUlid=s.TraceManager=s.parseHeadersEnv=s.envOptionsResolver=s.postOtlp=s.MemoryTransport=s.DiskTransport=s.MemoryRetryQueue=s.DiskRetryQueue=s.evaluateGuard=s.mergeBatch=s.buildPayload=s.clientAttrs=s.guardAttrs=s.attrsFromRecord=s.toOtlpValue=s.snakeCase=s.newSpanId=s.ulidToTraceId=s.MAX_BYTES=s.PATTERNS=s.applyMatches=s.resolveOverlaps=s.collectMatches=s.truncate=s.redact=void 0;var v=j();Object.defineProperty(s,"redact",{enumerable:!0,get:function(){return v.redact}});Object.defineProperty(s,"truncate",{enumerable:!0,get:function(){return v.truncate}});Object.defineProperty(s,"collectMatches",{enumerable:!0,get:function(){return v.collectMatches}});Object.defineProperty(s,"resolveOverlaps",{enumerable:!0,get:function(){return v.resolveOverlaps}});Object.defineProperty(s,"applyMatches",{enumerable:!0,get:function(){return v.applyMatches}});Object.defineProperty(s,"PATTERNS",{enumerable:!0,get:function(){return v.PATTERNS}});Object.defineProperty(s,"MAX_BYTES",{enumerable:!0,get:function(){return v.MAX_BYTES}});var g=N();Object.defineProperty(s,"ulidToTraceId",{enumerable:!0,get:function(){return g.ulidToTraceId}});Object.defineProperty(s,"newSpanId",{enumerable:!0,get:function(){return g.newSpanId}});Object.defineProperty(s,"snakeCase",{enumerable:!0,get:function(){return g.snakeCase}});Object.defineProperty(s,"toOtlpValue",{enumerable:!0,get:function(){return g.toOtlpValue}});Object.defineProperty(s,"attrsFromRecord",{enumerable:!0,get:function(){return g.attrsFromRecord}});Object.defineProperty(s,"guardAttrs",{enumerable:!0,get:function(){return g.guardAttrs}});Object.defineProperty(s,"clientAttrs",{enumerable:!0,get:function(){return g.clientAttrs}});Object.defineProperty(s,"buildPayload",{enumerable:!0,get:function(){return g.buildPayload}});Object.defineProperty(s,"mergeBatch",{enumerable:!0,get:function(){return g.mergeBatch}});var At=me();Object.defineProperty(s,"evaluateGuard",{enumerable:!0,get:function(){return At.evaluateGuard}});var we=B();Object.defineProperty(s,"DiskRetryQueue",{enumerable:!0,get:function(){return we.DiskRetryQueue}});Object.defineProperty(s,"MemoryRetryQueue",{enumerable:!0,get:function(){return we.MemoryRetryQueue}});var k=Ee();Object.defineProperty(s,"DiskTransport",{enumerable:!0,get:function(){return k.DiskTransport}});Object.defineProperty(s,"MemoryTransport",{enumerable:!0,get:function(){return k.MemoryTransport}});Object.defineProperty(s,"postOtlp",{enumerable:!0,get:function(){return k.postOtlp}});Object.defineProperty(s,"envOptionsResolver",{enumerable:!0,get:function(){return k.envOptionsResolver}});Object.defineProperty(s,"parseHeadersEnv",{enumerable:!0,get:function(){return k.parseHeadersEnv}});var Ae=Y();Object.defineProperty(s,"TraceManager",{enumerable:!0,get:function(){return Ae.TraceManager}});Object.defineProperty(s,"generateUlid",{enumerable:!0,get:function(){return Ae.generateUlid}});var De=xe();Object.defineProperty(s,"DiskSessionTraceManager",{enumerable:!0,get:function(){return De.DiskSessionTraceManager}});Object.defineProperty(s,"MemorySessionTraceManager",{enumerable:!0,get:function(){return De.MemorySessionTraceManager}});var J=Re();Object.defineProperty(s,"envFilePath",{enumerable:!0,get:function(){return J.envFilePath}});Object.defineProperty(s,"parseEnvFile",{enumerable:!0,get:function(){return J.parseEnvFile}});Object.defineProperty(s,"loadEnvFile",{enumerable:!0,get:function(){return J.loadEnvFile}})});var Q=m(require("node:fs")),Ie=m(require("node:os")),b=m(require("node:path")),Me=m(T());function Dt(e){let t={},r;try{r=Q.default.readFileSync(e,"utf-8")}catch{return t}for(let n of r.split(`
13
- `)){let o=n.trim();if(!o||o.startsWith("#"))continue;let i=o.indexOf("=");if(i<0)continue;let a=o.slice(0,i).trim(),u=o.slice(i+1).trim();(u.startsWith('"')&&u.endsWith('"')||u.startsWith("'")&&u.endsWith("'"))&&(u=u.slice(1,-1)),a&&(t[a]=u)}return t}function It(e){let t=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT??e.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;if(t)return t;let r=process.env.OTEL_EXPORTER_OTLP_ENDPOINT??e.OTEL_EXPORTER_OTLP_ENDPOINT;return r?r.replace(/\/+$/,"")+"/v1/traces":process.env.PINTA_CODEX_ENDPOINT??e.PINTA_CODEX_ENDPOINT??process.env.CLAUDE_PLUGIN_OPTION_ENDPOINT}function Mt(e){if(process.env.OTEL_EXPORTER_OTLP_HEADERS)return process.env.OTEL_EXPORTER_OTLP_HEADERS;if(e.OTEL_EXPORTER_OTLP_HEADERS)return e.OTEL_EXPORTER_OTLP_HEADERS;if(process.env.PINTA_CODEX_API_KEY)return`x-pinta-relay-token=${process.env.PINTA_CODEX_API_KEY}`;if(e.PINTA_CODEX_API_KEY)return`x-pinta-relay-token=${e.PINTA_CODEX_API_KEY}`;if(process.env.CLAUDE_PLUGIN_OPTION_API_KEY)return`x-pinta-relay-token=${process.env.CLAUDE_PLUGIN_OPTION_API_KEY}`}function Ce(){let e=process.env.CODEX_PLUGIN_ROOT??process.env.CLAUDE_PLUGIN_ROOT??process.cwd(),t=process.env.CODEX_PLUGIN_DATA??process.env.CLAUDE_PLUGIN_DATA??b.default.join(e,".plugin-data"),r=process.env.CODEX_HOME??b.default.join(Ie.default.homedir(),".codex"),n=b.default.join(r,"pinta-codex.env"),o=Q.default.existsSync(n)?Dt(n):{},i=It(o),a=Mt(o);if(a&&!process.env.PINTA_RELAY_TOKEN){let S=a.match(/x-pinta-relay-token=([^,\s]+)/i);S&&(process.env.PINTA_RELAY_TOKEN=S[1])}let u=process.env.PINTA_GUARD_ENDPOINT??o.PINTA_GUARD_ENDPOINT;return{pluginRoot:e,pluginData:t,tracePath:b.default.join(t,"trace.json"),endpoint:i?.replace(/\/+$/,""),headers:(0,Me.parseHeadersEnv)(a??""),guardEndpoint:u}}function je(e){return e.hook_event_name==="PreToolUse"}function Ne(e){return e.hook_event_name==="PostToolUse"}function Ue(e){return e.hook_event_name==="UserPromptSubmit"}function Le(e){return e.hook_event_name==="SessionStart"}function qe(e){return e.hook_event_name==="Stop"}var Ct=new Set(["PreToolUse","PostToolUse","SessionStart","UserPromptSubmit","Stop"]);function Be(e){return!Ct.has(e.hook_event_name)}var Ge=m(T()),jt=50,Nt="pinta-codex/1.5.0";async function Ve(e,t){let r=await(0,Ge.evaluateGuard)(e,t,{timeoutMs:jt,token:process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:Nt});if(r===null)return null;let n={decision:r.decision,reason:r.reason,durationMs:r.durationMs,clientRttMs:r.clientRttMs};return r.failOpenReason!==void 0&&(n.failOpenReason=r.failOpenReason),n}var Fe=m(T()),D=class extends Fe.DiskTransport{constructor(t){super({pluginData:t.pluginData,logPrefix:"pinta-codex",resolveOptions:()=>t.endpoint?{endpoint:t.endpoint,headers:t.headers}:null})}};var Xe=m(T()),I=class extends Xe.TraceManager{constructor(t){super(t.tracePath)}};var C=m(require("os")),O=m(T());var $e="1.5.0",M=null;function Ut(){return M!==null||(M=process.env.CODEX_CLI_VERSION||"unknown"),M}var Lt=new Set(["codex.hook","codex.tool_name","codex.tool_use_id","codex.session_id","codex.transcript_path","codex.cwd","codex.permission_mode"]),qt=new Set(["codex.tool_input","codex.tool_response"]),Bt={skipRedactKeys:Lt,bashContextKeys:qt};function Gt(e){let t=[];t.push({key:"ingest.type",value:{stringValue:"codex"}}),t.push({key:"codex.hook",value:{stringValue:e.hook_event_name}});let r={};for(let[n,o]of Object.entries(e))n!=="hook_event_name"&&(r[n]=o);return t.push(...(0,O.attrsFromRecord)(r,"codex",Bt)),t}function Vt(){return[{key:"service.name",value:{stringValue:"codex"}},{key:"service.version",value:{stringValue:Ut()}},{key:"telemetry.sdk.name",value:{stringValue:"pinta-codex"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:$e}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:C.default.userInfo().username}},{key:"host.name",value:{stringValue:C.default.hostname()}},{key:"host.arch",value:{stringValue:C.default.arch()}}]}function Ke(e){return(0,O.buildPayload)({traceId:e.traceId,spanName:`codex.${(0,O.snakeCase)(e.event.hook_event_name)}`,attributes:Gt(e.event),resource:Vt(),scope:{name:"pinta-codex",version:$e},now:e.now,guard:e.guard})}async function d(e,t,r){let n=new D(t);await n.flush();let o=new I(t),i=r.trace==="new"?o.newTrace():o.currentTrace(),a=Ke({event:e,traceId:i,guard:r.guard});await n.send(a)}async function Ye(e,t){let r=typeof e.tool_input=="string"?e.tool_input:JSON.stringify(e.tool_input),n=await Ve({spanId:e.session_id??"unknown",toolName:e.tool_name,toolInput:e.tool_input,rawTextFields:{toolInput:r}},t.guardEndpoint);if(await d(e,t,{trace:"current",guard:n}),n?.decision==="DENY"){let o={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:n.reason??"guard_deny"}};process.stdout.write(JSON.stringify(o)+`
14
- `)}return 0}async function He(e,t){return await d(e,t,{trace:"current"}),0}async function Ze(e,t){return await d(e,t,{trace:"new"}),0}async function We(e,t){return await d(e,t,{trace:"current"}),0}async function ze(e,t){return await d(e,t,{trace:"current"}),0}async function ee(e){return 0}async function Ft(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function Je(){let e=0;try{let t=Ce(),r=await Ft(),n=JSON.parse(r);Be(n)?e=await ee(n):je(n)?e=await Ye(n,t):Ne(n)?e=await He(n,t):Ue(n)?e=await Ze(n,t):Le(n)?e=await We(n,t):qe(n)?e=await ze(n,t):e=await ee(n)}catch(t){process.stderr.write(`[pinta-codex] error: ${t}
15
- `),e=0}return e}async function Xt(){let e=await Je();process.exit(e)}Xt();
7
+ `)}}tryAcquireLock(){let t=Date.now();try{f.default.mkdirSync(j.default.dirname(this.lockPath),{recursive:!0})}catch(r){return process.stderr.write(`[${this.logPrefix}] retry-queue lock mkdir failed: ${r}
8
+ `),!1}for(;Date.now()-t<Bt;)try{let r=f.default.openSync(this.lockPath,"wx");return f.default.writeSync(r,String(process.pid)),f.default.closeSync(r),!0}catch(r){if(r?.code!=="EEXIST")return process.stderr.write(`[${this.logPrefix}] retry-queue lock open failed: ${r}
9
+ `),!1;try{let s=f.default.statSync(this.lockPath);if(Date.now()-s.mtimeMs>3e4){f.default.unlinkSync(this.lockPath);continue}}catch{}let n=Ut,o=Date.now()+n;for(;Date.now()<o;);}return!1}release(){try{f.default.unlinkSync(this.lockPath)}catch{}}trim(){let t=this.readAll();if(t.length<=C)return;let r=t.length-C;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${r} oldest entries
10
+ `),this.rewrite(t.slice(r))}};P.DiskRetryQueue=K;var z=class{entries=[];enqueue(t){this.entries.push(t),this.entries.length>C&&this.entries.splice(0,this.entries.length-C)}drain(){let t=this.entries;return this.entries=[],t}get size(){return this.entries.length}};P.MemoryRetryQueue=z});var Me=m(l=>{"use strict";Object.defineProperty(l,"__esModule",{value:!0});l.MemoryTransport=l.DiskTransport=l.MAX_POST_BYTES=void 0;l.parseHeadersEnv=we;l.envOptionsResolver=Re;l.postOtlp=w;var ke=H(),xe=G(),Lt=5e3;l.MAX_POST_BYTES=900*1024;function B(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}function Ae(e,t,r){let n=[],o=[],s=[],a=0;for(let u of e){let c=t(u);if(c>r){o.push(u);continue}s.length>0&&a+c>r&&(n.push(s),s=[],a=0),s.push(u),a+=c}return s.length>0&&n.push(s),{chunks:n,oversize:o}}function we(e){if(!e)return{};if(typeof e=="object")return{...e};let t={};for(let r of e.split(",")){let[n,...o]=r.split("=");n&&o.length>0&&(t[n.trim()]=o.join("=").trim())}return t}function Re(){let e=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,t=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,r;return e?r=e.replace(/\/+$/,""):t&&(r=t.replace(/\/+$/,"")+"/v1/traces"),r?{endpoint:r,headers:we(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function w(e,t,r){let n=new AbortController,o=setTimeout(()=>n.abort(),Lt);try{let s=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify(e),signal:n.signal});if(!s.ok){let a="";try{a=(await s.text()).slice(0,200)}catch{}let u=s.status===401||s.status===403?" \u2014 check OTEL_EXPORTER_OTLP_HEADERS (relay token)":s.status===404?" \u2014 check OTEL_EXPORTER_OTLP_TRACES_ENDPOINT path":s.status>=500?" \u2014 collector may be down":"";return process.stderr.write(`[${r}] OTLP POST ${s.status} ${t.endpoint}${u}${a?` body=${a}`:""}
11
+ `),!1}return!0}catch(s){return process.stderr.write(`[${r}] OTLP POST failed: ${s.message??String(s)}
12
+ `),!1}finally{clearTimeout(o)}}var W=class{queue;logPrefix;resolveOptions;constructor(t){this.queue=new ke.DiskRetryQueue(t.pluginData,t.logPrefix),this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions??Re}async send(t){let r=this.resolveOptions();if(!r||this.dropIfOversized(t))return;await w(t,r,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(t&&this.queue.tryAcquireLock())try{let r=this.queue.readAll();if(r.length===0)return;let{chunks:n,oversize:o}=Ae(r,u=>B(u.payload),l.MAX_POST_BYTES);o.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${o.length} oversized retry ${o.length===1?"entry":"entries"} (each > ${l.MAX_POST_BYTES} bytes \u2014 the backend caps the request body, so they can never be delivered)
13
+ `);let s=[].concat(...n),a=0;for(let u of n){if(!await w((0,xe.mergeBatch)(u.map(g=>g.payload)),t,this.logPrefix))break;a+=u.length}this.queue.rewrite(s.slice(a))}catch(r){process.stderr.write(`[${this.logPrefix}] flush failed: ${r?.message??String(r)}
14
+ `)}finally{this.queue.release()}}dropIfOversized(t){let r=B(t);return r<=l.MAX_POST_BYTES?!1:(process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (${r} > ${l.MAX_POST_BYTES} bytes) \u2014 undeliverable, not queued
15
+ `),!0)}};l.DiskTransport=W;var Z=class{queue=new ke.MemoryRetryQueue;logPrefix;resolveOptions;constructor(t){this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions}async send(t){let r=this.resolveOptions();if(!r)return;if(B(t)>l.MAX_POST_BYTES){process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (> ${l.MAX_POST_BYTES} bytes) \u2014 undeliverable, not buffered
16
+ `);return}await w(t,r,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(!t)return;let r=this.queue.drain();if(r.length===0)return;let{chunks:n,oversize:o}=Ae(r,B,l.MAX_POST_BYTES);o.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${o.length} oversized buffered ${o.length===1?"payload":"payloads"} (each > ${l.MAX_POST_BYTES} bytes \u2014 undeliverable)
17
+ `);let s=[].concat(...n),a=0;for(let u of n){if(!await w((0,xe.mergeBatch)(u),t,this.logPrefix))break;a+=u.length}for(let u of s.slice(a))this.queue.enqueue(u)}};l.MemoryTransport=Z});var te=m(T=>{"use strict";var ee=T&&T.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(T,"__esModule",{value:!0});T.TraceManager=void 0;T.generateUlid=Ne;var De=ee(require("fs")),qt=ee(require("path")),$t=ee(require("crypto")),Xt=I(),J="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Ne(){let e=Date.now(),t="",r=e;for(let s=0;s<10;s++)t=J[r&31]+t,r=Math.floor(r/32);let n=$t.default.randomBytes(10),o="";for(let s=0;s<10;s++)o+=J[n[s]&31];for(;o.length<16;)o+=J[0];return t+o}var Q=class{tracePath;constructor(t){this.tracePath=t}newTrace(){let t=Ne();return this.save(t),t}currentTrace(){try{let t=De.default.readFileSync(this.tracePath,"utf-8"),{traceId:r}=JSON.parse(t);if(r)return r}catch{}return this.newTrace()}save(t){try{De.default.mkdirSync(qt.default.dirname(this.tracePath),{recursive:!0}),(0,Xt.atomicWriteFileSync)(this.tracePath,JSON.stringify({traceId:t}))}catch(r){process.stderr.write(`[pinta-core] trace persistence failed: ${r}
18
+ `)}}};T.TraceManager=Q});var Ue=m(E=>{"use strict";var je=E&&E.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(E,"__esModule",{value:!0});E.MemorySessionTraceManager=E.DiskSessionTraceManager=void 0;var Ie=je(require("fs")),Yt=je(require("path")),Ce=te(),Gt=I(),Be=200,re=class{tracePath;maxSessions;constructor(t,r={}){this.tracePath=t,this.maxSessions=r.maxSessions??Be}read(){try{let t=JSON.parse(Ie.default.readFileSync(this.tracePath,"utf-8"));if(t&&typeof t=="object"&&!("traceId"in t))return t}catch{}return{}}write(t){try{Ie.default.mkdirSync(Yt.default.dirname(this.tracePath),{recursive:!0});let r=Object.entries(t),n=r.length>this.maxSessions?Object.fromEntries(r.slice(-this.maxSessions)):t;(0,Gt.atomicWriteFileSync)(this.tracePath,JSON.stringify(n))}catch{}}newTrace(t){let r=t||"default",n=(0,Ce.generateUlid)(),o=this.read();return o[r]=n,this.write(o),n}currentTrace(t){let r=t||"default",n=this.read()[r];return n||this.newTrace(r)}};E.DiskSessionTraceManager=re;var ne=class{map=new Map;maxSessions;constructor(t={}){this.maxSessions=t.maxSessions??Be}newTrace(t){let r=t||"default",n=(0,Ce.generateUlid)();if(this.map.set(r,n),this.map.size>this.maxSessions){let o=this.map.keys().next().value;o!==void 0&&this.map.delete(o)}return n}currentTrace(t){let r=t||"default";return this.map.get(r)??this.newTrace(r)}};E.MemorySessionTraceManager=ne});var $e=m(O=>{"use strict";var oe=O&&O.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(O,"__esModule",{value:!0});O.envFilePath=Kt;O.parseEnvFile=qe;O.loadEnvFile=zt;var Vt=oe(require("node:fs")),Ft=oe(require("node:os")),Le=oe(require("node:path"));function Kt(e,t,r){let n=r?process.env[r]:void 0,o=n&&n.length>0?n:Le.default.join(Ft.default.homedir(),e);return Le.default.join(o,t)}function qe(e){let t={};for(let r of e.split(`
19
+ `)){let n=r.trim();if(!n||n.startsWith("#"))continue;let o=n.indexOf("=");if(o<0)continue;let s=n.slice(0,o).trim(),a=n.slice(o+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),s&&(t[s]=a)}return t}function zt(e){let t;try{t=Vt.default.readFileSync(e,"utf-8")}catch{return}let r=qe(t);for(let[n,o]of Object.entries(r))process.env[n]===void 0&&(process.env[n]=o)}});var k=m(i=>{"use strict";Object.defineProperty(i,"__esModule",{value:!0});i.loadEnvFile=i.parseEnvFile=i.envFilePath=i.MemorySessionTraceManager=i.DiskSessionTraceManager=i.generateUlid=i.TraceManager=i.MAX_POST_BYTES=i.parseHeadersEnv=i.envOptionsResolver=i.postOtlp=i.MemoryTransport=i.DiskTransport=i.MemoryRetryQueue=i.DiskRetryQueue=i.evaluateGuard=i.MAX_SPAN_BYTES=i.enforceSpanBudget=i.mergeBatch=i.buildPayload=i.clientAttrs=i.guardAttrs=i.attrsFromRecord=i.toOtlpValue=i.snakeCase=i.newSpanId=i.ulidToTraceId=i.MAX_BYTES=i.PATTERNS=i.applyMatches=i.resolveOverlaps=i.collectMatches=i.truncateTo=i.truncate=i.redact=void 0;var v=X();Object.defineProperty(i,"redact",{enumerable:!0,get:function(){return v.redact}});Object.defineProperty(i,"truncate",{enumerable:!0,get:function(){return v.truncate}});Object.defineProperty(i,"truncateTo",{enumerable:!0,get:function(){return v.truncateTo}});Object.defineProperty(i,"collectMatches",{enumerable:!0,get:function(){return v.collectMatches}});Object.defineProperty(i,"resolveOverlaps",{enumerable:!0,get:function(){return v.resolveOverlaps}});Object.defineProperty(i,"applyMatches",{enumerable:!0,get:function(){return v.applyMatches}});Object.defineProperty(i,"PATTERNS",{enumerable:!0,get:function(){return v.PATTERNS}});Object.defineProperty(i,"MAX_BYTES",{enumerable:!0,get:function(){return v.MAX_BYTES}});var h=G();Object.defineProperty(i,"ulidToTraceId",{enumerable:!0,get:function(){return h.ulidToTraceId}});Object.defineProperty(i,"newSpanId",{enumerable:!0,get:function(){return h.newSpanId}});Object.defineProperty(i,"snakeCase",{enumerable:!0,get:function(){return h.snakeCase}});Object.defineProperty(i,"toOtlpValue",{enumerable:!0,get:function(){return h.toOtlpValue}});Object.defineProperty(i,"attrsFromRecord",{enumerable:!0,get:function(){return h.attrsFromRecord}});Object.defineProperty(i,"guardAttrs",{enumerable:!0,get:function(){return h.guardAttrs}});Object.defineProperty(i,"clientAttrs",{enumerable:!0,get:function(){return h.clientAttrs}});Object.defineProperty(i,"buildPayload",{enumerable:!0,get:function(){return h.buildPayload}});Object.defineProperty(i,"mergeBatch",{enumerable:!0,get:function(){return h.mergeBatch}});Object.defineProperty(i,"enforceSpanBudget",{enumerable:!0,get:function(){return h.enforceSpanBudget}});Object.defineProperty(i,"MAX_SPAN_BYTES",{enumerable:!0,get:function(){return h.MAX_SPAN_BYTES}});var Ht=Oe();Object.defineProperty(i,"evaluateGuard",{enumerable:!0,get:function(){return Ht.evaluateGuard}});var Xe=H();Object.defineProperty(i,"DiskRetryQueue",{enumerable:!0,get:function(){return Xe.DiskRetryQueue}});Object.defineProperty(i,"MemoryRetryQueue",{enumerable:!0,get:function(){return Xe.MemoryRetryQueue}});var b=Me();Object.defineProperty(i,"DiskTransport",{enumerable:!0,get:function(){return b.DiskTransport}});Object.defineProperty(i,"MemoryTransport",{enumerable:!0,get:function(){return b.MemoryTransport}});Object.defineProperty(i,"postOtlp",{enumerable:!0,get:function(){return b.postOtlp}});Object.defineProperty(i,"envOptionsResolver",{enumerable:!0,get:function(){return b.envOptionsResolver}});Object.defineProperty(i,"parseHeadersEnv",{enumerable:!0,get:function(){return b.parseHeadersEnv}});Object.defineProperty(i,"MAX_POST_BYTES",{enumerable:!0,get:function(){return b.MAX_POST_BYTES}});var Ye=te();Object.defineProperty(i,"TraceManager",{enumerable:!0,get:function(){return Ye.TraceManager}});Object.defineProperty(i,"generateUlid",{enumerable:!0,get:function(){return Ye.generateUlid}});var Ge=Ue();Object.defineProperty(i,"DiskSessionTraceManager",{enumerable:!0,get:function(){return Ge.DiskSessionTraceManager}});Object.defineProperty(i,"MemorySessionTraceManager",{enumerable:!0,get:function(){return Ge.MemorySessionTraceManager}});var se=$e();Object.defineProperty(i,"envFilePath",{enumerable:!0,get:function(){return se.envFilePath}});Object.defineProperty(i,"parseEnvFile",{enumerable:!0,get:function(){return se.parseEnvFile}});Object.defineProperty(i,"loadEnvFile",{enumerable:!0,get:function(){return se.loadEnvFile}})});var ie=_(require("node:fs")),Ve=_(require("node:os")),R=_(require("node:path")),Fe=_(k());function Wt(e){let t={},r;try{r=ie.default.readFileSync(e,"utf-8")}catch{return t}for(let n of r.split(`
20
+ `)){let o=n.trim();if(!o||o.startsWith("#"))continue;let s=o.indexOf("=");if(s<0)continue;let a=o.slice(0,s).trim(),u=o.slice(s+1).trim();(u.startsWith('"')&&u.endsWith('"')||u.startsWith("'")&&u.endsWith("'"))&&(u=u.slice(1,-1)),a&&(t[a]=u)}return t}function Zt(e){let t=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT??e.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;if(t)return t;let r=process.env.OTEL_EXPORTER_OTLP_ENDPOINT??e.OTEL_EXPORTER_OTLP_ENDPOINT;return r?r.replace(/\/+$/,"")+"/v1/traces":process.env.PINTA_CODEX_ENDPOINT??e.PINTA_CODEX_ENDPOINT??process.env.CLAUDE_PLUGIN_OPTION_ENDPOINT}function Jt(e){if(process.env.OTEL_EXPORTER_OTLP_HEADERS)return process.env.OTEL_EXPORTER_OTLP_HEADERS;if(e.OTEL_EXPORTER_OTLP_HEADERS)return e.OTEL_EXPORTER_OTLP_HEADERS;if(process.env.PINTA_CODEX_API_KEY)return`x-pinta-relay-token=${process.env.PINTA_CODEX_API_KEY}`;if(e.PINTA_CODEX_API_KEY)return`x-pinta-relay-token=${e.PINTA_CODEX_API_KEY}`;if(process.env.CLAUDE_PLUGIN_OPTION_API_KEY)return`x-pinta-relay-token=${process.env.CLAUDE_PLUGIN_OPTION_API_KEY}`}function Ke(){let e=process.env.CODEX_PLUGIN_ROOT??process.env.CLAUDE_PLUGIN_ROOT??process.cwd(),t=process.env.CODEX_PLUGIN_DATA??process.env.CLAUDE_PLUGIN_DATA??R.default.join(e,".plugin-data"),r=process.env.CODEX_HOME??R.default.join(Ve.default.homedir(),".codex"),n=R.default.join(r,"pinta-codex.env"),o=ie.default.existsSync(n)?Wt(n):{},s=Zt(o),a=Jt(o);if(a&&!process.env.PINTA_RELAY_TOKEN){let c=a.match(/x-pinta-relay-token=([^,\s]+)/i);c&&(process.env.PINTA_RELAY_TOKEN=c[1])}let u=process.env.PINTA_GUARD_ENDPOINT??o.PINTA_GUARD_ENDPOINT;return{pluginRoot:e,pluginData:t,tracePath:R.default.join(t,"trace.json"),endpoint:s?.replace(/\/+$/,""),headers:(0,Fe.parseHeadersEnv)(a??""),guardEndpoint:u}}function ze(e){return e.hook_event_name==="PreToolUse"}function He(e){return e.hook_event_name==="PostToolUse"}function We(e){return e.hook_event_name==="UserPromptSubmit"}function Ze(e){return e.hook_event_name==="SessionStart"}function Je(e){return e.hook_event_name==="Stop"}var Qt=new Set(["PreToolUse","PostToolUse","SessionStart","UserPromptSubmit","Stop"]);function Qe(e){return!Qt.has(e.hook_event_name)}var et=_(k()),er=50,tr="pinta-codex/1.6.0";async function tt(e,t){let r=await(0,et.evaluateGuard)(e,t,{timeoutMs:er,token:process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:tr});if(r===null)return null;let n={decision:r.decision,reason:r.reason,durationMs:r.durationMs,clientRttMs:r.clientRttMs};return r.failOpenReason!==void 0&&(n.failOpenReason=r.failOpenReason),n}var rt=_(k()),U=class extends rt.DiskTransport{constructor(t){super({pluginData:t.pluginData,logPrefix:"pinta-codex",resolveOptions:()=>t.endpoint?{endpoint:t.endpoint,headers:t.headers}:null})}};var nt=_(k()),L=class extends nt.TraceManager{constructor(t){super(t.tracePath)}};var M=_(require("fs")),$=_(require("os")),st=_(require("path")),S=_(k()),q;function rr(){if(q===void 0)try{q=$.default.userInfo().username}catch{q=process.env.USER??process.env.LOGNAME??(typeof process.getuid=="function"?String(process.getuid()):"unknown")}return q}var it="1.6.0",ae;function D(e){return typeof e=="string"&&e.trim()!==""?e.trim():void 0}var ot=256*1024;function nr(e){if(!e)return;let t;try{t=M.default.openSync(e,"r");let r=Buffer.allocUnsafe(ot),n=M.default.readSync(t,r,0,ot,0),o=r.toString("utf8",0,n),s=o.indexOf(`
21
+ `);if(s<0)return;let a=JSON.parse(o.slice(0,s));return a?.type!=="session_meta"?void 0:D(a.payload?.cli_version)}catch{return}finally{if(t!==void 0)try{M.default.closeSync(t)}catch{}}}function or(){let e=D(process.env.CODEX_MANAGED_PACKAGE_ROOT);if(e)try{let t=JSON.parse(M.default.readFileSync(st.default.join(e,"package.json"),"utf8"));return D(t.version)}catch{return}}function sr(e){return ae===void 0&&(ae=nr(D(e?.transcript_path))??or()??D(process.env.CODEX_CLI_VERSION)??null),ae??void 0}var ir=new Set(["codex.hook","codex.tool_name","codex.tool_use_id","codex.session_id","codex.transcript_path","codex.cwd","codex.permission_mode"]),ar=new Set(["codex.tool_input","codex.tool_response"]),ur={skipRedactKeys:ir,bashContextKeys:ar};function cr(e){let t=[];t.push({key:"ingest.type",value:{stringValue:"codex"}}),t.push({key:"codex.hook",value:{stringValue:e.hook_event_name}});let r={};for(let[n,o]of Object.entries(e))n!=="hook_event_name"&&(r[n]=o);return t.push(...(0,S.attrsFromRecord)(r,"codex",ur)),t}function lr(e){let t=sr(e);return[{key:"service.name",value:{stringValue:"codex"}},...t?[{key:"service.version",value:{stringValue:t}}]:[],{key:"telemetry.sdk.name",value:{stringValue:"pinta-codex"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:it}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:rr()}},{key:"host.name",value:{stringValue:$.default.hostname()}},{key:"host.arch",value:{stringValue:$.default.arch()}}]}function at(e){return(0,S.buildPayload)({traceId:e.traceId,spanName:`codex.${(0,S.snakeCase)(e.event.hook_event_name)}`,attributes:cr(e.event),resource:lr(e.event),scope:{name:"pinta-codex",version:it},now:e.now,guard:e.guard})}async function y(e,t,r){let n=new U(t);await n.flush();let o=new L(t),s=r.trace==="new"?o.newTrace():o.currentTrace(),a=at({event:e,traceId:s,guard:r.guard});await n.send(a)}async function ut(e,t){let r=typeof e.tool_input=="string"?e.tool_input:JSON.stringify(e.tool_input),n=await tt({spanId:e.session_id??"unknown",toolName:e.tool_name,method:e.hook_event_name,cwd:e.cwd,toolInput:e.tool_input,rawTextFields:{toolInput:r}},t.guardEndpoint);if(n?.decision==="DENY"){let o={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:n.reason??"guard_deny"}};process.stdout.write(JSON.stringify(o)+`
22
+ `)}try{await y(e,t,{trace:"current",guard:n})}catch(o){process.stderr.write(`[pinta-codex] telemetry emit failed: ${o}
23
+ `)}return 0}async function ct(e,t){return await y(e,t,{trace:"current"}),0}async function lt(e,t){return await y(e,t,{trace:"new"}),0}async function dt(e,t){return await y(e,t,{trace:"current"}),0}async function pt(e,t){return await y(e,t,{trace:"current"}),0}async function ue(e){return 0}async function dr(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function ft(){let e=0;try{let t=Ke(),r=await dr(),n=JSON.parse(r);Qe(n)?e=await ue(n):ze(n)?e=await ut(n,t):He(n)?e=await ct(n,t):We(n)?e=await lt(n,t):Ze(n)?e=await dt(n,t):Je(n)?e=await pt(n,t):e=await ue(n)}catch(t){process.stderr.write(`[pinta-codex] error: ${t}
24
+ `),e=0}return e}async function pr(){let e=await ft();process.exit(e)}pr();
package/dist/index.mjs CHANGED
@@ -1,16 +1,25 @@
1
1
  import{createRequire as __pintaCreateRequire}from 'node:module';const require=__pintaCreateRequire(import.meta.url);
2
- var st=Object.create;var ne=Object.defineProperty;var it=Object.getOwnPropertyDescriptor;var at=Object.getOwnPropertyNames;var ut=Object.getPrototypeOf,ct=Object.prototype.hasOwnProperty;var d=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var m=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var lt=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of at(t))!ct.call(e,o)&&o!==r&&ne(e,o,{get:()=>t[o],enumerable:!(n=it(t,o))||n.enumerable});return e};var S=(e,t,r)=>(r=e!=null?st(ut(e)):{},lt(t||!e||!e.__esModule?ne(r,"default",{value:e,enumerable:!0}):r,e));var C=m(c=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});c.PATTERNS=c.MAX_BYTES=void 0;c.truncate=pt;c.collectMatches=oe;c.resolveOverlaps=se;c.applyMatches=ie;c.redact=dt;c.MAX_BYTES=102400;function pt(e){let t=Buffer.from(e,"utf-8");return t.length<=c.MAX_BYTES?e:`${t.subarray(0,c.MAX_BYTES).toString("utf-8")}\u2026[TRUNCATED:${t.length}]`}c.PATTERNS=[{type:"aws_access_key",regex:/AKIA[0-9A-Z]{16}/g},{type:"aws_secret_key",regex:/(?:aws[_-]?secret(?:[_-]?(?:access)?[_-]?key)?)\s*[:=]\s*["']?([A-Za-z0-9/+=]{40})(?![A-Za-z0-9/+=])/gi,captureGroup:1},{type:"gcp_service_account",regex:/\{[\s\S]{0,200}?"type"\s*:\s*"service_account"[\s\S]*?\}/g},{type:"github_token",regex:/gh[pousr]_[A-Za-z0-9]{36,}/g},{type:"gitlab_token",regex:/glpat-[A-Za-z0-9_-]{20}/g},{type:"slack_token",regex:/xox[abrsp]-[0-9A-Za-z-]{10,}/g},{type:"openai_key",regex:/sk-(?:proj-)?[A-Za-z0-9_-]{40,}/g},{type:"anthropic_key",regex:/sk-ant-[A-Za-z0-9_-]{50,}/g},{type:"stripe_key",regex:/(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g},{type:"jwt",regex:/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g},{type:"private_key_block",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g},{type:"bearer_token",regex:/bearer\s+([A-Za-z0-9._~+/=-]{12,})/gi,captureGroup:1},{type:"basic_auth",regex:/basic\s+([A-Za-z0-9+/=]{12,})/gi,captureGroup:1},{type:"db_url_password",regex:/\b(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|redis):\/\/[^:\s/]+:([^@\s]+)@/gi,captureGroup:1},{type:"cli_password_flag",regex:/(?:--password|--pass|--pwd)[=\s]([^\s'"]+)/g,captureGroup:1},{type:"cli_password_short",regex:/\s-p([^\s'"]+)/g,captureGroup:1,requireContext:"bash"},{type:"env_var_secret",regex:/^(?:export\s+)?([A-Z][A-Z0-9_]*(?:KEY|SECRET|TOKEN|PASSWORD|PASSWD|PWD|API_KEY)[A-Z0-9_]*)\s*=\s*["']?([^\s"'\n]+)/gm,captureGroup:2}];function oe(e,t){let r=[];for(let n of c.PATTERNS){if(n.requireContext&&n.requireContext!==t.context)continue;let o=new RegExp(n.regex.source,n.regex.flags),s;for(;(s=o.exec(e))!==null;){let a=n.captureGroup??0,u=s[a];if(u===void 0){s.index===o.lastIndex&&o.lastIndex++;continue}let x=s.index,nt=s.index+s[0].length,re=x+s[0].indexOf(u),ot=re+u.length;r.push({start:x,end:nt,replaceStart:re,replaceEnd:ot,type:n.type}),s.index===o.lastIndex&&o.lastIndex++}}return r}function se(e){let t=[...e].sort((o,s)=>o.start!==s.start?o.start-s.start:s.end-s.start-(o.end-o.start)),r=[],n=-1;for(let o of t)o.start<n||(r.push(o),n=o.end);return r}function ie(e,t){let r=[...t].sort((o,s)=>s.replaceStart-o.replaceStart),n=e;for(let o of r)n=n.slice(0,o.replaceStart)+`[REDACTED:${o.type}]`+n.slice(o.replaceEnd);return n}function dt(e,t={}){if(e.length===0)return e;let r=oe(e,t);if(r.length===0)return e;let n=se(r);return ie(e,n)}});var N=m(p=>{"use strict";var ft=p&&p.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(p,"__esModule",{value:!0});p.ulidToTraceId=ce;p.newSpanId=le;p.snakeCase=ht;p.toOtlpValue=pe;p.attrsFromRecord=gt;p.guardAttrs=de;p.clientAttrs=fe;p.buildPayload=yt;p.mergeBatch=Pt;var mt=ft(d("crypto")),ae=C(),_t="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function ce(e){if(e.length!==26)throw new Error(`ulidToTraceId: expected 26 chars, got ${e.length}`);let t=0n;for(let n of e){let o=_t.indexOf(n);if(o<0)throw new Error(`ulidToTraceId: invalid Crockford char "${n}"`);t=t<<5n|BigInt(o)}let r=(1n<<128n)-1n;return t&=r,t.toString(16).padStart(32,"0")}function le(){return mt.default.randomBytes(8).toString("hex")}function ht(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var ue=new Set;function A(e,t,r){let n=(0,ae.truncate)(t);if((r.skipRedactKeys??ue).has(e))return n;let o=(r.bashContextKeys??ue).has(e)?"bash":void 0;return(0,ae.redact)(n,{context:o})}function pe(e,t,r={}){if(t==null)return null;switch(typeof t){case"string":return{stringValue:A(e,t,r)};case"boolean":return{boolValue:t};case"number":return Number.isInteger(t)?{intValue:t}:{doubleValue:t};case"object":try{return{stringValue:A(e,JSON.stringify(t),r)}}catch{return{stringValue:A(e,String(t),r)}}default:return{stringValue:A(e,String(t),r)}}}function gt(e,t,r={}){let n=[];for(let[o,s]of Object.entries(e)){let a=`${t}.${o}`,u=pe(a,s,r);u!==null&&n.push({key:a,value:u})}return n}function de(e){let t=[{key:"pinta.guard.decision",value:{stringValue:e.decision.toLowerCase()}},{key:"pinta.guard.duration_ms",value:{intValue:e.durationMs}}];return e.reason&&t.push({key:"pinta.guard.matched_rule",value:{stringValue:e.reason}}),e.failOpenReason&&t.push({key:"pinta.guard.fail_open_reason",value:{stringValue:e.failOpenReason}}),t}function fe(e){return[{key:"pinta.client.rtt_ms",value:Number.isInteger(e.rttMs)?{intValue:e.rttMs}:{doubleValue:e.rttMs}},{key:"pinta.client.op",value:{stringValue:e.op}}]}function yt(e){let t=e.now??Date.now(),r=(BigInt(t)*1000000n).toString(),n=[...e.attributes];e.guard&&n.push(...de(e.guard));let o=e.clientTiming??(e.guard?.clientRttMs!==void 0?{op:"guard",rttMs:e.guard.clientRttMs}:null);o&&n.push(...fe(o));let s={traceId:ce(e.traceId),spanId:le(),name:e.spanName,kind:e.spanKind??1,startTimeUnixNano:r,endTimeUnixNano:r,attributes:n};return{resourceSpans:[{resource:{attributes:e.resource},scopeSpans:[{scope:e.scope,spans:[s]}]}]}}function Pt(e){let t=[];for(let r of e)t.push(...r.resourceSpans);return{resourceSpans:t}}});var _e=m(U=>{"use strict";Object.defineProperty(U,"__esModule",{value:!0});U.evaluateGuard=Ot;var Et=1e4,vt="pinta-core";function me(e,t){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:e,clientRttMs:e,failOpenReason:t}}function Tt(e){return new Promise((t,r)=>setTimeout(()=>{let n=new Error("Guard request timed out");n.name="TimeoutError",r(n)},e))}async function Ot(e,t,r={}){if(!t||r.disabled)return null;let n=r.timeoutMs??Et,o=Date.now();try{let s=await Promise.race([fetch(t,{method:"POST",headers:{"content-type":"application/json","user-agent":r.userAgent??vt,"x-pinta-relay-token":r.token??""},body:JSON.stringify({input:e})}),Tt(n)]);if(s.status!==200)return me(Date.now()-o,"error");let a=await s.json(),u=Date.now()-o;return{decision:a.decision,reason:a.reason,userMessage:a.userMessage??null,durationMs:a.durationMs??u,clientRttMs:u}}catch(s){let a=s.name==="TimeoutError"?"timeout":"error";return me(Date.now()-o,a)}}});var B=m(g=>{"use strict";var he=g&&g.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(g,"__esModule",{value:!0});g.MemoryRetryQueue=g.DiskRetryQueue=void 0;var l=he(d("fs")),R=he(d("path")),w=1e3,St=50,xt=5,L=class{filePath;lockPath;logPrefix;constructor(t,r){this.filePath=R.default.join(t,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=r}enqueue(t){try{l.default.mkdirSync(R.default.dirname(this.filePath),{recursive:!0});let r=JSON.stringify({savedAt:new Date().toISOString(),payload:t})+`
3
- `;l.default.appendFileSync(this.filePath,r),this.trim()}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue enqueue failed: ${r}
4
- `)}}readAll(){try{let t=l.default.readFileSync(this.filePath,"utf-8"),r=[];for(let n of t.split(`
5
- `))if(n.trim())try{r.push(JSON.parse(n))}catch{}return r}catch{return[]}}rewrite(t){try{if(t.length===0){l.default.existsSync(this.filePath)&&l.default.unlinkSync(this.filePath);return}l.default.mkdirSync(R.default.dirname(this.filePath),{recursive:!0}),l.default.writeFileSync(this.filePath,t.map(r=>JSON.stringify(r)).join(`
2
+ var yt=Object.create;var le=Object.defineProperty;var Pt=Object.getOwnPropertyDescriptor;var Et=Object.getOwnPropertyNames;var Tt=Object.getPrototypeOf,vt=Object.prototype.hasOwnProperty;var _=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var g=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Ot=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Et(t))!vt.call(e,o)&&o!==r&&le(e,o,{get:()=>t[o],enumerable:!(n=Pt(t,o))||n.enumerable});return e};var x=(e,t,r)=>(r=e!=null?yt(Tt(e)):{},Ot(t||!e||!e.__esModule?le(r,"default",{value:e,enumerable:!0}):r,e));var $=g(f=>{"use strict";Object.defineProperty(f,"__esModule",{value:!0});f.PATTERNS=f.MAX_BYTES=void 0;f.truncateTo=de;f.truncate=St;f.collectMatches=fe;f.resolveOverlaps=pe;f.applyMatches=_e;f.redact=bt;f.MAX_BYTES=102400;function de(e,t){let r=Buffer.from(e,"utf-8");return r.length<=t?e:`${r.subarray(0,Math.max(0,t)).toString("utf-8")}\u2026[TRUNCATED:${r.length}]`}function St(e){return de(e,f.MAX_BYTES)}f.PATTERNS=[{type:"aws_access_key",regex:/AKIA[0-9A-Z]{16}/g},{type:"aws_secret_key",regex:/(?:aws[_-]?secret(?:[_-]?(?:access)?[_-]?key)?)\s*[:=]\s*["']?([A-Za-z0-9/+=]{40})(?![A-Za-z0-9/+=])/gi,captureGroup:1},{type:"gcp_service_account",regex:/\{[\s\S]{0,200}?"type"\s*:\s*"service_account"[\s\S]*?\}/g},{type:"github_token",regex:/gh[pousr]_[A-Za-z0-9]{36,}/g},{type:"gitlab_token",regex:/glpat-[A-Za-z0-9_-]{20}/g},{type:"slack_token",regex:/xox[abrsp]-[0-9A-Za-z-]{10,}/g},{type:"openai_key",regex:/sk-(?:proj-)?[A-Za-z0-9_-]{40,}/g},{type:"anthropic_key",regex:/sk-ant-[A-Za-z0-9_-]{50,}/g},{type:"stripe_key",regex:/(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g},{type:"jwt",regex:/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g},{type:"private_key_block",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g},{type:"bearer_token",regex:/bearer\s+([A-Za-z0-9._~+/=-]{12,})/gi,captureGroup:1},{type:"basic_auth",regex:/basic\s+([A-Za-z0-9+/=]{12,})/gi,captureGroup:1},{type:"db_url_password",regex:/\b(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|redis):\/\/[^:\s/]+:([^@\s]+)@/gi,captureGroup:1},{type:"cli_password_flag",regex:/(?:--password|--pass|--pwd)[=\s]([^\s'"]+)/g,captureGroup:1},{type:"cli_password_short",regex:/\s-p([^\s'"]+)/g,captureGroup:1,requireContext:"bash"},{type:"env_var_secret",regex:/^(?:export\s+)?([A-Z][A-Z0-9_]*(?:KEY|SECRET|TOKEN|PASSWORD|PASSWD|PWD|API_KEY)[A-Z0-9_]*)\s*=\s*["']?([^\s"'\n]+)/gm,captureGroup:2}];function fe(e,t){let r=[];for(let n of f.PATTERNS){if(n.requireContext&&n.requireContext!==t.context)continue;let o=new RegExp(n.regex.source,n.regex.flags),s;for(;(s=o.exec(e))!==null;){let a=n.captureGroup??0,u=s[a];if(u===void 0){s.index===o.lastIndex&&o.lastIndex++;continue}let c=s.index,h=s.index+s[0].length,A=c+s[0].indexOf(u),gt=A+u.length;r.push({start:c,end:h,replaceStart:A,replaceEnd:gt,type:n.type}),s.index===o.lastIndex&&o.lastIndex++}}return r}function pe(e){let t=[...e].sort((o,s)=>o.start!==s.start?o.start-s.start:s.end-s.start-(o.end-o.start)),r=[],n=-1;for(let o of t)o.start<n||(r.push(o),n=o.end);return r}function _e(e,t){let r=[...t].sort((o,s)=>s.replaceStart-o.replaceStart),n=e;for(let o of r)n=n.slice(0,o.replaceStart)+`[REDACTED:${o.type}]`+n.slice(o.replaceEnd);return n}function bt(e,t={}){if(e.length===0)return e;let r=fe(e,t);if(r.length===0)return e;let n=pe(r);return _e(e,n)}});var G=g(d=>{"use strict";var xt=d&&d.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(d,"__esModule",{value:!0});d.MAX_SPAN_BYTES=void 0;d.ulidToTraceId=ye;d.newSpanId=Pe;d.snakeCase=wt;d.toOtlpValue=Ee;d.attrsFromRecord=Rt;d.guardAttrs=Te;d.clientAttrs=ve;d.enforceSpanBudget=Oe;d.buildPayload=Mt;d.mergeBatch=Dt;var kt=xt(_("crypto")),X=$(),At="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function ye(e){if(e.length!==26)throw new Error(`ulidToTraceId: expected 26 chars, got ${e.length}`);let t=0n;for(let n of e){let o=At.indexOf(n);if(o<0)throw new Error(`ulidToTraceId: invalid Crockford char "${n}"`);t=t<<5n|BigInt(o)}let r=(1n<<128n)-1n;return t&=r,t.toString(16).padStart(32,"0")}function Pe(){return kt.default.randomBytes(8).toString("hex")}function wt(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var me=new Set;function D(e,t,r){let n=(0,X.truncate)(t);if((r.skipRedactKeys??me).has(e))return n;let o=(r.bashContextKeys??me).has(e)?"bash":void 0;return(0,X.redact)(n,{context:o})}function Ee(e,t,r={}){if(t==null)return null;switch(typeof t){case"string":return{stringValue:D(e,t,r)};case"boolean":return{boolValue:t};case"number":return Number.isInteger(t)?{intValue:t}:{doubleValue:t};case"object":try{return{stringValue:D(e,JSON.stringify(t),r)}}catch{return{stringValue:D(e,String(t),r)}}default:return{stringValue:D(e,String(t),r)}}}function Rt(e,t,r={}){let n=[];for(let[o,s]of Object.entries(e)){let a=`${t}.${o}`,u=Ee(a,s,r);u!==null&&n.push({key:a,value:u})}return n}function Te(e){let t=[{key:"pinta.guard.decision",value:{stringValue:e.decision.toLowerCase()}},{key:"pinta.guard.duration_ms",value:{intValue:e.durationMs}}];return e.reason&&t.push({key:"pinta.guard.matched_rule",value:{stringValue:e.reason}}),e.failOpenReason&&t.push({key:"pinta.guard.fail_open_reason",value:{stringValue:e.failOpenReason}}),t}function ve(e){return[{key:"pinta.client.rtt_ms",value:Number.isInteger(e.rttMs)?{intValue:e.rttMs}:{doubleValue:e.rttMs}},{key:"pinta.client.op",value:{stringValue:e.op}}]}d.MAX_SPAN_BYTES=800*1024;function he(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}var ge=1024;function Oe(e,t=d.MAX_SPAN_BYTES){let r=he(e);for(let n=0;n<100&&r>t;n++){let o=null,s=0;for(let c of e.attributes){if(!("stringValue"in c.value))continue;let h=Buffer.byteLength(c.value.stringValue,"utf-8");h>s&&(s=h,o=c.value)}if(o===null||s<=ge)break;let a=r-t,u=Math.max(ge,s-a-64);o.stringValue=(0,X.truncateTo)(o.stringValue,u),r=he(e)}return e}function Mt(e){let t=e.now??Date.now(),r=(BigInt(t)*1000000n).toString(),n=[...e.attributes];e.guard&&n.push(...Te(e.guard));let o=e.clientTiming??(e.guard?.clientRttMs!==void 0?{op:"guard",rttMs:e.guard.clientRttMs}:null);o&&n.push(...ve(o));let s={traceId:ye(e.traceId),spanId:Pe(),name:e.spanName,kind:e.spanKind??1,startTimeUnixNano:r,endTimeUnixNano:r,attributes:n};return Oe(s),{resourceSpans:[{resource:{attributes:e.resource},scopeSpans:[{scope:e.scope,spans:[s]}]}]}}function Dt(e){let t=[];for(let r of e)t.push(...r.resourceSpans);return{resourceSpans:t}}});var Se=g(V=>{"use strict";Object.defineProperty(V,"__esModule",{value:!0});V.evaluateGuard=Ct;var It=1e4,jt="pinta-core";function Y(e,t){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:e,clientRttMs:e,failOpenReason:t}}var Nt=new Set(["ALLOW","DENY","REVIEW"]);async function Ct(e,t,r={}){if(!t||r.disabled)return null;let n=r.timeoutMs??It,o=Date.now(),s=new AbortController,a=setTimeout(()=>s.abort(),n);try{let u=await fetch(t,{method:"POST",headers:{"content-type":"application/json","user-agent":r.userAgent??jt,"x-pinta-relay-token":r.token??""},body:JSON.stringify({input:e}),signal:s.signal});if(u.status!==200)return Y(Date.now()-o,"error");let c=await u.json(),h=c?.durationMs===void 0||typeof c.durationMs=="number"&&Number.isFinite(c.durationMs);if(!c||!Nt.has(c.decision)||!h)return Y(Date.now()-o,"error");let A=Date.now()-o;return{decision:c.decision,reason:c.reason??null,userMessage:c.userMessage??null,durationMs:c.durationMs??A,clientRttMs:A}}catch(u){let c=u.name,h=c==="AbortError"||c==="TimeoutError"?"timeout":"error";return Y(Date.now()-o,h)}finally{clearTimeout(a)}}});var I=g(w=>{"use strict";var Bt=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(w,"__esModule",{value:!0});w.atomicWriteFileSync=Ut;var be=Bt(_("fs"));function Ut(e,t){let r=`${e}.${process.pid}.tmp`;be.default.writeFileSync(r,t),be.default.renameSync(r,e)}});var W=g(P=>{"use strict";var xe=P&&P.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(P,"__esModule",{value:!0});P.MemoryRetryQueue=P.DiskRetryQueue=void 0;var p=xe(_("fs")),j=xe(_("path")),Lt=I(),N=1e3,qt=50,Ft=5,K=class{filePath;lockPath;logPrefix;constructor(t,r){this.filePath=j.default.join(t,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=r}enqueue(t){try{p.default.mkdirSync(j.default.dirname(this.filePath),{recursive:!0});let r=JSON.stringify({savedAt:new Date().toISOString(),payload:t})+`
3
+ `;p.default.appendFileSync(this.filePath,r),this.trim()}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue enqueue failed: ${r}
4
+ `)}}readAll(){try{let t=p.default.readFileSync(this.filePath,"utf-8"),r=[];for(let n of t.split(`
5
+ `))if(n.trim())try{let o=JSON.parse(n);Array.isArray(o?.payload?.resourceSpans)&&r.push(o)}catch{}return r}catch{return[]}}rewrite(t){try{if(t.length===0){p.default.existsSync(this.filePath)&&p.default.unlinkSync(this.filePath);return}p.default.mkdirSync(j.default.dirname(this.filePath),{recursive:!0}),(0,Lt.atomicWriteFileSync)(this.filePath,t.map(r=>JSON.stringify(r)).join(`
6
6
  `)+`
7
7
  `)}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue rewrite failed: ${r}
8
- `)}}tryAcquireLock(){let t=Date.now();for(l.default.mkdirSync(R.default.dirname(this.lockPath),{recursive:!0});Date.now()-t<St;)try{let r=l.default.openSync(this.lockPath,"wx");return l.default.writeSync(r,String(process.pid)),l.default.closeSync(r),!0}catch(r){if(r?.code!=="EEXIST")return process.stderr.write(`[${this.logPrefix}] retry-queue lock open failed: ${r}
9
- `),!1;try{let s=l.default.statSync(this.lockPath);if(Date.now()-s.mtimeMs>3e4){l.default.unlinkSync(this.lockPath);continue}}catch{}let n=xt,o=Date.now()+n;for(;Date.now()<o;);}return!1}release(){try{l.default.unlinkSync(this.lockPath)}catch{}}trim(){let t=this.readAll();if(t.length<=w)return;let r=t.length-w;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${r} oldest entries
10
- `),this.rewrite(t.slice(r))}};g.DiskRetryQueue=L;var q=class{entries=[];enqueue(t){this.entries.push(t),this.entries.length>w&&this.entries.splice(0,this.entries.length-w)}drain(){let t=this.entries;return this.entries=[],t}get size(){return this.entries.length}};g.MemoryRetryQueue=q});var ve=m(_=>{"use strict";Object.defineProperty(_,"__esModule",{value:!0});_.MemoryTransport=_.DiskTransport=void 0;_.parseHeadersEnv=Pe;_.envOptionsResolver=Ee;_.postOtlp=b;var ge=B(),ye=N(),bt=5e3;function Pe(e){if(!e)return{};if(typeof e=="object")return{...e};let t={};for(let r of e.split(",")){let[n,...o]=r.split("=");n&&o.length>0&&(t[n.trim()]=o.join("=").trim())}return t}function Ee(){let e=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,t=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,r;return e?r=e.replace(/\/+$/,""):t&&(r=t.replace(/\/+$/,"")+"/v1/traces"),r?{endpoint:r,headers:Pe(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function b(e,t,r){let n=new AbortController,o=setTimeout(()=>n.abort(),bt);try{let s=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify(e),signal:n.signal});if(!s.ok){let a="";try{a=(await s.text()).slice(0,200)}catch{}let u=s.status===401||s.status===403?" \u2014 check OTEL_EXPORTER_OTLP_HEADERS (relay token)":s.status===404?" \u2014 check OTEL_EXPORTER_OTLP_TRACES_ENDPOINT path":s.status>=500?" \u2014 collector may be down":"";return process.stderr.write(`[${r}] OTLP POST ${s.status} ${t.endpoint}${u}${a?` body=${a}`:""}
8
+ `)}}tryAcquireLock(){let t=Date.now();try{p.default.mkdirSync(j.default.dirname(this.lockPath),{recursive:!0})}catch(r){return process.stderr.write(`[${this.logPrefix}] retry-queue lock mkdir failed: ${r}
9
+ `),!1}for(;Date.now()-t<qt;)try{let r=p.default.openSync(this.lockPath,"wx");return p.default.writeSync(r,String(process.pid)),p.default.closeSync(r),!0}catch(r){if(r?.code!=="EEXIST")return process.stderr.write(`[${this.logPrefix}] retry-queue lock open failed: ${r}
10
+ `),!1;try{let s=p.default.statSync(this.lockPath);if(Date.now()-s.mtimeMs>3e4){p.default.unlinkSync(this.lockPath);continue}}catch{}let n=Ft,o=Date.now()+n;for(;Date.now()<o;);}return!1}release(){try{p.default.unlinkSync(this.lockPath)}catch{}}trim(){let t=this.readAll();if(t.length<=N)return;let r=t.length-N;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${r} oldest entries
11
+ `),this.rewrite(t.slice(r))}};P.DiskRetryQueue=K;var z=class{entries=[];enqueue(t){this.entries.push(t),this.entries.length>N&&this.entries.splice(0,this.entries.length-N)}drain(){let t=this.entries;return this.entries=[],t}get size(){return this.entries.length}};P.MemoryRetryQueue=z});var De=g(l=>{"use strict";Object.defineProperty(l,"__esModule",{value:!0});l.MemoryTransport=l.DiskTransport=l.MAX_POST_BYTES=void 0;l.parseHeadersEnv=Re;l.envOptionsResolver=Me;l.postOtlp=R;var ke=W(),Ae=G(),$t=5e3;l.MAX_POST_BYTES=900*1024;function C(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}function we(e,t,r){let n=[],o=[],s=[],a=0;for(let u of e){let c=t(u);if(c>r){o.push(u);continue}s.length>0&&a+c>r&&(n.push(s),s=[],a=0),s.push(u),a+=c}return s.length>0&&n.push(s),{chunks:n,oversize:o}}function Re(e){if(!e)return{};if(typeof e=="object")return{...e};let t={};for(let r of e.split(",")){let[n,...o]=r.split("=");n&&o.length>0&&(t[n.trim()]=o.join("=").trim())}return t}function Me(){let e=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,t=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,r;return e?r=e.replace(/\/+$/,""):t&&(r=t.replace(/\/+$/,"")+"/v1/traces"),r?{endpoint:r,headers:Re(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function R(e,t,r){let n=new AbortController,o=setTimeout(()=>n.abort(),$t);try{let s=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify(e),signal:n.signal});if(!s.ok){let a="";try{a=(await s.text()).slice(0,200)}catch{}let u=s.status===401||s.status===403?" \u2014 check OTEL_EXPORTER_OTLP_HEADERS (relay token)":s.status===404?" \u2014 check OTEL_EXPORTER_OTLP_TRACES_ENDPOINT path":s.status>=500?" \u2014 collector may be down":"";return process.stderr.write(`[${r}] OTLP POST ${s.status} ${t.endpoint}${u}${a?` body=${a}`:""}
11
12
  `),!1}return!0}catch(s){return process.stderr.write(`[${r}] OTLP POST failed: ${s.message??String(s)}
12
- `),!1}finally{clearTimeout(o)}}var F=class{queue;logPrefix;resolveOptions;constructor(t){this.queue=new ge.DiskRetryQueue(t.pluginData,t.logPrefix),this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions??Ee}async send(t){let r=this.resolveOptions();if(!r)return;await b(t,r,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(t&&this.queue.tryAcquireLock())try{let r=this.queue.readAll();if(r.length===0)return;let n=(0,ye.mergeBatch)(r.map(s=>s.payload));await b(n,t,this.logPrefix)&&this.queue.rewrite([])}finally{this.queue.release()}}};_.DiskTransport=F;var G=class{queue=new ge.MemoryRetryQueue;logPrefix;resolveOptions;constructor(t){this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions}async send(t){let r=this.resolveOptions();if(!r)return;await b(t,r,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(!t)return;let r=this.queue.drain();if(r.length===0)return;let n=(0,ye.mergeBatch)(r);if(!await b(n,t,this.logPrefix))for(let s of r)this.queue.enqueue(s)}};_.MemoryTransport=G});var Y=m(P=>{"use strict";var K=P&&P.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(P,"__esModule",{value:!0});P.TraceManager=void 0;P.generateUlid=Te;var V=K(d("fs")),kt=K(d("path")),At=K(d("crypto")),X="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Te(){let e=Date.now(),t="",r=e;for(let s=0;s<10;s++)t=X[r&31]+t,r=Math.floor(r/32);let n=At.default.randomBytes(10),o="";for(let s=0;s<10;s++)o+=X[n[s]&31];for(;o.length<16;)o+=X[0];return t+o}var $=class{tracePath;constructor(t){this.tracePath=t}newTrace(){let t=Te();return this.save(t),t}currentTrace(){try{let t=V.default.readFileSync(this.tracePath,"utf-8"),{traceId:r}=JSON.parse(t);if(r)return r}catch{}return this.newTrace()}save(t){V.default.mkdirSync(kt.default.dirname(this.tracePath),{recursive:!0}),V.default.writeFileSync(this.tracePath,JSON.stringify({traceId:t}))}};P.TraceManager=$});var be=m(y=>{"use strict";var Oe=y&&y.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(y,"__esModule",{value:!0});y.MemorySessionTraceManager=y.DiskSessionTraceManager=void 0;var H=Oe(d("fs")),Rt=Oe(d("path")),Se=Y(),xe=200,Z=class{tracePath;maxSessions;constructor(t,r={}){this.tracePath=t,this.maxSessions=r.maxSessions??xe}read(){try{let t=JSON.parse(H.default.readFileSync(this.tracePath,"utf-8"));if(t&&typeof t=="object"&&!("traceId"in t))return t}catch{}return{}}write(t){try{H.default.mkdirSync(Rt.default.dirname(this.tracePath),{recursive:!0});let r=Object.entries(t),n=r.length>this.maxSessions?Object.fromEntries(r.slice(-this.maxSessions)):t;H.default.writeFileSync(this.tracePath,JSON.stringify(n))}catch{}}newTrace(t){let r=t||"default",n=(0,Se.generateUlid)(),o=this.read();return o[r]=n,this.write(o),n}currentTrace(t){let r=t||"default",n=this.read()[r];return n||this.newTrace(r)}};y.DiskSessionTraceManager=Z;var W=class{map=new Map;maxSessions;constructor(t={}){this.maxSessions=t.maxSessions??xe}newTrace(t){let r=t||"default",n=(0,Se.generateUlid)();if(this.map.set(r,n),this.map.size>this.maxSessions){let o=this.map.keys().next().value;o!==void 0&&this.map.delete(o)}return n}currentTrace(t){let r=t||"default";return this.map.get(r)??this.newTrace(r)}};y.MemorySessionTraceManager=W});var Re=m(E=>{"use strict";var z=E&&E.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(E,"__esModule",{value:!0});E.envFilePath=It;E.parseEnvFile=Ae;E.loadEnvFile=jt;var wt=z(d("node:fs")),Dt=z(d("node:os")),ke=z(d("node:path"));function It(e,t,r){let n=r?process.env[r]:void 0,o=n&&n.length>0?n:ke.default.join(Dt.default.homedir(),e);return ke.default.join(o,t)}function Ae(e){let t={};for(let r of e.split(`
13
- `)){let n=r.trim();if(!n||n.startsWith("#"))continue;let o=n.indexOf("=");if(o<0)continue;let s=n.slice(0,o).trim(),a=n.slice(o+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),s&&(t[s]=a)}return t}function jt(e){let t;try{t=wt.default.readFileSync(e,"utf-8")}catch{return}let r=Ae(t);for(let[n,o]of Object.entries(r))process.env[n]===void 0&&(process.env[n]=o)}});var T=m(i=>{"use strict";Object.defineProperty(i,"__esModule",{value:!0});i.loadEnvFile=i.parseEnvFile=i.envFilePath=i.MemorySessionTraceManager=i.DiskSessionTraceManager=i.generateUlid=i.TraceManager=i.parseHeadersEnv=i.envOptionsResolver=i.postOtlp=i.MemoryTransport=i.DiskTransport=i.MemoryRetryQueue=i.DiskRetryQueue=i.evaluateGuard=i.mergeBatch=i.buildPayload=i.clientAttrs=i.guardAttrs=i.attrsFromRecord=i.toOtlpValue=i.snakeCase=i.newSpanId=i.ulidToTraceId=i.MAX_BYTES=i.PATTERNS=i.applyMatches=i.resolveOverlaps=i.collectMatches=i.truncate=i.redact=void 0;var v=C();Object.defineProperty(i,"redact",{enumerable:!0,get:function(){return v.redact}});Object.defineProperty(i,"truncate",{enumerable:!0,get:function(){return v.truncate}});Object.defineProperty(i,"collectMatches",{enumerable:!0,get:function(){return v.collectMatches}});Object.defineProperty(i,"resolveOverlaps",{enumerable:!0,get:function(){return v.resolveOverlaps}});Object.defineProperty(i,"applyMatches",{enumerable:!0,get:function(){return v.applyMatches}});Object.defineProperty(i,"PATTERNS",{enumerable:!0,get:function(){return v.PATTERNS}});Object.defineProperty(i,"MAX_BYTES",{enumerable:!0,get:function(){return v.MAX_BYTES}});var h=N();Object.defineProperty(i,"ulidToTraceId",{enumerable:!0,get:function(){return h.ulidToTraceId}});Object.defineProperty(i,"newSpanId",{enumerable:!0,get:function(){return h.newSpanId}});Object.defineProperty(i,"snakeCase",{enumerable:!0,get:function(){return h.snakeCase}});Object.defineProperty(i,"toOtlpValue",{enumerable:!0,get:function(){return h.toOtlpValue}});Object.defineProperty(i,"attrsFromRecord",{enumerable:!0,get:function(){return h.attrsFromRecord}});Object.defineProperty(i,"guardAttrs",{enumerable:!0,get:function(){return h.guardAttrs}});Object.defineProperty(i,"clientAttrs",{enumerable:!0,get:function(){return h.clientAttrs}});Object.defineProperty(i,"buildPayload",{enumerable:!0,get:function(){return h.buildPayload}});Object.defineProperty(i,"mergeBatch",{enumerable:!0,get:function(){return h.mergeBatch}});var Mt=_e();Object.defineProperty(i,"evaluateGuard",{enumerable:!0,get:function(){return Mt.evaluateGuard}});var we=B();Object.defineProperty(i,"DiskRetryQueue",{enumerable:!0,get:function(){return we.DiskRetryQueue}});Object.defineProperty(i,"MemoryRetryQueue",{enumerable:!0,get:function(){return we.MemoryRetryQueue}});var k=ve();Object.defineProperty(i,"DiskTransport",{enumerable:!0,get:function(){return k.DiskTransport}});Object.defineProperty(i,"MemoryTransport",{enumerable:!0,get:function(){return k.MemoryTransport}});Object.defineProperty(i,"postOtlp",{enumerable:!0,get:function(){return k.postOtlp}});Object.defineProperty(i,"envOptionsResolver",{enumerable:!0,get:function(){return k.envOptionsResolver}});Object.defineProperty(i,"parseHeadersEnv",{enumerable:!0,get:function(){return k.parseHeadersEnv}});var De=Y();Object.defineProperty(i,"TraceManager",{enumerable:!0,get:function(){return De.TraceManager}});Object.defineProperty(i,"generateUlid",{enumerable:!0,get:function(){return De.generateUlid}});var Ie=be();Object.defineProperty(i,"DiskSessionTraceManager",{enumerable:!0,get:function(){return Ie.DiskSessionTraceManager}});Object.defineProperty(i,"MemorySessionTraceManager",{enumerable:!0,get:function(){return Ie.MemorySessionTraceManager}});var J=Re();Object.defineProperty(i,"envFilePath",{enumerable:!0,get:function(){return J.envFilePath}});Object.defineProperty(i,"parseEnvFile",{enumerable:!0,get:function(){return J.parseEnvFile}});Object.defineProperty(i,"loadEnvFile",{enumerable:!0,get:function(){return J.loadEnvFile}})});import{realpathSync as ir}from"node:fs";import{pathToFileURL as ar}from"node:url";var Me=S(T());import je from"node:fs";import Ct from"node:os";import D from"node:path";function Nt(e){let t={},r;try{r=je.readFileSync(e,"utf-8")}catch{return t}for(let n of r.split(`
14
- `)){let o=n.trim();if(!o||o.startsWith("#"))continue;let s=o.indexOf("=");if(s<0)continue;let a=o.slice(0,s).trim(),u=o.slice(s+1).trim();(u.startsWith('"')&&u.endsWith('"')||u.startsWith("'")&&u.endsWith("'"))&&(u=u.slice(1,-1)),a&&(t[a]=u)}return t}function Ut(e){let t=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT??e.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;if(t)return t;let r=process.env.OTEL_EXPORTER_OTLP_ENDPOINT??e.OTEL_EXPORTER_OTLP_ENDPOINT;return r?r.replace(/\/+$/,"")+"/v1/traces":process.env.PINTA_CODEX_ENDPOINT??e.PINTA_CODEX_ENDPOINT??process.env.CLAUDE_PLUGIN_OPTION_ENDPOINT}function Lt(e){if(process.env.OTEL_EXPORTER_OTLP_HEADERS)return process.env.OTEL_EXPORTER_OTLP_HEADERS;if(e.OTEL_EXPORTER_OTLP_HEADERS)return e.OTEL_EXPORTER_OTLP_HEADERS;if(process.env.PINTA_CODEX_API_KEY)return`x-pinta-relay-token=${process.env.PINTA_CODEX_API_KEY}`;if(e.PINTA_CODEX_API_KEY)return`x-pinta-relay-token=${e.PINTA_CODEX_API_KEY}`;if(process.env.CLAUDE_PLUGIN_OPTION_API_KEY)return`x-pinta-relay-token=${process.env.CLAUDE_PLUGIN_OPTION_API_KEY}`}function Ce(){let e=process.env.CODEX_PLUGIN_ROOT??process.env.CLAUDE_PLUGIN_ROOT??process.cwd(),t=process.env.CODEX_PLUGIN_DATA??process.env.CLAUDE_PLUGIN_DATA??D.join(e,".plugin-data"),r=process.env.CODEX_HOME??D.join(Ct.homedir(),".codex"),n=D.join(r,"pinta-codex.env"),o=je.existsSync(n)?Nt(n):{},s=Ut(o),a=Lt(o);if(a&&!process.env.PINTA_RELAY_TOKEN){let x=a.match(/x-pinta-relay-token=([^,\s]+)/i);x&&(process.env.PINTA_RELAY_TOKEN=x[1])}let u=process.env.PINTA_GUARD_ENDPOINT??o.PINTA_GUARD_ENDPOINT;return{pluginRoot:e,pluginData:t,tracePath:D.join(t,"trace.json"),endpoint:s?.replace(/\/+$/,""),headers:(0,Me.parseHeadersEnv)(a??""),guardEndpoint:u}}function Ne(e){return e.hook_event_name==="PreToolUse"}function Ue(e){return e.hook_event_name==="PostToolUse"}function Le(e){return e.hook_event_name==="UserPromptSubmit"}function qe(e){return e.hook_event_name==="SessionStart"}function Be(e){return e.hook_event_name==="Stop"}var qt=new Set(["PreToolUse","PostToolUse","SessionStart","UserPromptSubmit","Stop"]);function Fe(e){return!qt.has(e.hook_event_name)}var Ge=S(T()),Bt=50,Ft="pinta-codex/1.5.0";async function Ve(e,t){let r=await(0,Ge.evaluateGuard)(e,t,{timeoutMs:Bt,token:process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:Ft});if(r===null)return null;let n={decision:r.decision,reason:r.reason,durationMs:r.durationMs,clientRttMs:r.clientRttMs};return r.failOpenReason!==void 0&&(n.failOpenReason=r.failOpenReason),n}var Xe=S(T()),I=class extends Xe.DiskTransport{constructor(t){super({pluginData:t.pluginData,logPrefix:"pinta-codex",resolveOptions:()=>t.endpoint?{endpoint:t.endpoint,headers:t.headers}:null})}};var $e=S(T()),j=class extends $e.TraceManager{constructor(t){super(t.tracePath)}};var O=S(T());import Q from"os";var Ke="1.5.0",M=null;function Gt(){return M!==null||(M=process.env.CODEX_CLI_VERSION||"unknown"),M}var Vt=new Set(["codex.hook","codex.tool_name","codex.tool_use_id","codex.session_id","codex.transcript_path","codex.cwd","codex.permission_mode"]),Xt=new Set(["codex.tool_input","codex.tool_response"]),$t={skipRedactKeys:Vt,bashContextKeys:Xt};function Kt(e){let t=[];t.push({key:"ingest.type",value:{stringValue:"codex"}}),t.push({key:"codex.hook",value:{stringValue:e.hook_event_name}});let r={};for(let[n,o]of Object.entries(e))n!=="hook_event_name"&&(r[n]=o);return t.push(...(0,O.attrsFromRecord)(r,"codex",$t)),t}function Yt(){return[{key:"service.name",value:{stringValue:"codex"}},{key:"service.version",value:{stringValue:Gt()}},{key:"telemetry.sdk.name",value:{stringValue:"pinta-codex"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:Ke}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:Q.userInfo().username}},{key:"host.name",value:{stringValue:Q.hostname()}},{key:"host.arch",value:{stringValue:Q.arch()}}]}function Ye(e){return(0,O.buildPayload)({traceId:e.traceId,spanName:`codex.${(0,O.snakeCase)(e.event.hook_event_name)}`,attributes:Kt(e.event),resource:Yt(),scope:{name:"pinta-codex",version:Ke},now:e.now,guard:e.guard})}async function f(e,t,r){let n=new I(t);await n.flush();let o=new j(t),s=r.trace==="new"?o.newTrace():o.currentTrace(),a=Ye({event:e,traceId:s,guard:r.guard});await n.send(a)}async function He(e,t){let r=typeof e.tool_input=="string"?e.tool_input:JSON.stringify(e.tool_input),n=await Ve({spanId:e.session_id??"unknown",toolName:e.tool_name,toolInput:e.tool_input,rawTextFields:{toolInput:r}},t.guardEndpoint);if(await f(e,t,{trace:"current",guard:n}),n?.decision==="DENY"){let o={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:n.reason??"guard_deny"}};process.stdout.write(JSON.stringify(o)+`
15
- `)}return 0}async function Ze(e,t){return await f(e,t,{trace:"current"}),0}async function We(e,t){return await f(e,t,{trace:"new"}),0}async function ze(e,t){return await f(e,t,{trace:"current"}),0}async function Je(e,t){return await f(e,t,{trace:"current"}),0}async function ee(e){return 0}async function Ht(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function Qe(){let e=0;try{let t=Ce(),r=await Ht(),n=JSON.parse(r);Fe(n)?e=await ee(n):Ne(n)?e=await He(n,t):Ue(n)?e=await Ze(n,t):Le(n)?e=await We(n,t):qe(n)?e=await ze(n,t):Be(n)?e=await Je(n,t):e=await ee(n)}catch(t){process.stderr.write(`[pinta-codex] error: ${t}
16
- `),e=0}return e}var et=S(T());import{opendir as Zt,stat as Wt}from"node:fs/promises";import te from"node:path";var zt="pinta-codex",Jt=/^rollout-.+-([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})\.jsonl$/;function Qt(){return(0,et.envFilePath)(".codex","sessions","CODEX_HOME")}function er(e,t){return te.relative(e,t).split(te.sep).join("/")}function tr(e){return e.endsWith(".jsonl")?"append-log":"rewritten-doc"}function rr(e){return e.endsWith(".jsonl")?"session-log":"other"}function nr(e){let t=e.slice(e.lastIndexOf("/")+1);return Jt.exec(t)?.[1]}async function tt(){return[Qt()]}async function*rt(e,t){let r;try{r=await Zt(t)}catch{return}try{for await(let n of r){let o=te.join(t,n.name);n.isDirectory()?yield*rt(e,o):n.isFile()&&(yield{absPath:o,relPath:er(e,o)})}}catch{return}}async function*or(e){let[t]=await tt(),r=e.since?.getTime();for await(let{absPath:n,relPath:o}of rt(t,t)){let s;try{s=await Wt(n)}catch{continue}r!==void 0&&s.mtime.getTime()<=r||(yield{relPath:o,absPath:n,size:s.size,mtime:s.mtime,sessionId:nr(o),semantics:tr(o)})}}var sr={id:zt,roots:tt,scan:or,classify:rr};function ur(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===ar(ir(e)).href}catch{return!1}}async function cr(){let e=await Qe();process.exit(e)}ur()&&cr();export{sr as lifecycle};
13
+ `),!1}finally{clearTimeout(o)}}var H=class{queue;logPrefix;resolveOptions;constructor(t){this.queue=new ke.DiskRetryQueue(t.pluginData,t.logPrefix),this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions??Me}async send(t){let r=this.resolveOptions();if(!r||this.dropIfOversized(t))return;await R(t,r,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(t&&this.queue.tryAcquireLock())try{let r=this.queue.readAll();if(r.length===0)return;let{chunks:n,oversize:o}=we(r,u=>C(u.payload),l.MAX_POST_BYTES);o.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${o.length} oversized retry ${o.length===1?"entry":"entries"} (each > ${l.MAX_POST_BYTES} bytes \u2014 the backend caps the request body, so they can never be delivered)
14
+ `);let s=[].concat(...n),a=0;for(let u of n){if(!await R((0,Ae.mergeBatch)(u.map(h=>h.payload)),t,this.logPrefix))break;a+=u.length}this.queue.rewrite(s.slice(a))}catch(r){process.stderr.write(`[${this.logPrefix}] flush failed: ${r?.message??String(r)}
15
+ `)}finally{this.queue.release()}}dropIfOversized(t){let r=C(t);return r<=l.MAX_POST_BYTES?!1:(process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (${r} > ${l.MAX_POST_BYTES} bytes) \u2014 undeliverable, not queued
16
+ `),!0)}};l.DiskTransport=H;var Z=class{queue=new ke.MemoryRetryQueue;logPrefix;resolveOptions;constructor(t){this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions}async send(t){let r=this.resolveOptions();if(!r)return;if(C(t)>l.MAX_POST_BYTES){process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (> ${l.MAX_POST_BYTES} bytes) \u2014 undeliverable, not buffered
17
+ `);return}await R(t,r,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(!t)return;let r=this.queue.drain();if(r.length===0)return;let{chunks:n,oversize:o}=we(r,C,l.MAX_POST_BYTES);o.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${o.length} oversized buffered ${o.length===1?"payload":"payloads"} (each > ${l.MAX_POST_BYTES} bytes \u2014 undeliverable)
18
+ `);let s=[].concat(...n),a=0;for(let u of n){if(!await R((0,Ae.mergeBatch)(u),t,this.logPrefix))break;a+=u.length}for(let u of s.slice(a))this.queue.enqueue(u)}};l.MemoryTransport=Z});var te=g(v=>{"use strict";var ee=v&&v.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(v,"__esModule",{value:!0});v.TraceManager=void 0;v.generateUlid=je;var Ie=ee(_("fs")),Xt=ee(_("path")),Gt=ee(_("crypto")),Yt=I(),J="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function je(){let e=Date.now(),t="",r=e;for(let s=0;s<10;s++)t=J[r&31]+t,r=Math.floor(r/32);let n=Gt.default.randomBytes(10),o="";for(let s=0;s<10;s++)o+=J[n[s]&31];for(;o.length<16;)o+=J[0];return t+o}var Q=class{tracePath;constructor(t){this.tracePath=t}newTrace(){let t=je();return this.save(t),t}currentTrace(){try{let t=Ie.default.readFileSync(this.tracePath,"utf-8"),{traceId:r}=JSON.parse(t);if(r)return r}catch{}return this.newTrace()}save(t){try{Ie.default.mkdirSync(Xt.default.dirname(this.tracePath),{recursive:!0}),(0,Yt.atomicWriteFileSync)(this.tracePath,JSON.stringify({traceId:t}))}catch(r){process.stderr.write(`[pinta-core] trace persistence failed: ${r}
19
+ `)}}};v.TraceManager=Q});var Le=g(E=>{"use strict";var Ce=E&&E.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(E,"__esModule",{value:!0});E.MemorySessionTraceManager=E.DiskSessionTraceManager=void 0;var Ne=Ce(_("fs")),Vt=Ce(_("path")),Be=te(),Kt=I(),Ue=200,re=class{tracePath;maxSessions;constructor(t,r={}){this.tracePath=t,this.maxSessions=r.maxSessions??Ue}read(){try{let t=JSON.parse(Ne.default.readFileSync(this.tracePath,"utf-8"));if(t&&typeof t=="object"&&!("traceId"in t))return t}catch{}return{}}write(t){try{Ne.default.mkdirSync(Vt.default.dirname(this.tracePath),{recursive:!0});let r=Object.entries(t),n=r.length>this.maxSessions?Object.fromEntries(r.slice(-this.maxSessions)):t;(0,Kt.atomicWriteFileSync)(this.tracePath,JSON.stringify(n))}catch{}}newTrace(t){let r=t||"default",n=(0,Be.generateUlid)(),o=this.read();return o[r]=n,this.write(o),n}currentTrace(t){let r=t||"default",n=this.read()[r];return n||this.newTrace(r)}};E.DiskSessionTraceManager=re;var ne=class{map=new Map;maxSessions;constructor(t={}){this.maxSessions=t.maxSessions??Ue}newTrace(t){let r=t||"default",n=(0,Be.generateUlid)();if(this.map.set(r,n),this.map.size>this.maxSessions){let o=this.map.keys().next().value;o!==void 0&&this.map.delete(o)}return n}currentTrace(t){let r=t||"default";return this.map.get(r)??this.newTrace(r)}};E.MemorySessionTraceManager=ne});var $e=g(O=>{"use strict";var oe=O&&O.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(O,"__esModule",{value:!0});O.envFilePath=Ht;O.parseEnvFile=Fe;O.loadEnvFile=Zt;var zt=oe(_("node:fs")),Wt=oe(_("node:os")),qe=oe(_("node:path"));function Ht(e,t,r){let n=r?process.env[r]:void 0,o=n&&n.length>0?n:qe.default.join(Wt.default.homedir(),e);return qe.default.join(o,t)}function Fe(e){let t={};for(let r of e.split(`
20
+ `)){let n=r.trim();if(!n||n.startsWith("#"))continue;let o=n.indexOf("=");if(o<0)continue;let s=n.slice(0,o).trim(),a=n.slice(o+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),s&&(t[s]=a)}return t}function Zt(e){let t;try{t=zt.default.readFileSync(e,"utf-8")}catch{return}let r=Fe(t);for(let[n,o]of Object.entries(r))process.env[n]===void 0&&(process.env[n]=o)}});var S=g(i=>{"use strict";Object.defineProperty(i,"__esModule",{value:!0});i.loadEnvFile=i.parseEnvFile=i.envFilePath=i.MemorySessionTraceManager=i.DiskSessionTraceManager=i.generateUlid=i.TraceManager=i.MAX_POST_BYTES=i.parseHeadersEnv=i.envOptionsResolver=i.postOtlp=i.MemoryTransport=i.DiskTransport=i.MemoryRetryQueue=i.DiskRetryQueue=i.evaluateGuard=i.MAX_SPAN_BYTES=i.enforceSpanBudget=i.mergeBatch=i.buildPayload=i.clientAttrs=i.guardAttrs=i.attrsFromRecord=i.toOtlpValue=i.snakeCase=i.newSpanId=i.ulidToTraceId=i.MAX_BYTES=i.PATTERNS=i.applyMatches=i.resolveOverlaps=i.collectMatches=i.truncateTo=i.truncate=i.redact=void 0;var T=$();Object.defineProperty(i,"redact",{enumerable:!0,get:function(){return T.redact}});Object.defineProperty(i,"truncate",{enumerable:!0,get:function(){return T.truncate}});Object.defineProperty(i,"truncateTo",{enumerable:!0,get:function(){return T.truncateTo}});Object.defineProperty(i,"collectMatches",{enumerable:!0,get:function(){return T.collectMatches}});Object.defineProperty(i,"resolveOverlaps",{enumerable:!0,get:function(){return T.resolveOverlaps}});Object.defineProperty(i,"applyMatches",{enumerable:!0,get:function(){return T.applyMatches}});Object.defineProperty(i,"PATTERNS",{enumerable:!0,get:function(){return T.PATTERNS}});Object.defineProperty(i,"MAX_BYTES",{enumerable:!0,get:function(){return T.MAX_BYTES}});var m=G();Object.defineProperty(i,"ulidToTraceId",{enumerable:!0,get:function(){return m.ulidToTraceId}});Object.defineProperty(i,"newSpanId",{enumerable:!0,get:function(){return m.newSpanId}});Object.defineProperty(i,"snakeCase",{enumerable:!0,get:function(){return m.snakeCase}});Object.defineProperty(i,"toOtlpValue",{enumerable:!0,get:function(){return m.toOtlpValue}});Object.defineProperty(i,"attrsFromRecord",{enumerable:!0,get:function(){return m.attrsFromRecord}});Object.defineProperty(i,"guardAttrs",{enumerable:!0,get:function(){return m.guardAttrs}});Object.defineProperty(i,"clientAttrs",{enumerable:!0,get:function(){return m.clientAttrs}});Object.defineProperty(i,"buildPayload",{enumerable:!0,get:function(){return m.buildPayload}});Object.defineProperty(i,"mergeBatch",{enumerable:!0,get:function(){return m.mergeBatch}});Object.defineProperty(i,"enforceSpanBudget",{enumerable:!0,get:function(){return m.enforceSpanBudget}});Object.defineProperty(i,"MAX_SPAN_BYTES",{enumerable:!0,get:function(){return m.MAX_SPAN_BYTES}});var Jt=Se();Object.defineProperty(i,"evaluateGuard",{enumerable:!0,get:function(){return Jt.evaluateGuard}});var Xe=W();Object.defineProperty(i,"DiskRetryQueue",{enumerable:!0,get:function(){return Xe.DiskRetryQueue}});Object.defineProperty(i,"MemoryRetryQueue",{enumerable:!0,get:function(){return Xe.MemoryRetryQueue}});var k=De();Object.defineProperty(i,"DiskTransport",{enumerable:!0,get:function(){return k.DiskTransport}});Object.defineProperty(i,"MemoryTransport",{enumerable:!0,get:function(){return k.MemoryTransport}});Object.defineProperty(i,"postOtlp",{enumerable:!0,get:function(){return k.postOtlp}});Object.defineProperty(i,"envOptionsResolver",{enumerable:!0,get:function(){return k.envOptionsResolver}});Object.defineProperty(i,"parseHeadersEnv",{enumerable:!0,get:function(){return k.parseHeadersEnv}});Object.defineProperty(i,"MAX_POST_BYTES",{enumerable:!0,get:function(){return k.MAX_POST_BYTES}});var Ge=te();Object.defineProperty(i,"TraceManager",{enumerable:!0,get:function(){return Ge.TraceManager}});Object.defineProperty(i,"generateUlid",{enumerable:!0,get:function(){return Ge.generateUlid}});var Ye=Le();Object.defineProperty(i,"DiskSessionTraceManager",{enumerable:!0,get:function(){return Ye.DiskSessionTraceManager}});Object.defineProperty(i,"MemorySessionTraceManager",{enumerable:!0,get:function(){return Ye.MemorySessionTraceManager}});var se=$e();Object.defineProperty(i,"envFilePath",{enumerable:!0,get:function(){return se.envFilePath}});Object.defineProperty(i,"parseEnvFile",{enumerable:!0,get:function(){return se.parseEnvFile}});Object.defineProperty(i,"loadEnvFile",{enumerable:!0,get:function(){return se.loadEnvFile}})});import{realpathSync as Ar}from"node:fs";import{pathToFileURL as wr}from"node:url";var Ke=x(S());import Ve from"node:fs";import Qt from"node:os";import B from"node:path";function er(e){let t={},r;try{r=Ve.readFileSync(e,"utf-8")}catch{return t}for(let n of r.split(`
21
+ `)){let o=n.trim();if(!o||o.startsWith("#"))continue;let s=o.indexOf("=");if(s<0)continue;let a=o.slice(0,s).trim(),u=o.slice(s+1).trim();(u.startsWith('"')&&u.endsWith('"')||u.startsWith("'")&&u.endsWith("'"))&&(u=u.slice(1,-1)),a&&(t[a]=u)}return t}function tr(e){let t=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT??e.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;if(t)return t;let r=process.env.OTEL_EXPORTER_OTLP_ENDPOINT??e.OTEL_EXPORTER_OTLP_ENDPOINT;return r?r.replace(/\/+$/,"")+"/v1/traces":process.env.PINTA_CODEX_ENDPOINT??e.PINTA_CODEX_ENDPOINT??process.env.CLAUDE_PLUGIN_OPTION_ENDPOINT}function rr(e){if(process.env.OTEL_EXPORTER_OTLP_HEADERS)return process.env.OTEL_EXPORTER_OTLP_HEADERS;if(e.OTEL_EXPORTER_OTLP_HEADERS)return e.OTEL_EXPORTER_OTLP_HEADERS;if(process.env.PINTA_CODEX_API_KEY)return`x-pinta-relay-token=${process.env.PINTA_CODEX_API_KEY}`;if(e.PINTA_CODEX_API_KEY)return`x-pinta-relay-token=${e.PINTA_CODEX_API_KEY}`;if(process.env.CLAUDE_PLUGIN_OPTION_API_KEY)return`x-pinta-relay-token=${process.env.CLAUDE_PLUGIN_OPTION_API_KEY}`}function ze(){let e=process.env.CODEX_PLUGIN_ROOT??process.env.CLAUDE_PLUGIN_ROOT??process.cwd(),t=process.env.CODEX_PLUGIN_DATA??process.env.CLAUDE_PLUGIN_DATA??B.join(e,".plugin-data"),r=process.env.CODEX_HOME??B.join(Qt.homedir(),".codex"),n=B.join(r,"pinta-codex.env"),o=Ve.existsSync(n)?er(n):{},s=tr(o),a=rr(o);if(a&&!process.env.PINTA_RELAY_TOKEN){let c=a.match(/x-pinta-relay-token=([^,\s]+)/i);c&&(process.env.PINTA_RELAY_TOKEN=c[1])}let u=process.env.PINTA_GUARD_ENDPOINT??o.PINTA_GUARD_ENDPOINT;return{pluginRoot:e,pluginData:t,tracePath:B.join(t,"trace.json"),endpoint:s?.replace(/\/+$/,""),headers:(0,Ke.parseHeadersEnv)(a??""),guardEndpoint:u}}function We(e){return e.hook_event_name==="PreToolUse"}function He(e){return e.hook_event_name==="PostToolUse"}function Ze(e){return e.hook_event_name==="UserPromptSubmit"}function Je(e){return e.hook_event_name==="SessionStart"}function Qe(e){return e.hook_event_name==="Stop"}var nr=new Set(["PreToolUse","PostToolUse","SessionStart","UserPromptSubmit","Stop"]);function et(e){return!nr.has(e.hook_event_name)}var tt=x(S()),or=50,sr="pinta-codex/1.6.0";async function rt(e,t){let r=await(0,tt.evaluateGuard)(e,t,{timeoutMs:or,token:process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:sr});if(r===null)return null;let n={decision:r.decision,reason:r.reason,durationMs:r.durationMs,clientRttMs:r.clientRttMs};return r.failOpenReason!==void 0&&(n.failOpenReason=r.failOpenReason),n}var nt=x(S()),U=class extends nt.DiskTransport{constructor(t){super({pluginData:t.pluginData,logPrefix:"pinta-codex",resolveOptions:()=>t.endpoint?{endpoint:t.endpoint,headers:t.headers}:null})}};var ot=x(S()),L=class extends ot.TraceManager{constructor(t){super(t.tracePath)}};var b=x(S());import F from"fs";import ae from"os";import ir from"path";var q;function ar(){if(q===void 0)try{q=ae.userInfo().username}catch{q=process.env.USER??process.env.LOGNAME??(typeof process.getuid=="function"?String(process.getuid()):"unknown")}return q}var it="1.6.0",ie;function M(e){return typeof e=="string"&&e.trim()!==""?e.trim():void 0}var st=256*1024;function ur(e){if(!e)return;let t;try{t=F.openSync(e,"r");let r=Buffer.allocUnsafe(st),n=F.readSync(t,r,0,st,0),o=r.toString("utf8",0,n),s=o.indexOf(`
22
+ `);if(s<0)return;let a=JSON.parse(o.slice(0,s));return a?.type!=="session_meta"?void 0:M(a.payload?.cli_version)}catch{return}finally{if(t!==void 0)try{F.closeSync(t)}catch{}}}function cr(){let e=M(process.env.CODEX_MANAGED_PACKAGE_ROOT);if(e)try{let t=JSON.parse(F.readFileSync(ir.join(e,"package.json"),"utf8"));return M(t.version)}catch{return}}function lr(e){return ie===void 0&&(ie=ur(M(e?.transcript_path))??cr()??M(process.env.CODEX_CLI_VERSION)??null),ie??void 0}var dr=new Set(["codex.hook","codex.tool_name","codex.tool_use_id","codex.session_id","codex.transcript_path","codex.cwd","codex.permission_mode"]),fr=new Set(["codex.tool_input","codex.tool_response"]),pr={skipRedactKeys:dr,bashContextKeys:fr};function _r(e){let t=[];t.push({key:"ingest.type",value:{stringValue:"codex"}}),t.push({key:"codex.hook",value:{stringValue:e.hook_event_name}});let r={};for(let[n,o]of Object.entries(e))n!=="hook_event_name"&&(r[n]=o);return t.push(...(0,b.attrsFromRecord)(r,"codex",pr)),t}function mr(e){let t=lr(e);return[{key:"service.name",value:{stringValue:"codex"}},...t?[{key:"service.version",value:{stringValue:t}}]:[],{key:"telemetry.sdk.name",value:{stringValue:"pinta-codex"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:it}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:ar()}},{key:"host.name",value:{stringValue:ae.hostname()}},{key:"host.arch",value:{stringValue:ae.arch()}}]}function at(e){return(0,b.buildPayload)({traceId:e.traceId,spanName:`codex.${(0,b.snakeCase)(e.event.hook_event_name)}`,attributes:_r(e.event),resource:mr(e.event),scope:{name:"pinta-codex",version:it},now:e.now,guard:e.guard})}async function y(e,t,r){let n=new U(t);await n.flush();let o=new L(t),s=r.trace==="new"?o.newTrace():o.currentTrace(),a=at({event:e,traceId:s,guard:r.guard});await n.send(a)}async function ut(e,t){let r=typeof e.tool_input=="string"?e.tool_input:JSON.stringify(e.tool_input),n=await rt({spanId:e.session_id??"unknown",toolName:e.tool_name,method:e.hook_event_name,cwd:e.cwd,toolInput:e.tool_input,rawTextFields:{toolInput:r}},t.guardEndpoint);if(n?.decision==="DENY"){let o={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:n.reason??"guard_deny"}};process.stdout.write(JSON.stringify(o)+`
23
+ `)}try{await y(e,t,{trace:"current",guard:n})}catch(o){process.stderr.write(`[pinta-codex] telemetry emit failed: ${o}
24
+ `)}return 0}async function ct(e,t){return await y(e,t,{trace:"current"}),0}async function lt(e,t){return await y(e,t,{trace:"new"}),0}async function dt(e,t){return await y(e,t,{trace:"current"}),0}async function ft(e,t){return await y(e,t,{trace:"current"}),0}async function ue(e){return 0}async function hr(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function pt(){let e=0;try{let t=ze(),r=await hr(),n=JSON.parse(r);et(n)?e=await ue(n):We(n)?e=await ut(n,t):He(n)?e=await ct(n,t):Ze(n)?e=await lt(n,t):Je(n)?e=await dt(n,t):Qe(n)?e=await ft(n,t):e=await ue(n)}catch(t){process.stderr.write(`[pinta-codex] error: ${t}
25
+ `),e=0}return e}var _t=x(S());import{opendir as gr,stat as yr}from"node:fs/promises";import ce from"node:path";var Pr="pinta-codex",Er=/^rollout-.+-([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})\.jsonl$/;function Tr(){return(0,_t.envFilePath)(".codex","sessions","CODEX_HOME")}function vr(e,t){return ce.relative(e,t).split(ce.sep).join("/")}function Or(e){return e.endsWith(".jsonl")?"append-log":"rewritten-doc"}function Sr(e){return e.endsWith(".jsonl")?"session-log":"other"}function br(e){let t=e.slice(e.lastIndexOf("/")+1);return Er.exec(t)?.[1]}async function mt(){return[Tr()]}async function*ht(e,t){let r;try{r=await gr(t)}catch{return}try{for await(let n of r){let o=ce.join(t,n.name);n.isDirectory()?yield*ht(e,o):n.isFile()&&(yield{absPath:o,relPath:vr(e,o)})}}catch{return}}async function*xr(e){let[t]=await mt(),r=e.since?.getTime();for await(let{absPath:n,relPath:o}of ht(t,t)){let s;try{s=await yr(n)}catch{continue}r!==void 0&&s.mtime.getTime()<=r||(yield{relPath:o,absPath:n,size:s.size,mtime:s.mtime,sessionId:br(o),semantics:Or(o)})}}var kr={id:Pr,roots:mt,scan:xr,classify:Sr};function Rr(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===wr(Ar(e)).href}catch{return!1}}async function Mr(){let e=await pt();process.exit(e)}Rr()&&Mr();export{kr as lifecycle};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pinta-ai/pinta-codex",
3
- "version": "1.5.0",
3
+ "version": "1.7.0",
4
4
  "description": "Generic OTLP forwarder for Codex hook events",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -48,7 +48,7 @@
48
48
  "prepublishOnly": "npm run build"
49
49
  },
50
50
  "devDependencies": {
51
- "@pinta-ai/core": "^0.3.0",
51
+ "@pinta-ai/core": "^0.6.0",
52
52
  "@types/node": "^22.0.0",
53
53
  "esbuild": "^0.24.0",
54
54
  "typescript": "^5.7.0",
package/tools/_lib.ts CHANGED
@@ -29,6 +29,9 @@ export interface HookMatcher {
29
29
  }
30
30
  export interface HooksFile {
31
31
  hooks: Record<string, HookMatcher[]>;
32
+ // Preserve any other top-level keys a user may have in their hooks.json;
33
+ // the merge/strip helpers pass these through untouched.
34
+ [key: string]: unknown;
32
35
  }
33
36
 
34
37
  // --- JSON helpers ---
@@ -41,6 +44,39 @@ export function readJson<T>(p: string, fallback: T): T {
41
44
  }
42
45
  }
43
46
 
47
+ /**
48
+ * Read + parse a JSON config file that may legitimately be absent.
49
+ *
50
+ * - missing file (ENOENT) → return `fallback` (fresh install)
51
+ * - present but unparseable → THROW a clear error (never fall back)
52
+ * - other read error → rethrow
53
+ *
54
+ * Unlike {@link readJson}, this refuses to silently substitute the fallback
55
+ * when the file EXISTS but can't be parsed. Callers that merge-then-write-back
56
+ * (setup / install-hooks / uninstall-hooks) must abort here instead of
57
+ * clobbering a user's slightly-corrupt config (trailing comma / BOM) and
58
+ * wiping their other hooks.
59
+ */
60
+ export function readJsonAllowMissing<T>(p: string, fallback: T): T {
61
+ let raw: string;
62
+ try {
63
+ raw = fs.readFileSync(p, "utf-8");
64
+ } catch (err) {
65
+ if ((err as NodeJS.ErrnoException).code === "ENOENT") return fallback;
66
+ throw err;
67
+ }
68
+ try {
69
+ return JSON.parse(raw) as T;
70
+ } catch (err) {
71
+ const detail = err instanceof Error ? err.message : String(err);
72
+ throw new Error(
73
+ `${p} exists but is not valid JSON (${detail}).\n` +
74
+ `Refusing to overwrite it — that would discard your other Codex hooks. ` +
75
+ `Fix or remove the file, then re-run.`,
76
+ );
77
+ }
78
+ }
79
+
44
80
  // --- env file ("KEY=VALUE" per line) ---
45
81
 
46
82
  export function readEnvFile(p: string): Record<string, string> {
@@ -223,7 +259,9 @@ export function mergeHooks(
223
259
  existing: HooksFile,
224
260
  incoming: HooksFile,
225
261
  ): { next: HooksFile; staleRemoved: number } {
226
- const merged: HooksFile = { hooks: { ...existing.hooks } };
262
+ // Spread `existing` first so unknown top-level keys survive the merge;
263
+ // then override `hooks` with a shallow copy we can mutate.
264
+ const merged: HooksFile = { ...existing, hooks: { ...existing.hooks } };
227
265
  let staleRemoved = 0;
228
266
  for (const [eventName, incomingMatchers] of Object.entries(incoming.hooks)) {
229
267
  const current = merged.hooks[eventName] ?? [];
@@ -244,7 +282,8 @@ export function stripPintaCodex(existing: HooksFile): {
244
282
  next: HooksFile;
245
283
  removed: number;
246
284
  } {
247
- const cleaned: HooksFile = { hooks: {} };
285
+ // Preserve unknown top-level keys; rebuild only the `hooks` map.
286
+ const cleaned: HooksFile = { ...existing, hooks: {} };
248
287
  let removed = 0;
249
288
  for (const [eventName, matchers] of Object.entries(existing.hooks)) {
250
289
  const next = matchers
@@ -18,7 +18,7 @@ import {
18
18
  PLUGIN_ENTRY,
19
19
  loadResolvedTemplate,
20
20
  mergeHooks,
21
- readJson,
21
+ readJsonAllowMissing,
22
22
  type HooksFile,
23
23
  } from "./_lib.js";
24
24
 
@@ -34,7 +34,7 @@ function main(): void {
34
34
  }
35
35
 
36
36
  const incoming = loadResolvedTemplate();
37
- const existing: HooksFile = readJson(CODEX_HOOKS_PATH, { hooks: {} });
37
+ const existing: HooksFile = readJsonAllowMissing(CODEX_HOOKS_PATH, { hooks: {} });
38
38
  const { next: merged, staleRemoved } = mergeHooks(existing, incoming);
39
39
  const serialized = JSON.stringify(merged, null, 2) + "\n";
40
40
 
@@ -68,4 +68,11 @@ function main(): void {
68
68
  process.stdout.write(`[install-hooks] plugin entry: ${PLUGIN_ENTRY}\n`);
69
69
  }
70
70
 
71
- main();
71
+ try {
72
+ main();
73
+ } catch (err) {
74
+ process.stderr.write(
75
+ `[install-hooks] ${err instanceof Error ? err.message : String(err)}\n`,
76
+ );
77
+ process.exit(1);
78
+ }
package/tools/setup.ts CHANGED
@@ -30,7 +30,7 @@ import {
30
30
  mergeHooks,
31
31
  migrateLegacyEnvKeys,
32
32
  readEnvFile,
33
- readJson,
33
+ readJsonAllowMissing,
34
34
  writeEnvFile,
35
35
  type HooksFile,
36
36
  } from "./_lib.js";
@@ -142,7 +142,7 @@ async function stepConfigToml(): Promise<void> {
142
142
  async function stepHooks(): Promise<void> {
143
143
  heading("4. Register hooks");
144
144
  const incoming = loadResolvedTemplate();
145
- const existing: HooksFile = readJson(CODEX_HOOKS_PATH, { hooks: {} });
145
+ const existing: HooksFile = readJsonAllowMissing(CODEX_HOOKS_PATH, { hooks: {} });
146
146
  const { next: merged, staleRemoved } = mergeHooks(existing, incoming);
147
147
  const serialized = JSON.stringify(merged, null, 2) + "\n";
148
148
  const previous = fs.existsSync(CODEX_HOOKS_PATH)
@@ -8,7 +8,7 @@
8
8
  import fs from "node:fs";
9
9
  import {
10
10
  CODEX_HOOKS_PATH,
11
- readJson,
11
+ readJsonAllowMissing,
12
12
  stripPintaCodex,
13
13
  type HooksFile,
14
14
  } from "./_lib.js";
@@ -20,7 +20,7 @@ function main(): void {
20
20
  process.stdout.write(`[uninstall-hooks] nothing to do: ${CODEX_HOOKS_PATH} does not exist\n`);
21
21
  return;
22
22
  }
23
- const existing: HooksFile = readJson(CODEX_HOOKS_PATH, { hooks: {} });
23
+ const existing: HooksFile = readJsonAllowMissing(CODEX_HOOKS_PATH, { hooks: {} });
24
24
  const { next, removed } = stripPintaCodex(existing);
25
25
  const serialized = JSON.stringify(next, null, 2) + "\n";
26
26
 
@@ -36,4 +36,11 @@ function main(): void {
36
36
  process.stdout.write(`[uninstall-hooks] removed ${removed} entries from ${CODEX_HOOKS_PATH}\n`);
37
37
  }
38
38
 
39
- main();
39
+ try {
40
+ main();
41
+ } catch (err) {
42
+ process.stderr.write(
43
+ `[uninstall-hooks] ${err instanceof Error ? err.message : String(err)}\n`,
44
+ );
45
+ process.exit(1);
46
+ }