@pinta-ai/pinta-gemini 0.11.0 → 0.13.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/CHANGELOG.md +46 -0
- package/README.md +62 -2
- package/dist/index.js +16 -16
- package/dist/index.mjs +19 -19
- package/docs/SPEC.md +11 -2
- package/package.json +3 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.13.0
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- The guard gate waits **100ms** for a verdict (was 50ms) before failing open.
|
|
7
|
+
50ms sat under the manager's own round trip at the tail (prod p99 58ms), so
|
|
8
|
+
calls the manager would have decided were allowed by the timeout instead.
|
|
9
|
+
Applies to both Gemini CLI and Antigravity.
|
|
10
|
+
- `@pinta-ai/core` `^0.9.0`: the guard request now carries
|
|
11
|
+
`x-pinta-guard-budget-ms: 100`. Pinta Manager 0.1.10+ bounds its package
|
|
12
|
+
check by this value (80% of it) instead of its built-in table, which still
|
|
13
|
+
lists pinta-gemini at 50ms — without the header the manager would keep
|
|
14
|
+
abandoning the package check at 40ms.
|
|
15
|
+
|
|
16
|
+
### Compatibility
|
|
17
|
+
- Pinta Manager 0.1.11 or later remains the guard-payload compatibility floor.
|
|
18
|
+
Older managers ignore the new header; nothing else in the request changes.
|
|
19
|
+
|
|
20
|
+
Refs PTA-579.
|
|
21
|
+
|
|
22
|
+
## 0.12.0
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- Truthful scalar `gemini.model` and `antigravity.model` attributes with
|
|
26
|
+
`model_source` provenance. Gemini request models are read from the verified
|
|
27
|
+
nested `llm_request.model` field; conflicting raw values remain available as
|
|
28
|
+
`model_raw`.
|
|
29
|
+
- Regression and built-hook loopback OTLP coverage for model switches,
|
|
30
|
+
concurrent sessions, same-session subagents, missing metadata, raw payload
|
|
31
|
+
preservation, redaction and guard-span identity.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
- Omit blank, placeholder, non-string and JSON-prefixed model IDs, including
|
|
35
|
+
malformed or truncated strings starting with `{` or `[` after trimming.
|
|
36
|
+
|
|
37
|
+
### Compatibility
|
|
38
|
+
- Pinta Manager 0.1.11 or later remains the guard-payload compatibility floor;
|
|
39
|
+
the `@pinta-ai/core` dependency remains `^0.8.0`. No new required envelope
|
|
40
|
+
fields, hook registration changes or additional desktop upgrade are needed.
|
|
41
|
+
- Gemini `AfterModel` remains skipped: the verified native translator exposes
|
|
42
|
+
response content/token counts, not actual response model identity, and fires
|
|
43
|
+
per streamed chunk. Current Antigravity native hooks expose no model.
|
|
44
|
+
Unavailable models are omitted; no transcript scans or session-model guesses.
|
|
45
|
+
|
|
46
|
+
Refs PTA-524.
|
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ src/
|
|
|
23
23
|
agent.ts --agent/--event 파싱 + antigravity 제품 서브라벨(transcriptPath)
|
|
24
24
|
normalize.ts 호스트 payload → canonical (snake/camel 흡수)
|
|
25
25
|
config.ts endpoint/headers/guard/data-dir 해석
|
|
26
|
-
guard.ts 원격 guard 평가 (
|
|
26
|
+
guard.ts 원격 guard 평가 (100ms, fail-open) ← pinta-cc 재사용
|
|
27
27
|
decision.ts 호스트별 allow/deny 출력
|
|
28
28
|
otlp.ts 멀티호스트 Bronze flatten + ingest.type/prefix/service.name
|
|
29
29
|
transport.ts OTLP/HTTP POST (5s) + 실패 시 retry-queue
|
|
@@ -61,8 +61,68 @@ npx tsx tools/hook-verify.ts teardown # 원복 (hook 제거, jsonl 보존)
|
|
|
61
61
|
- 이벤트/agent 식별: install 시 command 에 박는 `--agent`/`--event` 인자가 유일 수단(인자보존 실측 확정).
|
|
62
62
|
- 출력: stdout 에 **항상 단일 JSON**, **항상 exit 0**(fail-open).
|
|
63
63
|
- deny: gemini `{decision,reason,systemMessage}` / antigravity `{decision,reason}`. allow: gemini `{}` / antigravity PreToolUse `{decision:"allow"}`.
|
|
64
|
-
- guard: `PINTA_GUARD_ENDPOINT` POST,
|
|
64
|
+
- guard: `PINTA_GUARD_ENDPOINT` POST, 100ms, fail-open. 텔레메트리: `GEMINI_PLUGIN_OPTION_*` > `OTEL_EXPORTER_OTLP_*`.
|
|
65
65
|
- 설정 주입: 호스트가 hook 에 env 를 안 주므로 `~/.gemini/pinta-gemini.env`(어댑터가 읽음)로 주입.
|
|
66
66
|
|
|
67
|
+
## Model telemetry
|
|
68
|
+
|
|
69
|
+
`gemini.model` / `antigravity.model` is a **scalar, host-supplied model ID**,
|
|
70
|
+
not a guessed default. `*.model_source` distinguishes evidence:
|
|
71
|
+
|
|
72
|
+
| Surface | Precedence / source |
|
|
73
|
+
| --- | --- |
|
|
74
|
+
| Gemini `BeforeModel`, `BeforeToolSelection` | `llm_request.model` → `requested:llm_request.model`, then top-level `model` → `reported:model` |
|
|
75
|
+
| Gemini response normalization | Explicit `llm_response.modelVersion`, then `llm_response.model` → `response:…`, then the request; **`AfterModel` remains skipped**, preserving streaming span counts |
|
|
76
|
+
| Other Gemini hooks | Top-level scalar `model` only → `reported:model` |
|
|
77
|
+
| Antigravity (agy and 2.0) | Top-level scalar `model`, then `modelId` → `reported:…`; never Gemini's nested fields |
|
|
78
|
+
|
|
79
|
+
The [Gemini hook types](https://github.com/google-gemini/gemini-cli/blob/v0.59.0/packages/core/src/hooks/types.ts)
|
|
80
|
+
expose a model on the **request**, not on ordinary tool/session hooks. The
|
|
81
|
+
[response translator](https://github.com/google-gemini/gemini-cli/blob/v0.59.0/packages/core/src/hooks/hookTranslator.ts)
|
|
82
|
+
currently omits actual response model identity. Before-model hooks are not
|
|
83
|
+
registered by the default installer; this change does not alter registration.
|
|
84
|
+
The verified [Antigravity payloads](./docs/BACKGROUND_RESEARCH.md#f3-확정된-이벤트별-payload-형상-실측-키셋)
|
|
85
|
+
do not expose a model at all, so existing Antigravity hooks normally omit it.
|
|
86
|
+
Explicit fields from host versions that supply them are preserved, not invented.
|
|
87
|
+
|
|
88
|
+
Blank, non-string and placeholder IDs (`unknown`, `undefined`, `null`, `n/a`,
|
|
89
|
+
`none`, `-`, `auto`, `default`) are omitted. Any trimmed string starting with
|
|
90
|
+
`{` or `[` is also omitted, including malformed or truncated JSON-like strings;
|
|
91
|
+
matching closing braces are not required. A conflicting or unusable top-level
|
|
92
|
+
host value is retained as `*.model_raw`; nested raw payloads remain unchanged
|
|
93
|
+
and use the existing redaction pipeline. Requested aliases are not claimed to
|
|
94
|
+
be an actual provider response identity.
|
|
95
|
+
|
|
96
|
+
Resolution is event-local: fixed field checks, **no added I/O, host commands,
|
|
97
|
+
file scans or cache**. A session/transcript path alone cannot disambiguate a
|
|
98
|
+
tool's model call from an earlier turn or same-session subagent. Such missing
|
|
99
|
+
models stay missing, including after switches, resumed sessions, and end hooks.
|
|
100
|
+
|
|
101
|
+
### AfterModel decision
|
|
102
|
+
|
|
103
|
+
Reviewed against Gemini CLI **v0.59.0** and upstream main's response schema on
|
|
104
|
+
2026-09-21. [`fireAfterModelEvent`](https://github.com/google-gemini/gemini-cli/blob/v0.59.0/packages/core/src/hooks/hookEventHandler.ts)
|
|
105
|
+
does **not** give hooks the raw GenAI SDK response: it calls
|
|
106
|
+
[`toHookLLMResponse`](https://github.com/google-gemini/gemini-cli/blob/v0.59.0/packages/core/src/hooks/hookTranslator.ts).
|
|
107
|
+
That translator explicitly constructs only `text`, `candidates` (content parts,
|
|
108
|
+
finish reason, index, safety ratings), and `usageMetadata` (token counts).
|
|
109
|
+
Neither `model` nor `modelVersion` is exposed on `llm_response`; the model field
|
|
110
|
+
that *is* present is `llm_request.model`, which is request evidence only.
|
|
111
|
+
|
|
112
|
+
The [host reference](https://github.com/google-gemini/gemini-cli/blob/v0.59.0/docs/hooks/reference.md#aftermodel)
|
|
113
|
+
says `AfterModel` fires after **each response chunk**, not once per completed
|
|
114
|
+
turn. The existing skip therefore avoids chunk-level span multiplication and
|
|
115
|
+
forwarding request/response content without recovering an additional
|
|
116
|
+
authoritative model identity. It stays in place; no event is renamed or
|
|
117
|
+
fabricated as `AfterAgent`, and hook registration/counts are unchanged.
|
|
118
|
+
|
|
119
|
+
Explicit response-ID support in the pure normalizer is not a claim that today's
|
|
120
|
+
native hook delivers it. If a verified host version does expose an actual
|
|
121
|
+
`model`/`modelVersion`, the appropriate follow-up is a **metadata-only
|
|
122
|
+
`AfterModel` observation**, excluding prompt/response content and using a
|
|
123
|
+
verified request identity for any deduplication. That requires evidence of the
|
|
124
|
+
new payload and coordination of the original hook's runtime classification;
|
|
125
|
+
it is not enabled speculatively here.
|
|
126
|
+
|
|
67
127
|
## 라이선스
|
|
68
128
|
PolyForm Noncommercial 1.0.0
|
package/dist/index.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { createRequire as __pintaCreateRequire } from 'module'; const require = __pintaCreateRequire(import.meta.url);
|
|
2
|
-
var
|
|
2
|
+
var wt=Object.create;var he=Object.defineProperty;var Rt=Object.getOwnPropertyDescriptor;var Mt=Object.getOwnPropertyNames;var It=Object.getPrototypeOf,Dt=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 h=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var xt=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Mt(t))!Dt.call(e,i)&&i!==n&&he(e,i,{get:()=>t[i],enumerable:!(r=Rt(t,i))||r.enumerable});return e};var P=(e,t,n)=>(n=e!=null?wt(It(e)):{},xt(t||!e||!e.__esModule?he(n,"default",{value:e,enumerable:!0}):n,e));var Z=h(f=>{"use strict";Object.defineProperty(f,"__esModule",{value:!0});f.PATTERNS=f.MAX_BYTES=void 0;f.truncateTo=Ee;f.truncate=Nt;f.collectMatches=ve;f.resolveOverlaps=Pe;f.applyMatches=Se;f.redact=jt;f.MAX_BYTES=102400;function Ee(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 Nt(e){return Ee(e,f.MAX_BYTES)}f.PATTERNS=[{type:"aws_access_key",regex:/AKIA[0-9A-Z]{16}/g},{type:"aws_secret_key",regex:/(?:aws[_-]?secret(?:[_-]?(?:access)?[_-]?key)?)\s*[:=]\s*["']?([A-Za-z0-9/+=]{40})(?![A-Za-z0-9/+=])/gi,captureGroup:1},{type:"gcp_service_account",regex:/\{[\s\S]{0,200}?"type"\s*:\s*"service_account"[\s\S]*?\}/g},{type:"github_token",regex:/gh[pousr]_[A-Za-z0-9]{36,}/g},{type:"gitlab_token",regex:/glpat-[A-Za-z0-9_-]{20}/g},{type:"slack_token",regex:/xox[abrsp]-[0-9A-Za-z-]{10,}/g},{type:"openai_key",regex:/sk-(?:proj-)?[A-Za-z0-9_-]{40,}/g},{type:"anthropic_key",regex:/sk-ant-[A-Za-z0-9_-]{50,}/g},{type:"stripe_key",regex:/(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g},{type:"jwt",regex:/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g},{type:"private_key_block",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g},{type:"bearer_token",regex:/bearer\s+([A-Za-z0-9._~+/=-]{12,})/gi,captureGroup:1},{type:"basic_auth",regex:/basic\s+([A-Za-z0-9+/=]{12,})/gi,captureGroup:1},{type:"db_url_password",regex:/\b(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|redis):\/\/[^:\s/]+:([^@\s]+)@/gi,captureGroup:1},{type:"cli_password_flag",regex:/(?:--password|--pass|--pwd)[=\s]([^\s'"]+)/g,captureGroup:1},{type:"cli_password_short",regex:/\s-p([^\s'"]+)/g,captureGroup:1,requireContext:"bash"},{type:"env_var_secret",regex:/^(?:export\s+)?([A-Z][A-Z0-9_]*(?:KEY|SECRET|TOKEN|PASSWORD|PASSWD|PWD|API_KEY)[A-Z0-9_]*)\s*=\s*["']?([^\s"'\n]+)/gm,captureGroup:2}];function ve(e,t){let n=[];for(let r of f.PATTERNS){if(r.requireContext&&r.requireContext!==t.context)continue;let i=new RegExp(r.regex.source,r.regex.flags),o;for(;(o=i.exec(e))!==null;){let a=r.captureGroup??0,u=o[a];if(u===void 0){o.index===i.lastIndex&&i.lastIndex++;continue}let c=o.index,p=o.index+o[0].length,b=c+o[0].indexOf(u),z=b+u.length;n.push({start:c,end:p,replaceStart:b,replaceEnd:z,type:r.type}),o.index===i.lastIndex&&i.lastIndex++}}return n}function Pe(e){let t=[...e].sort((i,o)=>i.start!==o.start?i.start-o.start:o.end-o.start-(i.end-i.start)),n=[],r=-1;for(let i of t)i.start<r||(n.push(i),r=i.end);return n}function Se(e,t){let n=[...t].sort((i,o)=>o.replaceStart-i.replaceStart),r=e;for(let i of n)r=r.slice(0,i.replaceStart)+`[REDACTED:${i.type}]`+r.slice(i.replaceEnd);return r}function jt(e,t={}){if(e.length===0)return e;let n=ve(e,t);if(n.length===0)return e;let r=Pe(n);return Se(e,r)}});var J=h(d=>{"use strict";var Gt=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=ke;d.snakeCase=Vt;d.toOtlpValue=we;d.attrsFromRecord=qt;d.guardAttrs=Re;d.clientAttrs=Me;d.enforceSpanBudget=Ie;d.buildPayload=Ut;d.attachGuard=De;d.mergeBatch=Ft;var $t=Gt(_("crypto")),W=Z(),Bt="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 i=Bt.indexOf(r);if(i<0)throw new Error(`ulidToTraceId: invalid Crockford char "${r}"`);t=t<<5n|BigInt(i)}let n=(1n<<128n)-1n;return t&=n,t.toString(16).padStart(32,"0")}function ke(){return $t.default.randomBytes(8).toString("hex")}function Vt(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var Te=new Set;function G(e,t,n){let r=(0,W.truncate)(t);if((n.skipRedactKeys??Te).has(e))return r;let i=(n.bashContextKeys??Te).has(e)?"bash":void 0;return(0,W.redact)(r,{context:i})}function we(e,t,n={}){if(t==null)return null;switch(typeof t){case"string":return{stringValue:G(e,t,n)};case"boolean":return{boolValue:t};case"number":return Number.isInteger(t)?{intValue:t}:{doubleValue:t};case"object":try{return{stringValue:G(e,JSON.stringify(t),n)}}catch{return{stringValue:G(e,String(t),n)}}default:return{stringValue:G(e,String(t),n)}}}function qt(e,t,n={}){let r=[];for(let[i,o]of Object.entries(e)){let a=`${t}.${i}`,u=we(a,o,n);u!==null&&r.push({key:a,value:u})}return r}function Re(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 Me(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 Oe(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}var Ae=1024;function Ie(e,t=d.MAX_SPAN_BYTES){let n=Oe(e);for(let r=0;r<100&&n>t;r++){let i=null,o=0;for(let c of e.attributes){if(!("stringValue"in c.value))continue;let p=Buffer.byteLength(c.value.stringValue,"utf-8");p>o&&(o=p,i=c.value)}if(i===null||o<=Ae)break;let a=n-t,u=Math.max(Ae,o-a-64);i.stringValue=(0,W.truncateTo)(i.stringValue,u),n=Oe(e)}return e}function Ut(e){let t=e.now??Date.now(),n=(BigInt(t)*1000000n).toString(),r=[...e.attributes],i={traceId:be(e.traceId),spanId:ke(),name:e.spanName,kind:e.spanKind??1,startTimeUnixNano:n,endTimeUnixNano:n,attributes:r};Ie(i);let o={resourceSpans:[{resource:{attributes:e.resource},scopeSpans:[{scope:e.scope,spans:[i]}]}]};return De(o,e.guard,e.clientTiming)}function De(e,t,n){let r=e.resourceSpans[0]?.scopeSpans[0]?.spans[0];if(!r)return e;t&&r.attributes.push(...Re(t));let i=n??(t?.clientRttMs!==void 0?{op:"guard",rttMs:t.clientRttMs}:null);return i&&r.attributes.push(...Me(i)),e}function Ft(e){let t=[];for(let n of e)t.push(...n.resourceSpans);return{resourceSpans:t}}});var xe=h(E=>{"use strict";Object.defineProperty(E,"__esModule",{value:!0});E.GUARD_STATUS_REFUSED=E.GUARD_BUDGET_HEADER=void 0;E.evaluateGuard=Xt;var Lt=1e4,Ct="pinta-core";E.GUARD_BUDGET_HEADER="x-pinta-guard-budget-ms";function $(e,t){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:e,clientRttMs:e,failOpenReason:t}}var Yt=new Set(["ALLOW","DENY","REVIEW"]);E.GUARD_STATUS_REFUSED=410;async function Xt(e,t,n={}){if(!t||n.disabled)return null;let r=n.timeoutMs??Lt,i=Date.now(),o=new AbortController,a=setTimeout(()=>o.abort(),r);try{let u=await fetch(t,{method:"POST",headers:{"content-type":"application/json","user-agent":n.userAgent??Ct,"x-pinta-relay-token":n.token??"",...n.agentType?{"x-pinta-agent-type":n.agentType}:{},...Number.isFinite(r)&&r>0?{[E.GUARD_BUDGET_HEADER]:String(r)}:{}},body:JSON.stringify(e),signal:o.signal});if(u.status===E.GUARD_STATUS_REFUSED)return $(Date.now()-i,"refused");if(u.status!==200)return $(Date.now()-i,"error");let c=await u.json(),p=c?.durationMs===void 0||typeof c.durationMs=="number"&&Number.isFinite(c.durationMs);if(!c||!Yt.has(c.decision)||!p)return $(Date.now()-i,"error");let b=Date.now()-i;return{decision:c.decision,reason:c.reason??null,userMessage:c.userMessage??null,durationMs:c.durationMs??b,clientRttMs:b}}catch(u){let c=u.name,p=c==="AbortError"||c==="TimeoutError"?"timeout":"error";return $(Date.now()-i,p)}finally{clearTimeout(a)}}});var B=h(D=>{"use strict";var Ht=D&&D.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(D,"__esModule",{value:!0});D.atomicWriteFileSync=zt;var Ne=Ht(_("fs"));function zt(e,t){let n=`${e}.${process.pid}.tmp`;Ne.default.writeFileSync(n,t),Ne.default.renameSync(n,e)}});var te=h(S=>{"use strict";var je=S&&S.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(S,"__esModule",{value:!0});S.MemoryRetryQueue=S.DiskRetryQueue=void 0;var g=je(_("fs")),V=je(_("path")),Kt=B(),q=1e3,Zt=50,Wt=5,Q=class{filePath;lockPath;logPrefix;constructor(t,n){this.filePath=V.default.join(t,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=n}enqueue(t){try{g.default.mkdirSync(V.default.dirname(this.filePath),{recursive:!0});let n=JSON.stringify({savedAt:new Date().toISOString(),payload:t})+`
|
|
3
3
|
`;g.default.appendFileSync(this.filePath,n),this.trim()}catch(n){process.stderr.write(`[${this.logPrefix}] retry-queue enqueue failed: ${n}
|
|
4
4
|
`)}}readAll(){try{let t=g.default.readFileSync(this.filePath,"utf-8"),n=[];for(let r of t.split(`
|
|
5
|
-
`))if(r.trim())try{let i=JSON.parse(r);Array.isArray(i?.payload?.resourceSpans)&&n.push(i)}catch{}return n}catch{return[]}}rewrite(t){try{if(t.length===0){g.default.existsSync(this.filePath)&&g.default.unlinkSync(this.filePath);return}g.default.mkdirSync(V.default.dirname(this.filePath),{recursive:!0}),(0,
|
|
5
|
+
`))if(r.trim())try{let i=JSON.parse(r);Array.isArray(i?.payload?.resourceSpans)&&n.push(i)}catch{}return n}catch{return[]}}rewrite(t){try{if(t.length===0){g.default.existsSync(this.filePath)&&g.default.unlinkSync(this.filePath);return}g.default.mkdirSync(V.default.dirname(this.filePath),{recursive:!0}),(0,Kt.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
8
|
`)}}tryAcquireLock(){let t=Date.now();try{g.default.mkdirSync(V.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<
|
|
10
|
-
`),!1;try{let o=g.default.statSync(this.lockPath);if(Date.now()-o.mtimeMs>3e4){g.default.unlinkSync(this.lockPath);continue}}catch{}let r=
|
|
11
|
-
`),this.rewrite(t.slice(n))}};S.DiskRetryQueue=
|
|
9
|
+
`),!1}for(;Date.now()-t<Zt;)try{let n=g.default.openSync(this.lockPath,"wx");return g.default.writeSync(n,String(process.pid)),g.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 o=g.default.statSync(this.lockPath);if(Date.now()-o.mtimeMs>3e4){g.default.unlinkSync(this.lockPath);continue}}catch{}let r=Wt,i=Date.now()+r;for(;Date.now()<i;);}return!1}release(){try{g.default.unlinkSync(this.lockPath)}catch{}}trim(){let t=this.readAll();if(t.length<=q)return;let n=t.length-q;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${n} oldest entries
|
|
11
|
+
`),this.rewrite(t.slice(n))}};S.DiskRetryQueue=Q;var ee=class{entries=[];enqueue(t){this.entries.push(t),this.entries.length>q&&this.entries.splice(0,this.entries.length-q)}drain(){let t=this.entries;return this.entries=[],t}get size(){return this.entries.length}};S.MemoryRetryQueue=ee});var Ue=h(l=>{"use strict";Object.defineProperty(l,"__esModule",{value:!0});l.MemoryTransport=l.DiskTransport=l.MAX_POST_BYTES=void 0;l.parseHeadersEnv=Ve;l.envOptionsResolver=qe;l.postOtlp=x;var Ge=te(),$e=J(),Jt=5e3;l.MAX_POST_BYTES=900*1024;function U(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}function Be(e,t,n){let r=[],i=[],o=[],a=0;for(let u of e){let c=t(u);if(c>n){i.push(u);continue}o.length>0&&a+c>n&&(r.push(o),o=[],a=0),o.push(u),a+=c}return o.length>0&&r.push(o),{chunks:r,oversize:i}}function Ve(e){if(!e)return{};if(typeof e=="object")return{...e};let t={};for(let n of e.split(",")){let[r,...i]=n.split("=");r&&i.length>0&&(t[r.trim()]=i.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:Ve(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function x(e,t,n){let r=new AbortController,i=setTimeout(()=>r.abort(),Jt);try{let o=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify(e),signal:r.signal});if(!o.ok){let a="";try{a=(await o.text()).slice(0,200)}catch{}let u=o.status===401||o.status===403?" \u2014 check OTEL_EXPORTER_OTLP_HEADERS (relay token)":o.status===404?" \u2014 check OTEL_EXPORTER_OTLP_TRACES_ENDPOINT path":o.status>=500?" \u2014 collector may be down":"";return process.stderr.write(`[${n}] OTLP POST ${o.status} ${t.endpoint}${u}${a?` body=${a}`:""}
|
|
12
12
|
`),!1}return!0}catch(o){return process.stderr.write(`[${n}] OTLP POST failed: ${o.message??String(o)}
|
|
13
|
-
`),!1}finally{clearTimeout(i)}}var
|
|
14
|
-
`);let o=[].concat(...r),a=0;for(let u of r){if(!await x((0
|
|
15
|
-
`)}finally{this.queue.release()}}dropIfOversized(t){let n=
|
|
16
|
-
`),!0)}};l.DiskTransport=
|
|
17
|
-
`);return}await x(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:i}=
|
|
18
|
-
`);let o=[].concat(...r),a=0;for(let u of r){if(!await x((0
|
|
19
|
-
`)}}};
|
|
20
|
-
`)){let r=n.trim();if(!r||r.startsWith("#"))continue;let i=r.indexOf("=");if(i<0)continue;let o=r.slice(0,i).trim(),a=r.slice(i+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),o&&(t[o]=a)}return t}function on(e){let t;try{t=tn.default.readFileSync(e,"utf-8")}catch{return}let n=He(t);for(let[r,i]of Object.entries(n))process.env[r]===void 0&&(process.env[r]=i)}});var v=m(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 O=K();Object.defineProperty(s,"redact",{enumerable:!0,get:function(){return O.redact}});Object.defineProperty(s,"truncate",{enumerable:!0,get:function(){return O.truncate}});Object.defineProperty(s,"truncateTo",{enumerable:!0,get:function(){return O.truncateTo}});Object.defineProperty(s,"collectMatches",{enumerable:!0,get:function(){return O.collectMatches}});Object.defineProperty(s,"resolveOverlaps",{enumerable:!0,get:function(){return O.resolveOverlaps}});Object.defineProperty(s,"applyMatches",{enumerable:!0,get:function(){return O.applyMatches}});Object.defineProperty(s,"PATTERNS",{enumerable:!0,get:function(){return O.PATTERNS}});Object.defineProperty(s,"MAX_BYTES",{enumerable:!0,get:function(){return O.MAX_BYTES}});var h=J();Object.defineProperty(s,"ulidToTraceId",{enumerable:!0,get:function(){return h.ulidToTraceId}});Object.defineProperty(s,"newSpanId",{enumerable:!0,get:function(){return h.newSpanId}});Object.defineProperty(s,"snakeCase",{enumerable:!0,get:function(){return h.snakeCase}});Object.defineProperty(s,"toOtlpValue",{enumerable:!0,get:function(){return h.toOtlpValue}});Object.defineProperty(s,"attrsFromRecord",{enumerable:!0,get:function(){return h.attrsFromRecord}});Object.defineProperty(s,"guardAttrs",{enumerable:!0,get:function(){return h.guardAttrs}});Object.defineProperty(s,"clientAttrs",{enumerable:!0,get:function(){return h.clientAttrs}});Object.defineProperty(s,"buildPayload",{enumerable:!0,get:function(){return h.buildPayload}});Object.defineProperty(s,"attachGuard",{enumerable:!0,get:function(){return h.attachGuard}});Object.defineProperty(s,"mergeBatch",{enumerable:!0,get:function(){return h.mergeBatch}});Object.defineProperty(s,"enforceSpanBudget",{enumerable:!0,get:function(){return h.enforceSpanBudget}});Object.defineProperty(s,"MAX_SPAN_BYTES",{enumerable:!0,get:function(){return h.MAX_SPAN_BYTES}});var Ze=Ie();Object.defineProperty(s,"evaluateGuard",{enumerable:!0,get:function(){return Ze.evaluateGuard}});Object.defineProperty(s,"GUARD_STATUS_REFUSED",{enumerable:!0,get:function(){return Ze.GUARD_STATUS_REFUSED}});var Je=ee();Object.defineProperty(s,"DiskRetryQueue",{enumerable:!0,get:function(){return Je.DiskRetryQueue}});Object.defineProperty(s,"MemoryRetryQueue",{enumerable:!0,get:function(){return Je.MemoryRetryQueue}});var M=Be();Object.defineProperty(s,"DiskTransport",{enumerable:!0,get:function(){return M.DiskTransport}});Object.defineProperty(s,"MemoryTransport",{enumerable:!0,get:function(){return M.MemoryTransport}});Object.defineProperty(s,"postOtlp",{enumerable:!0,get:function(){return M.postOtlp}});Object.defineProperty(s,"envOptionsResolver",{enumerable:!0,get:function(){return M.envOptionsResolver}});Object.defineProperty(s,"parseHeadersEnv",{enumerable:!0,get:function(){return M.parseHeadersEnv}});Object.defineProperty(s,"MAX_POST_BYTES",{enumerable:!0,get:function(){return M.MAX_POST_BYTES}});var We=se();Object.defineProperty(s,"TraceManager",{enumerable:!0,get:function(){return We.TraceManager}});Object.defineProperty(s,"generateUlid",{enumerable:!0,get:function(){return We.generateUlid}});var Qe=Xe();Object.defineProperty(s,"DiskSessionTraceManager",{enumerable:!0,get:function(){return Qe.DiskSessionTraceManager}});Object.defineProperty(s,"MemorySessionTraceManager",{enumerable:!0,get:function(){return Qe.MemorySessionTraceManager}});var le=Ke();Object.defineProperty(s,"envFilePath",{enumerable:!0,get:function(){return le.envFilePath}});Object.defineProperty(s,"parseEnvFile",{enumerable:!0,get:function(){return le.parseEnvFile}});Object.defineProperty(s,"loadEnvFile",{enumerable:!0,get:function(){return le.loadEnvFile}})});var N=P(v(),1);function sn(){return(0,N.envFilePath)(".gemini","pinta-gemini.env","GEMINI_HOME")}function et(e=sn()){(0,N.loadEnvFile)(e)}var tt=P(v(),1);import an from"os";import de from"path";function un(){return process.env.GEMINI_HOME||de.join(an.homedir(),".gemini")}function cn(){let e=process.env.GEMINI_PLUGIN_OPTION_ENDPOINT||process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;if(e)return e.replace(/\/+$/,"");let t=process.env.OTEL_EXPORTER_OTLP_ENDPOINT;if(t)return t.replace(/\/+$/,"")+"/v1/traces"}function ln(){let e=(0,tt.parseHeadersEnv)(process.env.GEMINI_PLUGIN_OPTION_HEADERS||process.env.OTEL_EXPORTER_OTLP_HEADERS),t=process.env.GEMINI_PLUGIN_OPTION_API_KEY;return t&&!e["x-pinta-relay-token"]&&(e["x-pinta-relay-token"]=t),e}function nt(){let e=process.env.GEMINI_PLUGIN_DATA||de.join(un(),"pinta-gemini-data");return!process.env.PINTA_RELAY_TOKEN&&process.env.GEMINI_PLUGIN_OPTION_API_KEY&&(process.env.PINTA_RELAY_TOKEN=process.env.GEMINI_PLUGIN_OPTION_API_KEY),{pluginData:e,tracePath:de.join(e,"trace.json"),endpoint:cn(),headers:ln(),guardEndpoint:process.env.PINTA_GUARD_ENDPOINT}}function rt(e=process.argv){let t=n=>{let r=e.indexOf(n);return r>=0?e[r+1]:void 0};return{agent:t("--agent")||"gemini",event:t("--event")}}function it(e){let t=e.transcriptPath;if(typeof t=="string"){if(t.includes("/antigravity-cli/brain/"))return"agy";if(t.includes("/antigravity/brain/"))return"antigravity2"}}var _=e=>e==="gemini",dn={identity:{prefix:"gemini",ingest:"gemini",service:"gemini-cli"},gateEvent:"BeforeTool"},fn={identity:{prefix:"antigravity",ingest:"antigravity",service:"antigravity-cli"},gateEvent:"PreToolUse"},ot=e=>_(e)?dn:fn;function F(e){return ot(e).identity}function st(e){return ot(e).gateEvent}var pn=new Set(["AfterModel"]),at=e=>pn.has(e);function ut(e,t,n){if(_(e))return{hook:t||n.hook_event_name||"unknown",session_id:D(n.session_id),cwd:D(n.cwd),tool_name:D(n.tool_name),tool_input:n.tool_input};let r=n.workspacePaths,i=n.toolCall;return{hook:t||"unknown",session_id:D(n.conversationId),cwd:Array.isArray(r)?D(r[0]):void 0,tool_name:i?.name,tool_input:i?.args}}function D(e){return typeof e=="string"?e:void 0}var Ot=P(v(),1);var ct=P(v(),1);var C="0.11.0";var gn=50,yn=`pinta-gemini/${C}`;function lt(e,t,n,r){return(0,ct.evaluateGuard)(e,t,{timeoutMs:gn,token:n??process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:yn,agentType:r?F(r).ingest:void 0})}var dt=P(v(),1),L=class extends dt.DiskTransport{constructor(t){super({pluginData:t.pluginData,logPrefix:"pinta-gemini",resolveOptions:()=>t.endpoint?{endpoint:t.endpoint,headers:t.headers}:null})}};var ft=P(v(),1),U=class extends ft.DiskSessionTraceManager{constructor(t){super(t.tracePath)}};import ge from"os";import{execFileSync as gt}from"node:child_process";import Y from"node:fs";import R from"node:path";var hn=new Set(["","unknown","undefined","null","n/a","none","-"]);function pe(e){let t=typeof e=="string"?e.trim():void 0;return t&&!hn.has(t.toLowerCase())?t:void 0}var _n=/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/;function yt(e){let t=pe(e);return t&&_n.test(t)?t:void 0}var mn=["cli_version","cliVersion","gemini_version","geminiVersion","agent_version","agentVersion","app_version","appVersion","version"],vn="PINTA_GEMINI_HOST_VERSION",pt="PINTA_GEMINI_VERSION_PROBE",Pn=2e3,Sn=/(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)/;function ht(e){return _(e)?["gemini"]:["agy","antigravity","antigravity-cli"]}function En(e){let t=e;for(let n=0;n<5;n++){try{let i=Y.readFileSync(R.join(t,"package.json"),"utf8"),o=yt(JSON.parse(i).version);if(o)return o}catch{}let r=R.dirname(t);if(r===t)break;t=r}}function On(e){if(process.env[pt]==="1")return;let t;try{t=gt(e,["--version"],{encoding:"utf8",timeout:Pn,stdio:["ignore","pipe","ignore"],env:{...process.env,[pt]:"1"}})}catch{return}let n=t.split(/\r?\n/,5).map(r=>r.trim()).filter(Boolean);for(let r of n){let i=yt(r);if(i)return i}for(let r of n){let i=Sn.exec(r);if(i)return i[1]}}function _t(e){let t=e;try{t=Y.realpathSync(e)}catch{}return En(R.dirname(t))??On(e)}function Tn(e){if(process.platform==="win32")return;let t=process.ppid;if(!t||t<=1)return;let n;try{n=gt("ps",["-o","command=","-p",String(t)],{encoding:"utf8",timeout:2e3,stdio:["ignore","pipe","ignore"]}).trim()}catch{return}if(!n)return;let r=ht(e);for(let i of n.split(/\s+/)){if(!i.startsWith("/"))continue;let o=R.basename(i).replace(/\.(js|mjs|cjs)$/,"");if(!r.includes(o))continue;let a=_t(i);if(a)return a}}function An(e){let t=(process.env.PATH??"").split(R.delimiter).filter(Boolean);if(t.length===0)return;let n=process.platform==="win32"?[".cmd",".exe",""]:[""];for(let r of ht(e))for(let i of t)for(let o of n){let a=R.join(i,r+o);try{Y.accessSync(a,Y.constants.X_OK)}catch{continue}let u=_t(a);if(u)return u}}var fe;function bn(e){return pe(process.env[vn])??Tn(e)??An(e)??null}function mt(e,t){if(t)for(let n of mn){let r=pe(t[n]);if(r)return r}return fe===void 0&&(fe=bn(e)),fe??void 0}var T=P(v(),1),Rn=P(v(),1),X;function kn(){if(X===void 0)try{X=ge.userInfo().username}catch{X=process.env.USER??process.env.LOGNAME??(typeof process.getuid=="function"?String(process.getuid()):"unknown")}return X}var vt=C;function wn(e){return{skipRedactKeys:new Set([`${e}.hook`,`${e}.agent`,`${e}.tool_name`,`${e}.session_id`,`${e}.transcript_path`,`${e}.transcriptPath`,`${e}.cwd`]),bashContextKeys:new Set([`${e}.tool_input`,`${e}.tool_response`,`${e}.toolCall`])}}function Mn(e,t){return[{key:"service.name",value:{stringValue:e}},...t?[{key:"service.version",value:{stringValue:t}}]:[],{key:"telemetry.sdk.name",value:{stringValue:"pinta-gemini"}},{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:kn()}},{key:"host.name",value:{stringValue:ge.hostname()}},{key:"host.arch",value:{stringValue:ge.arch()}}]}function Pt(e){let t=F(e.agent),n=wn(t.prefix),r=[{key:"ingest.type",value:{stringValue:t.ingest}},{key:`${t.prefix}.hook`,value:{stringValue:e.canonical.hook}},{key:`${t.prefix}.agent`,value:{stringValue:e.agent}}];e.product&&r.push({key:`${t.prefix}.product`,value:{stringValue:e.product}}),r.push(...(0,T.attrsFromRecord)(e.event,t.prefix,n));let i=new Set(r.map(o=>o.key));for(let[o,a]of[["session_id",e.canonical.session_id],["cwd",e.canonical.cwd],["tool_name",e.canonical.tool_name]]){let u=`${t.prefix}.${o}`;if(a!=null&&!i.has(u)){let c=(0,T.toOtlpValue)(u,String(a),n);c!==null&&r.push({key:u,value:c})}}return(0,T.buildPayload)({traceId:e.traceId,spanName:`${t.ingest}.${(0,T.snakeCase)(e.canonical.hook)}`,attributes:r,resource:Mn(t.service,mt(e.agent,e.event)),scope:{name:"pinta-gemini",version:vt},now:e.now})}function ye(e,t,n){if(n&&n.decision==="DENY"){let r=n.userMessage??n.reason??"guard_deny";return _(e)?{decision:"deny",reason:r,systemMessage:n.userMessage??void 0}:{decision:"deny",reason:r}}return!_(e)&&t==="PreToolUse"?{decision:"allow"}:{}}import St from"fs";import In from"path";function Et(e,t){if(process.env.PINTA_GEMINI_DEBUG==="1")try{St.mkdirSync(e.pluginData,{recursive:!0}),St.appendFileSync(In.join(e.pluginData,"invocations.jsonl"),JSON.stringify(t)+`
|
|
21
|
-
`)}catch{}}async function
|
|
22
|
-
`),n=o?ye(e,t,o):{}}
|
|
23
|
-
`),process.exit(0)}
|
|
13
|
+
`),!1}finally{clearTimeout(i)}}var ne=class{queue;logPrefix;resolveOptions;constructor(t){this.queue=new Ge.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 x(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:i}=Be(n,u=>U(u.payload),l.MAX_POST_BYTES);i.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${i.length} oversized retry ${i.length===1?"entry":"entries"} (each > ${l.MAX_POST_BYTES} bytes \u2014 the backend caps the request body, so they can never be delivered)
|
|
14
|
+
`);let o=[].concat(...r),a=0;for(let u of r){if(!await x((0,$e.mergeBatch)(u.map(p=>p.payload)),t,this.logPrefix))break;a+=u.length}this.queue.rewrite(o.slice(a))}catch(n){process.stderr.write(`[${this.logPrefix}] flush failed: ${n?.message??String(n)}
|
|
15
|
+
`)}finally{this.queue.release()}}dropIfOversized(t){let n=U(t);return n<=l.MAX_POST_BYTES?!1:(process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (${n} > ${l.MAX_POST_BYTES} bytes) \u2014 undeliverable, not queued
|
|
16
|
+
`),!0)}};l.DiskTransport=ne;var re=class{queue=new Ge.MemoryRetryQueue;logPrefix;resolveOptions;constructor(t){this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions}async send(t){let n=this.resolveOptions();if(!n)return;if(U(t)>l.MAX_POST_BYTES){process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (> ${l.MAX_POST_BYTES} bytes) \u2014 undeliverable, not buffered
|
|
17
|
+
`);return}await x(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:i}=Be(n,U,l.MAX_POST_BYTES);i.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${i.length} oversized buffered ${i.length===1?"payload":"payloads"} (each > ${l.MAX_POST_BYTES} bytes \u2014 undeliverable)
|
|
18
|
+
`);let o=[].concat(...r),a=0;for(let u of r){if(!await x((0,$e.mergeBatch)(u),t,this.logPrefix))break;a+=u.length}for(let u of o.slice(a))this.queue.enqueue(u)}};l.MemoryTransport=re});var ae=h(k=>{"use strict";var se=k&&k.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(k,"__esModule",{value:!0});k.TraceManager=void 0;k.generateUlid=Le;var Fe=se(_("fs")),Qt=se(_("path")),en=se(_("crypto")),tn=B(),ie="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Le(){let e=Date.now(),t="",n=e;for(let o=0;o<10;o++)t=ie[n&31]+t,n=Math.floor(n/32);let r=en.default.randomBytes(10),i="";for(let o=0;o<10;o++)i+=ie[r[o]&31];for(;i.length<16;)i+=ie[0];return t+i}var oe=class{tracePath;constructor(t){this.tracePath=t}newTrace(){let t=Le();return this.save(t),t}currentTrace(){try{let t=Fe.default.readFileSync(this.tracePath,"utf-8"),{traceId:n}=JSON.parse(t);if(n)return n}catch{}return this.newTrace()}save(t){try{Fe.default.mkdirSync(Qt.default.dirname(this.tracePath),{recursive:!0}),(0,tn.atomicWriteFileSync)(this.tracePath,JSON.stringify({traceId:t}))}catch(n){process.stderr.write(`[pinta-core] trace persistence failed: ${n}
|
|
19
|
+
`)}}};k.TraceManager=oe});var ze=h(T=>{"use strict";var Ye=T&&T.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(T,"__esModule",{value:!0});T.MemorySessionTraceManager=T.DiskSessionTraceManager=void 0;var Ce=Ye(_("fs")),nn=Ye(_("path")),Xe=ae(),rn=B(),He=200,ue=class{tracePath;maxSessions;constructor(t,n={}){this.tracePath=t,this.maxSessions=n.maxSessions??He}read(){try{let t=JSON.parse(Ce.default.readFileSync(this.tracePath,"utf-8"));if(t&&typeof t=="object"&&!("traceId"in t))return t}catch{}return{}}write(t){try{Ce.default.mkdirSync(nn.default.dirname(this.tracePath),{recursive:!0});let n=Object.entries(t),r=n.length>this.maxSessions?Object.fromEntries(n.slice(-this.maxSessions)):t;(0,rn.atomicWriteFileSync)(this.tracePath,JSON.stringify(r))}catch{}}newTrace(t){let n=t||"default",r=(0,Xe.generateUlid)(),i=this.read();return i[n]=r,this.write(i),r}currentTrace(t){let n=t||"default",r=this.read()[n];return r||this.newTrace(n)}};T.DiskSessionTraceManager=ue;var ce=class{map=new Map;maxSessions;constructor(t={}){this.maxSessions=t.maxSessions??He}newTrace(t){let n=t||"default",r=(0,Xe.generateUlid)();if(this.map.set(n,r),this.map.size>this.maxSessions){let i=this.map.keys().next().value;i!==void 0&&this.map.delete(i)}return r}currentTrace(t){let n=t||"default";return this.map.get(n)??this.newTrace(n)}};T.MemorySessionTraceManager=ce});var We=h(w=>{"use strict";var le=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(w,"__esModule",{value:!0});w.envFilePath=an;w.parseEnvFile=Ze;w.loadEnvFile=un;var on=le(_("node:fs")),sn=le(_("node:os")),Ke=le(_("node:path"));function an(e,t,n){let r=n?process.env[n]:void 0,i=r&&r.length>0?r:Ke.default.join(sn.default.homedir(),e);return Ke.default.join(i,t)}function Ze(e){let t={};for(let n of e.split(`
|
|
20
|
+
`)){let r=n.trim();if(!r||r.startsWith("#"))continue;let i=r.indexOf("=");if(i<0)continue;let o=r.slice(0,i).trim(),a=r.slice(i+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),o&&(t[o]=a)}return t}function un(e){let t;try{t=on.default.readFileSync(e,"utf-8")}catch{return}let n=Ze(t);for(let[r,i]of Object.entries(n))process.env[r]===void 0&&(process.env[r]=i)}});var v=h(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_BUDGET_HEADER=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 O=Z();Object.defineProperty(s,"redact",{enumerable:!0,get:function(){return O.redact}});Object.defineProperty(s,"truncate",{enumerable:!0,get:function(){return O.truncate}});Object.defineProperty(s,"truncateTo",{enumerable:!0,get:function(){return O.truncateTo}});Object.defineProperty(s,"collectMatches",{enumerable:!0,get:function(){return O.collectMatches}});Object.defineProperty(s,"resolveOverlaps",{enumerable:!0,get:function(){return O.resolveOverlaps}});Object.defineProperty(s,"applyMatches",{enumerable:!0,get:function(){return O.applyMatches}});Object.defineProperty(s,"PATTERNS",{enumerable:!0,get:function(){return O.PATTERNS}});Object.defineProperty(s,"MAX_BYTES",{enumerable:!0,get:function(){return O.MAX_BYTES}});var y=J();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 de=xe();Object.defineProperty(s,"evaluateGuard",{enumerable:!0,get:function(){return de.evaluateGuard}});Object.defineProperty(s,"GUARD_STATUS_REFUSED",{enumerable:!0,get:function(){return de.GUARD_STATUS_REFUSED}});Object.defineProperty(s,"GUARD_BUDGET_HEADER",{enumerable:!0,get:function(){return de.GUARD_BUDGET_HEADER}});var Je=te();Object.defineProperty(s,"DiskRetryQueue",{enumerable:!0,get:function(){return Je.DiskRetryQueue}});Object.defineProperty(s,"MemoryRetryQueue",{enumerable:!0,get:function(){return Je.MemoryRetryQueue}});var R=Ue();Object.defineProperty(s,"DiskTransport",{enumerable:!0,get:function(){return R.DiskTransport}});Object.defineProperty(s,"MemoryTransport",{enumerable:!0,get:function(){return R.MemoryTransport}});Object.defineProperty(s,"postOtlp",{enumerable:!0,get:function(){return R.postOtlp}});Object.defineProperty(s,"envOptionsResolver",{enumerable:!0,get:function(){return R.envOptionsResolver}});Object.defineProperty(s,"parseHeadersEnv",{enumerable:!0,get:function(){return R.parseHeadersEnv}});Object.defineProperty(s,"MAX_POST_BYTES",{enumerable:!0,get:function(){return R.MAX_POST_BYTES}});var Qe=ae();Object.defineProperty(s,"TraceManager",{enumerable:!0,get:function(){return Qe.TraceManager}});Object.defineProperty(s,"generateUlid",{enumerable:!0,get:function(){return Qe.generateUlid}});var et=ze();Object.defineProperty(s,"DiskSessionTraceManager",{enumerable:!0,get:function(){return et.DiskSessionTraceManager}});Object.defineProperty(s,"MemorySessionTraceManager",{enumerable:!0,get:function(){return et.MemorySessionTraceManager}});var fe=We();Object.defineProperty(s,"envFilePath",{enumerable:!0,get:function(){return fe.envFilePath}});Object.defineProperty(s,"parseEnvFile",{enumerable:!0,get:function(){return fe.parseEnvFile}});Object.defineProperty(s,"loadEnvFile",{enumerable:!0,get:function(){return fe.loadEnvFile}})});var N=P(v(),1);function cn(){return(0,N.envFilePath)(".gemini","pinta-gemini.env","GEMINI_HOME")}function tt(e=cn()){(0,N.loadEnvFile)(e)}var nt=P(v(),1);import ln from"os";import pe from"path";function dn(){return process.env.GEMINI_HOME||pe.join(ln.homedir(),".gemini")}function fn(){let e=process.env.GEMINI_PLUGIN_OPTION_ENDPOINT||process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;if(e)return e.replace(/\/+$/,"");let t=process.env.OTEL_EXPORTER_OTLP_ENDPOINT;if(t)return t.replace(/\/+$/,"")+"/v1/traces"}function pn(){let e=(0,nt.parseHeadersEnv)(process.env.GEMINI_PLUGIN_OPTION_HEADERS||process.env.OTEL_EXPORTER_OTLP_HEADERS),t=process.env.GEMINI_PLUGIN_OPTION_API_KEY;return t&&!e["x-pinta-relay-token"]&&(e["x-pinta-relay-token"]=t),e}function rt(){let e=process.env.GEMINI_PLUGIN_DATA||pe.join(dn(),"pinta-gemini-data");return!process.env.PINTA_RELAY_TOKEN&&process.env.GEMINI_PLUGIN_OPTION_API_KEY&&(process.env.PINTA_RELAY_TOKEN=process.env.GEMINI_PLUGIN_OPTION_API_KEY),{pluginData:e,tracePath:pe.join(e,"trace.json"),endpoint:fn(),headers:pn(),guardEndpoint:process.env.PINTA_GUARD_ENDPOINT}}function it(e=process.argv){let t=n=>{let r=e.indexOf(n);return r>=0?e[r+1]:void 0};return{agent:t("--agent")||"gemini",event:t("--event")}}function ot(e){let t=e.transcriptPath;if(typeof t=="string"){if(t.includes("/antigravity-cli/brain/"))return"agy";if(t.includes("/antigravity/brain/"))return"antigravity2"}}var m=e=>e==="gemini",gn={identity:{prefix:"gemini",ingest:"gemini",service:"gemini-cli"},gateEvent:"BeforeTool"},mn={identity:{prefix:"antigravity",ingest:"antigravity",service:"antigravity-cli"},gateEvent:"PreToolUse"},st=e=>m(e)?gn:mn;function F(e){return st(e).identity}function at(e){return st(e).gateEvent}var _n=new Set(["AfterModel"]),ut=e=>_n.has(e);function ct(e,t,n){if(m(e))return{hook:t||n.hook_event_name||"unknown",session_id:j(n.session_id),cwd:j(n.cwd),tool_name:j(n.tool_name),tool_input:n.tool_input};let r=n.workspacePaths,i=n.toolCall;return{hook:t||"unknown",session_id:j(n.conversationId),cwd:Array.isArray(r)?j(r[0]):void 0,tool_name:i?.name,tool_input:i?.args}}function j(e){return typeof e=="string"?e:void 0}var bt=P(v(),1);var lt=P(v(),1);var L="0.13.0";var yn=100,hn=`pinta-gemini/${L}`;function dt(e,t,n,r){return(0,lt.evaluateGuard)(e,t,{timeoutMs:yn,token:n??process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:hn,agentType:r?F(r).ingest:void 0})}var ft=P(v(),1),C=class extends ft.DiskTransport{constructor(t){super({pluginData:t.pluginData,logPrefix:"pinta-gemini",resolveOptions:()=>t.endpoint?{endpoint:t.endpoint,headers:t.headers}:null})}};var pt=P(v(),1),Y=class extends pt.DiskSessionTraceManager{constructor(t){super(t.tracePath)}};import _e from"os";import{execFileSync as mt}from"node:child_process";import X from"node:fs";import M from"node:path";var En=new Set(["","unknown","undefined","null","n/a","none","-"]);function me(e){let t=typeof e=="string"?e.trim():void 0;return t&&!En.has(t.toLowerCase())?t:void 0}var vn=/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/;function _t(e){let t=me(e);return t&&vn.test(t)?t:void 0}var Pn=["cli_version","cliVersion","gemini_version","geminiVersion","agent_version","agentVersion","app_version","appVersion","version"],Sn="PINTA_GEMINI_HOST_VERSION",gt="PINTA_GEMINI_VERSION_PROBE",Tn=2e3,On=/(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)/;function yt(e){return m(e)?["gemini"]:["agy","antigravity","antigravity-cli"]}function An(e){let t=e;for(let n=0;n<5;n++){try{let i=X.readFileSync(M.join(t,"package.json"),"utf8"),o=_t(JSON.parse(i).version);if(o)return o}catch{}let r=M.dirname(t);if(r===t)break;t=r}}function bn(e){if(process.env[gt]==="1")return;let t;try{t=mt(e,["--version"],{encoding:"utf8",timeout:Tn,stdio:["ignore","pipe","ignore"],env:{...process.env,[gt]:"1"}})}catch{return}let n=t.split(/\r?\n/,5).map(r=>r.trim()).filter(Boolean);for(let r of n){let i=_t(r);if(i)return i}for(let r of n){let i=On.exec(r);if(i)return i[1]}}function ht(e){let t=e;try{t=X.realpathSync(e)}catch{}return An(M.dirname(t))??bn(e)}function kn(e){if(process.platform==="win32")return;let t=process.ppid;if(!t||t<=1)return;let n;try{n=mt("ps",["-o","command=","-p",String(t)],{encoding:"utf8",timeout:2e3,stdio:["ignore","pipe","ignore"]}).trim()}catch{return}if(!n)return;let r=yt(e);for(let i of n.split(/\s+/)){if(!i.startsWith("/"))continue;let o=M.basename(i).replace(/\.(js|mjs|cjs)$/,"");if(!r.includes(o))continue;let a=ht(i);if(a)return a}}function wn(e){let t=(process.env.PATH??"").split(M.delimiter).filter(Boolean);if(t.length===0)return;let n=process.platform==="win32"?[".cmd",".exe",""]:[""];for(let r of yt(e))for(let i of t)for(let o of n){let a=M.join(i,r+o);try{X.accessSync(a,X.constants.X_OK)}catch{continue}let u=ht(a);if(u)return u}}var ge;function Rn(e){return me(process.env[Sn])??kn(e)??wn(e)??null}function Et(e,t){if(t)for(let n of Pn){let r=me(t[n]);if(r)return r}return ge===void 0&&(ge=Rn(e)),ge??void 0}var Mn=new Set(["unknown","undefined","null","n/a","none","-","auto","default"]);function In(e){if(typeof e!="string")return;let t=e.trim();if(!(!t||t.startsWith("{")||t.startsWith("[")||Mn.has(t.toLowerCase())))return t}function vt(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function I(e,t){let n=In(e);return n?{model:n,source:t}:void 0}function Dn(e,t,n){if(m(e)){if(t==="AfterModel"){let r=vt(n.llm_response),i=I(r?.modelVersion,"response:llm_response.modelVersion")??I(r?.model,"response:llm_response.model");if(i)return i}if(t==="BeforeModel"||t==="BeforeToolSelection"||t==="AfterModel"){let r=I(vt(n.llm_request)?.model,"requested:llm_request.model");if(r)return r}return I(n.model,"reported:model")}return I(n.model,"reported:model")??I(n.modelId,"reported:modelId")}function Pt(e,t,n){let r=Dn(e,t,n),{model:i,model_source:o,...a}=n;return"model"in n&&i!==r?.model&&(a.model_raw=i),"model_source"in n&&(a.model_source_raw=o),r&&(a.model=r.model,a.model_source=r.source),a}var A=P(v(),1),Gn=P(v(),1),H;function xn(){if(H===void 0)try{H=_e.userInfo().username}catch{H=process.env.USER??process.env.LOGNAME??(typeof process.getuid=="function"?String(process.getuid()):"unknown")}return H}var St=L;function Nn(e){return{skipRedactKeys:new Set([`${e}.hook`,`${e}.agent`,`${e}.tool_name`,`${e}.session_id`,`${e}.transcript_path`,`${e}.transcriptPath`,`${e}.cwd`]),bashContextKeys:new Set([`${e}.tool_input`,`${e}.tool_response`,`${e}.toolCall`])}}function jn(e,t){return[{key:"service.name",value:{stringValue:e}},...t?[{key:"service.version",value:{stringValue:t}}]:[],{key:"telemetry.sdk.name",value:{stringValue:"pinta-gemini"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:St}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:xn()}},{key:"host.name",value:{stringValue:_e.hostname()}},{key:"host.arch",value:{stringValue:_e.arch()}}]}function Tt(e){let t=F(e.agent),n=Nn(t.prefix),r=[{key:"ingest.type",value:{stringValue:t.ingest}},{key:`${t.prefix}.hook`,value:{stringValue:e.canonical.hook}},{key:`${t.prefix}.agent`,value:{stringValue:e.agent}}];e.product&&r.push({key:`${t.prefix}.product`,value:{stringValue:e.product}}),r.push(...(0,A.attrsFromRecord)(Pt(e.agent,e.canonical.hook,e.event),t.prefix,n));let i=new Set(r.map(o=>o.key));for(let[o,a]of[["session_id",e.canonical.session_id],["cwd",e.canonical.cwd],["tool_name",e.canonical.tool_name]]){let u=`${t.prefix}.${o}`;if(a!=null&&!i.has(u)){let c=(0,A.toOtlpValue)(u,String(a),n);c!==null&&r.push({key:u,value:c})}}return(0,A.buildPayload)({traceId:e.traceId,spanName:`${t.ingest}.${(0,A.snakeCase)(e.canonical.hook)}`,attributes:r,resource:jn(t.service,Et(e.agent,e.event)),scope:{name:"pinta-gemini",version:St},now:e.now})}function ye(e,t,n){if(n&&n.decision==="DENY"){let r=n.userMessage??n.reason??"guard_deny";return m(e)?{decision:"deny",reason:r,systemMessage:n.userMessage??void 0}:{decision:"deny",reason:r}}return!m(e)&&t==="PreToolUse"?{decision:"allow"}:{}}import Ot from"fs";import $n from"path";function At(e,t){if(process.env.PINTA_GEMINI_DEBUG==="1")try{Ot.mkdirSync(e.pluginData,{recursive:!0}),Ot.appendFileSync($n.join(e.pluginData,"invocations.jsonl"),JSON.stringify(t)+`
|
|
21
|
+
`)}catch{}}async function Bn(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}function Vn(e,t,n){return m(e)?t.hook==="BeforeAgent":t.hook==="PreInvocation"&&n.invocationNum===1}async function kt(){let{agent:e,event:t}=it(),n={},r={},i,o=null,a=rt();try{if(r=JSON.parse(await Bn()||"{}"),i=ct(e,t,r),!ut(i.hook)){let u=new C(a);await u.flush();let c=i.session_id??"unknown",p=new Y(a),b=Vn(e,i,r)?p.newTrace(c):p.currentTrace(c),z=m(e)?void 0:ot(r),K=Tt({agent:e,canonical:i,event:r,traceId:b,product:z});i.hook===at(e)&&(o=await dt(K,a.guardEndpoint,a.headers["x-pinta-relay-token"],e)),n=ye(e,t,o),(0,bt.attachGuard)(K,o),await u.send(K)}}catch(u){process.stderr.write(`[pinta-gemini] error: ${u}
|
|
22
|
+
`),n=o?ye(e,t,o):{}}At(a,{ts:new Date().toISOString(),pid:process.pid,agent:e,event:t,argv:process.argv.slice(2),received_payload:r,normalized:i??null,guard:o,decision_returned:n}),process.stdout.write(JSON.stringify(n)+`
|
|
23
|
+
`),process.exit(0)}tt();kt();
|
package/dist/index.mjs
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { createRequire as __pintaCreateRequire } from 'module'; const require = __pintaCreateRequire(import.meta.url);
|
|
2
|
-
var
|
|
3
|
-
`;
|
|
4
|
-
`)}}readAll(){try{let t=
|
|
5
|
-
`))if(r.trim())try{let i=JSON.parse(r);Array.isArray(i?.payload?.resourceSpans)&&n.push(i)}catch{}return n}catch{return[]}}rewrite(t){try{if(t.length===0){
|
|
2
|
+
var Xt=Object.create;var Ae=Object.defineProperty;var Ht=Object.getOwnPropertyDescriptor;var zt=Object.getOwnPropertyNames;var Wt=Object.getPrototypeOf,Zt=Object.prototype.hasOwnProperty;var P=(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 E=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Jt=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of zt(t))!Zt.call(e,i)&&i!==n&&Ae(e,i,{get:()=>t[i],enumerable:!(r=Ht(t,i))||r.enumerable});return e};var O=(e,t,n)=>(n=e!=null?Xt(Wt(e)):{},Jt(t||!e||!e.__esModule?Ae(n,"default",{value:e,enumerable:!0}):n,e));var re=E(y=>{"use strict";Object.defineProperty(y,"__esModule",{value:!0});y.PATTERNS=y.MAX_BYTES=void 0;y.truncateTo=ke;y.truncate=Qt;y.collectMatches=Re;y.resolveOverlaps=Me;y.applyMatches=Ie;y.redact=en;y.MAX_BYTES=102400;function ke(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 Qt(e){return ke(e,y.MAX_BYTES)}y.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 Re(e,t){let n=[];for(let r of y.PATTERNS){if(r.requireContext&&r.requireContext!==t.context)continue;let i=new RegExp(r.regex.source,r.regex.flags),s;for(;(s=i.exec(e))!==null;){let a=r.captureGroup??0,c=s[a];if(c===void 0){s.index===i.lastIndex&&i.lastIndex++;continue}let u=s.index,l=s.index+s[0].length,m=u+s[0].indexOf(c),f=m+c.length;n.push({start:u,end:l,replaceStart:m,replaceEnd:f,type:r.type}),s.index===i.lastIndex&&i.lastIndex++}}return n}function Me(e){let t=[...e].sort((i,s)=>i.start!==s.start?i.start-s.start:s.end-s.start-(i.end-i.start)),n=[],r=-1;for(let i of t)i.start<r||(n.push(i),r=i.end);return n}function Ie(e,t){let n=[...t].sort((i,s)=>s.replaceStart-i.replaceStart),r=e;for(let i of n)r=r.slice(0,i.replaceStart)+`[REDACTED:${i.type}]`+r.slice(i.replaceEnd);return r}function en(e,t={}){if(e.length===0)return e;let n=Re(e,t);if(n.length===0)return e;let r=Me(n);return Ie(e,r)}});var se=E(p=>{"use strict";var tn=p&&p.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(p,"__esModule",{value:!0});p.MAX_SPAN_BYTES=void 0;p.ulidToTraceId=Ne;p.newSpanId=Ge;p.snakeCase=sn;p.toOtlpValue=$e;p.attrsFromRecord=on;p.guardAttrs=qe;p.clientAttrs=Fe;p.enforceSpanBudget=Ce;p.buildPayload=an;p.attachGuard=Be;p.mergeBatch=cn;var nn=tn(P("crypto")),ie=re(),rn="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Ne(e){if(e.length!==26)throw new Error(`ulidToTraceId: expected 26 chars, got ${e.length}`);let t=0n;for(let r of e){let i=rn.indexOf(r);if(i<0)throw new Error(`ulidToTraceId: invalid Crockford char "${r}"`);t=t<<5n|BigInt(i)}let n=(1n<<128n)-1n;return t&=n,t.toString(16).padStart(32,"0")}function Ge(){return nn.default.randomBytes(8).toString("hex")}function sn(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var De=new Set;function U(e,t,n){let r=(0,ie.truncate)(t);if((n.skipRedactKeys??De).has(e))return r;let i=(n.bashContextKeys??De).has(e)?"bash":void 0;return(0,ie.redact)(r,{context:i})}function $e(e,t,n={}){if(t==null)return null;switch(typeof t){case"string":return{stringValue:U(e,t,n)};case"boolean":return{boolValue:t};case"number":return Number.isInteger(t)?{intValue:t}:{doubleValue:t};case"object":try{return{stringValue:U(e,JSON.stringify(t),n)}}catch{return{stringValue:U(e,String(t),n)}}default:return{stringValue:U(e,String(t),n)}}}function on(e,t,n={}){let r=[];for(let[i,s]of Object.entries(e)){let a=`${t}.${i}`,c=$e(a,s,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 Fe(e){return[{key:"pinta.client.rtt_ms",value:Number.isInteger(e.rttMs)?{intValue:e.rttMs}:{doubleValue:e.rttMs}},{key:"pinta.client.op",value:{stringValue:e.op}}]}p.MAX_SPAN_BYTES=800*1024;function je(e){let t=JSON.stringify(e);return t===void 0?0:Buffer.byteLength(t,"utf-8")}var xe=1024;function Ce(e,t=p.MAX_SPAN_BYTES){let n=je(e);for(let r=0;r<100&&n>t;r++){let i=null,s=0;for(let u of e.attributes){if(!("stringValue"in u.value))continue;let l=Buffer.byteLength(u.value.stringValue,"utf-8");l>s&&(s=l,i=u.value)}if(i===null||s<=xe)break;let a=n-t,c=Math.max(xe,s-a-64);i.stringValue=(0,ie.truncateTo)(i.stringValue,c),n=je(e)}return e}function an(e){let t=e.now??Date.now(),n=(BigInt(t)*1000000n).toString(),r=[...e.attributes],i={traceId:Ne(e.traceId),spanId:Ge(),name:e.spanName,kind:e.spanKind??1,startTimeUnixNano:n,endTimeUnixNano:n,attributes:r};Ce(i);let s={resourceSpans:[{resource:{attributes:e.resource},scopeSpans:[{scope:e.scope,spans:[i]}]}]};return Be(s,e.guard,e.clientTiming)}function Be(e,t,n){let r=e.resourceSpans[0]?.scopeSpans[0]?.spans[0];if(!r)return e;t&&r.attributes.push(...qe(t));let i=n??(t?.clientRttMs!==void 0?{op:"guard",rttMs:t.clientRttMs}:null);return i&&r.attributes.push(...Fe(i)),e}function cn(e){let t=[];for(let n of e)t.push(...n.resourceSpans);return{resourceSpans:t}}});var Ve=E(T=>{"use strict";Object.defineProperty(T,"__esModule",{value:!0});T.GUARD_STATUS_REFUSED=T.GUARD_BUDGET_HEADER=void 0;T.evaluateGuard=fn;var un=1e4,ln="pinta-core";T.GUARD_BUDGET_HEADER="x-pinta-guard-budget-ms";function L(e,t){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:e,clientRttMs:e,failOpenReason:t}}var dn=new Set(["ALLOW","DENY","REVIEW"]);T.GUARD_STATUS_REFUSED=410;async function fn(e,t,n={}){if(!t||n.disabled)return null;let r=n.timeoutMs??un,i=Date.now(),s=new AbortController,a=setTimeout(()=>s.abort(),r);try{let c=await fetch(t,{method:"POST",headers:{"content-type":"application/json","user-agent":n.userAgent??ln,"x-pinta-relay-token":n.token??"",...n.agentType?{"x-pinta-agent-type":n.agentType}:{},...Number.isFinite(r)&&r>0?{[T.GUARD_BUDGET_HEADER]:String(r)}:{}},body:JSON.stringify(e),signal:s.signal});if(c.status===T.GUARD_STATUS_REFUSED)return L(Date.now()-i,"refused");if(c.status!==200)return L(Date.now()-i,"error");let u=await c.json(),l=u?.durationMs===void 0||typeof u.durationMs=="number"&&Number.isFinite(u.durationMs);if(!u||!dn.has(u.decision)||!l)return L(Date.now()-i,"error");let m=Date.now()-i;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 L(Date.now()-i,l)}finally{clearTimeout(a)}}});var Y=E(q=>{"use strict";var pn=q&&q.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(q,"__esModule",{value:!0});q.atomicWriteFileSync=gn;var Ue=pn(P("fs"));function gn(e,t){let n=`${e}.${process.pid}.tmp`;Ue.default.writeFileSync(n,t),Ue.default.renameSync(n,e)}});var ce=E(w=>{"use strict";var Le=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(w,"__esModule",{value:!0});w.MemoryRetryQueue=w.DiskRetryQueue=void 0;var h=Le(P("fs")),K=Le(P("path")),mn=Y(),X=1e3,yn=50,hn=5,oe=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{h.default.mkdirSync(K.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 i=JSON.parse(r);Array.isArray(i?.payload?.resourceSpans)&&n.push(i)}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(K.default.dirname(this.filePath),{recursive:!0}),(0,mn.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 s=
|
|
11
|
-
`),this.rewrite(t.slice(n))}};
|
|
8
|
+
`)}}tryAcquireLock(){let t=Date.now();try{h.default.mkdirSync(K.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<yn;)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 s=h.default.statSync(this.lockPath);if(Date.now()-s.mtimeMs>3e4){h.default.unlinkSync(this.lockPath);continue}}catch{}let r=hn,i=Date.now()+r;for(;Date.now()<i;);}return!1}release(){try{h.default.unlinkSync(this.lockPath)}catch{}}trim(){let t=this.readAll();if(t.length<=X)return;let n=t.length-X;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${n} oldest entries
|
|
11
|
+
`),this.rewrite(t.slice(n))}};w.DiskRetryQueue=oe;var ae=class{entries=[];enqueue(t){this.entries.push(t),this.entries.length>X&&this.entries.splice(0,this.entries.length-X)}drain(){let t=this.entries;return this.entries=[],t}get size(){return this.entries.length}};w.MemoryRetryQueue=ae});var We=E(d=>{"use strict";Object.defineProperty(d,"__esModule",{value:!0});d.MemoryTransport=d.DiskTransport=d.MAX_POST_BYTES=void 0;d.parseHeadersEnv=He;d.envOptionsResolver=ze;d.postOtlp=F;var Ye=ce(),Ke=se(),_n=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 Xe(e,t,n){let r=[],i=[],s=[],a=0;for(let c of e){let u=t(c);if(u>n){i.push(c);continue}s.length>0&&a+u>n&&(r.push(s),s=[],a=0),s.push(c),a+=u}return s.length>0&&r.push(s),{chunks:r,oversize:i}}function He(e){if(!e)return{};if(typeof e=="object")return{...e};let t={};for(let n of e.split(",")){let[r,...i]=n.split("=");r&&i.length>0&&(t[r.trim()]=i.join("=").trim())}return t}function ze(){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 F(e,t,n){let r=new AbortController,i=setTimeout(()=>r.abort(),_n);try{let s=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify(e),signal:r.signal});if(!s.ok){let a="";try{a=(await s.text()).slice(0,200)}catch{}let c=s.status===401||s.status===403?" \u2014 check OTEL_EXPORTER_OTLP_HEADERS (relay token)":s.status===404?" \u2014 check OTEL_EXPORTER_OTLP_TRACES_ENDPOINT path":s.status>=500?" \u2014 collector may be down":"";return process.stderr.write(`[${n}] OTLP POST ${s.status} ${t.endpoint}${c}${a?` body=${a}`:""}
|
|
12
12
|
`),!1}return!0}catch(s){return process.stderr.write(`[${n}] OTLP POST failed: ${s.message??String(s)}
|
|
13
|
-
`),!1}finally{clearTimeout(i)}}var
|
|
14
|
-
`);let s=[].concat(...r),a=0;for(let c of r){if(!await
|
|
15
|
-
`)}finally{this.queue.release()}}dropIfOversized(t){let n=
|
|
16
|
-
`),!0)}};
|
|
17
|
-
`);return}await
|
|
18
|
-
`);let s=[].concat(...r),a=0;for(let c of r){if(!await
|
|
19
|
-
`)}}};M.TraceManager=fe});var
|
|
20
|
-
`)){let r=n.trim();if(!r||r.startsWith("#"))continue;let i=r.indexOf("=");if(i<0)continue;let s=r.slice(0,i).trim(),a=r.slice(i+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),s&&(t[s]=a)}return t}function En(e){let t;try{t=Sn.default.readFileSync(e,"utf-8")}catch{return}let n=rt(t);for(let[r,i]of Object.entries(n))process.env[r]===void 0&&(process.env[r]=i)}});var b=S(o=>{"use strict";Object.defineProperty(o,"__esModule",{value:!0});o.loadEnvFile=o.parseEnvFile=o.envFilePath=o.MemorySessionTraceManager=o.DiskSessionTraceManager=o.generateUlid=o.TraceManager=o.MAX_POST_BYTES=o.parseHeadersEnv=o.envOptionsResolver=o.postOtlp=o.MemoryTransport=o.DiskTransport=o.MemoryRetryQueue=o.DiskRetryQueue=o.GUARD_STATUS_REFUSED=o.evaluateGuard=o.MAX_SPAN_BYTES=o.enforceSpanBudget=o.mergeBatch=o.attachGuard=o.buildPayload=o.clientAttrs=o.guardAttrs=o.attrsFromRecord=o.toOtlpValue=o.snakeCase=o.newSpanId=o.ulidToTraceId=o.MAX_BYTES=o.PATTERNS=o.applyMatches=o.resolveOverlaps=o.collectMatches=o.truncateTo=o.truncate=o.redact=void 0;var A=ne();Object.defineProperty(o,"redact",{enumerable:!0,get:function(){return A.redact}});Object.defineProperty(o,"truncate",{enumerable:!0,get:function(){return A.truncate}});Object.defineProperty(o,"truncateTo",{enumerable:!0,get:function(){return A.truncateTo}});Object.defineProperty(o,"collectMatches",{enumerable:!0,get:function(){return A.collectMatches}});Object.defineProperty(o,"resolveOverlaps",{enumerable:!0,get:function(){return A.resolveOverlaps}});Object.defineProperty(o,"applyMatches",{enumerable:!0,get:function(){return A.applyMatches}});Object.defineProperty(o,"PATTERNS",{enumerable:!0,get:function(){return A.PATTERNS}});Object.defineProperty(o,"MAX_BYTES",{enumerable:!0,get:function(){return A.MAX_BYTES}});var P=ie();Object.defineProperty(o,"ulidToTraceId",{enumerable:!0,get:function(){return P.ulidToTraceId}});Object.defineProperty(o,"newSpanId",{enumerable:!0,get:function(){return P.newSpanId}});Object.defineProperty(o,"snakeCase",{enumerable:!0,get:function(){return P.snakeCase}});Object.defineProperty(o,"toOtlpValue",{enumerable:!0,get:function(){return P.toOtlpValue}});Object.defineProperty(o,"attrsFromRecord",{enumerable:!0,get:function(){return P.attrsFromRecord}});Object.defineProperty(o,"guardAttrs",{enumerable:!0,get:function(){return P.guardAttrs}});Object.defineProperty(o,"clientAttrs",{enumerable:!0,get:function(){return P.clientAttrs}});Object.defineProperty(o,"buildPayload",{enumerable:!0,get:function(){return P.buildPayload}});Object.defineProperty(o,"attachGuard",{enumerable:!0,get:function(){return P.attachGuard}});Object.defineProperty(o,"mergeBatch",{enumerable:!0,get:function(){return P.mergeBatch}});Object.defineProperty(o,"enforceSpanBudget",{enumerable:!0,get:function(){return P.enforceSpanBudget}});Object.defineProperty(o,"MAX_SPAN_BYTES",{enumerable:!0,get:function(){return P.MAX_SPAN_BYTES}});var st=Ce();Object.defineProperty(o,"evaluateGuard",{enumerable:!0,get:function(){return st.evaluateGuard}});Object.defineProperty(o,"GUARD_STATUS_REFUSED",{enumerable:!0,get:function(){return st.GUARD_STATUS_REFUSED}});var ot=ae();Object.defineProperty(o,"DiskRetryQueue",{enumerable:!0,get:function(){return ot.DiskRetryQueue}});Object.defineProperty(o,"MemoryRetryQueue",{enumerable:!0,get:function(){return ot.MemoryRetryQueue}});var j=ze();Object.defineProperty(o,"DiskTransport",{enumerable:!0,get:function(){return j.DiskTransport}});Object.defineProperty(o,"MemoryTransport",{enumerable:!0,get:function(){return j.MemoryTransport}});Object.defineProperty(o,"postOtlp",{enumerable:!0,get:function(){return j.postOtlp}});Object.defineProperty(o,"envOptionsResolver",{enumerable:!0,get:function(){return j.envOptionsResolver}});Object.defineProperty(o,"parseHeadersEnv",{enumerable:!0,get:function(){return j.parseHeadersEnv}});Object.defineProperty(o,"MAX_POST_BYTES",{enumerable:!0,get:function(){return j.MAX_POST_BYTES}});var at=pe();Object.defineProperty(o,"TraceManager",{enumerable:!0,get:function(){return at.TraceManager}});Object.defineProperty(o,"generateUlid",{enumerable:!0,get:function(){return at.generateUlid}});var ct=tt();Object.defineProperty(o,"DiskSessionTraceManager",{enumerable:!0,get:function(){return ct.DiskSessionTraceManager}});Object.defineProperty(o,"MemorySessionTraceManager",{enumerable:!0,get:function(){return ct.MemorySessionTraceManager}});var ye=it();Object.defineProperty(o,"envFilePath",{enumerable:!0,get:function(){return ye.envFilePath}});Object.defineProperty(o,"parseEnvFile",{enumerable:!0,get:function(){return ye.parseEnvFile}});Object.defineProperty(o,"loadEnvFile",{enumerable:!0,get:function(){return ye.loadEnvFile}})});import{realpathSync as br}from"node:fs";import{pathToFileURL as Er}from"node:url";var F=E(b(),1);function On(){return(0,F.envFilePath)(".gemini","pinta-gemini.env","GEMINI_HOME")}function ut(e=On()){(0,F.loadEnvFile)(e)}var lt=E(b(),1);import wn from"os";import _e from"path";function An(){return process.env.GEMINI_HOME||_e.join(wn.homedir(),".gemini")}function kn(){let e=process.env.GEMINI_PLUGIN_OPTION_ENDPOINT||process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;if(e)return e.replace(/\/+$/,"");let t=process.env.OTEL_EXPORTER_OTLP_ENDPOINT;if(t)return t.replace(/\/+$/,"")+"/v1/traces"}function Mn(){let e=(0,lt.parseHeadersEnv)(process.env.GEMINI_PLUGIN_OPTION_HEADERS||process.env.OTEL_EXPORTER_OTLP_HEADERS),t=process.env.GEMINI_PLUGIN_OPTION_API_KEY;return t&&!e["x-pinta-relay-token"]&&(e["x-pinta-relay-token"]=t),e}function ft(){let e=process.env.GEMINI_PLUGIN_DATA||_e.join(An(),"pinta-gemini-data");return!process.env.PINTA_RELAY_TOKEN&&process.env.GEMINI_PLUGIN_OPTION_API_KEY&&(process.env.PINTA_RELAY_TOKEN=process.env.GEMINI_PLUGIN_OPTION_API_KEY),{pluginData:e,tracePath:_e.join(e,"trace.json"),endpoint:kn(),headers:Mn(),guardEndpoint:process.env.PINTA_GUARD_ENDPOINT}}function dt(e=process.argv){let t=n=>{let r=e.indexOf(n);return r>=0?e[r+1]:void 0};return{agent:t("--agent")||"gemini",event:t("--event")}}function pt(e){let t=e.transcriptPath;if(typeof t=="string"){if(t.includes("/antigravity-cli/brain/"))return"agy";if(t.includes("/antigravity/brain/"))return"antigravity2"}}var v=e=>e==="gemini",In={identity:{prefix:"gemini",ingest:"gemini",service:"gemini-cli"},gateEvent:"BeforeTool"},Rn={identity:{prefix:"antigravity",ingest:"antigravity",service:"antigravity-cli"},gateEvent:"PreToolUse"},gt=e=>v(e)?In:Rn;function z(e){return gt(e).identity}function mt(e){return gt(e).gateEvent}var jn=new Set(["AfterModel"]),ht=e=>jn.has(e);function yt(e,t,n){if(v(e))return{hook:t||n.hook_event_name||"unknown",session_id:C(n.session_id),cwd:C(n.cwd),tool_name:C(n.tool_name),tool_input:n.tool_input};let r=n.workspacePaths,i=n.toolCall;return{hook:t||"unknown",session_id:C(n.conversationId),cwd:Array.isArray(r)?C(r[0]):void 0,tool_name:i?.name,tool_input:i?.args}}function C(e){return typeof e=="string"?e:void 0}var jt=E(b(),1);var _t=E(b(),1);var H="0.11.0";var xn=50,Dn=`pinta-gemini/${H}`;function Pt(e,t,n,r){return(0,_t.evaluateGuard)(e,t,{timeoutMs:xn,token:n??process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:Dn,agentType:r?z(r).ingest:void 0})}var vt=E(b(),1),W=class extends vt.DiskTransport{constructor(t){super({pluginData:t.pluginData,logPrefix:"pinta-gemini",resolveOptions:()=>t.endpoint?{endpoint:t.endpoint,headers:t.headers}:null})}};var St=E(b(),1),Z=class extends St.DiskSessionTraceManager{constructor(t){super(t.tracePath)}};import Se from"os";import{execFileSync as bt}from"node:child_process";import J from"node:fs";import x from"node:path";var Nn=new Set(["","unknown","undefined","null","n/a","none","-"]);function ve(e){let t=typeof e=="string"?e.trim():void 0;return t&&!Nn.has(t.toLowerCase())?t:void 0}var $n=/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/;function Et(e){let t=ve(e);return t&&$n.test(t)?t:void 0}var Gn=["cli_version","cliVersion","gemini_version","geminiVersion","agent_version","agentVersion","app_version","appVersion","version"],qn="PINTA_GEMINI_HOST_VERSION",Tt="PINTA_GEMINI_VERSION_PROBE",Fn=2e3,Cn=/(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)/;function Ot(e){return v(e)?["gemini"]:["agy","antigravity","antigravity-cli"]}function Vn(e){let t=e;for(let n=0;n<5;n++){try{let i=J.readFileSync(x.join(t,"package.json"),"utf8"),s=Et(JSON.parse(i).version);if(s)return s}catch{}let r=x.dirname(t);if(r===t)break;t=r}}function Bn(e){if(process.env[Tt]==="1")return;let t;try{t=bt(e,["--version"],{encoding:"utf8",timeout:Fn,stdio:["ignore","pipe","ignore"],env:{...process.env,[Tt]:"1"}})}catch{return}let n=t.split(/\r?\n/,5).map(r=>r.trim()).filter(Boolean);for(let r of n){let i=Et(r);if(i)return i}for(let r of n){let i=Cn.exec(r);if(i)return i[1]}}function wt(e){let t=e;try{t=J.realpathSync(e)}catch{}return Vn(x.dirname(t))??Bn(e)}function Ln(e){if(process.platform==="win32")return;let t=process.ppid;if(!t||t<=1)return;let n;try{n=bt("ps",["-o","command=","-p",String(t)],{encoding:"utf8",timeout:2e3,stdio:["ignore","pipe","ignore"]}).trim()}catch{return}if(!n)return;let r=Ot(e);for(let i of n.split(/\s+/)){if(!i.startsWith("/"))continue;let s=x.basename(i).replace(/\.(js|mjs|cjs)$/,"");if(!r.includes(s))continue;let a=wt(i);if(a)return a}}function Un(e){let t=(process.env.PATH??"").split(x.delimiter).filter(Boolean);if(t.length===0)return;let n=process.platform==="win32"?[".cmd",".exe",""]:[""];for(let r of Ot(e))for(let i of t)for(let s of n){let a=x.join(i,r+s);try{J.accessSync(a,J.constants.X_OK)}catch{continue}let c=wt(a);if(c)return c}}var Pe;function Yn(e){return ve(process.env[qn])??Ln(e)??Un(e)??null}function At(e,t){if(t)for(let n of Gn){let r=ve(t[n]);if(r)return r}return Pe===void 0&&(Pe=Yn(e)),Pe??void 0}var k=E(b(),1),Hn=E(b(),1),Q;function Kn(){if(Q===void 0)try{Q=Se.userInfo().username}catch{Q=process.env.USER??process.env.LOGNAME??(typeof process.getuid=="function"?String(process.getuid()):"unknown")}return Q}var kt=H;function Xn(e){return{skipRedactKeys:new Set([`${e}.hook`,`${e}.agent`,`${e}.tool_name`,`${e}.session_id`,`${e}.transcript_path`,`${e}.transcriptPath`,`${e}.cwd`]),bashContextKeys:new Set([`${e}.tool_input`,`${e}.tool_response`,`${e}.toolCall`])}}function zn(e,t){return[{key:"service.name",value:{stringValue:e}},...t?[{key:"service.version",value:{stringValue:t}}]:[],{key:"telemetry.sdk.name",value:{stringValue:"pinta-gemini"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:kt}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:Kn()}},{key:"host.name",value:{stringValue:Se.hostname()}},{key:"host.arch",value:{stringValue:Se.arch()}}]}function Mt(e){let t=z(e.agent),n=Xn(t.prefix),r=[{key:"ingest.type",value:{stringValue:t.ingest}},{key:`${t.prefix}.hook`,value:{stringValue:e.canonical.hook}},{key:`${t.prefix}.agent`,value:{stringValue:e.agent}}];e.product&&r.push({key:`${t.prefix}.product`,value:{stringValue:e.product}}),r.push(...(0,k.attrsFromRecord)(e.event,t.prefix,n));let i=new Set(r.map(s=>s.key));for(let[s,a]of[["session_id",e.canonical.session_id],["cwd",e.canonical.cwd],["tool_name",e.canonical.tool_name]]){let c=`${t.prefix}.${s}`;if(a!=null&&!i.has(c)){let u=(0,k.toOtlpValue)(c,String(a),n);u!==null&&r.push({key:c,value:u})}}return(0,k.buildPayload)({traceId:e.traceId,spanName:`${t.ingest}.${(0,k.snakeCase)(e.canonical.hook)}`,attributes:r,resource:zn(t.service,At(e.agent,e.event)),scope:{name:"pinta-gemini",version:kt},now:e.now})}function Te(e,t,n){if(n&&n.decision==="DENY"){let r=n.userMessage??n.reason??"guard_deny";return v(e)?{decision:"deny",reason:r,systemMessage:n.userMessage??void 0}:{decision:"deny",reason:r}}return!v(e)&&t==="PreToolUse"?{decision:"allow"}:{}}import It from"fs";import Wn from"path";function Rt(e,t){if(process.env.PINTA_GEMINI_DEBUG==="1")try{It.mkdirSync(e.pluginData,{recursive:!0}),It.appendFileSync(Wn.join(e.pluginData,"invocations.jsonl"),JSON.stringify(t)+`
|
|
21
|
-
`)}catch{}}async function
|
|
22
|
-
`),n=s?
|
|
23
|
-
`),process.exit(0)}import{opendir as
|
|
13
|
+
`),!1}finally{clearTimeout(i)}}var ue=class{queue;logPrefix;resolveOptions;constructor(t){this.queue=new Ye.DiskRetryQueue(t.pluginData,t.logPrefix),this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions??ze}async send(t){let n=this.resolveOptions();if(!n||this.dropIfOversized(t))return;await F(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:i}=Xe(n,c=>H(c.payload),d.MAX_POST_BYTES);i.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${i.length} oversized retry ${i.length===1?"entry":"entries"} (each > ${d.MAX_POST_BYTES} bytes \u2014 the backend caps the request body, so they can never be delivered)
|
|
14
|
+
`);let s=[].concat(...r),a=0;for(let c of r){if(!await F((0,Ke.mergeBatch)(c.map(l=>l.payload)),t,this.logPrefix))break;a+=c.length}this.queue.rewrite(s.slice(a))}catch(n){process.stderr.write(`[${this.logPrefix}] flush failed: ${n?.message??String(n)}
|
|
15
|
+
`)}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
|
|
16
|
+
`),!0)}};d.DiskTransport=ue;var le=class{queue=new Ye.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
|
|
17
|
+
`);return}await F(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:i}=Xe(n,H,d.MAX_POST_BYTES);i.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${i.length} oversized buffered ${i.length===1?"payload":"payloads"} (each > ${d.MAX_POST_BYTES} bytes \u2014 undeliverable)
|
|
18
|
+
`);let s=[].concat(...r),a=0;for(let c of r){if(!await F((0,Ke.mergeBatch)(c),t,this.logPrefix))break;a+=c.length}for(let c of s.slice(a))this.queue.enqueue(c)}};d.MemoryTransport=le});var ge=E(M=>{"use strict";var pe=M&&M.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(M,"__esModule",{value:!0});M.TraceManager=void 0;M.generateUlid=Je;var Ze=pe(P("fs")),Pn=pe(P("path")),vn=pe(P("crypto")),En=Y(),de="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Je(){let e=Date.now(),t="",n=e;for(let s=0;s<10;s++)t=de[n&31]+t,n=Math.floor(n/32);let r=vn.default.randomBytes(10),i="";for(let s=0;s<10;s++)i+=de[r[s]&31];for(;i.length<16;)i+=de[0];return t+i}var fe=class{tracePath;constructor(t){this.tracePath=t}newTrace(){let t=Je();return this.save(t),t}currentTrace(){try{let t=Ze.default.readFileSync(this.tracePath,"utf-8"),{traceId:n}=JSON.parse(t);if(n)return n}catch{}return this.newTrace()}save(t){try{Ze.default.mkdirSync(Pn.default.dirname(this.tracePath),{recursive:!0}),(0,En.atomicWriteFileSync)(this.tracePath,JSON.stringify({traceId:t}))}catch(n){process.stderr.write(`[pinta-core] trace persistence failed: ${n}
|
|
19
|
+
`)}}};M.TraceManager=fe});var rt=E(A=>{"use strict";var et=A&&A.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(A,"__esModule",{value:!0});A.MemorySessionTraceManager=A.DiskSessionTraceManager=void 0;var Qe=et(P("fs")),Sn=et(P("path")),tt=ge(),Tn=Y(),nt=200,me=class{tracePath;maxSessions;constructor(t,n={}){this.tracePath=t,this.maxSessions=n.maxSessions??nt}read(){try{let t=JSON.parse(Qe.default.readFileSync(this.tracePath,"utf-8"));if(t&&typeof t=="object"&&!("traceId"in t))return t}catch{}return{}}write(t){try{Qe.default.mkdirSync(Sn.default.dirname(this.tracePath),{recursive:!0});let n=Object.entries(t),r=n.length>this.maxSessions?Object.fromEntries(n.slice(-this.maxSessions)):t;(0,Tn.atomicWriteFileSync)(this.tracePath,JSON.stringify(r))}catch{}}newTrace(t){let n=t||"default",r=(0,tt.generateUlid)(),i=this.read();return i[n]=r,this.write(i),r}currentTrace(t){let n=t||"default",r=this.read()[n];return r||this.newTrace(n)}};A.DiskSessionTraceManager=me;var ye=class{map=new Map;maxSessions;constructor(t={}){this.maxSessions=t.maxSessions??nt}newTrace(t){let n=t||"default",r=(0,tt.generateUlid)();if(this.map.set(n,r),this.map.size>this.maxSessions){let i=this.map.keys().next().value;i!==void 0&&this.map.delete(i)}return r}currentTrace(t){let n=t||"default";return this.map.get(n)??this.newTrace(n)}};A.MemorySessionTraceManager=ye});var ot=E(I=>{"use strict";var he=I&&I.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(I,"__esModule",{value:!0});I.envFilePath=wn;I.parseEnvFile=st;I.loadEnvFile=An;var bn=he(P("node:fs")),On=he(P("node:os")),it=he(P("node:path"));function wn(e,t,n){let r=n?process.env[n]:void 0,i=r&&r.length>0?r:it.default.join(On.default.homedir(),e);return it.default.join(i,t)}function st(e){let t={};for(let n of e.split(`
|
|
20
|
+
`)){let r=n.trim();if(!r||r.startsWith("#"))continue;let i=r.indexOf("=");if(i<0)continue;let s=r.slice(0,i).trim(),a=r.slice(i+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),s&&(t[s]=a)}return t}function An(e){let t;try{t=bn.default.readFileSync(e,"utf-8")}catch{return}let n=st(t);for(let[r,i]of Object.entries(n))process.env[r]===void 0&&(process.env[r]=i)}});var b=E(o=>{"use strict";Object.defineProperty(o,"__esModule",{value:!0});o.loadEnvFile=o.parseEnvFile=o.envFilePath=o.MemorySessionTraceManager=o.DiskSessionTraceManager=o.generateUlid=o.TraceManager=o.MAX_POST_BYTES=o.parseHeadersEnv=o.envOptionsResolver=o.postOtlp=o.MemoryTransport=o.DiskTransport=o.MemoryRetryQueue=o.DiskRetryQueue=o.GUARD_BUDGET_HEADER=o.GUARD_STATUS_REFUSED=o.evaluateGuard=o.MAX_SPAN_BYTES=o.enforceSpanBudget=o.mergeBatch=o.attachGuard=o.buildPayload=o.clientAttrs=o.guardAttrs=o.attrsFromRecord=o.toOtlpValue=o.snakeCase=o.newSpanId=o.ulidToTraceId=o.MAX_BYTES=o.PATTERNS=o.applyMatches=o.resolveOverlaps=o.collectMatches=o.truncateTo=o.truncate=o.redact=void 0;var k=re();Object.defineProperty(o,"redact",{enumerable:!0,get:function(){return k.redact}});Object.defineProperty(o,"truncate",{enumerable:!0,get:function(){return k.truncate}});Object.defineProperty(o,"truncateTo",{enumerable:!0,get:function(){return k.truncateTo}});Object.defineProperty(o,"collectMatches",{enumerable:!0,get:function(){return k.collectMatches}});Object.defineProperty(o,"resolveOverlaps",{enumerable:!0,get:function(){return k.resolveOverlaps}});Object.defineProperty(o,"applyMatches",{enumerable:!0,get:function(){return k.applyMatches}});Object.defineProperty(o,"PATTERNS",{enumerable:!0,get:function(){return k.PATTERNS}});Object.defineProperty(o,"MAX_BYTES",{enumerable:!0,get:function(){return k.MAX_BYTES}});var v=se();Object.defineProperty(o,"ulidToTraceId",{enumerable:!0,get:function(){return v.ulidToTraceId}});Object.defineProperty(o,"newSpanId",{enumerable:!0,get:function(){return v.newSpanId}});Object.defineProperty(o,"snakeCase",{enumerable:!0,get:function(){return v.snakeCase}});Object.defineProperty(o,"toOtlpValue",{enumerable:!0,get:function(){return v.toOtlpValue}});Object.defineProperty(o,"attrsFromRecord",{enumerable:!0,get:function(){return v.attrsFromRecord}});Object.defineProperty(o,"guardAttrs",{enumerable:!0,get:function(){return v.guardAttrs}});Object.defineProperty(o,"clientAttrs",{enumerable:!0,get:function(){return v.clientAttrs}});Object.defineProperty(o,"buildPayload",{enumerable:!0,get:function(){return v.buildPayload}});Object.defineProperty(o,"attachGuard",{enumerable:!0,get:function(){return v.attachGuard}});Object.defineProperty(o,"mergeBatch",{enumerable:!0,get:function(){return v.mergeBatch}});Object.defineProperty(o,"enforceSpanBudget",{enumerable:!0,get:function(){return v.enforceSpanBudget}});Object.defineProperty(o,"MAX_SPAN_BYTES",{enumerable:!0,get:function(){return v.MAX_SPAN_BYTES}});var _e=Ve();Object.defineProperty(o,"evaluateGuard",{enumerable:!0,get:function(){return _e.evaluateGuard}});Object.defineProperty(o,"GUARD_STATUS_REFUSED",{enumerable:!0,get:function(){return _e.GUARD_STATUS_REFUSED}});Object.defineProperty(o,"GUARD_BUDGET_HEADER",{enumerable:!0,get:function(){return _e.GUARD_BUDGET_HEADER}});var at=ce();Object.defineProperty(o,"DiskRetryQueue",{enumerable:!0,get:function(){return at.DiskRetryQueue}});Object.defineProperty(o,"MemoryRetryQueue",{enumerable:!0,get:function(){return at.MemoryRetryQueue}});var D=We();Object.defineProperty(o,"DiskTransport",{enumerable:!0,get:function(){return D.DiskTransport}});Object.defineProperty(o,"MemoryTransport",{enumerable:!0,get:function(){return D.MemoryTransport}});Object.defineProperty(o,"postOtlp",{enumerable:!0,get:function(){return D.postOtlp}});Object.defineProperty(o,"envOptionsResolver",{enumerable:!0,get:function(){return D.envOptionsResolver}});Object.defineProperty(o,"parseHeadersEnv",{enumerable:!0,get:function(){return D.parseHeadersEnv}});Object.defineProperty(o,"MAX_POST_BYTES",{enumerable:!0,get:function(){return D.MAX_POST_BYTES}});var ct=ge();Object.defineProperty(o,"TraceManager",{enumerable:!0,get:function(){return ct.TraceManager}});Object.defineProperty(o,"generateUlid",{enumerable:!0,get:function(){return ct.generateUlid}});var ut=rt();Object.defineProperty(o,"DiskSessionTraceManager",{enumerable:!0,get:function(){return ut.DiskSessionTraceManager}});Object.defineProperty(o,"MemorySessionTraceManager",{enumerable:!0,get:function(){return ut.MemorySessionTraceManager}});var Pe=ot();Object.defineProperty(o,"envFilePath",{enumerable:!0,get:function(){return Pe.envFilePath}});Object.defineProperty(o,"parseEnvFile",{enumerable:!0,get:function(){return Pe.parseEnvFile}});Object.defineProperty(o,"loadEnvFile",{enumerable:!0,get:function(){return Pe.loadEnvFile}})});import{realpathSync as Rr}from"node:fs";import{pathToFileURL as Mr}from"node:url";var C=O(b(),1);function kn(){return(0,C.envFilePath)(".gemini","pinta-gemini.env","GEMINI_HOME")}function lt(e=kn()){(0,C.loadEnvFile)(e)}var dt=O(b(),1);import Rn from"os";import ve from"path";function Mn(){return process.env.GEMINI_HOME||ve.join(Rn.homedir(),".gemini")}function In(){let e=process.env.GEMINI_PLUGIN_OPTION_ENDPOINT||process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;if(e)return e.replace(/\/+$/,"");let t=process.env.OTEL_EXPORTER_OTLP_ENDPOINT;if(t)return t.replace(/\/+$/,"")+"/v1/traces"}function Dn(){let e=(0,dt.parseHeadersEnv)(process.env.GEMINI_PLUGIN_OPTION_HEADERS||process.env.OTEL_EXPORTER_OTLP_HEADERS),t=process.env.GEMINI_PLUGIN_OPTION_API_KEY;return t&&!e["x-pinta-relay-token"]&&(e["x-pinta-relay-token"]=t),e}function ft(){let e=process.env.GEMINI_PLUGIN_DATA||ve.join(Mn(),"pinta-gemini-data");return!process.env.PINTA_RELAY_TOKEN&&process.env.GEMINI_PLUGIN_OPTION_API_KEY&&(process.env.PINTA_RELAY_TOKEN=process.env.GEMINI_PLUGIN_OPTION_API_KEY),{pluginData:e,tracePath:ve.join(e,"trace.json"),endpoint:In(),headers:Dn(),guardEndpoint:process.env.PINTA_GUARD_ENDPOINT}}function pt(e=process.argv){let t=n=>{let r=e.indexOf(n);return r>=0?e[r+1]:void 0};return{agent:t("--agent")||"gemini",event:t("--event")}}function gt(e){let t=e.transcriptPath;if(typeof t=="string"){if(t.includes("/antigravity-cli/brain/"))return"agy";if(t.includes("/antigravity/brain/"))return"antigravity2"}}var _=e=>e==="gemini",jn={identity:{prefix:"gemini",ingest:"gemini",service:"gemini-cli"},gateEvent:"BeforeTool"},xn={identity:{prefix:"antigravity",ingest:"antigravity",service:"antigravity-cli"},gateEvent:"PreToolUse"},mt=e=>_(e)?jn:xn;function z(e){return mt(e).identity}function yt(e){return mt(e).gateEvent}var Nn=new Set(["AfterModel"]),ht=e=>Nn.has(e);function _t(e,t,n){if(_(e))return{hook:t||n.hook_event_name||"unknown",session_id:B(n.session_id),cwd:B(n.cwd),tool_name:B(n.tool_name),tool_input:n.tool_input};let r=n.workspacePaths,i=n.toolCall;return{hook:t||"unknown",session_id:B(n.conversationId),cwd:Array.isArray(r)?B(r[0]):void 0,tool_name:i?.name,tool_input:i?.args}}function B(e){return typeof e=="string"?e:void 0}var Nt=O(b(),1);var Pt=O(b(),1);var W="0.13.0";var Gn=100,$n=`pinta-gemini/${W}`;function vt(e,t,n,r){return(0,Pt.evaluateGuard)(e,t,{timeoutMs:Gn,token:n??process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:$n,agentType:r?z(r).ingest:void 0})}var Et=O(b(),1),Z=class extends Et.DiskTransport{constructor(t){super({pluginData:t.pluginData,logPrefix:"pinta-gemini",resolveOptions:()=>t.endpoint?{endpoint:t.endpoint,headers:t.headers}:null})}};var St=O(b(),1),J=class extends St.DiskSessionTraceManager{constructor(t){super(t.tracePath)}};import Te from"os";import{execFileSync as bt}from"node:child_process";import Q from"node:fs";import j from"node:path";var qn=new Set(["","unknown","undefined","null","n/a","none","-"]);function Se(e){let t=typeof e=="string"?e.trim():void 0;return t&&!qn.has(t.toLowerCase())?t:void 0}var Fn=/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/;function Ot(e){let t=Se(e);return t&&Fn.test(t)?t:void 0}var Cn=["cli_version","cliVersion","gemini_version","geminiVersion","agent_version","agentVersion","app_version","appVersion","version"],Bn="PINTA_GEMINI_HOST_VERSION",Tt="PINTA_GEMINI_VERSION_PROBE",Vn=2e3,Un=/(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)/;function wt(e){return _(e)?["gemini"]:["agy","antigravity","antigravity-cli"]}function Ln(e){let t=e;for(let n=0;n<5;n++){try{let i=Q.readFileSync(j.join(t,"package.json"),"utf8"),s=Ot(JSON.parse(i).version);if(s)return s}catch{}let r=j.dirname(t);if(r===t)break;t=r}}function Yn(e){if(process.env[Tt]==="1")return;let t;try{t=bt(e,["--version"],{encoding:"utf8",timeout:Vn,stdio:["ignore","pipe","ignore"],env:{...process.env,[Tt]:"1"}})}catch{return}let n=t.split(/\r?\n/,5).map(r=>r.trim()).filter(Boolean);for(let r of n){let i=Ot(r);if(i)return i}for(let r of n){let i=Un.exec(r);if(i)return i[1]}}function At(e){let t=e;try{t=Q.realpathSync(e)}catch{}return Ln(j.dirname(t))??Yn(e)}function Kn(e){if(process.platform==="win32")return;let t=process.ppid;if(!t||t<=1)return;let n;try{n=bt("ps",["-o","command=","-p",String(t)],{encoding:"utf8",timeout:2e3,stdio:["ignore","pipe","ignore"]}).trim()}catch{return}if(!n)return;let r=wt(e);for(let i of n.split(/\s+/)){if(!i.startsWith("/"))continue;let s=j.basename(i).replace(/\.(js|mjs|cjs)$/,"");if(!r.includes(s))continue;let a=At(i);if(a)return a}}function Xn(e){let t=(process.env.PATH??"").split(j.delimiter).filter(Boolean);if(t.length===0)return;let n=process.platform==="win32"?[".cmd",".exe",""]:[""];for(let r of wt(e))for(let i of t)for(let s of n){let a=j.join(i,r+s);try{Q.accessSync(a,Q.constants.X_OK)}catch{continue}let c=At(a);if(c)return c}}var Ee;function Hn(e){return Se(process.env[Bn])??Kn(e)??Xn(e)??null}function kt(e,t){if(t)for(let n of Cn){let r=Se(t[n]);if(r)return r}return Ee===void 0&&(Ee=Hn(e)),Ee??void 0}var zn=new Set(["unknown","undefined","null","n/a","none","-","auto","default"]);function Wn(e){if(typeof e!="string")return;let t=e.trim();if(!(!t||t.startsWith("{")||t.startsWith("[")||zn.has(t.toLowerCase())))return t}function Rt(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function x(e,t){let n=Wn(e);return n?{model:n,source:t}:void 0}function Zn(e,t,n){if(_(e)){if(t==="AfterModel"){let r=Rt(n.llm_response),i=x(r?.modelVersion,"response:llm_response.modelVersion")??x(r?.model,"response:llm_response.model");if(i)return i}if(t==="BeforeModel"||t==="BeforeToolSelection"||t==="AfterModel"){let r=x(Rt(n.llm_request)?.model,"requested:llm_request.model");if(r)return r}return x(n.model,"reported:model")}return x(n.model,"reported:model")??x(n.modelId,"reported:modelId")}function Mt(e,t,n){let r=Zn(e,t,n),{model:i,model_source:s,...a}=n;return"model"in n&&i!==r?.model&&(a.model_raw=i),"model_source"in n&&(a.model_source_raw=s),r&&(a.model=r.model,a.model_source=r.source),a}var R=O(b(),1),tr=O(b(),1),ee;function Jn(){if(ee===void 0)try{ee=Te.userInfo().username}catch{ee=process.env.USER??process.env.LOGNAME??(typeof process.getuid=="function"?String(process.getuid()):"unknown")}return ee}var It=W;function Qn(e){return{skipRedactKeys:new Set([`${e}.hook`,`${e}.agent`,`${e}.tool_name`,`${e}.session_id`,`${e}.transcript_path`,`${e}.transcriptPath`,`${e}.cwd`]),bashContextKeys:new Set([`${e}.tool_input`,`${e}.tool_response`,`${e}.toolCall`])}}function er(e,t){return[{key:"service.name",value:{stringValue:e}},...t?[{key:"service.version",value:{stringValue:t}}]:[],{key:"telemetry.sdk.name",value:{stringValue:"pinta-gemini"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:It}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:Jn()}},{key:"host.name",value:{stringValue:Te.hostname()}},{key:"host.arch",value:{stringValue:Te.arch()}}]}function Dt(e){let t=z(e.agent),n=Qn(t.prefix),r=[{key:"ingest.type",value:{stringValue:t.ingest}},{key:`${t.prefix}.hook`,value:{stringValue:e.canonical.hook}},{key:`${t.prefix}.agent`,value:{stringValue:e.agent}}];e.product&&r.push({key:`${t.prefix}.product`,value:{stringValue:e.product}}),r.push(...(0,R.attrsFromRecord)(Mt(e.agent,e.canonical.hook,e.event),t.prefix,n));let i=new Set(r.map(s=>s.key));for(let[s,a]of[["session_id",e.canonical.session_id],["cwd",e.canonical.cwd],["tool_name",e.canonical.tool_name]]){let c=`${t.prefix}.${s}`;if(a!=null&&!i.has(c)){let u=(0,R.toOtlpValue)(c,String(a),n);u!==null&&r.push({key:c,value:u})}}return(0,R.buildPayload)({traceId:e.traceId,spanName:`${t.ingest}.${(0,R.snakeCase)(e.canonical.hook)}`,attributes:r,resource:er(t.service,kt(e.agent,e.event)),scope:{name:"pinta-gemini",version:It},now:e.now})}function be(e,t,n){if(n&&n.decision==="DENY"){let r=n.userMessage??n.reason??"guard_deny";return _(e)?{decision:"deny",reason:r,systemMessage:n.userMessage??void 0}:{decision:"deny",reason:r}}return!_(e)&&t==="PreToolUse"?{decision:"allow"}:{}}import jt from"fs";import nr from"path";function xt(e,t){if(process.env.PINTA_GEMINI_DEBUG==="1")try{jt.mkdirSync(e.pluginData,{recursive:!0}),jt.appendFileSync(nr.join(e.pluginData,"invocations.jsonl"),JSON.stringify(t)+`
|
|
21
|
+
`)}catch{}}async function rr(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}function ir(e,t,n){return _(e)?t.hook==="BeforeAgent":t.hook==="PreInvocation"&&n.invocationNum===1}async function Gt(){let{agent:e,event:t}=pt(),n={},r={},i,s=null,a=ft();try{if(r=JSON.parse(await rr()||"{}"),i=_t(e,t,r),!ht(i.hook)){let c=new Z(a);await c.flush();let u=i.session_id??"unknown",l=new J(a),m=ir(e,i,r)?l.newTrace(u):l.currentTrace(u),f=_(e)?void 0:gt(r),S=Dt({agent:e,canonical:i,event:r,traceId:m,product:f});i.hook===yt(e)&&(s=await vt(S,a.guardEndpoint,a.headers["x-pinta-relay-token"],e)),n=be(e,t,s),(0,Nt.attachGuard)(S,s),await c.send(S)}}catch(c){process.stderr.write(`[pinta-gemini] error: ${c}
|
|
22
|
+
`),n=s?be(e,t,s):{}}xt(a,{ts:new Date().toISOString(),pid:process.pid,agent:e,event:t,argv:process.argv.slice(2),received_payload:r,normalized:i??null,guard:s,decision_returned:n}),process.stdout.write(JSON.stringify(n)+`
|
|
23
|
+
`),process.exit(0)}import{opendir as Bt,stat as _r}from"node:fs/promises";import{homedir as Pr}from"node:os";import g from"node:path";import{spawn as qt}from"node:child_process";import{access as sr,copyFile as or,mkdtemp as ar,rm as cr,stat as Ft}from"node:fs/promises";import{constants as ur}from"node:fs";import lr from"node:os";import V from"node:path";var Oe,dr=["/usr/bin/sqlite3","/opt/homebrew/bin/sqlite3","/usr/local/bin/sqlite3"];async function fr(){for(let t of dr)try{return await sr(t,ur.X_OK),t}catch{}return await new Promise(t=>{let n;try{n=qt("sqlite3",["--version"],{stdio:"ignore"})}catch{t(!1);return}n.on("error",()=>t(!1)),n.on("close",r=>t(r===0))})?"sqlite3":null}async function pr(){return Oe===void 0&&(Oe=await fr()),Oe}async function gr(e,t,n,r){await new Promise((i,s)=>{let a=qt(e,[t,`.backup '${n}'`],{stdio:["ignore","ignore","pipe"]}),c="",u=!1,l,m=f=>{u||(u=!0,l&&clearTimeout(l),f())};r>0&&(l=setTimeout(()=>{a.kill("SIGKILL"),m(()=>s(new Error(`sqlite3 .backup timed out after ${r}ms: ${t}`)))},r),l.unref?.()),a.stderr?.on("data",f=>{c+=String(f)}),a.on("error",f=>m(()=>s(f))),a.on("close",f=>{m(()=>{f===0?i():s(new Error(`sqlite3 .backup exited ${f}${c?`: ${c.trim()}`:""}`))})})})}async function mr(e){try{let t=await Ft(e);return`${t.mtimeMs}:${t.size}`}catch{return"absent"}}async function $t(e){let t=new Map;for(let n of e)t.set(n,await mr(n));return t}function yr(e,t){for(let[n,r]of e)if(t.get(n)!==r)return!1;return!0}async function hr(e,t,n,r){let i=r.minStableMs??2e3,s=r.maxRetries??3,a=r.now??Date.now,c=r.sleep??(f=>new Promise(S=>setTimeout(S,f))),u=r.overallTimeoutMs??6e4,l=a(),m=[e,`${e}-wal`,`${e}-shm`];for(let f=1;f<=s;f++){if(u>0&&a()-l>u)throw new Error(`snapshot quiesce-copy exceeded overall deadline of ${u}ms: ${e}`);let S=await $t(m);if(S.get(e)==="absent")throw new Error(`snapshot source vanished: ${e}`);let ne=0;for(let $ of m)try{let Kt=await Ft($);ne=Math.max(ne,Kt.mtimeMs)}catch{}if(a()-ne<i){await c(i);continue}for(let $ of m)S.get($)!=="absent"&&await or($,V.join(t,V.basename($)));r.onCopied&&await r.onCopied(f);let Yt=await $t(m);if(yr(S,Yt))return n}throw new Error(`snapshot quiesce-copy did not stabilize after ${s} attempts: ${e}`)}async function Ct(e,t={}){let n=t.tmpDirBase??lr.tmpdir(),r=await ar(V.join(n,"pinta-gemini-snap-"));try{let i=V.join(r,V.basename(e.absPath)),s=t.sqlite3Path!==void 0?t.sqlite3Path:await pr();return s?(await gr(s,e.absPath,i,t.overallTimeoutMs??6e4),i):await hr(e.absPath,r,i,t)}catch(i){throw await cr(r,{recursive:!0,force:!0}).catch(()=>{}),i}}var vr="pinta-gemini",te="antigravity";function Er(){let e=process.env.GEMINI_HOME;return e&&e.length>0?e:g.join(Pr(),".gemini")}function N(e,t){return g.relative(e,t).split(g.sep).join("/")}function Vt(e){return e.endsWith("/.system_generated/logs/transcript.jsonl")||e.endsWith("/.system_generated/logs/transcript_full.jsonl")}function Sr(e){return e.endsWith(".jsonl")||e.endsWith(".json")}function we(e){let t=g.extname(e);return t?e.slice(0,-t.length):e}async function Ut(){return[Er()]}async function*Lt(e){let t;try{t=await Bt(e)}catch{return}try{for await(let n of t){let r=g.join(e,n.name);n.isDirectory()?yield*Lt(r):n.isFile()&&(yield r)}}catch{return}}async function*G(e){let t;try{t=await Bt(e)}catch{return}try{for await(let n of t)yield{name:n.name,isDir:n.isDirectory(),isFile:n.isFile()}}catch{return}}async function*Tr(e){let t=g.join(e,"tmp");for await(let n of G(t)){if(!n.isDir)continue;let r=n.name,i=g.join(t,r),s=g.join(i,"logs.json");yield{absPath:s,relPath:N(e,s),semantics:"rewritten-doc",projectKey:r};let a=g.join(i,"chats");for await(let c of G(a)){if(!c.isFile||!Sr(c.name))continue;let u=g.join(a,c.name);yield{absPath:u,relPath:N(e,u),semantics:"rewritten-doc",sessionId:we(c.name),projectKey:r}}}}async function*br(e){let t=g.join(e,"antigravity"),n=g.join(t,"conversations");for await(let s of G(n)){if(!s.isFile||!s.name.endsWith(".db"))continue;let a=g.join(n,s.name);yield{absPath:a,relPath:N(e,a),semantics:"database",sessionId:we(s.name),projectKey:te}}let r=g.join(t,"brain");for await(let s of G(r)){if(!s.isDir)continue;let a=s.name,c=g.join(r,a);for await(let u of Lt(c)){let l=N(e,u);yield{absPath:u,relPath:l,semantics:Vt(l)?"append-log":"rewritten-doc",sessionId:a,projectKey:te}}}let i=g.join(t,"annotations");for await(let s of G(i)){if(!s.isFile||!s.name.endsWith(".pbtxt"))continue;let a=g.join(i,s.name);yield{absPath:a,relPath:N(e,a),semantics:"rewritten-doc",sessionId:we(s.name),projectKey:te}}for await(let s of G(t))if(s.isFile&&(s.name.endsWith(".pb")||s.name.endsWith(".pbtxt")||s.name==="installation_id")){let a=g.join(t,s.name);yield{absPath:a,relPath:N(e,a),semantics:"rewritten-doc",projectKey:te}}}async function*Or(e){yield*Tr(e),yield*br(e)}async function*wr(e){let[t]=await Ut(),n=e.since?.getTime();for await(let r of Or(t)){let i;try{i=await _r(r.absPath)}catch{continue}i.isFile()&&(n!==void 0&&i.mtime.getTime()<=n||(yield{relPath:r.relPath,absPath:r.absPath,size:i.size,mtime:i.mtime,sessionId:r.sessionId,projectKey:r.projectKey,semantics:r.semantics}))}}function Ar(e){let t=e.split("/");if(t[0]==="tmp")return t[2]==="chats"?"session-log":t[2]==="logs.json"&&t.length===3?"meta":"other";if(t[0]==="antigravity")switch(t[1]){case"conversations":return"session-log";case"brain":return Vt(e)?"session-log":"meta";case"annotations":return"meta";default:return"other"}return"other"}var kr={id:vr,roots:Ut,scan:wr,classify:Ar,snapshot:e=>Ct(e)};lt();function Ir(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===Mr(Rr(e)).href}catch{return!1}}Ir()&&Gt();export{kr as lifecycle};
|
package/docs/SPEC.md
CHANGED
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
2. parse argv --agent, --event
|
|
81
81
|
3. read stdin raw 이벤트 payload
|
|
82
82
|
4. normalize() 호스트 payload → canonical (snake/camel 흡수)
|
|
83
|
-
5. guard (gate 이벤트만) PINTA_GUARD_ENDPOINT POST,
|
|
83
|
+
5. guard (gate 이벤트만) PINTA_GUARD_ENDPOINT POST, 100ms, fail-open
|
|
84
84
|
6. forward() OTLP span POST (실패 시 retry-queue)
|
|
85
85
|
7. formatDecision() 호스트별 allow/deny JSON
|
|
86
86
|
8. logInvocation() (DEBUG 시) invocations.jsonl 감사 로그
|
|
@@ -144,7 +144,7 @@ guard 평가는 gate 이벤트에서만: gemini=`BeforeTool`, antigravity=`PreTo
|
|
|
144
144
|
|
|
145
145
|
- 엔드포인트: `PINTA_GUARD_ENDPOINT` (없으면 guard skip = ALLOW). `PINTA_GUARD_DISABLED=1` 로 비활성.
|
|
146
146
|
- 요청: `POST { "input": { spanId, toolName, toolInput, rawTextFields:{toolInput} } }`, 헤더 `x-pinta-relay-token: $PINTA_RELAY_TOKEN`.
|
|
147
|
-
- 타임아웃
|
|
147
|
+
- 타임아웃 100ms, **fail-open**(timeout/비200/에러 → ALLOW). `@pinta-ai/core` 0.9.0+ 는 이 값을 `x-pinta-guard-budget-ms` 헤더로 manager 에 알린다 — manager 는 그 80% 안에 답한다 (PTA-579).
|
|
148
148
|
- 응답: `{ decision:'ALLOW'|'DENY'|'REVIEW', reason, userMessage?, durationMs? }`.
|
|
149
149
|
- MCP/PascalCase 인자도 `rawTextFields.toolInput`(JSON 문자열)에 포함해 정책 매칭 가능하게 한다.
|
|
150
150
|
|
|
@@ -164,6 +164,15 @@ guard 평가는 gate 이벤트에서만: gemini=`BeforeTool`, antigravity=`PreTo
|
|
|
164
164
|
### 9.3 Bronze flatten
|
|
165
165
|
모든 top-level 이벤트 필드를 `<prefix>.<key>` 속성으로. 문자열은 redact+truncate(§11). prefix = `gemini` | `antigravity`.
|
|
166
166
|
|
|
167
|
+
`<prefix>.model` is reserved for a non-placeholder scalar model ID. Nested
|
|
168
|
+
Gemini request models are lifted with `model_source=requested:llm_request.model`;
|
|
169
|
+
top-level model fields are reported, not asserted as actual response identity.
|
|
170
|
+
Unsupported/conflicting raw model values move to `model_raw`. No session model
|
|
171
|
+
is inferred from transcript paths, and Antigravity does not reuse Gemini's
|
|
172
|
+
request schema. See [Model telemetry](../README.md#model-telemetry) for evidence,
|
|
173
|
+
precedence and coverage limits. Hook registration and the AfterModel skip are
|
|
174
|
+
unchanged.
|
|
175
|
+
|
|
167
176
|
### 9.4 제품 서브라벨 (best-effort, 실측 기반)
|
|
168
177
|
agy 와 Antigravity 2.0 은 `transcriptPath` 로 구분 가능:
|
|
169
178
|
- agy: `.../antigravity-cli/brain/<id>/.../transcript_full.jsonl`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pinta-ai/pinta-gemini",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Unified OTLP forwarder + guard adapter for Gemini CLI and Antigravity (agy v1.0.x / 2.0) hooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"dist",
|
|
16
16
|
"LICENSE",
|
|
17
17
|
"README.md",
|
|
18
|
+
"CHANGELOG.md",
|
|
18
19
|
"docs"
|
|
19
20
|
],
|
|
20
21
|
"repository": {
|
|
@@ -38,7 +39,7 @@
|
|
|
38
39
|
"demo": "tsx tools/demo-trace.ts"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
|
-
"@pinta-ai/core": "^0.
|
|
42
|
+
"@pinta-ai/core": "^0.9.0",
|
|
42
43
|
"@types/node": "^22.0.0",
|
|
43
44
|
"esbuild": "^0.24.0",
|
|
44
45
|
"tsx": "^4.0.0",
|