@pinta-ai/pinta-codex 1.2.4 → 1.4.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.
Files changed (51) hide show
  1. package/.codex-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +31 -0
  3. package/dist/index.js +15 -53
  4. package/package.json +14 -6
  5. package/dist/core/config.d.ts +0 -12
  6. package/dist/core/config.js +0 -125
  7. package/dist/core/config.js.map +0 -1
  8. package/dist/core/guard.d.ts +0 -13
  9. package/dist/core/guard.js +0 -41
  10. package/dist/core/guard.js.map +0 -1
  11. package/dist/core/identity.d.ts +0 -1
  12. package/dist/core/identity.js +0 -3
  13. package/dist/core/identity.js.map +0 -1
  14. package/dist/core/otlp.d.ts +0 -59
  15. package/dist/core/otlp.js +0 -192
  16. package/dist/core/otlp.js.map +0 -1
  17. package/dist/core/redact.d.ts +0 -57
  18. package/dist/core/redact.js +0 -149
  19. package/dist/core/redact.js.map +0 -1
  20. package/dist/core/retry-queue.d.ts +0 -26
  21. package/dist/core/retry-queue.js +0 -127
  22. package/dist/core/retry-queue.js.map +0 -1
  23. package/dist/core/trace.d.ts +0 -10
  24. package/dist/core/trace.js +0 -61
  25. package/dist/core/trace.js.map +0 -1
  26. package/dist/core/transport.d.ts +0 -10
  27. package/dist/core/transport.js +0 -83
  28. package/dist/core/transport.js.map +0 -1
  29. package/dist/core/types.d.ts +0 -48
  30. package/dist/core/types.js +0 -45
  31. package/dist/core/types.js.map +0 -1
  32. package/dist/handlers/default.d.ts +0 -6
  33. package/dist/handlers/default.js +0 -11
  34. package/dist/handlers/default.js.map +0 -1
  35. package/dist/handlers/post-tool-use.d.ts +0 -3
  36. package/dist/handlers/post-tool-use.js +0 -15
  37. package/dist/handlers/post-tool-use.js.map +0 -1
  38. package/dist/handlers/pre-tool-use.d.ts +0 -3
  39. package/dist/handlers/pre-tool-use.js +0 -38
  40. package/dist/handlers/pre-tool-use.js.map +0 -1
  41. package/dist/handlers/session.d.ts +0 -3
  42. package/dist/handlers/session.js +0 -15
  43. package/dist/handlers/session.js.map +0 -1
  44. package/dist/handlers/stop.d.ts +0 -3
  45. package/dist/handlers/stop.js +0 -15
  46. package/dist/handlers/stop.js.map +0 -1
  47. package/dist/handlers/user-prompt.d.ts +0 -3
  48. package/dist/handlers/user-prompt.js +0 -15
  49. package/dist/handlers/user-prompt.js.map +0 -1
  50. package/dist/index.d.ts +0 -1
  51. package/dist/index.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinta-codex",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "Generic OTLP forwarder for Codex hook events",
5
5
  "author": {
6
6
  "name": "Pinta AI",
package/CHANGELOG.md CHANGED
@@ -2,6 +2,37 @@
2
2
 
3
3
  All notable changes to pinta-codex are documented here.
4
4
 
5
+ ## [1.4.0] - 2026-07-12
6
+
7
+ ### Changed
8
+
9
+ - Low-level utilities consolidated into the shared private `@pinta-ai/core`
10
+ package (`^0.3.0`, devDependency). `src/core/*` keeps thin adaptor bindings;
11
+ core is **bundled + minified into `dist/` by esbuild at build time**, so npmjs
12
+ consumers never need private-registry access and `dist/` carries no runtime
13
+ `@pinta-ai/core` dependency.
14
+
15
+ ### Added
16
+
17
+ - `pinta.client.rtt_ms` / `pinta.client.op` span attributes on PreToolUse spans.
18
+ `buildOtlpPayload` already forwards its `guard` result into core's
19
+ `buildPayload`, and core `0.3.0` derives the client-call timing from the
20
+ `GuardResult.clientRttMs` it now measures. The manager can only time its own
21
+ handler, so `clientRttMs - durationMs` gives it the transport overhead.
22
+
23
+ ### Fixed
24
+
25
+ - `package-lock.json` resolved `@pinta-ai/core` as a `link:` to a local
26
+ `../pinta-core` checkout. `npm ci` created a dangling symlink in CI and the
27
+ build failed with `TS2307: Cannot find module '@pinta-ai/core'`. It is now
28
+ pinned to core's GitHub Packages tarball URL + integrity hash.
29
+ - `publish` workflow: npm pinned to `11.18.0` (npm@latest is 12.x and requires
30
+ node >=22.22, but the job runs node 20).
31
+ - `publish` workflow: restored OIDC trusted publishing. The committed `.npmrc`
32
+ pointed npmjs auth at `${NPM_TOKEN}`, but no such secret exists — it expanded
33
+ to an empty token and would have failed `npm publish` with ENEEDAUTH.
34
+ `NODE_AUTH_TOKEN` is now scoped to the `npm ci` step alone.
35
+
5
36
  ## [1.2.1] - 2026-04-30
6
37
 
7
38
  ### Changed
package/dist/index.js CHANGED
@@ -1,53 +1,15 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const config_js_1 = require("./core/config.js");
4
- const types_js_1 = require("./core/types.js");
5
- const pre_tool_use_js_1 = require("./handlers/pre-tool-use.js");
6
- const post_tool_use_js_1 = require("./handlers/post-tool-use.js");
7
- const user_prompt_js_1 = require("./handlers/user-prompt.js");
8
- const session_js_1 = require("./handlers/session.js");
9
- const stop_js_1 = require("./handlers/stop.js");
10
- const default_js_1 = require("./handlers/default.js");
11
- async function readStdin() {
12
- const chunks = [];
13
- for await (const chunk of process.stdin) {
14
- chunks.push(chunk);
15
- }
16
- return Buffer.concat(chunks).toString("utf-8");
17
- }
18
- async function main() {
19
- let exitCode = 0;
20
- try {
21
- const config = (0, config_js_1.loadConfig)();
22
- const raw = await readStdin();
23
- const event = JSON.parse(raw);
24
- if ((0, types_js_1.isSkippedHook)(event)) {
25
- exitCode = await (0, default_js_1.handleDefault)(event);
26
- }
27
- else if ((0, types_js_1.isPreToolUseEvent)(event)) {
28
- exitCode = await (0, pre_tool_use_js_1.handlePreToolUse)(event, config);
29
- }
30
- else if ((0, types_js_1.isPostToolUseEvent)(event)) {
31
- exitCode = await (0, post_tool_use_js_1.handlePostToolUse)(event, config);
32
- }
33
- else if ((0, types_js_1.isUserPromptSubmitEvent)(event)) {
34
- exitCode = await (0, user_prompt_js_1.handleUserPrompt)(event, config);
35
- }
36
- else if ((0, types_js_1.isSessionEvent)(event)) {
37
- exitCode = await (0, session_js_1.handleSession)(event, config);
38
- }
39
- else if ((0, types_js_1.isStopEvent)(event)) {
40
- exitCode = await (0, stop_js_1.handleStop)(event, config);
41
- }
42
- else {
43
- exitCode = await (0, default_js_1.handleDefault)(event);
44
- }
45
- }
46
- catch (err) {
47
- process.stderr.write(`[pinta-codex] error: ${err}\n`);
48
- exitCode = 0; // top-level catch-all stays fail-open per spec §6
49
- }
50
- process.exit(exitCode);
51
- }
52
- main();
53
- //# sourceMappingURL=index.js.map
1
+ "use strict";var et=Object.create;var re=Object.defineProperty;var tt=Object.getOwnPropertyDescriptor;var rt=Object.getOwnPropertyNames;var nt=Object.getPrototypeOf,ot=Object.prototype.hasOwnProperty;var f=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var st=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of rt(e))!ot.call(t,o)&&o!==r&&re(t,o,{get:()=>e[o],enumerable:!(n=tt(e,o))||n.enumerable});return t};var _=(t,e,r)=>(r=t!=null?et(nt(t)):{},st(e||!t||!t.__esModule?re(r,"default",{value:t,enumerable:!0}):r,t));var C=f(c=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});c.PATTERNS=c.MAX_BYTES=void 0;c.truncate=it;c.collectMatches=ne;c.resolveOverlaps=oe;c.applyMatches=se;c.redact=at;c.MAX_BYTES=102400;function it(t){let e=Buffer.from(t,"utf-8");return e.length<=c.MAX_BYTES?t:`${e.subarray(0,c.MAX_BYTES).toString("utf-8")}\u2026[TRUNCATED:${e.length}]`}c.PATTERNS=[{type:"aws_access_key",regex:/AKIA[0-9A-Z]{16}/g},{type:"aws_secret_key",regex:/(?:aws[_-]?secret(?:[_-]?(?:access)?[_-]?key)?)\s*[:=]\s*["']?([A-Za-z0-9/+=]{40})(?![A-Za-z0-9/+=])/gi,captureGroup:1},{type:"gcp_service_account",regex:/\{[\s\S]{0,200}?"type"\s*:\s*"service_account"[\s\S]*?\}/g},{type:"github_token",regex:/gh[pousr]_[A-Za-z0-9]{36,}/g},{type:"gitlab_token",regex:/glpat-[A-Za-z0-9_-]{20}/g},{type:"slack_token",regex:/xox[abrsp]-[0-9A-Za-z-]{10,}/g},{type:"openai_key",regex:/sk-(?:proj-)?[A-Za-z0-9_-]{40,}/g},{type:"anthropic_key",regex:/sk-ant-[A-Za-z0-9_-]{50,}/g},{type:"stripe_key",regex:/(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g},{type:"jwt",regex:/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g},{type:"private_key_block",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g},{type:"bearer_token",regex:/bearer\s+([A-Za-z0-9._~+/=-]{12,})/gi,captureGroup:1},{type:"basic_auth",regex:/basic\s+([A-Za-z0-9+/=]{12,})/gi,captureGroup:1},{type:"db_url_password",regex:/\b(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|redis):\/\/[^:\s/]+:([^@\s]+)@/gi,captureGroup:1},{type:"cli_password_flag",regex:/(?:--password|--pass|--pwd)[=\s]([^\s'"]+)/g,captureGroup:1},{type:"cli_password_short",regex:/\s-p([^\s'"]+)/g,captureGroup:1,requireContext:"bash"},{type:"env_var_secret",regex:/^(?:export\s+)?([A-Z][A-Z0-9_]*(?:KEY|SECRET|TOKEN|PASSWORD|PASSWD|PWD|API_KEY)[A-Z0-9_]*)\s*=\s*["']?([^\s"'\n]+)/gm,captureGroup:2}];function ne(t,e){let r=[];for(let n of c.PATTERNS){if(n.requireContext&&n.requireContext!==e.context)continue;let o=new RegExp(n.regex.source,n.regex.flags),i;for(;(i=o.exec(t))!==null;){let a=n.captureGroup??0,u=i[a];if(u===void 0){i.index===o.lastIndex&&o.lastIndex++;continue}let S=i.index,Je=i.index+i[0].length,te=S+i[0].indexOf(u),Qe=te+u.length;r.push({start:S,end:Je,replaceStart:te,replaceEnd:Qe,type:n.type}),i.index===o.lastIndex&&o.lastIndex++}}return r}function oe(t){let e=[...t].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 e)o.start<n||(r.push(o),n=o.end);return r}function se(t,e){let r=[...e].sort((o,i)=>i.replaceStart-o.replaceStart),n=t;for(let o of r)n=n.slice(0,o.replaceStart)+`[REDACTED:${o.type}]`+n.slice(o.replaceEnd);return n}function at(t,e={}){if(t.length===0)return t;let r=ne(t,e);if(r.length===0)return t;let n=oe(r);return se(t,n)}});var N=f(p=>{"use strict";var ut=p&&p.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(p,"__esModule",{value:!0});p.ulidToTraceId=ue;p.newSpanId=ce;p.snakeCase=pt;p.toOtlpValue=le;p.attrsFromRecord=dt;p.guardAttrs=pe;p.clientAttrs=de;p.buildPayload=ft;p.mergeBatch=_t;var ct=ut(require("crypto")),ie=C(),lt="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function ue(t){if(t.length!==26)throw new Error(`ulidToTraceId: expected 26 chars, got ${t.length}`);let e=0n;for(let n of t){let o=lt.indexOf(n);if(o<0)throw new Error(`ulidToTraceId: invalid Crockford char "${n}"`);e=e<<5n|BigInt(o)}let r=(1n<<128n)-1n;return e&=r,e.toString(16).padStart(32,"0")}function ce(){return ct.default.randomBytes(8).toString("hex")}function pt(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var ae=new Set;function R(t,e,r){let n=(0,ie.truncate)(e);if((r.skipRedactKeys??ae).has(t))return n;let o=(r.bashContextKeys??ae).has(t)?"bash":void 0;return(0,ie.redact)(n,{context:o})}function le(t,e,r={}){if(e==null)return null;switch(typeof e){case"string":return{stringValue:R(t,e,r)};case"boolean":return{boolValue:e};case"number":return Number.isInteger(e)?{intValue:e}:{doubleValue:e};case"object":try{return{stringValue:R(t,JSON.stringify(e),r)}}catch{return{stringValue:R(t,String(e),r)}}default:return{stringValue:R(t,String(e),r)}}}function dt(t,e,r={}){let n=[];for(let[o,i]of Object.entries(t)){let a=`${e}.${o}`,u=le(a,i,r);u!==null&&n.push({key:a,value:u})}return n}function pe(t){let e=[{key:"pinta.guard.decision",value:{stringValue:t.decision.toLowerCase()}},{key:"pinta.guard.duration_ms",value:{intValue:t.durationMs}}];return t.reason&&e.push({key:"pinta.guard.matched_rule",value:{stringValue:t.reason}}),t.failOpenReason&&e.push({key:"pinta.guard.fail_open_reason",value:{stringValue:t.failOpenReason}}),e}function de(t){return[{key:"pinta.client.rtt_ms",value:Number.isInteger(t.rttMs)?{intValue:t.rttMs}:{doubleValue:t.rttMs}},{key:"pinta.client.op",value:{stringValue:t.op}}]}function ft(t){let e=t.now??Date.now(),r=(BigInt(e)*1000000n).toString(),n=[...t.attributes];t.guard&&n.push(...pe(t.guard));let o=t.clientTiming??(t.guard?.clientRttMs!==void 0?{op:"guard",rttMs:t.guard.clientRttMs}:null);o&&n.push(...de(o));let i={traceId:ue(t.traceId),spanId:ce(),name:t.spanName,kind:t.spanKind??1,startTimeUnixNano:r,endTimeUnixNano:r,attributes:n};return{resourceSpans:[{resource:{attributes:t.resource},scopeSpans:[{scope:t.scope,spans:[i]}]}]}}function _t(t){let e=[];for(let r of t)e.push(...r.resourceSpans);return{resourceSpans:e}}});var _e=f(U=>{"use strict";Object.defineProperty(U,"__esModule",{value:!0});U.evaluateGuard=yt;var mt=1e4,gt="pinta-core";function fe(t,e){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:t,clientRttMs:t,failOpenReason:e}}function ht(t){return new Promise((e,r)=>setTimeout(()=>{let n=new Error("Guard request timed out");n.name="TimeoutError",r(n)},t))}async function yt(t,e,r={}){if(!e||r.disabled)return null;let n=r.timeoutMs??mt,o=Date.now();try{let i=await Promise.race([fetch(e,{method:"POST",headers:{"content-type":"application/json","user-agent":r.userAgent??gt,"x-pinta-relay-token":r.token??""},body:JSON.stringify({input:t})}),ht(n)]);if(i.status!==200)return fe(Date.now()-o,"error");let a=await i.json(),u=Date.now()-o;return{decision:a.decision,reason:a.reason,userMessage:a.userMessage??null,durationMs:a.durationMs??u,clientRttMs:u}}catch(i){let a=i.name==="TimeoutError"?"timeout":"error";return fe(Date.now()-o,a)}}});var B=f(h=>{"use strict";var me=h&&h.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(h,"__esModule",{value:!0});h.MemoryRetryQueue=h.DiskRetryQueue=void 0;var l=me(require("fs")),A=me(require("path")),w=1e3,Pt=50,Et=5,L=class{filePath;lockPath;logPrefix;constructor(e,r){this.filePath=A.default.join(e,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=r}enqueue(e){try{l.default.mkdirSync(A.default.dirname(this.filePath),{recursive:!0});let r=JSON.stringify({savedAt:new Date().toISOString(),payload:e})+`
2
+ `;l.default.appendFileSync(this.filePath,r),this.trim()}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue enqueue failed: ${r}
3
+ `)}}readAll(){try{let e=l.default.readFileSync(this.filePath,"utf-8"),r=[];for(let n of e.split(`
4
+ `))if(n.trim())try{r.push(JSON.parse(n))}catch{}return r}catch{return[]}}rewrite(e){try{if(e.length===0){l.default.existsSync(this.filePath)&&l.default.unlinkSync(this.filePath);return}l.default.mkdirSync(A.default.dirname(this.filePath),{recursive:!0}),l.default.writeFileSync(this.filePath,e.map(r=>JSON.stringify(r)).join(`
5
+ `)+`
6
+ `)}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue rewrite failed: ${r}
7
+ `)}}tryAcquireLock(){let e=Date.now();for(l.default.mkdirSync(A.default.dirname(this.lockPath),{recursive:!0});Date.now()-e<Pt;)try{let r=l.default.openSync(this.lockPath,"wx");return l.default.writeSync(r,String(process.pid)),l.default.closeSync(r),!0}catch(r){if(r?.code!=="EEXIST")return process.stderr.write(`[${this.logPrefix}] retry-queue lock open failed: ${r}
8
+ `),!1;try{let i=l.default.statSync(this.lockPath);if(Date.now()-i.mtimeMs>3e4){l.default.unlinkSync(this.lockPath);continue}}catch{}let n=Et,o=Date.now()+n;for(;Date.now()<o;);}return!1}release(){try{l.default.unlinkSync(this.lockPath)}catch{}}trim(){let e=this.readAll();if(e.length<=w)return;let r=e.length-w;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${r} oldest entries
9
+ `),this.rewrite(e.slice(r))}};h.DiskRetryQueue=L;var q=class{entries=[];enqueue(e){this.entries.push(e),this.entries.length>w&&this.entries.splice(0,this.entries.length-w)}drain(){let e=this.entries;return this.entries=[],e}get size(){return this.entries.length}};h.MemoryRetryQueue=q});var Ee=f(m=>{"use strict";Object.defineProperty(m,"__esModule",{value:!0});m.MemoryTransport=m.DiskTransport=void 0;m.parseHeadersEnv=ye;m.envOptionsResolver=Pe;m.postOtlp=x;var ge=B(),he=N(),vt=5e3;function ye(t){if(!t)return{};if(typeof t=="object")return{...t};let e={};for(let r of t.split(",")){let[n,...o]=r.split("=");n&&o.length>0&&(e[n.trim()]=o.join("=").trim())}return e}function Pe(){let t=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,e=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,r;return t?r=t.replace(/\/+$/,""):e&&(r=e.replace(/\/+$/,"")+"/v1/traces"),r?{endpoint:r,headers:ye(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function x(t,e,r){let n=new AbortController,o=setTimeout(()=>n.abort(),vt);try{let i=await fetch(e.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...e.headers},body:JSON.stringify(t),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} ${e.endpoint}${u}${a?` body=${a}`:""}
10
+ `),!1}return!0}catch(i){return process.stderr.write(`[${r}] OTLP POST failed: ${i.message??String(i)}
11
+ `),!1}finally{clearTimeout(o)}}var G=class{queue;logPrefix;resolveOptions;constructor(e){this.queue=new ge.DiskRetryQueue(e.pluginData,e.logPrefix),this.logPrefix=e.logPrefix,this.resolveOptions=e.resolveOptions??Pe}async send(e){let r=this.resolveOptions();if(!r)return;await x(e,r,this.logPrefix)||this.queue.enqueue(e)}async flush(){let e=this.resolveOptions();if(e&&this.queue.tryAcquireLock())try{let r=this.queue.readAll();if(r.length===0)return;let n=(0,he.mergeBatch)(r.map(i=>i.payload));await x(n,e,this.logPrefix)&&this.queue.rewrite([])}finally{this.queue.release()}}};m.DiskTransport=G;var V=class{queue=new ge.MemoryRetryQueue;logPrefix;resolveOptions;constructor(e){this.logPrefix=e.logPrefix,this.resolveOptions=e.resolveOptions}async send(e){let r=this.resolveOptions();if(!r)return;await x(e,r,this.logPrefix)||this.queue.enqueue(e)}async flush(){let e=this.resolveOptions();if(!e)return;let r=this.queue.drain();if(r.length===0)return;let n=(0,he.mergeBatch)(r);if(!await x(n,e,this.logPrefix))for(let i of r)this.queue.enqueue(i)}};m.MemoryTransport=V});var Y=f(P=>{"use strict";var K=P&&P.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(P,"__esModule",{value:!0});P.TraceManager=void 0;P.generateUlid=ve;var F=K(require("fs")),Ot=K(require("path")),Tt=K(require("crypto")),X="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function ve(){let t=Date.now(),e="",r=t;for(let i=0;i<10;i++)e=X[r&31]+e,r=Math.floor(r/32);let n=Tt.default.randomBytes(10),o="";for(let i=0;i<10;i++)o+=X[n[i]&31];for(;o.length<16;)o+=X[0];return e+o}var $=class{tracePath;constructor(e){this.tracePath=e}newTrace(){let e=ve();return this.save(e),e}currentTrace(){try{let e=F.default.readFileSync(this.tracePath,"utf-8"),{traceId:r}=JSON.parse(e);if(r)return r}catch{}return this.newTrace()}save(e){F.default.mkdirSync(Ot.default.dirname(this.tracePath),{recursive:!0}),F.default.writeFileSync(this.tracePath,JSON.stringify({traceId:e}))}};P.TraceManager=$});var xe=f(y=>{"use strict";var Oe=y&&y.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(y,"__esModule",{value:!0});y.MemorySessionTraceManager=y.DiskSessionTraceManager=void 0;var H=Oe(require("fs")),St=Oe(require("path")),Te=Y(),Se=200,Z=class{tracePath;maxSessions;constructor(e,r={}){this.tracePath=e,this.maxSessions=r.maxSessions??Se}read(){try{let e=JSON.parse(H.default.readFileSync(this.tracePath,"utf-8"));if(e&&typeof e=="object"&&!("traceId"in e))return e}catch{}return{}}write(e){try{H.default.mkdirSync(St.default.dirname(this.tracePath),{recursive:!0});let r=Object.entries(e),n=r.length>this.maxSessions?Object.fromEntries(r.slice(-this.maxSessions)):e;H.default.writeFileSync(this.tracePath,JSON.stringify(n))}catch{}}newTrace(e){let r=e||"default",n=(0,Te.generateUlid)(),o=this.read();return o[r]=n,this.write(o),n}currentTrace(e){let r=e||"default",n=this.read()[r];return n||this.newTrace(r)}};y.DiskSessionTraceManager=Z;var W=class{map=new Map;maxSessions;constructor(e={}){this.maxSessions=e.maxSessions??Se}newTrace(e){let r=e||"default",n=(0,Te.generateUlid)();if(this.map.set(r,n),this.map.size>this.maxSessions){let o=this.map.keys().next().value;o!==void 0&&this.map.delete(o)}return n}currentTrace(e){let r=e||"default";return this.map.get(r)??this.newTrace(r)}};y.MemorySessionTraceManager=W});var Re=f(E=>{"use strict";var z=E&&E.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(E,"__esModule",{value:!0});E.envFilePath=bt;E.parseEnvFile=be;E.loadEnvFile=Rt;var xt=z(require("node:fs")),kt=z(require("node:os")),ke=z(require("node:path"));function bt(t,e,r){let n=r?process.env[r]:void 0,o=n&&n.length>0?n:ke.default.join(kt.default.homedir(),t);return ke.default.join(o,e)}function be(t){let e={};for(let r of t.split(`
12
+ `)){let n=r.trim();if(!n||n.startsWith("#"))continue;let o=n.indexOf("=");if(o<0)continue;let i=n.slice(0,o).trim(),a=n.slice(o+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),i&&(e[i]=a)}return e}function Rt(t){let e;try{e=xt.default.readFileSync(t,"utf-8")}catch{return}let r=be(e);for(let[n,o]of Object.entries(r))process.env[n]===void 0&&(process.env[n]=o)}});var T=f(s=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0});s.loadEnvFile=s.parseEnvFile=s.envFilePath=s.MemorySessionTraceManager=s.DiskSessionTraceManager=s.generateUlid=s.TraceManager=s.parseHeadersEnv=s.envOptionsResolver=s.postOtlp=s.MemoryTransport=s.DiskTransport=s.MemoryRetryQueue=s.DiskRetryQueue=s.evaluateGuard=s.mergeBatch=s.buildPayload=s.clientAttrs=s.guardAttrs=s.attrsFromRecord=s.toOtlpValue=s.snakeCase=s.newSpanId=s.ulidToTraceId=s.MAX_BYTES=s.PATTERNS=s.applyMatches=s.resolveOverlaps=s.collectMatches=s.truncate=s.redact=void 0;var v=C();Object.defineProperty(s,"redact",{enumerable:!0,get:function(){return v.redact}});Object.defineProperty(s,"truncate",{enumerable:!0,get:function(){return v.truncate}});Object.defineProperty(s,"collectMatches",{enumerable:!0,get:function(){return v.collectMatches}});Object.defineProperty(s,"resolveOverlaps",{enumerable:!0,get:function(){return v.resolveOverlaps}});Object.defineProperty(s,"applyMatches",{enumerable:!0,get:function(){return v.applyMatches}});Object.defineProperty(s,"PATTERNS",{enumerable:!0,get:function(){return v.PATTERNS}});Object.defineProperty(s,"MAX_BYTES",{enumerable:!0,get:function(){return v.MAX_BYTES}});var g=N();Object.defineProperty(s,"ulidToTraceId",{enumerable:!0,get:function(){return g.ulidToTraceId}});Object.defineProperty(s,"newSpanId",{enumerable:!0,get:function(){return g.newSpanId}});Object.defineProperty(s,"snakeCase",{enumerable:!0,get:function(){return g.snakeCase}});Object.defineProperty(s,"toOtlpValue",{enumerable:!0,get:function(){return g.toOtlpValue}});Object.defineProperty(s,"attrsFromRecord",{enumerable:!0,get:function(){return g.attrsFromRecord}});Object.defineProperty(s,"guardAttrs",{enumerable:!0,get:function(){return g.guardAttrs}});Object.defineProperty(s,"clientAttrs",{enumerable:!0,get:function(){return g.clientAttrs}});Object.defineProperty(s,"buildPayload",{enumerable:!0,get:function(){return g.buildPayload}});Object.defineProperty(s,"mergeBatch",{enumerable:!0,get:function(){return g.mergeBatch}});var At=_e();Object.defineProperty(s,"evaluateGuard",{enumerable:!0,get:function(){return At.evaluateGuard}});var Ae=B();Object.defineProperty(s,"DiskRetryQueue",{enumerable:!0,get:function(){return Ae.DiskRetryQueue}});Object.defineProperty(s,"MemoryRetryQueue",{enumerable:!0,get:function(){return Ae.MemoryRetryQueue}});var k=Ee();Object.defineProperty(s,"DiskTransport",{enumerable:!0,get:function(){return k.DiskTransport}});Object.defineProperty(s,"MemoryTransport",{enumerable:!0,get:function(){return k.MemoryTransport}});Object.defineProperty(s,"postOtlp",{enumerable:!0,get:function(){return k.postOtlp}});Object.defineProperty(s,"envOptionsResolver",{enumerable:!0,get:function(){return k.envOptionsResolver}});Object.defineProperty(s,"parseHeadersEnv",{enumerable:!0,get:function(){return k.parseHeadersEnv}});var we=Y();Object.defineProperty(s,"TraceManager",{enumerable:!0,get:function(){return we.TraceManager}});Object.defineProperty(s,"generateUlid",{enumerable:!0,get:function(){return we.generateUlid}});var De=xe();Object.defineProperty(s,"DiskSessionTraceManager",{enumerable:!0,get:function(){return De.DiskSessionTraceManager}});Object.defineProperty(s,"MemorySessionTraceManager",{enumerable:!0,get:function(){return De.MemorySessionTraceManager}});var J=Re();Object.defineProperty(s,"envFilePath",{enumerable:!0,get:function(){return J.envFilePath}});Object.defineProperty(s,"parseEnvFile",{enumerable:!0,get:function(){return J.parseEnvFile}});Object.defineProperty(s,"loadEnvFile",{enumerable:!0,get:function(){return J.loadEnvFile}})});var Q=_(require("node:fs")),Ie=_(require("node:os")),b=_(require("node:path")),Me=_(T());function wt(t){let e={},r;try{r=Q.default.readFileSync(t,"utf-8")}catch{return e}for(let n of r.split(`
13
+ `)){let o=n.trim();if(!o||o.startsWith("#"))continue;let i=o.indexOf("=");if(i<0)continue;let a=o.slice(0,i).trim(),u=o.slice(i+1).trim();(u.startsWith('"')&&u.endsWith('"')||u.startsWith("'")&&u.endsWith("'"))&&(u=u.slice(1,-1)),a&&(e[a]=u)}return e}function Dt(t){let e=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT??t.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;if(e)return e;let r=process.env.OTEL_EXPORTER_OTLP_ENDPOINT??t.OTEL_EXPORTER_OTLP_ENDPOINT;return r?r.replace(/\/+$/,"")+"/v1/traces":process.env.PINTA_CODEX_ENDPOINT??t.PINTA_CODEX_ENDPOINT??process.env.CLAUDE_PLUGIN_OPTION_ENDPOINT}function It(t){if(process.env.OTEL_EXPORTER_OTLP_HEADERS)return process.env.OTEL_EXPORTER_OTLP_HEADERS;if(t.OTEL_EXPORTER_OTLP_HEADERS)return t.OTEL_EXPORTER_OTLP_HEADERS;if(process.env.PINTA_CODEX_API_KEY)return`x-pinta-relay-token=${process.env.PINTA_CODEX_API_KEY}`;if(t.PINTA_CODEX_API_KEY)return`x-pinta-relay-token=${t.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 je(){let t=process.env.CODEX_PLUGIN_ROOT??process.env.CLAUDE_PLUGIN_ROOT??process.cwd(),e=process.env.CODEX_PLUGIN_DATA??process.env.CLAUDE_PLUGIN_DATA??b.default.join(t,".plugin-data"),r=process.env.CODEX_HOME??b.default.join(Ie.default.homedir(),".codex"),n=b.default.join(r,"pinta-codex.env"),o=Q.default.existsSync(n)?wt(n):{},i=Dt(o),a=It(o);if(a&&!process.env.PINTA_RELAY_TOKEN){let S=a.match(/x-pinta-relay-token=([^,\s]+)/i);S&&(process.env.PINTA_RELAY_TOKEN=S[1])}let u=process.env.PINTA_GUARD_ENDPOINT??o.PINTA_GUARD_ENDPOINT;return{pluginRoot:t,pluginData:e,tracePath:b.default.join(e,"trace.json"),endpoint:i?.replace(/\/+$/,""),headers:(0,Me.parseHeadersEnv)(a??""),guardEndpoint:u}}function Ce(t){return t.hook_event_name==="PreToolUse"}function Ne(t){return t.hook_event_name==="PostToolUse"}function Ue(t){return t.hook_event_name==="UserPromptSubmit"}function Le(t){return t.hook_event_name==="SessionStart"}function qe(t){return t.hook_event_name==="Stop"}var Mt=new Set(["PreToolUse","PostToolUse","SessionStart","UserPromptSubmit","Stop"]);function Be(t){return!Mt.has(t.hook_event_name)}var Ge=_(T()),jt=50,Ct="pinta-codex/1.4.0";async function Ve(t,e){let r=await(0,Ge.evaluateGuard)(t,e,{timeoutMs:jt,token:process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:Ct});if(r===null)return null;let n={decision:r.decision,reason:r.reason,durationMs:r.durationMs,clientRttMs:r.clientRttMs};return r.failOpenReason!==void 0&&(n.failOpenReason=r.failOpenReason),n}var Fe=_(T()),D=class extends Fe.DiskTransport{constructor(e){super({pluginData:e.pluginData,logPrefix:"pinta-codex",resolveOptions:()=>e.endpoint?{endpoint:e.endpoint,headers:e.headers}:null})}};var Xe=_(T()),I=class extends Xe.TraceManager{constructor(e){super(e.tracePath)}};var j=_(require("os")),O=_(T());var $e="1.4.0",M=null;function Nt(){return M!==null||(M=process.env.CODEX_CLI_VERSION||"unknown"),M}var Ut=new Set(["codex.hook","codex.tool_name","codex.tool_use_id","codex.session_id","codex.transcript_path","codex.cwd","codex.permission_mode"]),Lt=new Set(["codex.tool_input","codex.tool_response"]),qt={skipRedactKeys:Ut,bashContextKeys:Lt};function Bt(t){let e=[];e.push({key:"ingest.type",value:{stringValue:"codex"}}),e.push({key:"codex.hook",value:{stringValue:t.hook_event_name}});let r={};for(let[n,o]of Object.entries(t))n!=="hook_event_name"&&(r[n]=o);return e.push(...(0,O.attrsFromRecord)(r,"codex",qt)),e}function Gt(){return[{key:"service.name",value:{stringValue:"codex"}},{key:"service.version",value:{stringValue:Nt()}},{key:"telemetry.sdk.name",value:{stringValue:"pinta-codex"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:$e}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:j.default.userInfo().username}},{key:"host.name",value:{stringValue:j.default.hostname()}},{key:"host.arch",value:{stringValue:j.default.arch()}}]}function Ke(t){return(0,O.buildPayload)({traceId:t.traceId,spanName:`codex.${(0,O.snakeCase)(t.event.hook_event_name)}`,attributes:Bt(t.event),resource:Gt(),scope:{name:"pinta-codex",version:$e},now:t.now,guard:t.guard})}async function d(t,e,r){let n=new D(e);await n.flush();let o=new I(e),i=r.trace==="new"?o.newTrace():o.currentTrace(),a=Ke({event:t,traceId:i,guard:r.guard});await n.send(a)}async function Ye(t,e){let r=typeof t.tool_input=="string"?t.tool_input:JSON.stringify(t.tool_input),n=await Ve({spanId:t.session_id??"unknown",toolName:t.tool_name,toolInput:t.tool_input,rawTextFields:{toolInput:r}},e.guardEndpoint);if(await d(t,e,{trace:"current",guard:n}),n?.decision==="DENY"){let o={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:n.reason??"guard_deny"}};process.stdout.write(JSON.stringify(o)+`
14
+ `)}return 0}async function He(t,e){return await d(t,e,{trace:"current"}),0}async function Ze(t,e){return await d(t,e,{trace:"new"}),0}async function We(t,e){return await d(t,e,{trace:"current"}),0}async function ze(t,e){return await d(t,e,{trace:"current"}),0}async function ee(t){return 0}async function Vt(){let t=[];for await(let e of process.stdin)t.push(e);return Buffer.concat(t).toString("utf-8")}async function Ft(){let t=0;try{let e=je(),r=await Vt(),n=JSON.parse(r);Be(n)?t=await ee(n):Ce(n)?t=await Ye(n,e):Ne(n)?t=await He(n,e):Ue(n)?t=await Ze(n,e):Le(n)?t=await We(n,e):qe(n)?t=await ze(n,e):t=await ee(n)}catch(e){process.stderr.write(`[pinta-codex] error: ${e}
15
+ `),t=0}process.exit(t)}Ft();
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@pinta-ai/pinta-codex",
3
- "version": "1.2.4",
3
+ "version": "1.4.0",
4
4
  "description": "Generic OTLP forwarder for Codex hook events",
5
5
  "main": "dist/index.js",
6
6
  "license": "SEE LICENSE IN ./LICENSE",
7
7
  "author": "Pinta AI (https://pinta.sh)",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "https://github.com/awarecorp/pinta-codex.git"
10
+ "url": "git+https://github.com/pinta-ai/pinta-codex.git"
11
11
  },
12
- "homepage": "https://github.com/awarecorp/pinta-codex",
12
+ "homepage": "https://github.com/pinta-ai/pinta-codex",
13
13
  "bugs": {
14
- "url": "https://github.com/awarecorp/pinta-codex/issues"
14
+ "url": "https://github.com/pinta-ai/pinta-codex/issues"
15
15
  },
16
16
  "files": [
17
17
  "dist",
@@ -23,7 +23,8 @@
23
23
  "CHANGELOG.md"
24
24
  ],
25
25
  "scripts": {
26
- "build": "tsc",
26
+ "bump": "node scripts/bump.mjs",
27
+ "build": "tsc --noEmit && esbuild src/index.ts --bundle --platform=node --format=cjs --target=node18 --minify --outfile=dist/index.js",
27
28
  "dev": "tsc --watch",
28
29
  "setup": "npx tsx tools/setup.ts",
29
30
  "doctor": "npx tsx tools/doctor.ts",
@@ -33,11 +34,18 @@
33
34
  "test:otlp": "npx tsx tools/test-otlp.ts",
34
35
  "test:redact": "npx tsx tools/test-redact.ts",
35
36
  "test": "vitest run",
36
- "test:watch": "vitest"
37
+ "test:watch": "vitest",
38
+ "prepublishOnly": "npm run build"
37
39
  },
38
40
  "devDependencies": {
41
+ "@pinta-ai/core": "^0.3.0",
39
42
  "@types/node": "^22.0.0",
43
+ "esbuild": "^0.24.0",
40
44
  "typescript": "^5.7.0",
41
45
  "vitest": "^2.1.0"
46
+ },
47
+ "publishConfig": {
48
+ "registry": "https://registry.npmjs.org",
49
+ "access": "public"
42
50
  }
43
51
  }
@@ -1,12 +0,0 @@
1
- export interface PintaCodexConfig {
2
- pluginRoot: string;
3
- pluginData: string;
4
- tracePath: string;
5
- endpoint?: string;
6
- headers: Record<string, string>;
7
- /** Plan 5: manager-local guard endpoint (or undefined → guard skipped). */
8
- guardEndpoint?: string;
9
- }
10
- export declare function loadConfig(): PintaCodexConfig;
11
- /** Returns true if OTel endpoint is configured (signal to silently disable telemetry). */
12
- export declare function hasOtlpEndpoint(config: PintaCodexConfig): boolean;
@@ -1,125 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.loadConfig = loadConfig;
7
- exports.hasOtlpEndpoint = hasOtlpEndpoint;
8
- const node_fs_1 = __importDefault(require("node:fs"));
9
- const node_os_1 = __importDefault(require("node:os"));
10
- const node_path_1 = __importDefault(require("node:path"));
11
- function readEnvFile(p) {
12
- const out = {};
13
- let content;
14
- try {
15
- content = node_fs_1.default.readFileSync(p, "utf-8");
16
- }
17
- catch {
18
- return out;
19
- }
20
- for (const raw of content.split("\n")) {
21
- const line = raw.trim();
22
- if (!line || line.startsWith("#"))
23
- continue;
24
- const idx = line.indexOf("=");
25
- if (idx < 0)
26
- continue;
27
- const key = line.slice(0, idx).trim();
28
- let value = line.slice(idx + 1).trim();
29
- if ((value.startsWith('"') && value.endsWith('"')) ||
30
- (value.startsWith("'") && value.endsWith("'"))) {
31
- value = value.slice(1, -1);
32
- }
33
- if (key)
34
- out[key] = value;
35
- }
36
- return out;
37
- }
38
- function resolveEndpoint(envFile) {
39
- // Per OTel spec:
40
- // OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = full URL (use as-is)
41
- // OTEL_EXPORTER_OTLP_ENDPOINT = base URL (append /v1/traces)
42
- // We treat values from manager (and the user-facing parity vars) as full URLs.
43
- const tracesEndpoint = process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ??
44
- envFile.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;
45
- if (tracesEndpoint)
46
- return tracesEndpoint;
47
- const baseEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT ??
48
- envFile.OTEL_EXPORTER_OTLP_ENDPOINT;
49
- if (baseEndpoint)
50
- return baseEndpoint.replace(/\/+$/, "") + "/v1/traces";
51
- return (process.env.PINTA_CODEX_ENDPOINT ?? // legacy (full URL)
52
- envFile.PINTA_CODEX_ENDPOINT ?? // legacy
53
- process.env.CLAUDE_PLUGIN_OPTION_ENDPOINT // parity (full URL)
54
- );
55
- }
56
- function resolveHeaders(envFile) {
57
- // Primary: OTel-spec, already in `key=val,key=val` format
58
- if (process.env.OTEL_EXPORTER_OTLP_HEADERS)
59
- return process.env.OTEL_EXPORTER_OTLP_HEADERS;
60
- if (envFile.OTEL_EXPORTER_OTLP_HEADERS)
61
- return envFile.OTEL_EXPORTER_OTLP_HEADERS;
62
- // Legacy: raw token → wrap as x-pinta-relay-token header
63
- if (process.env.PINTA_CODEX_API_KEY) {
64
- return `x-pinta-relay-token=${process.env.PINTA_CODEX_API_KEY}`;
65
- }
66
- if (envFile.PINTA_CODEX_API_KEY) {
67
- return `x-pinta-relay-token=${envFile.PINTA_CODEX_API_KEY}`;
68
- }
69
- // Parity: Claude Code-style userConfig env (raw token, same wrap)
70
- if (process.env.CLAUDE_PLUGIN_OPTION_API_KEY) {
71
- return `x-pinta-relay-token=${process.env.CLAUDE_PLUGIN_OPTION_API_KEY}`;
72
- }
73
- return undefined;
74
- }
75
- function parseHeadersString(raw) {
76
- const out = {};
77
- if (!raw)
78
- return out;
79
- for (const pair of raw.split(",")) {
80
- const [k, ...rest] = pair.split("=");
81
- if (k && rest.length > 0)
82
- out[k.trim()] = rest.join("=").trim();
83
- }
84
- return out;
85
- }
86
- function loadConfig() {
87
- const pluginRoot = process.env.CODEX_PLUGIN_ROOT
88
- ?? process.env.CLAUDE_PLUGIN_ROOT
89
- ?? process.cwd();
90
- const pluginData = process.env.CODEX_PLUGIN_DATA
91
- ?? process.env.CLAUDE_PLUGIN_DATA
92
- ?? node_path_1.default.join(pluginRoot, ".plugin-data");
93
- const codexHome = process.env.CODEX_HOME ?? node_path_1.default.join(node_os_1.default.homedir(), ".codex");
94
- const envFilePath = node_path_1.default.join(codexHome, "pinta-codex.env");
95
- const envFile = node_fs_1.default.existsSync(envFilePath) ? readEnvFile(envFilePath) : {};
96
- const endpoint = resolveEndpoint(envFile);
97
- const headersRaw = resolveHeaders(envFile);
98
- // Plan 5: expose relay token for guard.ts (~/guard/evaluate auth header).
99
- // Parse x-pinta-relay-token from the resolved OTEL headers string so guard.ts
100
- // can read it from process.env.PINTA_RELAY_TOKEN (same as pinta-cc pattern).
101
- if (headersRaw && !process.env.PINTA_RELAY_TOKEN) {
102
- const tokenMatch = headersRaw.match(/x-pinta-relay-token=([^,\s]+)/i);
103
- if (tokenMatch) {
104
- process.env.PINTA_RELAY_TOKEN = tokenMatch[1];
105
- }
106
- }
107
- // Plan 5 v1.2.4: codex CLI does NOT inject pinta-codex.env into hook
108
- // subprocess env (unlike Claude Code's settings.json env-prefix). The hook
109
- // must read PINTA_GUARD_ENDPOINT from envFile too — not just process.env.
110
- // Same pattern as resolveEndpoint/resolveHeaders above.
111
- const guardEndpoint = process.env.PINTA_GUARD_ENDPOINT ?? envFile.PINTA_GUARD_ENDPOINT;
112
- return {
113
- pluginRoot,
114
- pluginData,
115
- tracePath: node_path_1.default.join(pluginData, "trace.json"),
116
- endpoint: endpoint?.replace(/\/+$/, ""),
117
- headers: parseHeadersString(headersRaw ?? ""),
118
- guardEndpoint,
119
- };
120
- }
121
- /** Returns true if OTel endpoint is configured (signal to silently disable telemetry). */
122
- function hasOtlpEndpoint(config) {
123
- return Boolean(config.endpoint);
124
- }
125
- //# sourceMappingURL=config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
@@ -1,13 +0,0 @@
1
- export interface GuardInput {
2
- spanId: string;
3
- toolName?: string;
4
- toolInput?: unknown;
5
- rawTextFields?: Record<string, string>;
6
- }
7
- export interface GuardResult {
8
- decision: 'ALLOW' | 'DENY' | 'REVIEW';
9
- reason: string | null;
10
- durationMs: number;
11
- failOpenReason?: 'timeout' | 'refused' | 'error';
12
- }
13
- export declare function evaluateGuard(input: GuardInput, endpoint: string | undefined): Promise<GuardResult | null>;
@@ -1,41 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.evaluateGuard = evaluateGuard;
4
- const TIMEOUT_MS = 50;
5
- function sleep(ms) {
6
- return new Promise((_, reject) => setTimeout(() => {
7
- const err = new Error('Guard request timed out');
8
- err.name = 'TimeoutError';
9
- reject(err);
10
- }, ms));
11
- }
12
- async function evaluateGuard(input, endpoint) {
13
- if (!endpoint)
14
- return null;
15
- if (process.env.PINTA_GUARD_DISABLED === '1')
16
- return null;
17
- const start = Date.now();
18
- try {
19
- const res = await Promise.race([
20
- fetch(endpoint, {
21
- method: 'POST',
22
- headers: {
23
- 'content-type': 'application/json',
24
- 'x-pinta-relay-token': process.env.PINTA_RELAY_TOKEN ?? '',
25
- },
26
- body: JSON.stringify({ input }),
27
- }),
28
- sleep(TIMEOUT_MS),
29
- ]);
30
- if (res.status !== 200) {
31
- return { decision: 'ALLOW', reason: null, durationMs: Date.now() - start, failOpenReason: 'error' };
32
- }
33
- const body = (await res.json());
34
- return { decision: body.decision, reason: body.reason, durationMs: body.durationMs ?? (Date.now() - start) };
35
- }
36
- catch (err) {
37
- const reason = err.name === 'TimeoutError' ? 'timeout' : 'error';
38
- return { decision: 'ALLOW', reason: null, durationMs: Date.now() - start, failOpenReason: reason };
39
- }
40
- }
41
- //# sourceMappingURL=guard.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/core/guard.ts"],"names":[],"mappings":";;AA0BA,sCA4BC;AAxCD,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACjD,GAAG,CAAC,IAAI,GAAG,cAAc,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,CAAC;IACd,CAAC,EAAE,EAAE,CAAC,CACP,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,aAAa,CACjC,KAAiB,EACjB,QAA4B;IAE5B,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAC7B,KAAK,CAAC,QAAQ,EAAE;gBACd,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,qBAAqB,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE;iBAC3D;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;aAChC,CAAC;YACF,KAAK,CAAC,UAAU,CAAC;SAClB,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC;QACtG,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsF,CAAC;QACrH,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;IAC/G,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAmC,GAAa,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;QAC3G,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC;IACrG,CAAC;AACH,CAAC"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=identity.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/core/identity.ts"],"names":[],"mappings":""}
@@ -1,59 +0,0 @@
1
- import type { BaseEvent } from "./types.js";
2
- import type { GuardResult } from "./guard.js";
3
- export interface OtlpAttribute {
4
- key: string;
5
- value: {
6
- stringValue: string;
7
- } | {
8
- intValue: number;
9
- } | {
10
- doubleValue: number;
11
- } | {
12
- boolValue: boolean;
13
- };
14
- }
15
- export interface OtlpSpan {
16
- traceId: string;
17
- spanId: string;
18
- name: string;
19
- kind: number;
20
- startTimeUnixNano: string;
21
- endTimeUnixNano: string;
22
- attributes: OtlpAttribute[];
23
- }
24
- export interface ResourceSpans {
25
- resource: {
26
- attributes: OtlpAttribute[];
27
- };
28
- scopeSpans: Array<{
29
- scope: {
30
- name: string;
31
- version: string;
32
- };
33
- spans: OtlpSpan[];
34
- }>;
35
- }
36
- export interface OtlpPayload {
37
- resourceSpans: ResourceSpans[];
38
- }
39
- /**
40
- * Convert a 26-char Crockford ULID into 32 lowercase hex chars (16 bytes)
41
- * suitable for an OTLP traceId. Decoding is straightforward because each
42
- * Crockford char carries 5 bits and 26 chars = 130 bits; we keep the low
43
- * 128 bits (the spec already pads timestamp+randomness into 128 bits).
44
- */
45
- export declare function ulidToTraceId(ulid: string): string;
46
- /** Generate a fresh 16-hex-char (8-byte) span ID. */
47
- export declare function newSpanId(): string;
48
- export declare function buildOtlpPayload(args: {
49
- event: BaseEvent;
50
- traceId: string;
51
- now?: number;
52
- guard?: GuardResult | null;
53
- }): OtlpPayload;
54
- /**
55
- * Combine multiple per-hook payloads into a single OTLP payload by
56
- * concatenating their resourceSpans arrays. The Pinta backend's parser
57
- * iterates over resourceSpans natively.
58
- */
59
- export declare function mergeBatch(payloads: OtlpPayload[]): OtlpPayload;