@pinta-ai/pinta-codex 1.5.0 → 1.6.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 +20 -12
- package/dist/index.mjs +20 -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,23 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`;
|
|
3
|
-
`)}}readAll(){try{let t=
|
|
4
|
-
`))if(n.trim())try{
|
|
1
|
+
"use strict";var pt=Object.create;var ae=Object.defineProperty;var dt=Object.getOwnPropertyDescriptor;var ft=Object.getOwnPropertyNames;var _t=Object.getPrototypeOf,ht=Object.prototype.hasOwnProperty;var g=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var gt=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ft(t))!ht.call(e,o)&&o!==r&&ae(e,o,{get:()=>t[o],enumerable:!(n=dt(t,o))||n.enumerable});return e};var y=(e,t,r)=>(r=e!=null?pt(_t(e)):{},gt(t||!e||!e.__esModule?ae(r,"default",{value:e,enumerable:!0}):r,e));var $=g(d=>{"use strict";Object.defineProperty(d,"__esModule",{value:!0});d.PATTERNS=d.MAX_BYTES=void 0;d.truncateTo=ue;d.truncate=mt;d.collectMatches=ce;d.resolveOverlaps=le;d.applyMatches=pe;d.redact=yt;d.MAX_BYTES=102400;function ue(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 mt(e){return ue(e,d.MAX_BYTES)}d.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 ce(e,t){let r=[];for(let n of d.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 c=i.index,h=i.index+i[0].length,x=c+i[0].indexOf(u),lt=x+u.length;r.push({start:c,end:h,replaceStart:x,replaceEnd:lt,type:n.type}),i.index===o.lastIndex&&o.lastIndex++}}return r}function le(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 pe(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 yt(e,t={}){if(e.length===0)return e;let r=ce(e,t);if(r.length===0)return e;let n=le(r);return pe(e,n)}});var Y=g(p=>{"use strict";var Pt=p&&p.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(p,"__esModule",{value:!0});p.MAX_SPAN_BYTES=void 0;p.ulidToTraceId=he;p.newSpanId=ge;p.snakeCase=Tt;p.toOtlpValue=me;p.attrsFromRecord=Ot;p.guardAttrs=ye;p.clientAttrs=Pe;p.enforceSpanBudget=Ee;p.buildPayload=St;p.mergeBatch=bt;var Et=Pt(require("crypto")),X=$(),vt="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function he(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=vt.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 ge(){return Et.default.randomBytes(8).toString("hex")}function Tt(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var de=new Set;function M(e,t,r){let n=(0,X.truncate)(t);if((r.skipRedactKeys??de).has(e))return n;let o=(r.bashContextKeys??de).has(e)?"bash":void 0;return(0,X.redact)(n,{context:o})}function me(e,t,r={}){if(t==null)return null;switch(typeof t){case"string":return{stringValue:M(e,t,r)};case"boolean":return{boolValue:t};case"number":return Number.isInteger(t)?{intValue:t}:{doubleValue:t};case"object":try{return{stringValue:M(e,JSON.stringify(t),r)}}catch{return{stringValue:M(e,String(t),r)}}default:return{stringValue:M(e,String(t),r)}}}function Ot(e,t,r={}){let n=[];for(let[o,i]of Object.entries(e)){let a=`${t}.${o}`,u=me(a,i,r);u!==null&&n.push({key:a,value:u})}return n}function ye(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 Pe(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}}]}p.MAX_SPAN_BYTES=800*1024;function fe(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}var _e=1024;function Ee(e,t=p.MAX_SPAN_BYTES){let r=fe(e);for(let n=0;n<100&&r>t;n++){let o=null,i=0;for(let c of e.attributes){if(!("stringValue"in c.value))continue;let h=Buffer.byteLength(c.value.stringValue,"utf-8");h>i&&(i=h,o=c.value)}if(o===null||i<=_e)break;let a=r-t,u=Math.max(_e,i-a-64);o.stringValue=(0,X.truncateTo)(o.stringValue,u),r=fe(e)}return e}function St(e){let t=e.now??Date.now(),r=(BigInt(t)*1000000n).toString(),n=[...e.attributes];e.guard&&n.push(...ye(e.guard));let o=e.clientTiming??(e.guard?.clientRttMs!==void 0?{op:"guard",rttMs:e.guard.clientRttMs}:null);o&&n.push(...Pe(o));let i={traceId:he(e.traceId),spanId:ge(),name:e.spanName,kind:e.spanKind??1,startTimeUnixNano:r,endTimeUnixNano:r,attributes:n};return Ee(i),{resourceSpans:[{resource:{attributes:e.resource},scopeSpans:[{scope:e.scope,spans:[i]}]}]}}function bt(e){let t=[];for(let r of e)t.push(...r.resourceSpans);return{resourceSpans:t}}});var ve=g(V=>{"use strict";Object.defineProperty(V,"__esModule",{value:!0});V.evaluateGuard=wt;var kt=1e4,xt="pinta-core";function G(e,t){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:e,clientRttMs:e,failOpenReason:t}}var At=new Set(["ALLOW","DENY","REVIEW"]);async function wt(e,t,r={}){if(!t||r.disabled)return null;let n=r.timeoutMs??kt,o=Date.now(),i=new AbortController,a=setTimeout(()=>i.abort(),n);try{let u=await fetch(t,{method:"POST",headers:{"content-type":"application/json","user-agent":r.userAgent??xt,"x-pinta-relay-token":r.token??""},body:JSON.stringify({input:e}),signal:i.signal});if(u.status!==200)return G(Date.now()-o,"error");let c=await u.json(),h=c?.durationMs===void 0||typeof c.durationMs=="number"&&Number.isFinite(c.durationMs);if(!c||!At.has(c.decision)||!h)return G(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,h=c==="AbortError"||c==="TimeoutError"?"timeout":"error";return G(Date.now()-o,h)}finally{clearTimeout(a)}}});var D=g(A=>{"use strict";var Rt=A&&A.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(A,"__esModule",{value:!0});A.atomicWriteFileSync=Mt;var Te=Rt(require("fs"));function Mt(e,t){let r=`${e}.${process.pid}.tmp`;Te.default.writeFileSync(r,t),Te.default.renameSync(r,e)}});var z=g(P=>{"use strict";var Oe=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=Oe(require("fs")),I=Oe(require("path")),Dt=D(),N=1e3,It=50,Nt=5,F=class{filePath;lockPath;logPrefix;constructor(t,r){this.filePath=I.default.join(t,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=r}enqueue(t){try{f.default.mkdirSync(I.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(I.default.dirname(this.filePath),{recursive:!0}),(0,Dt.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
|
-
`)
|
|
7
|
+
`)}}tryAcquireLock(){let t=Date.now();try{f.default.mkdirSync(I.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<It;)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 i=f.default.statSync(this.lockPath);if(Date.now()-i.mtimeMs>3e4){f.default.unlinkSync(this.lockPath);continue}}catch{}let n=Nt,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<=N)return;let r=t.length-N;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${r} oldest entries
|
|
10
|
+
`),this.rewrite(t.slice(r))}};P.DiskRetryQueue=F;var K=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=K});var we=g(l=>{"use strict";Object.defineProperty(l,"__esModule",{value:!0});l.MemoryTransport=l.DiskTransport=l.MAX_POST_BYTES=void 0;l.parseHeadersEnv=xe;l.envOptionsResolver=Ae;l.postOtlp=w;var Se=z(),be=Y(),jt=5e3;l.MAX_POST_BYTES=900*1024;function j(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}function ke(e,t,r){let n=[],o=[],i=[],a=0;for(let u of e){let c=t(u);if(c>r){o.push(u);continue}i.length>0&&a+c>r&&(n.push(i),i=[],a=0),i.push(u),a+=c}return i.length>0&&n.push(i),{chunks:n,oversize:o}}function xe(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 Ae(){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:xe(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function w(e,t,r){let n=new AbortController,o=setTimeout(()=>n.abort(),jt);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
11
|
`),!1}return!0}catch(i){return process.stderr.write(`[${r}] OTLP POST failed: ${i.message??String(i)}
|
|
11
|
-
`),!1}finally{clearTimeout(o)}}var
|
|
12
|
-
`)
|
|
13
|
-
`)
|
|
14
|
-
`)
|
|
15
|
-
`)
|
|
12
|
+
`),!1}finally{clearTimeout(o)}}var H=class{queue;logPrefix;resolveOptions;constructor(t){this.queue=new Se.DiskRetryQueue(t.pluginData,t.logPrefix),this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions??Ae}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}=ke(r,u=>j(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 i=[].concat(...n),a=0;for(let u of n){if(!await w((0,be.mergeBatch)(u.map(h=>h.payload)),t,this.logPrefix))break;a+=u.length}this.queue.rewrite(i.slice(a))}catch(r){process.stderr.write(`[${this.logPrefix}] flush failed: ${r?.message??String(r)}
|
|
14
|
+
`)}finally{this.queue.release()}}dropIfOversized(t){let r=j(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=H;var W=class{queue=new Se.MemoryRetryQueue;logPrefix;resolveOptions;constructor(t){this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions}async send(t){let r=this.resolveOptions();if(!r)return;if(j(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}=ke(r,j,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 i=[].concat(...n),a=0;for(let u of n){if(!await w((0,be.mergeBatch)(u),t,this.logPrefix))break;a+=u.length}for(let u of i.slice(a))this.queue.enqueue(u)}};l.MemoryTransport=W});var ee=g(T=>{"use strict";var Q=T&&T.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(T,"__esModule",{value:!0});T.TraceManager=void 0;T.generateUlid=Me;var Re=Q(require("fs")),Ct=Q(require("path")),Bt=Q(require("crypto")),Ut=D(),Z="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Me(){let e=Date.now(),t="",r=e;for(let i=0;i<10;i++)t=Z[r&31]+t,r=Math.floor(r/32);let n=Bt.default.randomBytes(10),o="";for(let i=0;i<10;i++)o+=Z[n[i]&31];for(;o.length<16;)o+=Z[0];return t+o}var J=class{tracePath;constructor(t){this.tracePath=t}newTrace(){let t=Me();return this.save(t),t}currentTrace(){try{let t=Re.default.readFileSync(this.tracePath,"utf-8"),{traceId:r}=JSON.parse(t);if(r)return r}catch{}return this.newTrace()}save(t){try{Re.default.mkdirSync(Ct.default.dirname(this.tracePath),{recursive:!0}),(0,Ut.atomicWriteFileSync)(this.tracePath,JSON.stringify({traceId:t}))}catch(r){process.stderr.write(`[pinta-core] trace persistence failed: ${r}
|
|
18
|
+
`)}}};T.TraceManager=J});var Ce=g(E=>{"use strict";var Ie=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 De=Ie(require("fs")),Lt=Ie(require("path")),Ne=ee(),qt=D(),je=200,te=class{tracePath;maxSessions;constructor(t,r={}){this.tracePath=t,this.maxSessions=r.maxSessions??je}read(){try{let t=JSON.parse(De.default.readFileSync(this.tracePath,"utf-8"));if(t&&typeof t=="object"&&!("traceId"in t))return t}catch{}return{}}write(t){try{De.default.mkdirSync(Lt.default.dirname(this.tracePath),{recursive:!0});let r=Object.entries(t),n=r.length>this.maxSessions?Object.fromEntries(r.slice(-this.maxSessions)):t;(0,qt.atomicWriteFileSync)(this.tracePath,JSON.stringify(n))}catch{}}newTrace(t){let r=t||"default",n=(0,Ne.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=te;var re=class{map=new Map;maxSessions;constructor(t={}){this.maxSessions=t.maxSessions??je}newTrace(t){let r=t||"default",n=(0,Ne.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=re});var Le=g(O=>{"use strict";var ne=O&&O.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(O,"__esModule",{value:!0});O.envFilePath=Yt;O.parseEnvFile=Ue;O.loadEnvFile=Gt;var $t=ne(require("node:fs")),Xt=ne(require("node:os")),Be=ne(require("node:path"));function Yt(e,t,r){let n=r?process.env[r]:void 0,o=n&&n.length>0?n:Be.default.join(Xt.default.homedir(),e);return Be.default.join(o,t)}function Ue(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 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 Gt(e){let t;try{t=$t.default.readFileSync(e,"utf-8")}catch{return}let r=Ue(t);for(let[n,o]of Object.entries(r))process.env[n]===void 0&&(process.env[n]=o)}});var k=g(s=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0});s.loadEnvFile=s.parseEnvFile=s.envFilePath=s.MemorySessionTraceManager=s.DiskSessionTraceManager=s.generateUlid=s.TraceManager=s.MAX_POST_BYTES=s.parseHeadersEnv=s.envOptionsResolver=s.postOtlp=s.MemoryTransport=s.DiskTransport=s.MemoryRetryQueue=s.DiskRetryQueue=s.evaluateGuard=s.MAX_SPAN_BYTES=s.enforceSpanBudget=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.truncateTo=s.truncate=s.redact=void 0;var v=$();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,"truncateTo",{enumerable:!0,get:function(){return v.truncateTo}});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 _=Y();Object.defineProperty(s,"ulidToTraceId",{enumerable:!0,get:function(){return _.ulidToTraceId}});Object.defineProperty(s,"newSpanId",{enumerable:!0,get:function(){return _.newSpanId}});Object.defineProperty(s,"snakeCase",{enumerable:!0,get:function(){return _.snakeCase}});Object.defineProperty(s,"toOtlpValue",{enumerable:!0,get:function(){return _.toOtlpValue}});Object.defineProperty(s,"attrsFromRecord",{enumerable:!0,get:function(){return _.attrsFromRecord}});Object.defineProperty(s,"guardAttrs",{enumerable:!0,get:function(){return _.guardAttrs}});Object.defineProperty(s,"clientAttrs",{enumerable:!0,get:function(){return _.clientAttrs}});Object.defineProperty(s,"buildPayload",{enumerable:!0,get:function(){return _.buildPayload}});Object.defineProperty(s,"mergeBatch",{enumerable:!0,get:function(){return _.mergeBatch}});Object.defineProperty(s,"enforceSpanBudget",{enumerable:!0,get:function(){return _.enforceSpanBudget}});Object.defineProperty(s,"MAX_SPAN_BYTES",{enumerable:!0,get:function(){return _.MAX_SPAN_BYTES}});var Vt=ve();Object.defineProperty(s,"evaluateGuard",{enumerable:!0,get:function(){return Vt.evaluateGuard}});var qe=z();Object.defineProperty(s,"DiskRetryQueue",{enumerable:!0,get:function(){return qe.DiskRetryQueue}});Object.defineProperty(s,"MemoryRetryQueue",{enumerable:!0,get:function(){return qe.MemoryRetryQueue}});var b=we();Object.defineProperty(s,"DiskTransport",{enumerable:!0,get:function(){return b.DiskTransport}});Object.defineProperty(s,"MemoryTransport",{enumerable:!0,get:function(){return b.MemoryTransport}});Object.defineProperty(s,"postOtlp",{enumerable:!0,get:function(){return b.postOtlp}});Object.defineProperty(s,"envOptionsResolver",{enumerable:!0,get:function(){return b.envOptionsResolver}});Object.defineProperty(s,"parseHeadersEnv",{enumerable:!0,get:function(){return b.parseHeadersEnv}});Object.defineProperty(s,"MAX_POST_BYTES",{enumerable:!0,get:function(){return b.MAX_POST_BYTES}});var $e=ee();Object.defineProperty(s,"TraceManager",{enumerable:!0,get:function(){return $e.TraceManager}});Object.defineProperty(s,"generateUlid",{enumerable:!0,get:function(){return $e.generateUlid}});var Xe=Ce();Object.defineProperty(s,"DiskSessionTraceManager",{enumerable:!0,get:function(){return Xe.DiskSessionTraceManager}});Object.defineProperty(s,"MemorySessionTraceManager",{enumerable:!0,get:function(){return Xe.MemorySessionTraceManager}});var oe=Le();Object.defineProperty(s,"envFilePath",{enumerable:!0,get:function(){return oe.envFilePath}});Object.defineProperty(s,"parseEnvFile",{enumerable:!0,get:function(){return oe.parseEnvFile}});Object.defineProperty(s,"loadEnvFile",{enumerable:!0,get:function(){return oe.loadEnvFile}})});var se=y(require("node:fs")),Ye=y(require("node:os")),R=y(require("node:path")),Ge=y(k());function Ft(e){let t={},r;try{r=se.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 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 Kt(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 zt(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 Ve(){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(Ye.default.homedir(),".codex"),n=R.default.join(r,"pinta-codex.env"),o=se.default.existsSync(n)?Ft(n):{},i=Kt(o),a=zt(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:i?.replace(/\/+$/,""),headers:(0,Ge.parseHeadersEnv)(a??""),guardEndpoint:u}}function Fe(e){return e.hook_event_name==="PreToolUse"}function Ke(e){return e.hook_event_name==="PostToolUse"}function ze(e){return e.hook_event_name==="UserPromptSubmit"}function He(e){return e.hook_event_name==="SessionStart"}function We(e){return e.hook_event_name==="Stop"}var Ht=new Set(["PreToolUse","PostToolUse","SessionStart","UserPromptSubmit","Stop"]);function Ze(e){return!Ht.has(e.hook_event_name)}var Je=y(k()),Wt=50,Zt="pinta-codex/1.6.0";async function Qe(e,t){let r=await(0,Je.evaluateGuard)(e,t,{timeoutMs:Wt,token:process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:Zt});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 et=y(k()),C=class extends et.DiskTransport{constructor(t){super({pluginData:t.pluginData,logPrefix:"pinta-codex",resolveOptions:()=>t.endpoint?{endpoint:t.endpoint,headers:t.headers}:null})}};var tt=y(k()),B=class extends tt.TraceManager{constructor(t){super(t.tracePath)}};var q=y(require("os")),S=y(k()),U;function Jt(){if(U===void 0)try{U=q.default.userInfo().username}catch{U=process.env.USER??process.env.LOGNAME??(typeof process.getuid=="function"?String(process.getuid()):"unknown")}return U}var rt="1.6.0",L=null;function Qt(){return L!==null||(L=process.env.CODEX_CLI_VERSION||"unknown"),L}var er=new Set(["codex.hook","codex.tool_name","codex.tool_use_id","codex.session_id","codex.transcript_path","codex.cwd","codex.permission_mode"]),tr=new Set(["codex.tool_input","codex.tool_response"]),rr={skipRedactKeys:er,bashContextKeys:tr};function nr(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",rr)),t}function or(){return[{key:"service.name",value:{stringValue:"codex"}},{key:"service.version",value:{stringValue:Qt()}},{key:"telemetry.sdk.name",value:{stringValue:"pinta-codex"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:rt}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:Jt()}},{key:"host.name",value:{stringValue:q.default.hostname()}},{key:"host.arch",value:{stringValue:q.default.arch()}}]}function nt(e){return(0,S.buildPayload)({traceId:e.traceId,spanName:`codex.${(0,S.snakeCase)(e.event.hook_event_name)}`,attributes:nr(e.event),resource:or(),scope:{name:"pinta-codex",version:rt},now:e.now,guard:e.guard})}async function m(e,t,r){let n=new C(t);await n.flush();let o=new B(t),i=r.trace==="new"?o.newTrace():o.currentTrace(),a=nt({event:e,traceId:i,guard:r.guard});await n.send(a)}async function ot(e,t){let r=typeof e.tool_input=="string"?e.tool_input:JSON.stringify(e.tool_input),n=await Qe({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)+`
|
|
21
|
+
`)}try{await m(e,t,{trace:"current",guard:n})}catch(o){process.stderr.write(`[pinta-codex] telemetry emit failed: ${o}
|
|
22
|
+
`)}return 0}async function st(e,t){return await m(e,t,{trace:"current"}),0}async function it(e,t){return await m(e,t,{trace:"new"}),0}async function at(e,t){return await m(e,t,{trace:"current"}),0}async function ut(e,t){return await m(e,t,{trace:"current"}),0}async function ie(e){return 0}async function sr(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function ct(){let e=0;try{let t=Ve(),r=await sr(),n=JSON.parse(r);Ze(n)?e=await ie(n):Fe(n)?e=await ot(n,t):Ke(n)?e=await st(n,t):ze(n)?e=await it(n,t):He(n)?e=await at(n,t):We(n)?e=await ut(n,t):e=await ie(n)}catch(t){process.stderr.write(`[pinta-codex] error: ${t}
|
|
23
|
+
`),e=0}return e}async function ir(){let e=await ct();process.exit(e)}ir();
|
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
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 mt=Object.create;var ue=Object.defineProperty;var ht=Object.getOwnPropertyDescriptor;var gt=Object.getOwnPropertyNames;var yt=Object.getPrototypeOf,Pt=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 Et=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of gt(t))!Pt.call(e,o)&&o!==r&&ue(e,o,{get:()=>t[o],enumerable:!(n=ht(t,o))||n.enumerable});return e};var x=(e,t,r)=>(r=e!=null?mt(yt(e)):{},Et(t||!e||!e.__esModule?ue(r,"default",{value:e,enumerable:!0}):r,e));var $=g(d=>{"use strict";Object.defineProperty(d,"__esModule",{value:!0});d.PATTERNS=d.MAX_BYTES=void 0;d.truncateTo=ce;d.truncate=Tt;d.collectMatches=le;d.resolveOverlaps=pe;d.applyMatches=de;d.redact=vt;d.MAX_BYTES=102400;function ce(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 Tt(e){return ce(e,d.MAX_BYTES)}d.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 le(e,t){let r=[];for(let n of d.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),_t=A+u.length;r.push({start:c,end:h,replaceStart:A,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 de(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 vt(e,t={}){if(e.length===0)return e;let r=le(e,t);if(r.length===0)return e;let n=pe(r);return de(e,n)}});var F=g(p=>{"use strict";var Ot=p&&p.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(p,"__esModule",{value:!0});p.MAX_SPAN_BYTES=void 0;p.ulidToTraceId=he;p.newSpanId=ge;p.snakeCase=xt;p.toOtlpValue=ye;p.attrsFromRecord=kt;p.guardAttrs=Pe;p.clientAttrs=Ee;p.enforceSpanBudget=Te;p.buildPayload=At;p.mergeBatch=wt;var St=Ot(_("crypto")),X=$(),bt="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function he(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 ge(){return St.default.randomBytes(8).toString("hex")}function xt(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var fe=new Set;function M(e,t,r){let n=(0,X.truncate)(t);if((r.skipRedactKeys??fe).has(e))return n;let o=(r.bashContextKeys??fe).has(e)?"bash":void 0;return(0,X.redact)(n,{context:o})}function ye(e,t,r={}){if(t==null)return null;switch(typeof t){case"string":return{stringValue:M(e,t,r)};case"boolean":return{boolValue:t};case"number":return Number.isInteger(t)?{intValue:t}:{doubleValue:t};case"object":try{return{stringValue:M(e,JSON.stringify(t),r)}}catch{return{stringValue:M(e,String(t),r)}}default:return{stringValue:M(e,String(t),r)}}}function kt(e,t,r={}){let n=[];for(let[o,s]of Object.entries(e)){let a=`${t}.${o}`,u=ye(a,s,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 Ee(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}}]}p.MAX_SPAN_BYTES=800*1024;function _e(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}var me=1024;function Te(e,t=p.MAX_SPAN_BYTES){let r=_e(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<=me)break;let a=r-t,u=Math.max(me,s-a-64);o.stringValue=(0,X.truncateTo)(o.stringValue,u),r=_e(e)}return e}function At(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(...Ee(o));let s={traceId:he(e.traceId),spanId:ge(),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 ve=g(G=>{"use strict";Object.defineProperty(G,"__esModule",{value:!0});G.evaluateGuard=It;var Rt=1e4,Mt="pinta-core";function Y(e,t){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:e,clientRttMs:e,failOpenReason:t}}var Dt=new Set(["ALLOW","DENY","REVIEW"]);async function It(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 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||!Dt.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 D=g(w=>{"use strict";var jt=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(w,"__esModule",{value:!0});w.atomicWriteFileSync=Nt;var Oe=jt(_("fs"));function Nt(e,t){let r=`${e}.${process.pid}.tmp`;Oe.default.writeFileSync(r,t),Oe.default.renameSync(r,e)}});var z=g(P=>{"use strict";var Se=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=Se(_("fs")),I=Se(_("path")),Ct=D(),j=1e3,Bt=50,Lt=5,V=class{filePath;lockPath;logPrefix;constructor(t,r){this.filePath=I.default.join(t,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=r}enqueue(t){try{f.default.mkdirSync(I.default.dirname(this.filePath),{recursive:!0});let r=JSON.stringify({savedAt:new Date().toISOString(),payload:t})+`
|
|
3
|
+
`;f.default.appendFileSync(this.filePath,r),this.trim()}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue enqueue failed: ${r}
|
|
4
|
+
`)}}readAll(){try{let t=f.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){f.default.existsSync(this.filePath)&&f.default.unlinkSync(this.filePath);return}f.default.mkdirSync(I.default.dirname(this.filePath),{recursive:!0}),(0,Ct.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{f.default.mkdirSync(I.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<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}
|
|
10
|
+
`),!1;try{let s=f.default.statSync(this.lockPath);if(Date.now()-s.mtimeMs>3e4){f.default.unlinkSync(this.lockPath);continue}}catch{}let n=Lt,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<=j)return;let r=t.length-j;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${r} oldest entries
|
|
11
|
+
`),this.rewrite(t.slice(r))}};P.DiskRetryQueue=V;var K=class{entries=[];enqueue(t){this.entries.push(t),this.entries.length>j&&this.entries.splice(0,this.entries.length-j)}drain(){let t=this.entries;return this.entries=[],t}get size(){return this.entries.length}};P.MemoryRetryQueue=K});var Re=g(l=>{"use strict";Object.defineProperty(l,"__esModule",{value:!0});l.MemoryTransport=l.DiskTransport=l.MAX_POST_BYTES=void 0;l.parseHeadersEnv=Ae;l.envOptionsResolver=we;l.postOtlp=R;var be=z(),xe=F(),Ut=5e3;l.MAX_POST_BYTES=900*1024;function N(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}function ke(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 Ae(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 we(){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:Ae(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function R(e,t,r){let n=new AbortController,o=setTimeout(()=>n.abort(),Ut);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 W=class{queue;logPrefix;resolveOptions;constructor(t){this.queue=new be.DiskRetryQueue(t.pluginData,t.logPrefix),this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions??we}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}=ke(r,u=>N(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,xe.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=N(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=W;var H=class{queue=new be.MemoryRetryQueue;logPrefix;resolveOptions;constructor(t){this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions}async send(t){let r=this.resolveOptions();if(!r)return;if(N(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}=ke(r,N,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,xe.mergeBatch)(u),t,this.logPrefix))break;a+=u.length}for(let u of s.slice(a))this.queue.enqueue(u)}};l.MemoryTransport=H});var ee=g(v=>{"use strict";var Q=v&&v.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(v,"__esModule",{value:!0});v.TraceManager=void 0;v.generateUlid=De;var Me=Q(_("fs")),qt=Q(_("path")),$t=Q(_("crypto")),Xt=D(),Z="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function De(){let e=Date.now(),t="",r=e;for(let s=0;s<10;s++)t=Z[r&31]+t,r=Math.floor(r/32);let n=$t.default.randomBytes(10),o="";for(let s=0;s<10;s++)o+=Z[n[s]&31];for(;o.length<16;)o+=Z[0];return t+o}var J=class{tracePath;constructor(t){this.tracePath=t}newTrace(){let t=De();return this.save(t),t}currentTrace(){try{let t=Me.default.readFileSync(this.tracePath,"utf-8"),{traceId:r}=JSON.parse(t);if(r)return r}catch{}return this.newTrace()}save(t){try{Me.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}
|
|
19
|
+
`)}}};v.TraceManager=J});var Be=g(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(_("fs")),Ft=je(_("path")),Ne=ee(),Yt=D(),Ce=200,te=class{tracePath;maxSessions;constructor(t,r={}){this.tracePath=t,this.maxSessions=r.maxSessions??Ce}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(Ft.default.dirname(this.tracePath),{recursive:!0});let r=Object.entries(t),n=r.length>this.maxSessions?Object.fromEntries(r.slice(-this.maxSessions)):t;(0,Yt.atomicWriteFileSync)(this.tracePath,JSON.stringify(n))}catch{}}newTrace(t){let r=t||"default",n=(0,Ne.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=te;var re=class{map=new Map;maxSessions;constructor(t={}){this.maxSessions=t.maxSessions??Ce}newTrace(t){let r=t||"default",n=(0,Ne.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=re});var qe=g(O=>{"use strict";var ne=O&&O.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(O,"__esModule",{value:!0});O.envFilePath=Kt;O.parseEnvFile=Ue;O.loadEnvFile=zt;var Gt=ne(_("node:fs")),Vt=ne(_("node:os")),Le=ne(_("node:path"));function Kt(e,t,r){let n=r?process.env[r]:void 0,o=n&&n.length>0?n:Le.default.join(Vt.default.homedir(),e);return Le.default.join(o,t)}function Ue(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=Gt.default.readFileSync(e,"utf-8")}catch{return}let r=Ue(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=F();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 Wt=ve();Object.defineProperty(i,"evaluateGuard",{enumerable:!0,get:function(){return Wt.evaluateGuard}});var $e=z();Object.defineProperty(i,"DiskRetryQueue",{enumerable:!0,get:function(){return $e.DiskRetryQueue}});Object.defineProperty(i,"MemoryRetryQueue",{enumerable:!0,get:function(){return $e.MemoryRetryQueue}});var k=Re();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 Xe=ee();Object.defineProperty(i,"TraceManager",{enumerable:!0,get:function(){return Xe.TraceManager}});Object.defineProperty(i,"generateUlid",{enumerable:!0,get:function(){return Xe.generateUlid}});var Fe=Be();Object.defineProperty(i,"DiskSessionTraceManager",{enumerable:!0,get:function(){return Fe.DiskSessionTraceManager}});Object.defineProperty(i,"MemorySessionTraceManager",{enumerable:!0,get:function(){return Fe.MemorySessionTraceManager}});var oe=qe();Object.defineProperty(i,"envFilePath",{enumerable:!0,get:function(){return oe.envFilePath}});Object.defineProperty(i,"parseEnvFile",{enumerable:!0,get:function(){return oe.parseEnvFile}});Object.defineProperty(i,"loadEnvFile",{enumerable:!0,get:function(){return oe.loadEnvFile}})});import{realpathSync as vr}from"node:fs";import{pathToFileURL as Or}from"node:url";var Ge=x(S());import Ye from"node:fs";import Ht from"node:os";import C from"node:path";function Zt(e){let t={},r;try{r=Ye.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 Jt(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 Qt(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 Ve(){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??C.join(e,".plugin-data"),r=process.env.CODEX_HOME??C.join(Ht.homedir(),".codex"),n=C.join(r,"pinta-codex.env"),o=Ye.existsSync(n)?Zt(n):{},s=Jt(o),a=Qt(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:C.join(t,"trace.json"),endpoint:s?.replace(/\/+$/,""),headers:(0,Ge.parseHeadersEnv)(a??""),guardEndpoint:u}}function Ke(e){return e.hook_event_name==="PreToolUse"}function ze(e){return e.hook_event_name==="PostToolUse"}function We(e){return e.hook_event_name==="UserPromptSubmit"}function He(e){return e.hook_event_name==="SessionStart"}function Ze(e){return e.hook_event_name==="Stop"}var er=new Set(["PreToolUse","PostToolUse","SessionStart","UserPromptSubmit","Stop"]);function Je(e){return!er.has(e.hook_event_name)}var Qe=x(S()),tr=50,rr="pinta-codex/1.6.0";async function et(e,t){let r=await(0,Qe.evaluateGuard)(e,t,{timeoutMs:tr,token:process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:rr});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 tt=x(S()),B=class extends tt.DiskTransport{constructor(t){super({pluginData:t.pluginData,logPrefix:"pinta-codex",resolveOptions:()=>t.endpoint?{endpoint:t.endpoint,headers:t.headers}:null})}};var rt=x(S()),L=class extends rt.TraceManager{constructor(t){super(t.tracePath)}};var b=x(S());import se from"os";var U;function nr(){if(U===void 0)try{U=se.userInfo().username}catch{U=process.env.USER??process.env.LOGNAME??(typeof process.getuid=="function"?String(process.getuid()):"unknown")}return U}var nt="1.6.0",q=null;function or(){return q!==null||(q=process.env.CODEX_CLI_VERSION||"unknown"),q}var sr=new Set(["codex.hook","codex.tool_name","codex.tool_use_id","codex.session_id","codex.transcript_path","codex.cwd","codex.permission_mode"]),ir=new Set(["codex.tool_input","codex.tool_response"]),ar={skipRedactKeys:sr,bashContextKeys:ir};function ur(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",ar)),t}function cr(){return[{key:"service.name",value:{stringValue:"codex"}},{key:"service.version",value:{stringValue:or()}},{key:"telemetry.sdk.name",value:{stringValue:"pinta-codex"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:nt}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:nr()}},{key:"host.name",value:{stringValue:se.hostname()}},{key:"host.arch",value:{stringValue:se.arch()}}]}function ot(e){return(0,b.buildPayload)({traceId:e.traceId,spanName:`codex.${(0,b.snakeCase)(e.event.hook_event_name)}`,attributes:ur(e.event),resource:cr(),scope:{name:"pinta-codex",version:nt},now:e.now,guard:e.guard})}async function y(e,t,r){let n=new B(t);await n.flush();let o=new L(t),s=r.trace==="new"?o.newTrace():o.currentTrace(),a=ot({event:e,traceId:s,guard:r.guard});await n.send(a)}async function st(e,t){let r=typeof e.tool_input=="string"?e.tool_input:JSON.stringify(e.tool_input),n=await et({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 it(e,t){return await y(e,t,{trace:"current"}),0}async function at(e,t){return await y(e,t,{trace:"new"}),0}async function ut(e,t){return await y(e,t,{trace:"current"}),0}async function ct(e,t){return await y(e,t,{trace:"current"}),0}async function ie(e){return 0}async function lr(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function lt(){let e=0;try{let t=Ve(),r=await lr(),n=JSON.parse(r);Je(n)?e=await ie(n):Ke(n)?e=await st(n,t):ze(n)?e=await it(n,t):We(n)?e=await at(n,t):He(n)?e=await ut(n,t):Ze(n)?e=await ct(n,t):e=await ie(n)}catch(t){process.stderr.write(`[pinta-codex] error: ${t}
|
|
24
|
+
`),e=0}return e}var pt=x(S());import{opendir as pr,stat as dr}from"node:fs/promises";import ae from"node:path";var fr="pinta-codex",_r=/^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 mr(){return(0,pt.envFilePath)(".codex","sessions","CODEX_HOME")}function hr(e,t){return ae.relative(e,t).split(ae.sep).join("/")}function gr(e){return e.endsWith(".jsonl")?"append-log":"rewritten-doc"}function yr(e){return e.endsWith(".jsonl")?"session-log":"other"}function Pr(e){let t=e.slice(e.lastIndexOf("/")+1);return _r.exec(t)?.[1]}async function dt(){return[mr()]}async function*ft(e,t){let r;try{r=await pr(t)}catch{return}try{for await(let n of r){let o=ae.join(t,n.name);n.isDirectory()?yield*ft(e,o):n.isFile()&&(yield{absPath:o,relPath:hr(e,o)})}}catch{return}}async function*Er(e){let[t]=await dt(),r=e.since?.getTime();for await(let{absPath:n,relPath:o}of ft(t,t)){let s;try{s=await dr(n)}catch{continue}r!==void 0&&s.mtime.getTime()<=r||(yield{relPath:o,absPath:n,size:s.size,mtime:s.mtime,sessionId:Pr(o),semantics:gr(o)})}}var Tr={id:fr,roots:dt,scan:Er,classify:yr};function Sr(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===Or(vr(e)).href}catch{return!1}}async function br(){let e=await lt();process.exit(e)}Sr()&&br();export{Tr 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.6.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
|
+
}
|