@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.
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +11 -0
- package/dist/index.js +22 -13
- package/dist/index.mjs +21 -12
- package/package.json +2 -2
- package/tools/_lib.ts +41 -2
- package/tools/install-hooks.ts +10 -3
- package/tools/setup.ts +2 -2
- package/tools/uninstall-hooks.ts +10 -3
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
|
|
2
|
-
`;
|
|
3
|
-
`)}}readAll(){try{let t=
|
|
4
|
-
`))if(n.trim())try{
|
|
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();
|
|
8
|
-
`),!1
|
|
9
|
-
`)
|
|
10
|
-
`)
|
|
11
|
-
`),!1}
|
|
12
|
-
`)
|
|
13
|
-
`)
|
|
14
|
-
`)}
|
|
15
|
-
`)
|
|
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
|
|
3
|
-
`;
|
|
4
|
-
`)}}readAll(){try{let t=
|
|
5
|
-
`))if(n.trim())try{
|
|
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();
|
|
9
|
-
`),!1
|
|
10
|
-
`)
|
|
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
|
|
13
|
-
`)
|
|
14
|
-
`)
|
|
15
|
-
`)
|
|
16
|
-
`)
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
package/tools/install-hooks.ts
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
PLUGIN_ENTRY,
|
|
19
19
|
loadResolvedTemplate,
|
|
20
20
|
mergeHooks,
|
|
21
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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)
|
package/tools/uninstall-hooks.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import fs from "node:fs";
|
|
9
9
|
import {
|
|
10
10
|
CODEX_HOOKS_PATH,
|
|
11
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
+
}
|