@pinta-ai/pinta-cc 1.8.0 → 1.9.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/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +18 -0
- package/README.md +55 -0
- package/dist/index.js +21 -21
- package/dist/index.mjs +21 -21
- package/package.json +2 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pinta-cc",
|
|
3
3
|
"description": "Generic OTLP forwarder for Claude Code hook events. Converts hook events into OTLP/HTTP spans and sends them to any OpenTelemetry-compatible collector.",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.9.0",
|
|
5
5
|
"license": "PolyForm-Noncommercial-1.0.0",
|
|
6
6
|
"userConfig": {
|
|
7
7
|
"endpoint": {
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to pinta-cc are documented here.
|
|
4
4
|
|
|
5
|
+
## [1.9.0] - 2026-09-22
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Truthful scalar `cc.model` IDs from explicit hook metadata, with source
|
|
10
|
+
preservation and omission of placeholders or stringified objects/arrays.
|
|
11
|
+
- Bounded, read-only assistant transcript lookup tied to the exact session,
|
|
12
|
+
tool-use ID, timestamp and subagent. Missing or uncorrelated evidence stays
|
|
13
|
+
absent; a SessionStart selection is never cached onto later tool hooks.
|
|
14
|
+
- CJS/ESM model and SDK-version wire checks in the Node 18/20/22 CI matrix.
|
|
15
|
+
|
|
16
|
+
### Compatibility
|
|
17
|
+
|
|
18
|
+
- Still requires Pinta Manager 0.1.11 or later. Guard payloads, denial ordering,
|
|
19
|
+
event counts and redaction are unchanged; bundled `@pinta-ai/core` remains
|
|
20
|
+
`^0.8.0`. No new required envelope fields.
|
|
21
|
+
- Host-selected models are not independently verified provider routing.
|
|
22
|
+
|
|
5
23
|
## [1.8.0] - 2026-09-20
|
|
6
24
|
|
|
7
25
|
### Changed
|
package/README.md
CHANGED
|
@@ -128,8 +128,55 @@ when telemetry is disabled.
|
|
|
128
128
|
|-----------|-------|
|
|
129
129
|
| `ingest.type` | `"cc"` (discriminator for aware-backend parser) |
|
|
130
130
|
| `cc.hook` | Hook event name (e.g. `PreToolUse`) |
|
|
131
|
+
| `cc.model` | Exact host-reported scalar model ID, when attributable |
|
|
132
|
+
| `cc.model_source` | Host provenance or adapter evidence (see below) |
|
|
131
133
|
| `cc.<key>` | All other top-level hook event fields (Bronze flattening) |
|
|
132
134
|
|
|
135
|
+
### Model attribution and its limits
|
|
136
|
+
|
|
137
|
+
An explicit hook `model` takes precedence: a string or a descriptor's `id`
|
|
138
|
+
(or `name` when no `id` field exists), not stringified JSON. The source preserves
|
|
139
|
+
the host's supplied `model_source` or defaults to `hook.model`.
|
|
140
|
+
In particular, a SessionStart model is a host-selected model,
|
|
141
|
+
**not proof of the routed response model**, and it is not cached for later
|
|
142
|
+
tool calls.
|
|
143
|
+
|
|
144
|
+
JSON-stringified objects/arrays (including `[object Object]`) are not IDs.
|
|
145
|
+
Provider and requested/response fields remain unchanged. If a transcript
|
|
146
|
+
replaces an unusable model, `model_source` describes that transcript evidence;
|
|
147
|
+
a previous host source is retained as `cc.model_original_source`.
|
|
148
|
+
|
|
149
|
+
For tool hooks without a usable model, the adapter reads the supplied
|
|
150
|
+
`transcript_path` and uses `message.model` only from an `assistant` record whose
|
|
151
|
+
`message.content` contains the exact `tool_use` ID from `tool_use_id`.
|
|
152
|
+
`cc.model_source=transcript.assistant.message` identifies this evidence.
|
|
153
|
+
The record's `sessionId` must match, its timestamp must not be in the future
|
|
154
|
+
relative to the hook (or processing time if no hook timestamp is supplied),
|
|
155
|
+
and its subagent identity must match. The agent is identified by `agent_id` or
|
|
156
|
+
a session-bound `<session_id>/subagents/agent-<id>.jsonl` path, never by agent
|
|
157
|
+
name. Sidechain/child records cannot supply a parent tool's model.
|
|
158
|
+
|
|
159
|
+
PreToolUse, PostToolUse, PostToolUseFailure and permission hooks can use this
|
|
160
|
+
lookup when they carry `tool_use_id`. Stop/lifecycle hooks without an explicit
|
|
161
|
+
model, missing or not-yet-flushed assistant records, unsupported transcript
|
|
162
|
+
formats, ambiguous/conflicting IDs, and records outside the read window remain
|
|
163
|
+
model-less. There is no "latest assistant" fallback, no session-wide
|
|
164
|
+
carry-forward, and no inference from global configuration, process/CLI
|
|
165
|
+
versions, agent names or user prose.
|
|
166
|
+
|
|
167
|
+
Blank, `unknown`, `undefined`, `null`, `n/a`, `none`, `auto` and `default` are
|
|
168
|
+
omitted case-insensitively. Non-ID objects, control characters and IDs longer
|
|
169
|
+
than 512 characters are also rejected. The input event is not mutated, and
|
|
170
|
+
all model attributes still use the existing redaction pipeline.
|
|
171
|
+
|
|
172
|
+
Model lookup is read-only and bounded to a 256 KiB prefix plus a 1 MiB tail
|
|
173
|
+
and 4,096 complete JSONL records, with no subprocess, directory scan or model
|
|
174
|
+
cache. Only absolute `.jsonl` regular files are opened; missing/unreadable
|
|
175
|
+
files, leaf symlinks, malformed records and invalid identities fail quietly,
|
|
176
|
+
and incomplete boundary lines are ignored. Transcript contents are never
|
|
177
|
+
logged or exported. Explicit models and missing tool IDs require no
|
|
178
|
+
model-lookup IO. Guard behavior and event counts are unchanged.
|
|
179
|
+
|
|
133
180
|
## Architecture
|
|
134
181
|
|
|
135
182
|
```
|
|
@@ -184,11 +231,19 @@ npm install
|
|
|
184
231
|
npm run build # tsc → dist/
|
|
185
232
|
npm test # vitest run
|
|
186
233
|
npm run smoke:version # built CJS/ESM hooks -> local collector (after build)
|
|
234
|
+
npm run smoke:model # model attribution -> isolated loopback collector
|
|
187
235
|
npm run mock-server # Generic OTLP collector at http://localhost:3000
|
|
188
236
|
```
|
|
189
237
|
|
|
190
238
|
### Local integration test
|
|
191
239
|
|
|
240
|
+
`smoke:model` exercises fresh built CJS/ESM hooks with isolated HOME/plugin
|
|
241
|
+
data, no real Claude executable, and no manager/guard calls. Supplied, missing,
|
|
242
|
+
placeholder, correlated, cross-session/subagent, future, partial and oversized
|
|
243
|
+
transcript cases are verified. Results go to `.validation/model-smoke.json`.
|
|
244
|
+
Optionally pass `-- --baseline=<previous-built-index.js>` for paired hook
|
|
245
|
+
wall-time comparisons, including Node startup, local HTTP and scheduler noise.
|
|
246
|
+
|
|
192
247
|
`smoke:version` uses isolated plugin data and a loopback collector, not your real
|
|
193
248
|
configuration. On macOS/Linux it supplies an executable fixture by default.
|
|
194
249
|
To check a real native installation (required on Windows), run after building:
|
package/dist/index.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`;
|
|
3
|
-
`)}}readAll(){try{let t=
|
|
4
|
-
`))if(r.trim())try{let o=JSON.parse(r);Array.isArray(o?.payload?.resourceSpans)&&n.push(o)}catch{}return n}catch{return[]}}rewrite(t){try{if(t.length===0){
|
|
1
|
+
"use strict";var en=Object.create;var Re=Object.defineProperty;var tn=Object.getOwnPropertyDescriptor;var nn=Object.getOwnPropertyNames;var rn=Object.getPrototypeOf,on=Object.prototype.hasOwnProperty;var S=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var sn=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of nn(t))!on.call(e,o)&&o!==n&&Re(e,o,{get:()=>t[o],enumerable:!(r=tn(t,o))||r.enumerable});return e};var g=(e,t,n)=>(n=e!=null?en(rn(e)):{},sn(t||!e||!e.__esModule?Re(n,"default",{value:e,enumerable:!0}):n,e));var oe=S(h=>{"use strict";Object.defineProperty(h,"__esModule",{value:!0});h.PATTERNS=h.MAX_BYTES=void 0;h.truncateTo=je;h.truncate=an;h.collectMatches=De;h.resolveOverlaps=Ne;h.applyMatches=Ce;h.redact=cn;h.MAX_BYTES=102400;function je(e,t){let n=Buffer.from(e,"utf-8");return n.length<=t?e:`${n.subarray(0,Math.max(0,t)).toString("utf-8")}\u2026[TRUNCATED:${n.length}]`}function an(e){return je(e,h.MAX_BYTES)}h.PATTERNS=[{type:"aws_access_key",regex:/AKIA[0-9A-Z]{16}/g},{type:"aws_secret_key",regex:/(?:aws[_-]?secret(?:[_-]?(?:access)?[_-]?key)?)\s*[:=]\s*["']?([A-Za-z0-9/+=]{40})(?![A-Za-z0-9/+=])/gi,captureGroup:1},{type:"gcp_service_account",regex:/\{[\s\S]{0,200}?"type"\s*:\s*"service_account"[\s\S]*?\}/g},{type:"github_token",regex:/gh[pousr]_[A-Za-z0-9]{36,}/g},{type:"gitlab_token",regex:/glpat-[A-Za-z0-9_-]{20}/g},{type:"slack_token",regex:/xox[abrsp]-[0-9A-Za-z-]{10,}/g},{type:"openai_key",regex:/sk-(?:proj-)?[A-Za-z0-9_-]{40,}/g},{type:"anthropic_key",regex:/sk-ant-[A-Za-z0-9_-]{50,}/g},{type:"stripe_key",regex:/(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g},{type:"jwt",regex:/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g},{type:"private_key_block",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g},{type:"bearer_token",regex:/bearer\s+([A-Za-z0-9._~+/=-]{12,})/gi,captureGroup:1},{type:"basic_auth",regex:/basic\s+([A-Za-z0-9+/=]{12,})/gi,captureGroup:1},{type:"db_url_password",regex:/\b(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|redis):\/\/[^:\s/]+:([^@\s]+)@/gi,captureGroup:1},{type:"cli_password_flag",regex:/(?:--password|--pass|--pwd)[=\s]([^\s'"]+)/g,captureGroup:1},{type:"cli_password_short",regex:/\s-p([^\s'"]+)/g,captureGroup:1,requireContext:"bash"},{type:"env_var_secret",regex:/^(?:export\s+)?([A-Z][A-Z0-9_]*(?:KEY|SECRET|TOKEN|PASSWORD|PASSWD|PWD|API_KEY)[A-Z0-9_]*)\s*=\s*["']?([^\s"'\n]+)/gm,captureGroup:2}];function De(e,t){let n=[];for(let r of h.PATTERNS){if(r.requireContext&&r.requireContext!==t.context)continue;let o=new RegExp(r.regex.source,r.regex.flags),i;for(;(i=o.exec(e))!==null;){let a=r.captureGroup??0,c=i[a];if(c===void 0){i.index===o.lastIndex&&o.lastIndex++;continue}let u=i.index,l=i.index+i[0].length,m=u+i[0].indexOf(c),k=m+c.length;n.push({start:u,end:l,replaceStart:m,replaceEnd:k,type:r.type}),i.index===o.lastIndex&&o.lastIndex++}}return n}function Ne(e){let t=[...e].sort((o,i)=>o.start!==i.start?o.start-i.start:i.end-i.start-(o.end-o.start)),n=[],r=-1;for(let o of t)o.start<r||(n.push(o),r=o.end);return n}function Ce(e,t){let n=[...t].sort((o,i)=>i.replaceStart-o.replaceStart),r=e;for(let o of n)r=r.slice(0,o.replaceStart)+`[REDACTED:${o.type}]`+r.slice(o.replaceEnd);return r}function cn(e,t={}){if(e.length===0)return e;let n=De(e,t);if(n.length===0)return e;let r=Ne(n);return Ce(e,r)}});var se=S(f=>{"use strict";var un=f&&f.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(f,"__esModule",{value:!0});f.MAX_SPAN_BYTES=void 0;f.ulidToTraceId=Le;f.newSpanId=Fe;f.snakeCase=fn;f.toOtlpValue=$e;f.attrsFromRecord=pn;f.guardAttrs=qe;f.clientAttrs=Ve;f.enforceSpanBudget=Ge;f.buildPayload=mn;f.attachGuard=Ye;f.mergeBatch=gn;var ln=un(require("crypto")),ie=oe(),dn="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Le(e){if(e.length!==26)throw new Error(`ulidToTraceId: expected 26 chars, got ${e.length}`);let t=0n;for(let r of e){let o=dn.indexOf(r);if(o<0)throw new Error(`ulidToTraceId: invalid Crockford char "${r}"`);t=t<<5n|BigInt(o)}let n=(1n<<128n)-1n;return t&=n,t.toString(16).padStart(32,"0")}function Fe(){return ln.default.randomBytes(8).toString("hex")}function fn(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var Ie=new Set;function Y(e,t,n){let r=(0,ie.truncate)(t);if((n.skipRedactKeys??Ie).has(e))return r;let o=(n.bashContextKeys??Ie).has(e)?"bash":void 0;return(0,ie.redact)(r,{context:o})}function $e(e,t,n={}){if(t==null)return null;switch(typeof t){case"string":return{stringValue:Y(e,t,n)};case"boolean":return{boolValue:t};case"number":return Number.isInteger(t)?{intValue:t}:{doubleValue:t};case"object":try{return{stringValue:Y(e,JSON.stringify(t),n)}}catch{return{stringValue:Y(e,String(t),n)}}default:return{stringValue:Y(e,String(t),n)}}}function pn(e,t,n={}){let r=[];for(let[o,i]of Object.entries(e)){let a=`${t}.${o}`,c=$e(a,i,n);c!==null&&r.push({key:a,value:c})}return r}function qe(e){let t=[{key:"pinta.guard.decision",value:{stringValue:e.decision.toLowerCase()}},{key:"pinta.guard.duration_ms",value:{intValue:e.durationMs}}];return e.reason&&t.push({key:"pinta.guard.matched_rule",value:{stringValue:e.reason}}),e.failOpenReason&&t.push({key:"pinta.guard.fail_open_reason",value:{stringValue:e.failOpenReason}}),t}function Ve(e){return[{key:"pinta.client.rtt_ms",value:Number.isInteger(e.rttMs)?{intValue:e.rttMs}:{doubleValue:e.rttMs}},{key:"pinta.client.op",value:{stringValue:e.op}}]}f.MAX_SPAN_BYTES=800*1024;function Ue(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}var Be=1024;function Ge(e,t=f.MAX_SPAN_BYTES){let n=Ue(e);for(let r=0;r<100&&n>t;r++){let o=null,i=0;for(let u of e.attributes){if(!("stringValue"in u.value))continue;let l=Buffer.byteLength(u.value.stringValue,"utf-8");l>i&&(i=l,o=u.value)}if(o===null||i<=Be)break;let a=n-t,c=Math.max(Be,i-a-64);o.stringValue=(0,ie.truncateTo)(o.stringValue,c),n=Ue(e)}return e}function mn(e){let t=e.now??Date.now(),n=(BigInt(t)*1000000n).toString(),r=[...e.attributes],o={traceId:Le(e.traceId),spanId:Fe(),name:e.spanName,kind:e.spanKind??1,startTimeUnixNano:n,endTimeUnixNano:n,attributes:r};Ge(o);let i={resourceSpans:[{resource:{attributes:e.resource},scopeSpans:[{scope:e.scope,spans:[o]}]}]};return Ye(i,e.guard,e.clientTiming)}function Ye(e,t,n){let r=e.resourceSpans[0]?.scopeSpans[0]?.spans[0];if(!r)return e;t&&r.attributes.push(...qe(t));let o=n??(t?.clientRttMs!==void 0?{op:"guard",rttMs:t.clientRttMs}:null);return o&&r.attributes.push(...Ve(o)),e}function gn(e){let t=[];for(let n of e)t.push(...n.resourceSpans);return{resourceSpans:t}}});var ze=S(C=>{"use strict";Object.defineProperty(C,"__esModule",{value:!0});C.GUARD_STATUS_REFUSED=void 0;C.evaluateGuard=vn;var hn=1e4,_n="pinta-core";function z(e,t){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:e,clientRttMs:e,failOpenReason:t}}var yn=new Set(["ALLOW","DENY","REVIEW"]);C.GUARD_STATUS_REFUSED=410;async function vn(e,t,n={}){if(!t||n.disabled)return null;let r=n.timeoutMs??hn,o=Date.now(),i=new AbortController,a=setTimeout(()=>i.abort(),r);try{let c=await fetch(t,{method:"POST",headers:{"content-type":"application/json","user-agent":n.userAgent??_n,"x-pinta-relay-token":n.token??"",...n.agentType?{"x-pinta-agent-type":n.agentType}:{}},body:JSON.stringify(e),signal:i.signal});if(c.status===C.GUARD_STATUS_REFUSED)return z(Date.now()-o,"refused");if(c.status!==200)return z(Date.now()-o,"error");let u=await c.json(),l=u?.durationMs===void 0||typeof u.durationMs=="number"&&Number.isFinite(u.durationMs);if(!u||!yn.has(u.decision)||!l)return z(Date.now()-o,"error");let m=Date.now()-o;return{decision:u.decision,reason:u.reason??null,userMessage:u.userMessage??null,durationMs:u.durationMs??m,clientRttMs:m}}catch(c){let u=c.name,l=u==="AbortError"||u==="TimeoutError"?"timeout":"error";return z(Date.now()-o,l)}finally{clearTimeout(a)}}});var X=S($=>{"use strict";var Pn=$&&$.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty($,"__esModule",{value:!0});$.atomicWriteFileSync=En;var Xe=Pn(require("fs"));function En(e,t){let n=`${e}.${process.pid}.tmp`;Xe.default.writeFileSync(n,t),Xe.default.renameSync(n,e)}});var ue=S(A=>{"use strict";var Ke=A&&A.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(A,"__esModule",{value:!0});A.MemoryRetryQueue=A.DiskRetryQueue=void 0;var _=Ke(require("fs")),K=Ke(require("path")),Sn=X(),Z=1e3,Tn=50,bn=5,ae=class{filePath;lockPath;logPrefix;constructor(t,n){this.filePath=K.default.join(t,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=n}enqueue(t){try{_.default.mkdirSync(K.default.dirname(this.filePath),{recursive:!0});let n=JSON.stringify({savedAt:new Date().toISOString(),payload:t})+`
|
|
2
|
+
`;_.default.appendFileSync(this.filePath,n),this.trim()}catch(n){process.stderr.write(`[${this.logPrefix}] retry-queue enqueue failed: ${n}
|
|
3
|
+
`)}}readAll(){try{let t=_.default.readFileSync(this.filePath,"utf-8"),n=[];for(let r of t.split(`
|
|
4
|
+
`))if(r.trim())try{let o=JSON.parse(r);Array.isArray(o?.payload?.resourceSpans)&&n.push(o)}catch{}return n}catch{return[]}}rewrite(t){try{if(t.length===0){_.default.existsSync(this.filePath)&&_.default.unlinkSync(this.filePath);return}_.default.mkdirSync(K.default.dirname(this.filePath),{recursive:!0}),(0,Sn.atomicWriteFileSync)(this.filePath,t.map(n=>JSON.stringify(n)).join(`
|
|
5
5
|
`)+`
|
|
6
6
|
`)}catch(n){process.stderr.write(`[${this.logPrefix}] retry-queue rewrite failed: ${n}
|
|
7
|
-
`)}}tryAcquireLock(){let t=Date.now();try{
|
|
8
|
-
`),!1}for(;Date.now()-t<
|
|
9
|
-
`),!1;try{let
|
|
10
|
-
`),this.rewrite(t.slice(n))}};
|
|
11
|
-
`),!1}return!0}catch(
|
|
12
|
-
`),!1}finally{clearTimeout(o)}}var
|
|
13
|
-
`);let
|
|
14
|
-
`)}finally{this.queue.release()}}dropIfOversized(t){let n=
|
|
15
|
-
`),!0)}};
|
|
16
|
-
`);return}await
|
|
17
|
-
`);let
|
|
18
|
-
`)}}};
|
|
19
|
-
`)){let r=n.trim();if(!r||r.startsWith("#"))continue;let o=r.indexOf("=");if(o<0)continue;let
|
|
20
|
-
`)}function
|
|
21
|
-
`)}try{(0,
|
|
22
|
-
`)}return 0}async function
|
|
23
|
-
`),e=0}return e}
|
|
7
|
+
`)}}tryAcquireLock(){let t=Date.now();try{_.default.mkdirSync(K.default.dirname(this.lockPath),{recursive:!0})}catch(n){return process.stderr.write(`[${this.logPrefix}] retry-queue lock mkdir failed: ${n}
|
|
8
|
+
`),!1}for(;Date.now()-t<Tn;)try{let n=_.default.openSync(this.lockPath,"wx");return _.default.writeSync(n,String(process.pid)),_.default.closeSync(n),!0}catch(n){if(n?.code!=="EEXIST")return process.stderr.write(`[${this.logPrefix}] retry-queue lock open failed: ${n}
|
|
9
|
+
`),!1;try{let i=_.default.statSync(this.lockPath);if(Date.now()-i.mtimeMs>3e4){_.default.unlinkSync(this.lockPath);continue}}catch{}let r=bn,o=Date.now()+r;for(;Date.now()<o;);}return!1}release(){try{_.default.unlinkSync(this.lockPath)}catch{}}trim(){let t=this.readAll();if(t.length<=Z)return;let n=t.length-Z;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${n} oldest entries
|
|
10
|
+
`),this.rewrite(t.slice(n))}};A.DiskRetryQueue=ae;var ce=class{entries=[];enqueue(t){this.entries.push(t),this.entries.length>Z&&this.entries.splice(0,this.entries.length-Z)}drain(){let t=this.entries;return this.entries=[],t}get size(){return this.entries.length}};A.MemoryRetryQueue=ce});var et=S(d=>{"use strict";Object.defineProperty(d,"__esModule",{value:!0});d.MemoryTransport=d.DiskTransport=d.MAX_POST_BYTES=void 0;d.parseHeadersEnv=We;d.envOptionsResolver=Qe;d.postOtlp=q;var Ze=ue(),He=se(),On=5e3;d.MAX_POST_BYTES=900*1024;function H(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}function Je(e,t,n){let r=[],o=[],i=[],a=0;for(let c of e){let u=t(c);if(u>n){o.push(c);continue}i.length>0&&a+u>n&&(r.push(i),i=[],a=0),i.push(c),a+=u}return i.length>0&&r.push(i),{chunks:r,oversize:o}}function We(e){if(!e)return{};if(typeof e=="object")return{...e};let t={};for(let n of e.split(",")){let[r,...o]=n.split("=");r&&o.length>0&&(t[r.trim()]=o.join("=").trim())}return t}function Qe(){let e=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,t=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,n;return e?n=e.replace(/\/+$/,""):t&&(n=t.replace(/\/+$/,"")+"/v1/traces"),n?{endpoint:n,headers:We(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function q(e,t,n){let r=new AbortController,o=setTimeout(()=>r.abort(),On);try{let i=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify(e),signal:r.signal});if(!i.ok){let a="";try{a=(await i.text()).slice(0,200)}catch{}let c=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(`[${n}] OTLP POST ${i.status} ${t.endpoint}${c}${a?` body=${a}`:""}
|
|
11
|
+
`),!1}return!0}catch(i){return process.stderr.write(`[${n}] OTLP POST failed: ${i.message??String(i)}
|
|
12
|
+
`),!1}finally{clearTimeout(o)}}var le=class{queue;logPrefix;resolveOptions;constructor(t){this.queue=new Ze.DiskRetryQueue(t.pluginData,t.logPrefix),this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions??Qe}async send(t){let n=this.resolveOptions();if(!n||this.dropIfOversized(t))return;await q(t,n,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(t&&this.queue.tryAcquireLock())try{let n=this.queue.readAll();if(n.length===0)return;let{chunks:r,oversize:o}=Je(n,c=>H(c.payload),d.MAX_POST_BYTES);o.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${o.length} oversized retry ${o.length===1?"entry":"entries"} (each > ${d.MAX_POST_BYTES} bytes \u2014 the backend caps the request body, so they can never be delivered)
|
|
13
|
+
`);let i=[].concat(...r),a=0;for(let c of r){if(!await q((0,He.mergeBatch)(c.map(l=>l.payload)),t,this.logPrefix))break;a+=c.length}this.queue.rewrite(i.slice(a))}catch(n){process.stderr.write(`[${this.logPrefix}] flush failed: ${n?.message??String(n)}
|
|
14
|
+
`)}finally{this.queue.release()}}dropIfOversized(t){let n=H(t);return n<=d.MAX_POST_BYTES?!1:(process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (${n} > ${d.MAX_POST_BYTES} bytes) \u2014 undeliverable, not queued
|
|
15
|
+
`),!0)}};d.DiskTransport=le;var de=class{queue=new Ze.MemoryRetryQueue;logPrefix;resolveOptions;constructor(t){this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions}async send(t){let n=this.resolveOptions();if(!n)return;if(H(t)>d.MAX_POST_BYTES){process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (> ${d.MAX_POST_BYTES} bytes) \u2014 undeliverable, not buffered
|
|
16
|
+
`);return}await q(t,n,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(!t)return;let n=this.queue.drain();if(n.length===0)return;let{chunks:r,oversize:o}=Je(n,H,d.MAX_POST_BYTES);o.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${o.length} oversized buffered ${o.length===1?"payload":"payloads"} (each > ${d.MAX_POST_BYTES} bytes \u2014 undeliverable)
|
|
17
|
+
`);let i=[].concat(...r),a=0;for(let c of r){if(!await q((0,He.mergeBatch)(c),t,this.logPrefix))break;a+=c.length}for(let c of i.slice(a))this.queue.enqueue(c)}};d.MemoryTransport=de});var ge=S(j=>{"use strict";var me=j&&j.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0});j.TraceManager=void 0;j.generateUlid=nt;var tt=me(require("fs")),kn=me(require("path")),An=me(require("crypto")),wn=X(),fe="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function nt(){let e=Date.now(),t="",n=e;for(let i=0;i<10;i++)t=fe[n&31]+t,n=Math.floor(n/32);let r=An.default.randomBytes(10),o="";for(let i=0;i<10;i++)o+=fe[r[i]&31];for(;o.length<16;)o+=fe[0];return t+o}var pe=class{tracePath;constructor(t){this.tracePath=t}newTrace(){let t=nt();return this.save(t),t}currentTrace(){try{let t=tt.default.readFileSync(this.tracePath,"utf-8"),{traceId:n}=JSON.parse(t);if(n)return n}catch{}return this.newTrace()}save(t){try{tt.default.mkdirSync(kn.default.dirname(this.tracePath),{recursive:!0}),(0,wn.atomicWriteFileSync)(this.tracePath,JSON.stringify({traceId:t}))}catch(n){process.stderr.write(`[pinta-core] trace persistence failed: ${n}
|
|
18
|
+
`)}}};j.TraceManager=pe});var at=S(w=>{"use strict";var ot=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(w,"__esModule",{value:!0});w.MemorySessionTraceManager=w.DiskSessionTraceManager=void 0;var rt=ot(require("fs")),xn=ot(require("path")),it=ge(),Mn=X(),st=200,he=class{tracePath;maxSessions;constructor(t,n={}){this.tracePath=t,this.maxSessions=n.maxSessions??st}read(){try{let t=JSON.parse(rt.default.readFileSync(this.tracePath,"utf-8"));if(t&&typeof t=="object"&&!("traceId"in t))return t}catch{}return{}}write(t){try{rt.default.mkdirSync(xn.default.dirname(this.tracePath),{recursive:!0});let n=Object.entries(t),r=n.length>this.maxSessions?Object.fromEntries(n.slice(-this.maxSessions)):t;(0,Mn.atomicWriteFileSync)(this.tracePath,JSON.stringify(r))}catch{}}newTrace(t){let n=t||"default",r=(0,it.generateUlid)(),o=this.read();return o[n]=r,this.write(o),r}currentTrace(t){let n=t||"default",r=this.read()[n];return r||this.newTrace(n)}};w.DiskSessionTraceManager=he;var _e=class{map=new Map;maxSessions;constructor(t={}){this.maxSessions=t.maxSessions??st}newTrace(t){let n=t||"default",r=(0,it.generateUlid)();if(this.map.set(n,r),this.map.size>this.maxSessions){let o=this.map.keys().next().value;o!==void 0&&this.map.delete(o)}return r}currentTrace(t){let n=t||"default";return this.map.get(n)??this.newTrace(n)}};w.MemorySessionTraceManager=_e});var lt=S(D=>{"use strict";var ye=D&&D.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(D,"__esModule",{value:!0});D.envFilePath=Dn;D.parseEnvFile=ut;D.loadEnvFile=Nn;var Rn=ye(require("node:fs")),jn=ye(require("node:os")),ct=ye(require("node:path"));function Dn(e,t,n){let r=n?process.env[n]:void 0,o=r&&r.length>0?r:ct.default.join(jn.default.homedir(),e);return ct.default.join(o,t)}function ut(e){let t={};for(let n of e.split(`
|
|
19
|
+
`)){let r=n.trim();if(!r||r.startsWith("#"))continue;let o=r.indexOf("=");if(o<0)continue;let i=r.slice(0,o).trim(),a=r.slice(o+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),i&&(t[i]=a)}return t}function Nn(e){let t;try{t=Rn.default.readFileSync(e,"utf-8")}catch{return}let n=ut(t);for(let[r,o]of Object.entries(n))process.env[r]===void 0&&(process.env[r]=o)}});var M=S(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.GUARD_STATUS_REFUSED=s.evaluateGuard=s.MAX_SPAN_BYTES=s.enforceSpanBudget=s.mergeBatch=s.attachGuard=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 x=oe();Object.defineProperty(s,"redact",{enumerable:!0,get:function(){return x.redact}});Object.defineProperty(s,"truncate",{enumerable:!0,get:function(){return x.truncate}});Object.defineProperty(s,"truncateTo",{enumerable:!0,get:function(){return x.truncateTo}});Object.defineProperty(s,"collectMatches",{enumerable:!0,get:function(){return x.collectMatches}});Object.defineProperty(s,"resolveOverlaps",{enumerable:!0,get:function(){return x.resolveOverlaps}});Object.defineProperty(s,"applyMatches",{enumerable:!0,get:function(){return x.applyMatches}});Object.defineProperty(s,"PATTERNS",{enumerable:!0,get:function(){return x.PATTERNS}});Object.defineProperty(s,"MAX_BYTES",{enumerable:!0,get:function(){return x.MAX_BYTES}});var y=se();Object.defineProperty(s,"ulidToTraceId",{enumerable:!0,get:function(){return y.ulidToTraceId}});Object.defineProperty(s,"newSpanId",{enumerable:!0,get:function(){return y.newSpanId}});Object.defineProperty(s,"snakeCase",{enumerable:!0,get:function(){return y.snakeCase}});Object.defineProperty(s,"toOtlpValue",{enumerable:!0,get:function(){return y.toOtlpValue}});Object.defineProperty(s,"attrsFromRecord",{enumerable:!0,get:function(){return y.attrsFromRecord}});Object.defineProperty(s,"guardAttrs",{enumerable:!0,get:function(){return y.guardAttrs}});Object.defineProperty(s,"clientAttrs",{enumerable:!0,get:function(){return y.clientAttrs}});Object.defineProperty(s,"buildPayload",{enumerable:!0,get:function(){return y.buildPayload}});Object.defineProperty(s,"attachGuard",{enumerable:!0,get:function(){return y.attachGuard}});Object.defineProperty(s,"mergeBatch",{enumerable:!0,get:function(){return y.mergeBatch}});Object.defineProperty(s,"enforceSpanBudget",{enumerable:!0,get:function(){return y.enforceSpanBudget}});Object.defineProperty(s,"MAX_SPAN_BYTES",{enumerable:!0,get:function(){return y.MAX_SPAN_BYTES}});var dt=ze();Object.defineProperty(s,"evaluateGuard",{enumerable:!0,get:function(){return dt.evaluateGuard}});Object.defineProperty(s,"GUARD_STATUS_REFUSED",{enumerable:!0,get:function(){return dt.GUARD_STATUS_REFUSED}});var ft=ue();Object.defineProperty(s,"DiskRetryQueue",{enumerable:!0,get:function(){return ft.DiskRetryQueue}});Object.defineProperty(s,"MemoryRetryQueue",{enumerable:!0,get:function(){return ft.MemoryRetryQueue}});var I=et();Object.defineProperty(s,"DiskTransport",{enumerable:!0,get:function(){return I.DiskTransport}});Object.defineProperty(s,"MemoryTransport",{enumerable:!0,get:function(){return I.MemoryTransport}});Object.defineProperty(s,"postOtlp",{enumerable:!0,get:function(){return I.postOtlp}});Object.defineProperty(s,"envOptionsResolver",{enumerable:!0,get:function(){return I.envOptionsResolver}});Object.defineProperty(s,"parseHeadersEnv",{enumerable:!0,get:function(){return I.parseHeadersEnv}});Object.defineProperty(s,"MAX_POST_BYTES",{enumerable:!0,get:function(){return I.MAX_POST_BYTES}});var pt=ge();Object.defineProperty(s,"TraceManager",{enumerable:!0,get:function(){return pt.TraceManager}});Object.defineProperty(s,"generateUlid",{enumerable:!0,get:function(){return pt.generateUlid}});var mt=at();Object.defineProperty(s,"DiskSessionTraceManager",{enumerable:!0,get:function(){return mt.DiskSessionTraceManager}});Object.defineProperty(s,"MemorySessionTraceManager",{enumerable:!0,get:function(){return mt.MemorySessionTraceManager}});var ve=lt();Object.defineProperty(s,"envFilePath",{enumerable:!0,get:function(){return ve.envFilePath}});Object.defineProperty(s,"parseEnvFile",{enumerable:!0,get:function(){return ve.parseEnvFile}});Object.defineProperty(s,"loadEnvFile",{enumerable:!0,get:function(){return ve.loadEnvFile}})});var V=g(M());function Cn(){return(0,V.envFilePath)(".claude","pinta-cc.env")}function gt(e=Cn()){(0,V.loadEnvFile)(e)}function ht(){process.env.CLAUDE_PLUGIN_OPTION_ENDPOINT&&!process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT&&(process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=process.env.CLAUDE_PLUGIN_OPTION_ENDPOINT),process.env.CLAUDE_PLUGIN_OPTION_API_KEY&&!process.env.OTEL_EXPORTER_OTLP_HEADERS&&(process.env.OTEL_EXPORTER_OTLP_HEADERS=`x-pinta-relay-token=${process.env.CLAUDE_PLUGIN_OPTION_API_KEY}`),!process.env.PINTA_RELAY_TOKEN&&process.env.CLAUDE_PLUGIN_OPTION_API_KEY&&(process.env.PINTA_RELAY_TOKEN=process.env.CLAUDE_PLUGIN_OPTION_API_KEY)}var Pe=g(require("path")),_t=g(M());function yt(){let e=process.env.CLAUDE_PLUGIN_ROOT||process.cwd(),t=process.env.CLAUDE_PLUGIN_DATA||Pe.default.join(e,".plugin-data");return{pluginRoot:e,pluginData:t,tracePath:Pe.default.join(t,"trace.json")}}function Ee(){return(0,_t.envOptionsResolver)()!==null}function vt(e){return e.hook_event_name==="PreToolUse"}function Pt(e){return e.hook_event_name==="PostToolUse"||e.hook_event_name==="PostToolUseFailure"}function Et(e){return e.hook_event_name==="UserPromptSubmit"}function St(e){return e.hook_event_name==="SessionStart"||e.hook_event_name==="SessionEnd"}function Tt(e){return e.hook_event_name==="SubagentStart"||e.hook_event_name==="SubagentStop"}function bt(e){return e.hook_event_name==="Stop"}function Ot(e){return e.hook_event_name==="PermissionRequest"||e.hook_event_name==="PermissionDenied"}var In=new Set(["Notification","TaskCreated","TaskCompleted"]);function kt(e){return In.has(e.hook_event_name)}var Yt=g(M());var At=g(M()),Un=1e4,Bn="pinta-cc/1.9.0";function wt(e,t){return(0,At.evaluateGuard)(e,t,{timeoutMs:Un,token:process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:Bn})}var xt=g(M()),J=class extends xt.DiskTransport{constructor(t){super({pluginData:t.pluginData,logPrefix:"pinta-cc"})}};var Mt=g(M()),W=class extends Mt.TraceManager{constructor(t){super(t.tracePath)}};var re=g(require("os"));var Dt=require("node:child_process"),Q=require("node:crypto"),v=g(require("node:fs")),Nt=g(require("node:os")),p=g(require("node:path")),Ct=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/,Ln=/^v?(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)\s+\(Claude Code\)$/m,Fn=2e3,$n=24*60*60*1e3,qn=3e4,Te=8,It="claude-version.json",U=new Map;function O(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"?e.code:"UNKNOWN"}function P(e){process.stderr.write(`[pinta-cc] CLI version: ${e}
|
|
20
|
+
`)}function ee(e){return O(e)==="ENOENT"||O(e)==="ENOTDIR"}function Vn(){let e=process.env.CLAUDE_CODE_EXECPATH,t=process.platform==="win32"?["claude.exe","claude.cmd"]:["claude"],n;if(e)n=[e];else{let r=(process.env.PATH??"").split(p.default.delimiter).filter(o=>p.default.isAbsolute(o));try{r.push(p.default.join(Nt.default.homedir(),".local","bin"))}catch(o){P(`native install directory lookup failed (${O(o)})`)}n=r.flatMap(o=>t.map(i=>p.default.join(o,i)))}for(let r of new Set(n))try{let o=v.default.realpathSync(r),i=v.default.statSync(o);if(!i.isFile())continue;return!e&&process.platform!=="win32"&&v.default.accessSync(o,v.default.constants.X_OK),{file:o,fingerprint:(0,Q.createHash)("sha256").update(JSON.stringify([o,i.ino,i.size,i.mtimeMs,i.ctimeMs])).digest("hex")}}catch(o){ee(o)||P(`executable lookup failed (${O(o)})`)}return P(e?"configured executable is unavailable":"no Claude executable found in PATH or ~/.local/bin"),null}function Se(e){let t;try{t=JSON.parse(v.default.readFileSync(e,"utf8"))}catch(n){return ee(n)||P(`package metadata could not be read (${n instanceof SyntaxError?"INVALID_JSON":O(n)})`),null}return typeof t!="object"||t===null||!("name"in t)||!("version"in t)||typeof t.name!="string"||typeof t.version!="string"||!Ct.test(t.version)?null:t.name==="@anthropic-ai/claude-code"||t.name.startsWith("@anthropic-ai/claude-code-")?t.version:null}function Gn(e){let t=p.default.dirname(e),n=p.default.basename(t)===".bin"&&/^claude(?:\.cmd)?$/i.test(p.default.basename(e));for(let r=0;r<6;r++){let o=Se(p.default.join(t,"package.json"));if(o)return o;if(p.default.basename(e).toLowerCase()==="claude.cmd"&&r===0){let a=Se(p.default.join(t,"node_modules","@anthropic-ai","claude-code","package.json"));if(a)return a}if(n&&p.default.basename(t)==="node_modules"){let a=Se(p.default.join(t,"@anthropic-ai","claude-code","package.json"));if(a)return a}let i=p.default.dirname(t);if(i===t)break;t=i}return null}function Yn(e){return typeof e=="object"&&e!==null&&"fingerprint"in e&&typeof e.fingerprint=="string"&&/^[0-9a-f]{64}$/.test(e.fingerprint)&&"version"in e&&(e.version===null||typeof e.version=="string"&&Ct.test(e.version))&&"checkedAt"in e&&typeof e.checkedAt=="number"&&Number.isFinite(e.checkedAt)}function Rt(e,t){let n=t-e.checkedAt;return n>=0&&n<(e.version===null?qn:$n)}function zn(e){if(!e)return[];let t=p.default.join(e,It);try{if(v.default.statSync(t).size>16384)return P("oversized version cache ignored"),[];let n=JSON.parse(v.default.readFileSync(t,"utf8"));if(Array.isArray(n)&&n.length<=Te&&n.every(Yn))return n;P("invalid version cache ignored")}catch(n){ee(n)||P(`version cache read failed (${n instanceof SyntaxError?"INVALID_JSON":O(n)})`)}return[]}function jt(e){for(U.delete(e.fingerprint),U.set(e.fingerprint,e);U.size>Te;){let t=U.keys().next().value;t!==void 0&&U.delete(t)}}function Xn(e,t){if(!e)return;let n=p.default.join(e,It),r=`${n}.${process.pid}.${(0,Q.randomUUID)()}.tmp`;try{v.default.mkdirSync(e,{recursive:!0,mode:448}),v.default.writeFileSync(r,JSON.stringify(t),{encoding:"utf8",mode:384,flag:"wx"}),v.default.renameSync(r,n)}catch(o){P(`version cache write failed (${O(o)})`)}finally{try{v.default.unlinkSync(r)}catch(o){ee(o)||P(`temporary version cache cleanup failed (${O(o)})`)}}}function Kn(e){if(/\.(cmd|bat|ps1)$/i.test(e))return P("command shim has no readable Claude package metadata"),null;let t=(0,Dt.spawnSync)(e,["--version"],{encoding:"utf8",stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0,timeout:Fn,killSignal:"SIGKILL",maxBuffer:4096});if(t.error||t.status!==0)return P(`version probe failed (${t.error?O(t.error):`exit ${t.status??t.signal}`})`),null;let n=Ln.exec(t.stdout.trim())?.[1];return n||(P("version probe did not identify Claude Code"),null)}function Ut(e){let t=Vn();if(!t)return"unknown";let n=Gn(t.file);if(n)return n;let r=Date.now(),o=zn(e),i=[U.get(t.fingerprint),...o].find(c=>c&&c.fingerprint===t.fingerprint&&Rt(c,r));if(i)return jt(i),i.version??"unknown";let a={fingerprint:t.fingerprint,version:Kn(t.file),checkedAt:Date.now()};return jt(a),Xn(e,[...o.filter(c=>c.fingerprint!==a.fingerprint&&Rt(c,a.checkedAt)),a].slice(-Te)),a.version??"unknown"}var R=g(require("node:path"));var T=g(require("node:fs")),be=g(require("node:path")),Zn=new Set(["","unknown","undefined","null","n/a","none","auto","default"]),Hn=256*1024,Jn=1024*1024,Wn=4096;function N(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0}function Oe(e){let t=N(e),n=t?"id"in t?t.id:t.name:e;if(typeof n!="string")return;let r=n.trim();if(!(r.startsWith("{")||r.startsWith("[")))return r.length<=512&&!/[\u0000-\u001f\u007f]/.test(r)&&!Zn.has(r.toLowerCase())?r:void 0}function Bt(e,t){delete e.model,t&&(e.model=t.name,!(t.source==="hook.model"&&e.model_source!==void 0)&&(e.model_source!==void 0&&(e.model_original_source=e.model_source),e.model_source=t.source))}function B(e){return typeof e=="string"&&/^[A-Za-z0-9][A-Za-z0-9_.:-]{0,255}$/.test(e)?e:void 0}function te(e){let t=typeof e=="number"?e:typeof e=="string"&&/^\d{4}-\d{2}-\d{2}T/.test(e)?Date.parse(e):NaN;return Number.isFinite(t)&&t>=0?t:void 0}function Lt(e,t){let n=e.timestamp===void 0?te(t):te(e.timestamp);return n!==void 0&&n<=t?n:void 0}function Ft(e){if(typeof e!="string"||e.length>4096||/[\u0000-\u001f]/.test(e)||!be.default.isAbsolute(e)||be.default.extname(e)!==".jsonl")return;let t;try{t=T.default.openSync(e,T.default.constants.O_RDONLY|T.default.constants.O_NONBLOCK|(T.default.constants.O_NOFOLLOW??0));let n=T.default.fstatSync(t);if(!n.isFile()||!Number.isSafeInteger(n.size)||n.size<=0)return;let r=Buffer.alloc(Math.min(n.size,Hn));if(T.default.readSync(t,r,0,r.length,0)!==r.length)return;let o=r.indexOf(10),i;if(o>=0)try{i=N(JSON.parse(r.toString("utf8",0,o)))}catch{}let a=Math.max(0,n.size-Jn),c=n.size<=r.length?r:Buffer.alloc(n.size-a);if(c!==r&&T.default.readSync(t,c,0,c.length,a)!==c.length)return;let u=T.default.fstatSync(t);if(u.size<n.size||u.size===n.size&&u.mtimeMs!==n.mtimeMs)return;let l=a>0?c.indexOf(10)+1:0,m=c.lastIndexOf(10);if(a>0&&l===0||m<l)return;let k=[],b=0;for(;m>l&&b<Wn;){let G=c.lastIndexOf(10,m-1),F=Math.max(l,G+1),xe=c.toString("utf8",F,m).trim();if(xe){let Me=N(JSON.parse(xe));Me&&k.push(Me)}m=F-1,b++}return k.reverse(),{first:i,rows:k,complete:a===0&&m<0&&c[c.length-1]===10}}catch{return}finally{if(t!==void 0)try{T.default.closeSync(t)}catch{}}}function $t(e){let t=e[0];return t&&e.every(n=>n?.name===t.name)?t:void 0}var Qn=new Set(["PreToolUse","PostToolUse","PostToolUseFailure","PermissionRequest","PermissionDenied"]);function er(e,t){let n=R.default.dirname(e);if(R.default.basename(n)!=="subagents"||R.default.basename(R.default.dirname(n))!==t)return;let r=/^agent-(.+)\.jsonl$/.exec(R.default.basename(e));return B(r?.[1])}function qt(e,t){let n=Oe(e.model);if(n)return{name:n,source:"hook.model"};try{return tr(e,t)}catch{return}}function tr(e,t){if(!Qn.has(e.hook_event_name))return;let n=B(e.session_id),r=B(e.tool_use_id),o=Lt(e,t);if(!n||!r||o===void 0||typeof e.transcript_path!="string")return;let i=er(e.transcript_path,n),a=e.agent_id===void 0?i:B(e.agent_id);if(e.agent_id!==void 0&&!a||i!==void 0&&i!==a||!a&&e.agent_type!==void 0||R.default.basename(R.default.dirname(e.transcript_path))==="subagents"&&!i)return;let c=Ft(e.transcript_path);if(!c)return;let u=[];for(let l of c.rows){let m=te(l.timestamp);if(l.type!=="assistant"||l.sessionId!==n||m===void 0||m>o)continue;let k=l.agentId===void 0?void 0:B(l.agentId);if(k!==a||l.agentId!==void 0&&!k||l.isSidechain===!0&&!a)continue;let b=N(l.message);if(!b||b.role!==void 0&&b.role!=="assistant"||!Array.isArray(b.content)||!b.content.some(F=>N(F)?.type==="tool_use"&&N(F)?.id===r))continue;let G=Oe(b.model);u.push(G?{name:G,source:"transcript.assistant.message"}:void 0)}return $t(u)}var L=g(M()),ne;function nr(){if(ne===void 0)try{ne=re.default.userInfo().username}catch{ne=process.env.USER??process.env.LOGNAME??(typeof process.getuid=="function"?String(process.getuid()):"unknown")}return ne}var Vt="1.9.0",rr=new Set(["cc.hook","cc.tool_name","cc.tool_use_id","cc.session_id","cc.transcript_path","cc.cwd","cc.permission_mode"]),or=new Set(["cc.tool_input","cc.tool_response"]),ir={skipRedactKeys:rr,bashContextKeys:or};function sr(e,t){let n=[];n.push({key:"ingest.type",value:{stringValue:"cc"}}),n.push({key:"cc.hook",value:{stringValue:e.hook_event_name}});let r={};for(let[o,i]of Object.entries(e))o!=="hook_event_name"&&(r[o]=i);return Bt(r,qt(e,t)),n.push(...(0,L.attrsFromRecord)(r,"cc",ir)),n}function ar(e){return[{key:"service.name",value:{stringValue:"claude-code"}},{key:"service.version",value:{stringValue:Ut(e)}},{key:"telemetry.sdk.name",value:{stringValue:"pinta-cc"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:Vt}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:nr()}},{key:"host.name",value:{stringValue:re.default.hostname()}},{key:"host.arch",value:{stringValue:re.default.arch()}}]}function Gt(e){let t=e.now??Date.now();return(0,L.buildPayload)({traceId:e.traceId,spanName:`cc.${(0,L.snakeCase)(e.event.hook_event_name)}`,attributes:sr(e.event,t),resource:ar(e.versionCacheDir),scope:{name:"pinta-cc",version:Vt},now:t})}function ke(e,t,n={}){let r=new W(t),o=n.traceMode==="new"?r.newTrace():r.currentTrace();return Gt({event:e,traceId:o,versionCacheDir:t.pluginData})}async function Ae(e,t){if(!Ee())return;let n=new J(t);await n.flush(),await n.send(e)}async function E(e,t,n={}){Ee()&&await Ae(ke(e,t,n),t)}async function zt(e,t){let n=ke(e,t),r=await wt(n,process.env.PINTA_GUARD_ENDPOINT);if(r?.decision==="DENY"){let i={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:r.userMessage??r.reason??"guard_deny"}};process.stdout.write(JSON.stringify(i)+`
|
|
21
|
+
`)}try{(0,Yt.attachGuard)(n,r),await Ae(n,t)}catch(o){process.stderr.write(`[pinta-cc] telemetry emit failed: ${o}
|
|
22
|
+
`)}return 0}async function Xt(e,t){return await E(e,t),0}async function Kt(e,t){return await E(e,t,{traceMode:"new"}),0}async function Zt(e,t){return await E(e,t),0}async function Ht(e,t){return await E(e,t),0}async function Jt(e,t){return await E(e,t),0}async function Wt(e,t){return await E(e,t),0}async function we(e){return 0}async function cr(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function Qt(){ht();let e=0;try{let t=yt(),n=await cr(),r=JSON.parse(n);kt(r)?e=await we(r):vt(r)?e=await zt(r,t):Pt(r)?e=await Xt(r,t):Et(r)?e=await Kt(r,t):St(r)?e=await Zt(r,t):Tt(r)?e=await Ht(r,t):bt(r)?e=await Jt(r,t):Ot(r)?e=await Wt(r,t):e=await we(r)}catch(t){process.stderr.write(`[pinta-cc] error: ${t}
|
|
23
|
+
`),e=0}return e}gt();async function ur(){let e=await Qt();process.exit(e)}ur();
|
package/dist/index.mjs
CHANGED
|
@@ -1,24 +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(r.trim())try{let o=JSON.parse(r);Array.isArray(o?.payload?.resourceSpans)&&n.push(o)}catch{}return n}catch{return[]}}rewrite(t){try{if(t.length===0){
|
|
2
|
+
var nn=Object.create;var Me=Object.defineProperty;var rn=Object.getOwnPropertyDescriptor;var on=Object.getOwnPropertyNames;var sn=Object.getPrototypeOf,an=Object.prototype.hasOwnProperty;var _=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var S=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var cn=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of on(t))!an.call(e,o)&&o!==n&&Me(e,o,{get:()=>t[o],enumerable:!(r=rn(t,o))||r.enumerable});return e};var R=(e,t,n)=>(n=e!=null?nn(sn(e)):{},cn(t||!e||!e.__esModule?Me(n,"default",{value:e,enumerable:!0}):n,e));var oe=S(g=>{"use strict";Object.defineProperty(g,"__esModule",{value:!0});g.PATTERNS=g.MAX_BYTES=void 0;g.truncateTo=Re;g.truncate=un;g.collectMatches=je;g.resolveOverlaps=De;g.applyMatches=Ie;g.redact=ln;g.MAX_BYTES=102400;function Re(e,t){let n=Buffer.from(e,"utf-8");return n.length<=t?e:`${n.subarray(0,Math.max(0,t)).toString("utf-8")}\u2026[TRUNCATED:${n.length}]`}function un(e){return Re(e,g.MAX_BYTES)}g.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 je(e,t){let n=[];for(let r of g.PATTERNS){if(r.requireContext&&r.requireContext!==t.context)continue;let o=new RegExp(r.regex.source,r.regex.flags),i;for(;(i=o.exec(e))!==null;){let a=r.captureGroup??0,c=i[a];if(c===void 0){i.index===o.lastIndex&&o.lastIndex++;continue}let u=i.index,l=i.index+i[0].length,p=u+i[0].indexOf(c),k=p+c.length;n.push({start:u,end:l,replaceStart:p,replaceEnd:k,type:r.type}),i.index===o.lastIndex&&o.lastIndex++}}return n}function De(e){let t=[...e].sort((o,i)=>o.start!==i.start?o.start-i.start:i.end-i.start-(o.end-o.start)),n=[],r=-1;for(let o of t)o.start<r||(n.push(o),r=o.end);return n}function Ie(e,t){let n=[...t].sort((o,i)=>i.replaceStart-o.replaceStart),r=e;for(let o of n)r=r.slice(0,o.replaceStart)+`[REDACTED:${o.type}]`+r.slice(o.replaceEnd);return r}function ln(e,t={}){if(e.length===0)return e;let n=je(e,t);if(n.length===0)return e;let r=De(n);return Ie(e,r)}});var se=S(d=>{"use strict";var fn=d&&d.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(d,"__esModule",{value:!0});d.MAX_SPAN_BYTES=void 0;d.ulidToTraceId=Be;d.newSpanId=Le;d.snakeCase=mn;d.toOtlpValue=Fe;d.attrsFromRecord=gn;d.guardAttrs=$e;d.clientAttrs=qe;d.enforceSpanBudget=Ve;d.buildPayload=hn;d.attachGuard=Ge;d.mergeBatch=_n;var dn=fn(_("crypto")),ie=oe(),pn="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Be(e){if(e.length!==26)throw new Error(`ulidToTraceId: expected 26 chars, got ${e.length}`);let t=0n;for(let r of e){let o=pn.indexOf(r);if(o<0)throw new Error(`ulidToTraceId: invalid Crockford char "${r}"`);t=t<<5n|BigInt(o)}let n=(1n<<128n)-1n;return t&=n,t.toString(16).padStart(32,"0")}function Le(){return dn.default.randomBytes(8).toString("hex")}function mn(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var Ne=new Set;function X(e,t,n){let r=(0,ie.truncate)(t);if((n.skipRedactKeys??Ne).has(e))return r;let o=(n.bashContextKeys??Ne).has(e)?"bash":void 0;return(0,ie.redact)(r,{context:o})}function Fe(e,t,n={}){if(t==null)return null;switch(typeof t){case"string":return{stringValue:X(e,t,n)};case"boolean":return{boolValue:t};case"number":return Number.isInteger(t)?{intValue:t}:{doubleValue:t};case"object":try{return{stringValue:X(e,JSON.stringify(t),n)}}catch{return{stringValue:X(e,String(t),n)}}default:return{stringValue:X(e,String(t),n)}}}function gn(e,t,n={}){let r=[];for(let[o,i]of Object.entries(e)){let a=`${t}.${o}`,c=Fe(a,i,n);c!==null&&r.push({key:a,value:c})}return r}function $e(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 qe(e){return[{key:"pinta.client.rtt_ms",value:Number.isInteger(e.rttMs)?{intValue:e.rttMs}:{doubleValue:e.rttMs}},{key:"pinta.client.op",value:{stringValue:e.op}}]}d.MAX_SPAN_BYTES=800*1024;function Ce(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}var Ue=1024;function Ve(e,t=d.MAX_SPAN_BYTES){let n=Ce(e);for(let r=0;r<100&&n>t;r++){let o=null,i=0;for(let u of e.attributes){if(!("stringValue"in u.value))continue;let l=Buffer.byteLength(u.value.stringValue,"utf-8");l>i&&(i=l,o=u.value)}if(o===null||i<=Ue)break;let a=n-t,c=Math.max(Ue,i-a-64);o.stringValue=(0,ie.truncateTo)(o.stringValue,c),n=Ce(e)}return e}function hn(e){let t=e.now??Date.now(),n=(BigInt(t)*1000000n).toString(),r=[...e.attributes],o={traceId:Be(e.traceId),spanId:Le(),name:e.spanName,kind:e.spanKind??1,startTimeUnixNano:n,endTimeUnixNano:n,attributes:r};Ve(o);let i={resourceSpans:[{resource:{attributes:e.resource},scopeSpans:[{scope:e.scope,spans:[o]}]}]};return Ge(i,e.guard,e.clientTiming)}function Ge(e,t,n){let r=e.resourceSpans[0]?.scopeSpans[0]?.spans[0];if(!r)return e;t&&r.attributes.push(...$e(t));let o=n??(t?.clientRttMs!==void 0?{op:"guard",rttMs:t.clientRttMs}:null);return o&&r.attributes.push(...qe(o)),e}function _n(e){let t=[];for(let n of e)t.push(...n.resourceSpans);return{resourceSpans:t}}});var ze=S(C=>{"use strict";Object.defineProperty(C,"__esModule",{value:!0});C.GUARD_STATUS_REFUSED=void 0;C.evaluateGuard=En;var yn=1e4,Pn="pinta-core";function K(e,t){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:e,clientRttMs:e,failOpenReason:t}}var vn=new Set(["ALLOW","DENY","REVIEW"]);C.GUARD_STATUS_REFUSED=410;async function En(e,t,n={}){if(!t||n.disabled)return null;let r=n.timeoutMs??yn,o=Date.now(),i=new AbortController,a=setTimeout(()=>i.abort(),r);try{let c=await fetch(t,{method:"POST",headers:{"content-type":"application/json","user-agent":n.userAgent??Pn,"x-pinta-relay-token":n.token??"",...n.agentType?{"x-pinta-agent-type":n.agentType}:{}},body:JSON.stringify(e),signal:i.signal});if(c.status===C.GUARD_STATUS_REFUSED)return K(Date.now()-o,"refused");if(c.status!==200)return K(Date.now()-o,"error");let u=await c.json(),l=u?.durationMs===void 0||typeof u.durationMs=="number"&&Number.isFinite(u.durationMs);if(!u||!vn.has(u.decision)||!l)return K(Date.now()-o,"error");let p=Date.now()-o;return{decision:u.decision,reason:u.reason??null,userMessage:u.userMessage??null,durationMs:u.durationMs??p,clientRttMs:p}}catch(c){let u=c.name,l=u==="AbortError"||u==="TimeoutError"?"timeout":"error";return K(Date.now()-o,l)}finally{clearTimeout(a)}}});var Z=S(q=>{"use strict";var Sn=q&&q.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(q,"__esModule",{value:!0});q.atomicWriteFileSync=Tn;var Ye=Sn(_("fs"));function Tn(e,t){let n=`${e}.${process.pid}.tmp`;Ye.default.writeFileSync(n,t),Ye.default.renameSync(n,e)}});var ue=S(A=>{"use strict";var Xe=A&&A.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(A,"__esModule",{value:!0});A.MemoryRetryQueue=A.DiskRetryQueue=void 0;var h=Xe(_("fs")),W=Xe(_("path")),bn=Z(),H=1e3,On=50,kn=5,ae=class{filePath;lockPath;logPrefix;constructor(t,n){this.filePath=W.default.join(t,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=n}enqueue(t){try{h.default.mkdirSync(W.default.dirname(this.filePath),{recursive:!0});let n=JSON.stringify({savedAt:new Date().toISOString(),payload:t})+`
|
|
3
|
+
`;h.default.appendFileSync(this.filePath,n),this.trim()}catch(n){process.stderr.write(`[${this.logPrefix}] retry-queue enqueue failed: ${n}
|
|
4
|
+
`)}}readAll(){try{let t=h.default.readFileSync(this.filePath,"utf-8"),n=[];for(let r of t.split(`
|
|
5
|
+
`))if(r.trim())try{let o=JSON.parse(r);Array.isArray(o?.payload?.resourceSpans)&&n.push(o)}catch{}return n}catch{return[]}}rewrite(t){try{if(t.length===0){h.default.existsSync(this.filePath)&&h.default.unlinkSync(this.filePath);return}h.default.mkdirSync(W.default.dirname(this.filePath),{recursive:!0}),(0,bn.atomicWriteFileSync)(this.filePath,t.map(n=>JSON.stringify(n)).join(`
|
|
6
6
|
`)+`
|
|
7
7
|
`)}catch(n){process.stderr.write(`[${this.logPrefix}] retry-queue rewrite failed: ${n}
|
|
8
|
-
`)}}tryAcquireLock(){let t=Date.now();try{
|
|
9
|
-
`),!1}for(;Date.now()-t<
|
|
10
|
-
`),!1;try{let
|
|
11
|
-
`),this.rewrite(t.slice(n))}};
|
|
12
|
-
`),!1}return!0}catch(
|
|
13
|
-
`),!1}finally{clearTimeout(o)}}var
|
|
14
|
-
`);let
|
|
15
|
-
`)}finally{this.queue.release()}}dropIfOversized(t){let n=
|
|
16
|
-
`),!0)}};
|
|
17
|
-
`);return}await
|
|
18
|
-
`);let
|
|
19
|
-
`)}}};
|
|
20
|
-
`)){let r=n.trim();if(!r||r.startsWith("#"))continue;let o=r.indexOf("=");if(o<0)continue;let
|
|
21
|
-
`)}function
|
|
22
|
-
`)}try{(0,
|
|
23
|
-
`)}return 0}async function
|
|
24
|
-
`),e=0}return e}import{opendir as
|
|
8
|
+
`)}}tryAcquireLock(){let t=Date.now();try{h.default.mkdirSync(W.default.dirname(this.lockPath),{recursive:!0})}catch(n){return process.stderr.write(`[${this.logPrefix}] retry-queue lock mkdir failed: ${n}
|
|
9
|
+
`),!1}for(;Date.now()-t<On;)try{let n=h.default.openSync(this.lockPath,"wx");return h.default.writeSync(n,String(process.pid)),h.default.closeSync(n),!0}catch(n){if(n?.code!=="EEXIST")return process.stderr.write(`[${this.logPrefix}] retry-queue lock open failed: ${n}
|
|
10
|
+
`),!1;try{let i=h.default.statSync(this.lockPath);if(Date.now()-i.mtimeMs>3e4){h.default.unlinkSync(this.lockPath);continue}}catch{}let r=kn,o=Date.now()+r;for(;Date.now()<o;);}return!1}release(){try{h.default.unlinkSync(this.lockPath)}catch{}}trim(){let t=this.readAll();if(t.length<=H)return;let n=t.length-H;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${n} oldest entries
|
|
11
|
+
`),this.rewrite(t.slice(n))}};A.DiskRetryQueue=ae;var ce=class{entries=[];enqueue(t){this.entries.push(t),this.entries.length>H&&this.entries.splice(0,this.entries.length-H)}drain(){let t=this.entries;return this.entries=[],t}get size(){return this.entries.length}};A.MemoryRetryQueue=ce});var Qe=S(f=>{"use strict";Object.defineProperty(f,"__esModule",{value:!0});f.MemoryTransport=f.DiskTransport=f.MAX_POST_BYTES=void 0;f.parseHeadersEnv=He;f.envOptionsResolver=Je;f.postOtlp=V;var Ke=ue(),Ze=se(),An=5e3;f.MAX_POST_BYTES=900*1024;function J(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}function We(e,t,n){let r=[],o=[],i=[],a=0;for(let c of e){let u=t(c);if(u>n){o.push(c);continue}i.length>0&&a+u>n&&(r.push(i),i=[],a=0),i.push(c),a+=u}return i.length>0&&r.push(i),{chunks:r,oversize:o}}function He(e){if(!e)return{};if(typeof e=="object")return{...e};let t={};for(let n of e.split(",")){let[r,...o]=n.split("=");r&&o.length>0&&(t[r.trim()]=o.join("=").trim())}return t}function Je(){let e=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,t=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,n;return e?n=e.replace(/\/+$/,""):t&&(n=t.replace(/\/+$/,"")+"/v1/traces"),n?{endpoint:n,headers:He(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function V(e,t,n){let r=new AbortController,o=setTimeout(()=>r.abort(),An);try{let i=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify(e),signal:r.signal});if(!i.ok){let a="";try{a=(await i.text()).slice(0,200)}catch{}let c=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(`[${n}] OTLP POST ${i.status} ${t.endpoint}${c}${a?` body=${a}`:""}
|
|
12
|
+
`),!1}return!0}catch(i){return process.stderr.write(`[${n}] OTLP POST failed: ${i.message??String(i)}
|
|
13
|
+
`),!1}finally{clearTimeout(o)}}var le=class{queue;logPrefix;resolveOptions;constructor(t){this.queue=new Ke.DiskRetryQueue(t.pluginData,t.logPrefix),this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions??Je}async send(t){let n=this.resolveOptions();if(!n||this.dropIfOversized(t))return;await V(t,n,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(t&&this.queue.tryAcquireLock())try{let n=this.queue.readAll();if(n.length===0)return;let{chunks:r,oversize:o}=We(n,c=>J(c.payload),f.MAX_POST_BYTES);o.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${o.length} oversized retry ${o.length===1?"entry":"entries"} (each > ${f.MAX_POST_BYTES} bytes \u2014 the backend caps the request body, so they can never be delivered)
|
|
14
|
+
`);let i=[].concat(...r),a=0;for(let c of r){if(!await V((0,Ze.mergeBatch)(c.map(l=>l.payload)),t,this.logPrefix))break;a+=c.length}this.queue.rewrite(i.slice(a))}catch(n){process.stderr.write(`[${this.logPrefix}] flush failed: ${n?.message??String(n)}
|
|
15
|
+
`)}finally{this.queue.release()}}dropIfOversized(t){let n=J(t);return n<=f.MAX_POST_BYTES?!1:(process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (${n} > ${f.MAX_POST_BYTES} bytes) \u2014 undeliverable, not queued
|
|
16
|
+
`),!0)}};f.DiskTransport=le;var fe=class{queue=new Ke.MemoryRetryQueue;logPrefix;resolveOptions;constructor(t){this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions}async send(t){let n=this.resolveOptions();if(!n)return;if(J(t)>f.MAX_POST_BYTES){process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (> ${f.MAX_POST_BYTES} bytes) \u2014 undeliverable, not buffered
|
|
17
|
+
`);return}await V(t,n,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(!t)return;let n=this.queue.drain();if(n.length===0)return;let{chunks:r,oversize:o}=We(n,J,f.MAX_POST_BYTES);o.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${o.length} oversized buffered ${o.length===1?"payload":"payloads"} (each > ${f.MAX_POST_BYTES} bytes \u2014 undeliverable)
|
|
18
|
+
`);let i=[].concat(...r),a=0;for(let c of r){if(!await V((0,Ze.mergeBatch)(c),t,this.logPrefix))break;a+=c.length}for(let c of i.slice(a))this.queue.enqueue(c)}};f.MemoryTransport=fe});var ge=S(j=>{"use strict";var me=j&&j.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0});j.TraceManager=void 0;j.generateUlid=tt;var et=me(_("fs")),wn=me(_("path")),xn=me(_("crypto")),Mn=Z(),de="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function tt(){let e=Date.now(),t="",n=e;for(let i=0;i<10;i++)t=de[n&31]+t,n=Math.floor(n/32);let r=xn.default.randomBytes(10),o="";for(let i=0;i<10;i++)o+=de[r[i]&31];for(;o.length<16;)o+=de[0];return t+o}var pe=class{tracePath;constructor(t){this.tracePath=t}newTrace(){let t=tt();return this.save(t),t}currentTrace(){try{let t=et.default.readFileSync(this.tracePath,"utf-8"),{traceId:n}=JSON.parse(t);if(n)return n}catch{}return this.newTrace()}save(t){try{et.default.mkdirSync(wn.default.dirname(this.tracePath),{recursive:!0}),(0,Mn.atomicWriteFileSync)(this.tracePath,JSON.stringify({traceId:t}))}catch(n){process.stderr.write(`[pinta-core] trace persistence failed: ${n}
|
|
19
|
+
`)}}};j.TraceManager=pe});var st=S(w=>{"use strict";var rt=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(w,"__esModule",{value:!0});w.MemorySessionTraceManager=w.DiskSessionTraceManager=void 0;var nt=rt(_("fs")),Rn=rt(_("path")),ot=ge(),jn=Z(),it=200,he=class{tracePath;maxSessions;constructor(t,n={}){this.tracePath=t,this.maxSessions=n.maxSessions??it}read(){try{let t=JSON.parse(nt.default.readFileSync(this.tracePath,"utf-8"));if(t&&typeof t=="object"&&!("traceId"in t))return t}catch{}return{}}write(t){try{nt.default.mkdirSync(Rn.default.dirname(this.tracePath),{recursive:!0});let n=Object.entries(t),r=n.length>this.maxSessions?Object.fromEntries(n.slice(-this.maxSessions)):t;(0,jn.atomicWriteFileSync)(this.tracePath,JSON.stringify(r))}catch{}}newTrace(t){let n=t||"default",r=(0,ot.generateUlid)(),o=this.read();return o[n]=r,this.write(o),r}currentTrace(t){let n=t||"default",r=this.read()[n];return r||this.newTrace(n)}};w.DiskSessionTraceManager=he;var _e=class{map=new Map;maxSessions;constructor(t={}){this.maxSessions=t.maxSessions??it}newTrace(t){let n=t||"default",r=(0,ot.generateUlid)();if(this.map.set(n,r),this.map.size>this.maxSessions){let o=this.map.keys().next().value;o!==void 0&&this.map.delete(o)}return r}currentTrace(t){let n=t||"default";return this.map.get(n)??this.newTrace(n)}};w.MemorySessionTraceManager=_e});var ut=S(D=>{"use strict";var ye=D&&D.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(D,"__esModule",{value:!0});D.envFilePath=Nn;D.parseEnvFile=ct;D.loadEnvFile=Cn;var Dn=ye(_("node:fs")),In=ye(_("node:os")),at=ye(_("node:path"));function Nn(e,t,n){let r=n?process.env[n]:void 0,o=r&&r.length>0?r:at.default.join(In.default.homedir(),e);return at.default.join(o,t)}function ct(e){let t={};for(let n of e.split(`
|
|
20
|
+
`)){let r=n.trim();if(!r||r.startsWith("#"))continue;let o=r.indexOf("=");if(o<0)continue;let i=r.slice(0,o).trim(),a=r.slice(o+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),i&&(t[i]=a)}return t}function Cn(e){let t;try{t=Dn.default.readFileSync(e,"utf-8")}catch{return}let n=ct(t);for(let[r,o]of Object.entries(n))process.env[r]===void 0&&(process.env[r]=o)}});var M=S(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.GUARD_STATUS_REFUSED=s.evaluateGuard=s.MAX_SPAN_BYTES=s.enforceSpanBudget=s.mergeBatch=s.attachGuard=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 x=oe();Object.defineProperty(s,"redact",{enumerable:!0,get:function(){return x.redact}});Object.defineProperty(s,"truncate",{enumerable:!0,get:function(){return x.truncate}});Object.defineProperty(s,"truncateTo",{enumerable:!0,get:function(){return x.truncateTo}});Object.defineProperty(s,"collectMatches",{enumerable:!0,get:function(){return x.collectMatches}});Object.defineProperty(s,"resolveOverlaps",{enumerable:!0,get:function(){return x.resolveOverlaps}});Object.defineProperty(s,"applyMatches",{enumerable:!0,get:function(){return x.applyMatches}});Object.defineProperty(s,"PATTERNS",{enumerable:!0,get:function(){return x.PATTERNS}});Object.defineProperty(s,"MAX_BYTES",{enumerable:!0,get:function(){return x.MAX_BYTES}});var y=se();Object.defineProperty(s,"ulidToTraceId",{enumerable:!0,get:function(){return y.ulidToTraceId}});Object.defineProperty(s,"newSpanId",{enumerable:!0,get:function(){return y.newSpanId}});Object.defineProperty(s,"snakeCase",{enumerable:!0,get:function(){return y.snakeCase}});Object.defineProperty(s,"toOtlpValue",{enumerable:!0,get:function(){return y.toOtlpValue}});Object.defineProperty(s,"attrsFromRecord",{enumerable:!0,get:function(){return y.attrsFromRecord}});Object.defineProperty(s,"guardAttrs",{enumerable:!0,get:function(){return y.guardAttrs}});Object.defineProperty(s,"clientAttrs",{enumerable:!0,get:function(){return y.clientAttrs}});Object.defineProperty(s,"buildPayload",{enumerable:!0,get:function(){return y.buildPayload}});Object.defineProperty(s,"attachGuard",{enumerable:!0,get:function(){return y.attachGuard}});Object.defineProperty(s,"mergeBatch",{enumerable:!0,get:function(){return y.mergeBatch}});Object.defineProperty(s,"enforceSpanBudget",{enumerable:!0,get:function(){return y.enforceSpanBudget}});Object.defineProperty(s,"MAX_SPAN_BYTES",{enumerable:!0,get:function(){return y.MAX_SPAN_BYTES}});var lt=ze();Object.defineProperty(s,"evaluateGuard",{enumerable:!0,get:function(){return lt.evaluateGuard}});Object.defineProperty(s,"GUARD_STATUS_REFUSED",{enumerable:!0,get:function(){return lt.GUARD_STATUS_REFUSED}});var ft=ue();Object.defineProperty(s,"DiskRetryQueue",{enumerable:!0,get:function(){return ft.DiskRetryQueue}});Object.defineProperty(s,"MemoryRetryQueue",{enumerable:!0,get:function(){return ft.MemoryRetryQueue}});var U=Qe();Object.defineProperty(s,"DiskTransport",{enumerable:!0,get:function(){return U.DiskTransport}});Object.defineProperty(s,"MemoryTransport",{enumerable:!0,get:function(){return U.MemoryTransport}});Object.defineProperty(s,"postOtlp",{enumerable:!0,get:function(){return U.postOtlp}});Object.defineProperty(s,"envOptionsResolver",{enumerable:!0,get:function(){return U.envOptionsResolver}});Object.defineProperty(s,"parseHeadersEnv",{enumerable:!0,get:function(){return U.parseHeadersEnv}});Object.defineProperty(s,"MAX_POST_BYTES",{enumerable:!0,get:function(){return U.MAX_POST_BYTES}});var dt=ge();Object.defineProperty(s,"TraceManager",{enumerable:!0,get:function(){return dt.TraceManager}});Object.defineProperty(s,"generateUlid",{enumerable:!0,get:function(){return dt.generateUlid}});var pt=st();Object.defineProperty(s,"DiskSessionTraceManager",{enumerable:!0,get:function(){return pt.DiskSessionTraceManager}});Object.defineProperty(s,"MemorySessionTraceManager",{enumerable:!0,get:function(){return pt.MemorySessionTraceManager}});var Pe=ut();Object.defineProperty(s,"envFilePath",{enumerable:!0,get:function(){return Pe.envFilePath}});Object.defineProperty(s,"parseEnvFile",{enumerable:!0,get:function(){return Pe.parseEnvFile}});Object.defineProperty(s,"loadEnvFile",{enumerable:!0,get:function(){return Pe.loadEnvFile}})});import{realpathSync as Ar}from"node:fs";import{pathToFileURL as wr}from"node:url";var G=R(M());function Un(){return(0,G.envFilePath)(".claude","pinta-cc.env")}function mt(e=Un()){(0,G.loadEnvFile)(e)}function gt(){process.env.CLAUDE_PLUGIN_OPTION_ENDPOINT&&!process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT&&(process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=process.env.CLAUDE_PLUGIN_OPTION_ENDPOINT),process.env.CLAUDE_PLUGIN_OPTION_API_KEY&&!process.env.OTEL_EXPORTER_OTLP_HEADERS&&(process.env.OTEL_EXPORTER_OTLP_HEADERS=`x-pinta-relay-token=${process.env.CLAUDE_PLUGIN_OPTION_API_KEY}`),!process.env.PINTA_RELAY_TOKEN&&process.env.CLAUDE_PLUGIN_OPTION_API_KEY&&(process.env.PINTA_RELAY_TOKEN=process.env.CLAUDE_PLUGIN_OPTION_API_KEY)}var _t=R(M());import ht from"path";function yt(){let e=process.env.CLAUDE_PLUGIN_ROOT||process.cwd(),t=process.env.CLAUDE_PLUGIN_DATA||ht.join(e,".plugin-data");return{pluginRoot:e,pluginData:t,tracePath:ht.join(t,"trace.json")}}function ve(){return(0,_t.envOptionsResolver)()!==null}function Pt(e){return e.hook_event_name==="PreToolUse"}function vt(e){return e.hook_event_name==="PostToolUse"||e.hook_event_name==="PostToolUseFailure"}function Et(e){return e.hook_event_name==="UserPromptSubmit"}function St(e){return e.hook_event_name==="SessionStart"||e.hook_event_name==="SessionEnd"}function Tt(e){return e.hook_event_name==="SubagentStart"||e.hook_event_name==="SubagentStop"}function bt(e){return e.hook_event_name==="Stop"}function Ot(e){return e.hook_event_name==="PermissionRequest"||e.hook_event_name==="PermissionDenied"}var Bn=new Set(["Notification","TaskCreated","TaskCompleted"]);function kt(e){return Bn.has(e.hook_event_name)}var Gt=R(M());var At=R(M()),Ln=1e4,Fn="pinta-cc/1.9.0";function wt(e,t){return(0,At.evaluateGuard)(e,t,{timeoutMs:Ln,token:process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:Fn})}var xt=R(M()),Q=class extends xt.DiskTransport{constructor(t){super({pluginData:t.pluginData,logPrefix:"pinta-cc"})}};var Mt=R(M()),ee=class extends Mt.TraceManager{constructor(t){super(t.tracePath)}};import be from"os";import{spawnSync as $n}from"node:child_process";import{createHash as qn,randomUUID as Vn}from"node:crypto";import E from"node:fs";import Gn from"node:os";import m from"node:path";var Dt=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/,zn=/^v?(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)\s+\(Claude Code\)$/m,Yn=2e3,Xn=24*60*60*1e3,Kn=3e4,Se=8,It="claude-version.json",B=new Map;function b(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"?e.code:"UNKNOWN"}function P(e){process.stderr.write(`[pinta-cc] CLI version: ${e}
|
|
21
|
+
`)}function te(e){return b(e)==="ENOENT"||b(e)==="ENOTDIR"}function Zn(){let e=process.env.CLAUDE_CODE_EXECPATH,t=process.platform==="win32"?["claude.exe","claude.cmd"]:["claude"],n;if(e)n=[e];else{let r=(process.env.PATH??"").split(m.delimiter).filter(o=>m.isAbsolute(o));try{r.push(m.join(Gn.homedir(),".local","bin"))}catch(o){P(`native install directory lookup failed (${b(o)})`)}n=r.flatMap(o=>t.map(i=>m.join(o,i)))}for(let r of new Set(n))try{let o=E.realpathSync(r),i=E.statSync(o);if(!i.isFile())continue;return!e&&process.platform!=="win32"&&E.accessSync(o,E.constants.X_OK),{file:o,fingerprint:qn("sha256").update(JSON.stringify([o,i.ino,i.size,i.mtimeMs,i.ctimeMs])).digest("hex")}}catch(o){te(o)||P(`executable lookup failed (${b(o)})`)}return P(e?"configured executable is unavailable":"no Claude executable found in PATH or ~/.local/bin"),null}function Ee(e){let t;try{t=JSON.parse(E.readFileSync(e,"utf8"))}catch(n){return te(n)||P(`package metadata could not be read (${n instanceof SyntaxError?"INVALID_JSON":b(n)})`),null}return typeof t!="object"||t===null||!("name"in t)||!("version"in t)||typeof t.name!="string"||typeof t.version!="string"||!Dt.test(t.version)?null:t.name==="@anthropic-ai/claude-code"||t.name.startsWith("@anthropic-ai/claude-code-")?t.version:null}function Wn(e){let t=m.dirname(e),n=m.basename(t)===".bin"&&/^claude(?:\.cmd)?$/i.test(m.basename(e));for(let r=0;r<6;r++){let o=Ee(m.join(t,"package.json"));if(o)return o;if(m.basename(e).toLowerCase()==="claude.cmd"&&r===0){let a=Ee(m.join(t,"node_modules","@anthropic-ai","claude-code","package.json"));if(a)return a}if(n&&m.basename(t)==="node_modules"){let a=Ee(m.join(t,"@anthropic-ai","claude-code","package.json"));if(a)return a}let i=m.dirname(t);if(i===t)break;t=i}return null}function Hn(e){return typeof e=="object"&&e!==null&&"fingerprint"in e&&typeof e.fingerprint=="string"&&/^[0-9a-f]{64}$/.test(e.fingerprint)&&"version"in e&&(e.version===null||typeof e.version=="string"&&Dt.test(e.version))&&"checkedAt"in e&&typeof e.checkedAt=="number"&&Number.isFinite(e.checkedAt)}function Rt(e,t){let n=t-e.checkedAt;return n>=0&&n<(e.version===null?Kn:Xn)}function Jn(e){if(!e)return[];let t=m.join(e,It);try{if(E.statSync(t).size>16384)return P("oversized version cache ignored"),[];let n=JSON.parse(E.readFileSync(t,"utf8"));if(Array.isArray(n)&&n.length<=Se&&n.every(Hn))return n;P("invalid version cache ignored")}catch(n){te(n)||P(`version cache read failed (${n instanceof SyntaxError?"INVALID_JSON":b(n)})`)}return[]}function jt(e){for(B.delete(e.fingerprint),B.set(e.fingerprint,e);B.size>Se;){let t=B.keys().next().value;t!==void 0&&B.delete(t)}}function Qn(e,t){if(!e)return;let n=m.join(e,It),r=`${n}.${process.pid}.${Vn()}.tmp`;try{E.mkdirSync(e,{recursive:!0,mode:448}),E.writeFileSync(r,JSON.stringify(t),{encoding:"utf8",mode:384,flag:"wx"}),E.renameSync(r,n)}catch(o){P(`version cache write failed (${b(o)})`)}finally{try{E.unlinkSync(r)}catch(o){te(o)||P(`temporary version cache cleanup failed (${b(o)})`)}}}function er(e){if(/\.(cmd|bat|ps1)$/i.test(e))return P("command shim has no readable Claude package metadata"),null;let t=$n(e,["--version"],{encoding:"utf8",stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0,timeout:Yn,killSignal:"SIGKILL",maxBuffer:4096});if(t.error||t.status!==0)return P(`version probe failed (${t.error?b(t.error):`exit ${t.status??t.signal}`})`),null;let n=zn.exec(t.stdout.trim())?.[1];return n||(P("version probe did not identify Claude Code"),null)}function Nt(e){let t=Zn();if(!t)return"unknown";let n=Wn(t.file);if(n)return n;let r=Date.now(),o=Jn(e),i=[B.get(t.fingerprint),...o].find(c=>c&&c.fingerprint===t.fingerprint&&Rt(c,r));if(i)return jt(i),i.version??"unknown";let a={fingerprint:t.fingerprint,version:er(t.file),checkedAt:Date.now()};return jt(a),Qn(e,[...o.filter(c=>c.fingerprint!==a.fingerprint&&Rt(c,a.checkedAt)),a].slice(-Se)),a.version??"unknown"}import N from"node:path";import O from"node:fs";import Ct from"node:path";var tr=new Set(["","unknown","undefined","null","n/a","none","auto","default"]),nr=256*1024,rr=1024*1024,or=4096;function I(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0}function Te(e){let t=I(e),n=t?"id"in t?t.id:t.name:e;if(typeof n!="string")return;let r=n.trim();if(!(r.startsWith("{")||r.startsWith("[")))return r.length<=512&&!/[\u0000-\u001f\u007f]/.test(r)&&!tr.has(r.toLowerCase())?r:void 0}function Ut(e,t){delete e.model,t&&(e.model=t.name,!(t.source==="hook.model"&&e.model_source!==void 0)&&(e.model_source!==void 0&&(e.model_original_source=e.model_source),e.model_source=t.source))}function L(e){return typeof e=="string"&&/^[A-Za-z0-9][A-Za-z0-9_.:-]{0,255}$/.test(e)?e:void 0}function ne(e){let t=typeof e=="number"?e:typeof e=="string"&&/^\d{4}-\d{2}-\d{2}T/.test(e)?Date.parse(e):NaN;return Number.isFinite(t)&&t>=0?t:void 0}function Bt(e,t){let n=e.timestamp===void 0?ne(t):ne(e.timestamp);return n!==void 0&&n<=t?n:void 0}function Lt(e){if(typeof e!="string"||e.length>4096||/[\u0000-\u001f]/.test(e)||!Ct.isAbsolute(e)||Ct.extname(e)!==".jsonl")return;let t;try{t=O.openSync(e,O.constants.O_RDONLY|O.constants.O_NONBLOCK|(O.constants.O_NOFOLLOW??0));let n=O.fstatSync(t);if(!n.isFile()||!Number.isSafeInteger(n.size)||n.size<=0)return;let r=Buffer.alloc(Math.min(n.size,nr));if(O.readSync(t,r,0,r.length,0)!==r.length)return;let o=r.indexOf(10),i;if(o>=0)try{i=I(JSON.parse(r.toString("utf8",0,o)))}catch{}let a=Math.max(0,n.size-rr),c=n.size<=r.length?r:Buffer.alloc(n.size-a);if(c!==r&&O.readSync(t,c,0,c.length,a)!==c.length)return;let u=O.fstatSync(t);if(u.size<n.size||u.size===n.size&&u.mtimeMs!==n.mtimeMs)return;let l=a>0?c.indexOf(10)+1:0,p=c.lastIndexOf(10);if(a>0&&l===0||p<l)return;let k=[],T=0;for(;p>l&&T<or;){let Y=c.lastIndexOf(10,p-1),$=Math.max(l,Y+1),we=c.toString("utf8",$,p).trim();if(we){let xe=I(JSON.parse(we));xe&&k.push(xe)}p=$-1,T++}return k.reverse(),{first:i,rows:k,complete:a===0&&p<0&&c[c.length-1]===10}}catch{return}finally{if(t!==void 0)try{O.closeSync(t)}catch{}}}function Ft(e){let t=e[0];return t&&e.every(n=>n?.name===t.name)?t:void 0}var ir=new Set(["PreToolUse","PostToolUse","PostToolUseFailure","PermissionRequest","PermissionDenied"]);function sr(e,t){let n=N.dirname(e);if(N.basename(n)!=="subagents"||N.basename(N.dirname(n))!==t)return;let r=/^agent-(.+)\.jsonl$/.exec(N.basename(e));return L(r?.[1])}function $t(e,t){let n=Te(e.model);if(n)return{name:n,source:"hook.model"};try{return ar(e,t)}catch{return}}function ar(e,t){if(!ir.has(e.hook_event_name))return;let n=L(e.session_id),r=L(e.tool_use_id),o=Bt(e,t);if(!n||!r||o===void 0||typeof e.transcript_path!="string")return;let i=sr(e.transcript_path,n),a=e.agent_id===void 0?i:L(e.agent_id);if(e.agent_id!==void 0&&!a||i!==void 0&&i!==a||!a&&e.agent_type!==void 0||N.basename(N.dirname(e.transcript_path))==="subagents"&&!i)return;let c=Lt(e.transcript_path);if(!c)return;let u=[];for(let l of c.rows){let p=ne(l.timestamp);if(l.type!=="assistant"||l.sessionId!==n||p===void 0||p>o)continue;let k=l.agentId===void 0?void 0:L(l.agentId);if(k!==a||l.agentId!==void 0&&!k||l.isSidechain===!0&&!a)continue;let T=I(l.message);if(!T||T.role!==void 0&&T.role!=="assistant"||!Array.isArray(T.content)||!T.content.some($=>I($)?.type==="tool_use"&&I($)?.id===r))continue;let Y=Te(T.model);u.push(Y?{name:Y,source:"transcript.assistant.message"}:void 0)}return Ft(u)}var F=R(M()),re;function cr(){if(re===void 0)try{re=be.userInfo().username}catch{re=process.env.USER??process.env.LOGNAME??(typeof process.getuid=="function"?String(process.getuid()):"unknown")}return re}var qt="1.9.0",ur=new Set(["cc.hook","cc.tool_name","cc.tool_use_id","cc.session_id","cc.transcript_path","cc.cwd","cc.permission_mode"]),lr=new Set(["cc.tool_input","cc.tool_response"]),fr={skipRedactKeys:ur,bashContextKeys:lr};function dr(e,t){let n=[];n.push({key:"ingest.type",value:{stringValue:"cc"}}),n.push({key:"cc.hook",value:{stringValue:e.hook_event_name}});let r={};for(let[o,i]of Object.entries(e))o!=="hook_event_name"&&(r[o]=i);return Ut(r,$t(e,t)),n.push(...(0,F.attrsFromRecord)(r,"cc",fr)),n}function pr(e){return[{key:"service.name",value:{stringValue:"claude-code"}},{key:"service.version",value:{stringValue:Nt(e)}},{key:"telemetry.sdk.name",value:{stringValue:"pinta-cc"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:qt}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:cr()}},{key:"host.name",value:{stringValue:be.hostname()}},{key:"host.arch",value:{stringValue:be.arch()}}]}function Vt(e){let t=e.now??Date.now();return(0,F.buildPayload)({traceId:e.traceId,spanName:`cc.${(0,F.snakeCase)(e.event.hook_event_name)}`,attributes:dr(e.event,t),resource:pr(e.versionCacheDir),scope:{name:"pinta-cc",version:qt},now:t})}function Oe(e,t,n={}){let r=new ee(t),o=n.traceMode==="new"?r.newTrace():r.currentTrace();return Vt({event:e,traceId:o,versionCacheDir:t.pluginData})}async function ke(e,t){if(!ve())return;let n=new Q(t);await n.flush(),await n.send(e)}async function v(e,t,n={}){ve()&&await ke(Oe(e,t,n),t)}async function zt(e,t){let n=Oe(e,t),r=await wt(n,process.env.PINTA_GUARD_ENDPOINT);if(r?.decision==="DENY"){let i={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:r.userMessage??r.reason??"guard_deny"}};process.stdout.write(JSON.stringify(i)+`
|
|
22
|
+
`)}try{(0,Gt.attachGuard)(n,r),await ke(n,t)}catch(o){process.stderr.write(`[pinta-cc] telemetry emit failed: ${o}
|
|
23
|
+
`)}return 0}async function Yt(e,t){return await v(e,t),0}async function Xt(e,t){return await v(e,t,{traceMode:"new"}),0}async function Kt(e,t){return await v(e,t),0}async function Zt(e,t){return await v(e,t),0}async function Wt(e,t){return await v(e,t),0}async function Ht(e,t){return await v(e,t),0}async function Ae(e){return 0}async function mr(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function Jt(){gt();let e=0;try{let t=yt(),n=await mr(),r=JSON.parse(n);kt(r)?e=await Ae(r):Pt(r)?e=await zt(r,t):vt(r)?e=await Yt(r,t):Et(r)?e=await Xt(r,t):St(r)?e=await Kt(r,t):Tt(r)?e=await Zt(r,t):bt(r)?e=await Wt(r,t):Ot(r)?e=await Ht(r,t):e=await Ae(r)}catch(t){process.stderr.write(`[pinta-cc] error: ${t}
|
|
24
|
+
`),e=0}return e}import{opendir as gr,stat as hr}from"node:fs/promises";import{homedir as _r}from"node:os";import z from"node:path";var yr="pinta-cc",Qt="memory";function Pr(){let e=process.env.CLAUDE_CONFIG_DIR;return e&&e.length>0?e:z.join(_r(),".claude")}function vr(){return z.join(Pr(),"projects")}function Er(e,t){return z.relative(e,t).split(z.sep).join("/")}function Sr(e){return e.endsWith(".jsonl")?"append-log":"rewritten-doc"}function Tr(e){let t=e.split("/");if(t.length<2)return{};let n=t[0],r=t[1];return t.length===2?r.endsWith(".jsonl")?{projectKey:n,sessionId:r.slice(0,-6)}:{projectKey:n}:r===Qt?{projectKey:n}:{projectKey:n,sessionId:r}}function br(e){return e.endsWith(".jsonl")?"session-log":e.split("/")[1]===Qt?"memory":e.endsWith(".json")?"meta":"other"}async function en(){return[vr()]}async function*tn(e,t){let n;try{n=await gr(t)}catch{return}try{for await(let r of n){let o=z.join(t,r.name);r.isDirectory()?yield*tn(e,o):r.isFile()&&(yield{absPath:o,relPath:Er(e,o)})}}catch{return}}async function*Or(e){let[t]=await en(),n=e.since?.getTime();for await(let{absPath:r,relPath:o}of tn(t,t)){let i;try{i=await hr(r)}catch{continue}if(n!==void 0&&i.mtime.getTime()<=n)continue;let{projectKey:a,sessionId:c}=Tr(o);yield{relPath:o,absPath:r,size:i.size,mtime:i.mtime,sessionId:c,projectKey:a,semantics:Sr(o)}}}var kr={id:yr,roots:en,scan:Or,classify:br};mt();function xr(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===wr(Ar(e)).href}catch{return!1}}async function Mr(){let e=await Jt();process.exit(e)}xr()&&Mr();export{kr as lifecycle};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pinta-ai/pinta-cc",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Generic OTLP forwarder for Claude Code hook events",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"test:watch": "vitest",
|
|
38
38
|
"smoke:import": "node scripts/smoke-import.mjs",
|
|
39
39
|
"smoke:version": "node scripts/smoke-version.mjs",
|
|
40
|
+
"smoke:model": "node scripts/smoke-model.mjs",
|
|
40
41
|
"mock-server": "npx tsx tools/mock-server.ts",
|
|
41
42
|
"prepublishOnly": "npm run build"
|
|
42
43
|
},
|