@pinta-ai/pinta-opencode 0.11.1 → 0.11.3-skax.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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.11.2
4
+
5
+ - Bundle published `@pinta-ai/core` 0.9.2, including the narrowly scoped
6
+ `CommandLine` JSON-command masking alias fix. Arbitrary JSON strings and fake
7
+ executable wrappers are not treated as native command fields.
8
+ - Preserve the existing output gate, original evidence, fail-open behavior and
9
+ collector-independent DENY. OpenCode 1.18.31 still skips the after hook for
10
+ MCP `isError: true`; this distinct host gap remains open as PTA-608.
11
+ - Forward-only patch: the published 0.11.1 version, tag and artifact are
12
+ unchanged. No Manager, backend or catalog change accompanies this release.
13
+
14
+ Refs PTA-584, PTA-608.
15
+
3
16
  ## 0.11.1
4
17
 
5
18
  - Evaluate the original `tool.execute.after` payload before OpenCode delivers
package/README.md CHANGED
@@ -26,6 +26,11 @@ opencode fires plugin hooks around every built-in **and** MCP tool. This adapter
26
26
 
27
27
  ## Install
28
28
 
29
+ Staging builds live on `staging/skax-a`, use the `skax` npm tag, and pin
30
+ Core `0.9.3-skax.0`. Returned-content findings exclude completed arguments
31
+ and non-returned result metadata. Use the isolated stage catalog and coordinated
32
+ Manager build; keep `main` and the production catalog separate.
33
+
29
34
  Add to global `~/.config/opencode/opencode.json` (or a project `opencode.json`):
30
35
 
31
36
  ```jsonc
@@ -120,6 +125,9 @@ and [tool runner](https://github.com/anomalyco/opencode/blob/v1.18.31/packages/o
120
125
  define this boundary. Returned builtin results, including nonzero shell exit
121
126
  codes, and successful raw MCP results use the awaited after hook; undispatched
122
127
  host paths are not treated as protected.
128
+ This native MCP-error gap is tracked separately in
129
+ [PTA-608](https://linear.app/pinta-ai/issue/PTA-608); a shared-core masking upgrade
130
+ does not make the missing host callback fire.
123
131
 
124
132
  ## Span conventions
125
133
 
package/dist/index.mjs CHANGED
@@ -372,7 +372,7 @@ var require_mysql_password = __commonJS({
372
372
  let match;
373
373
  while (match = strings.exec(input)) {
374
374
  const key2 = JSON.parse(match[0]);
375
- if (key2 !== "command" && key2 !== "cmd")
375
+ if (key2 !== "command" && key2 !== "cmd" && key2 !== "CommandLine")
376
376
  continue;
377
377
  const separator = /^\s*:\s*/.exec(input.slice(strings.lastIndex));
378
378
  if (!separator)
@@ -406,6 +406,7 @@ var require_redact = __commonJS({
406
406
  exports.collectMatches = collectMatches;
407
407
  exports.resolveOverlaps = resolveOverlaps;
408
408
  exports.applyMatches = applyMatches;
409
+ exports.createDetectedValueMasker = createDetectedValueMasker;
409
410
  exports.redact = redact;
410
411
  var mysql_password_js_1 = require_mysql_password();
411
412
  exports.MAX_BYTES = 102400;
@@ -502,6 +503,8 @@ var require_redact = __commonJS({
502
503
  re.lastIndex++;
503
504
  continue;
504
505
  }
506
+ if (/^\[REDACTED(?::[^\]]+)?\]$/i.test(captured))
507
+ continue;
505
508
  const start = m.index;
506
509
  const end = m.index + m[0].length;
507
510
  const replaceStart = start + m[0].indexOf(captured);
@@ -514,18 +517,17 @@ var require_redact = __commonJS({
514
517
  return out;
515
518
  }
516
519
  function resolveOverlaps(matches) {
517
- const sorted = [...matches].sort((a, b) => {
518
- if (a.start !== b.start)
519
- return a.start - b.start;
520
- return b.end - b.start - (a.end - a.start);
521
- });
520
+ const sorted = [...matches].sort((a, b) => a.replaceStart - b.replaceStart || b.replaceEnd - a.replaceEnd);
522
521
  const kept = [];
523
- let lastEnd = -1;
524
522
  for (const m of sorted) {
525
- if (m.start < lastEnd)
526
- continue;
527
- kept.push(m);
528
- lastEnd = m.end;
523
+ const previous = kept[kept.length - 1];
524
+ if (previous && m.replaceStart < previous.replaceEnd) {
525
+ previous.replaceEnd = Math.max(previous.replaceEnd, m.replaceEnd);
526
+ previous.start = Math.min(previous.start, m.start);
527
+ previous.end = Math.max(previous.end, m.end);
528
+ } else {
529
+ kept.push({ ...m });
530
+ }
529
531
  }
530
532
  return kept;
531
533
  }
@@ -537,6 +539,63 @@ var require_redact = __commonJS({
537
539
  }
538
540
  return out;
539
541
  }
542
+ function createDetectedValueMasker(values) {
543
+ const unique = /* @__PURE__ */ new Map();
544
+ for (const entry of values) {
545
+ if (entry.value.length > 0 && !unique.has(entry.value))
546
+ unique.set(entry.value, entry);
547
+ }
548
+ const replacements = [...unique.values()];
549
+ const escaped = replacements.flatMap((entry) => {
550
+ const value = JSON.stringify(entry.value).slice(1, -1);
551
+ return value === entry.value ? [entry] : [entry, { ...entry, value }];
552
+ });
553
+ const replace = (input, entries) => {
554
+ const ranges = [];
555
+ const markers = [...input.matchAll(/\[(?:PINTA_)?REDACTED(?::[^\]]+)?\]/gi)];
556
+ for (const entry of entries) {
557
+ for (let at = input.indexOf(entry.value); at >= 0; at = input.indexOf(entry.value, at + 1)) {
558
+ if (markers.some((marker) => at >= marker.index && at + entry.value.length <= marker.index + marker[0].length))
559
+ continue;
560
+ ranges.push({
561
+ start: at,
562
+ end: at + entry.value.length,
563
+ replaceStart: at,
564
+ replaceEnd: at + entry.value.length,
565
+ type: entry.type
566
+ });
567
+ }
568
+ }
569
+ return applyMatches(input, resolveOverlaps(ranges));
570
+ };
571
+ const mask = (input) => {
572
+ if (replacements.length === 0)
573
+ return input;
574
+ if (unique.has(input))
575
+ return replace(input, replacements);
576
+ const first = input.trimStart()[0];
577
+ if (first === "{" || first === "[" || first === '"') {
578
+ let json = false;
579
+ try {
580
+ JSON.parse(input);
581
+ json = true;
582
+ } catch (error) {
583
+ if (!(error instanceof SyntaxError))
584
+ throw error;
585
+ }
586
+ if (json) {
587
+ return input.replace(/"(?:\\.|[^"\\])*"|-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/gs, (token) => {
588
+ const quoted = token.startsWith('"');
589
+ const decoded = quoted ? JSON.parse(token) : token;
590
+ const masked = quoted ? mask(decoded) : replace(decoded, replacements);
591
+ return masked === decoded ? token : JSON.stringify(masked);
592
+ });
593
+ }
594
+ }
595
+ return replace(input, escaped);
596
+ };
597
+ return mask;
598
+ }
540
599
  function redact(input, opts = {}) {
541
600
  if (input.length === 0)
542
601
  return input;
@@ -594,34 +653,55 @@ var require_otlp = __commonJS({
594
653
  return name.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").toLowerCase();
595
654
  }
596
655
  var EMPTY_SET = /* @__PURE__ */ new Set();
597
- function maybeRedactString(key2, raw, policy) {
598
- const truncated = (0, redact_js_1.truncate)(raw);
599
- if ((policy.skipRedactKeys ?? EMPTY_SET).has(key2))
600
- return truncated;
656
+ var stringSources = /* @__PURE__ */ new WeakMap();
657
+ var outputSources = /* @__PURE__ */ new WeakMap();
658
+ var payloadMaskers = /* @__PURE__ */ new WeakMap();
659
+ function sourceText(value) {
660
+ if (typeof value === "string")
661
+ return value;
662
+ try {
663
+ return JSON.stringify(value);
664
+ } catch (error) {
665
+ if (!(error instanceof TypeError))
666
+ throw error;
667
+ return String(value);
668
+ }
669
+ }
670
+ function stringValue(key2, raw, policy) {
601
671
  const context = (policy.bashContextKeys ?? EMPTY_SET).has(key2) ? "bash" : void 0;
602
- return (0, redact_js_1.redact)(truncated, { context });
672
+ const matches = (policy.skipRedactKeys ?? EMPTY_SET).has(key2) ? [] : (0, redact_js_1.collectMatches)(raw, { context });
673
+ const value = { stringValue: (0, redact_js_1.truncate)((0, redact_js_1.applyMatches)(raw, (0, redact_js_1.resolveOverlaps)(matches))) };
674
+ stringSources.set(value, {
675
+ original: raw,
676
+ detections: matches.map((match) => ({ value: raw.slice(match.replaceStart, match.replaceEnd), type: match.type }))
677
+ });
678
+ return value;
603
679
  }
604
680
  function toOtlpValue(key2, v, policy = {}) {
605
681
  if (v === null || v === void 0)
606
682
  return null;
683
+ let value;
607
684
  switch (typeof v) {
608
685
  case "string":
609
- return { stringValue: maybeRedactString(key2, v, policy) };
686
+ value = stringValue(key2, v, policy);
687
+ break;
610
688
  case "boolean":
611
- return { boolValue: v };
689
+ value = { boolValue: v };
690
+ break;
612
691
  case "number":
613
- if (Number.isInteger(v))
614
- return { intValue: v };
615
- return { doubleValue: v };
616
- case "object":
617
- try {
618
- return { stringValue: maybeRedactString(key2, JSON.stringify(v), policy) };
619
- } catch {
620
- return { stringValue: maybeRedactString(key2, String(v), policy) };
621
- }
692
+ value = Number.isInteger(v) ? { intValue: v } : { doubleValue: v };
693
+ break;
694
+ case "object": {
695
+ value = stringValue(key2, sourceText(v) ?? String(v), policy);
696
+ break;
697
+ }
622
698
  default:
623
- return { stringValue: maybeRedactString(key2, String(v), policy) };
699
+ value = stringValue(key2, String(v), policy);
624
700
  }
701
+ const outputText = sourceText(policy.outputForKey?.(key2, v));
702
+ if (outputText !== void 0)
703
+ outputSources.set(value, outputText);
704
+ return value;
625
705
  }
626
706
  function attrsFromRecord2(record2, prefix, policy = {}) {
627
707
  const out = [];
@@ -688,33 +768,93 @@ var require_otlp = __commonJS({
688
768
  function buildPayload2(args) {
689
769
  const ts = args.now ?? Date.now();
690
770
  const tsNano = (BigInt(ts) * 1000000n).toString();
691
- const attrs = [...args.attributes];
771
+ const sources = [...args.resource, ...args.attributes].flatMap((attr) => {
772
+ const source = stringSources.get(attr.value);
773
+ return source ? [source] : [];
774
+ });
775
+ const detected = sources.flatMap((source) => source.detections);
776
+ const outputs = [...args.resource, ...args.attributes].flatMap((attr) => {
777
+ const output = outputSources.get(attr.value);
778
+ return output === void 0 ? [] : [output];
779
+ });
780
+ const outputValues = new Set(detected.filter((entry) => {
781
+ const maskValue = (0, redact_js_1.createDetectedValueMasker)([entry]);
782
+ return outputs.some((text) => maskValue(text) !== text);
783
+ }).map((entry) => entry.value));
784
+ const mask = (0, redact_js_1.createDetectedValueMasker)(detected);
785
+ const attrs = args.attributes.map((attr) => maskAttribute(attr, mask));
692
786
  const span = {
693
787
  traceId: ulidToTraceId2(args.traceId),
694
788
  spanId: newSpanId(),
695
- name: args.spanName,
789
+ name: mask(args.spanName),
696
790
  kind: args.spanKind ?? 1,
697
791
  startTimeUnixNano: tsNano,
698
792
  endTimeUnixNano: tsNano,
699
793
  attributes: attrs
700
794
  };
701
- enforceSpanBudget(span);
702
795
  const payload = {
703
796
  resourceSpans: [
704
797
  {
705
- resource: { attributes: args.resource },
706
- scopeSpans: [{ scope: args.scope, spans: [span] }]
798
+ resource: { attributes: args.resource.map((attr) => maskAttribute(attr, mask)) },
799
+ scopeSpans: [{
800
+ scope: { name: mask(args.scope.name), version: mask(args.scope.version) },
801
+ spans: [span]
802
+ }]
707
803
  }
708
804
  ]
709
805
  };
806
+ if (detected.length > 0) {
807
+ payloadMaskers.set(payload, mask);
808
+ attrs.push({
809
+ key: "pinta.facts",
810
+ value: { stringValue: JSON.stringify({
811
+ items: [
812
+ { origin: "attributes", values: detected.filter((entry) => !outputValues.has(entry.value)) },
813
+ { origin: "toolOutput", values: detected.filter((entry) => outputValues.has(entry.value)) }
814
+ ].filter((group) => group.values.length > 0).map(({ origin, values }) => ({
815
+ category: "DATA_EXFILTRATION",
816
+ source: "CORE_REDACT",
817
+ path: "$",
818
+ secrets: {
819
+ kinds: ["credential"],
820
+ count: new Set(values.map((entry) => entry.value)).size,
821
+ origins: [origin],
822
+ scannedFields: ["attributes"],
823
+ scanner: "core-tier1",
824
+ truncated: false,
825
+ corroboration: ["pattern"]
826
+ }
827
+ }))
828
+ }) }
829
+ });
830
+ }
831
+ enforceSpanBudget(span);
710
832
  return attachGuard3(payload, args.guard, args.clientTiming);
711
833
  }
834
+ function maskAttribute(attr, mask) {
835
+ const result = { key: mask(attr.key), value: { ...attr.value } };
836
+ const value = result.value;
837
+ if ("stringValue" in value) {
838
+ const source = stringSources.get(attr.value);
839
+ const masked = mask(source?.original ?? value.stringValue);
840
+ value.stringValue = source ? (0, redact_js_1.truncate)(masked) : masked;
841
+ } else if ("intValue" in value || "doubleValue" in value) {
842
+ const text = String("intValue" in value ? value.intValue : value.doubleValue);
843
+ const masked = mask(text);
844
+ if (masked !== text)
845
+ result.value = { stringValue: masked };
846
+ }
847
+ return result;
848
+ }
712
849
  function attachGuard3(payload, guard, clientTiming) {
713
850
  const span = payload.resourceSpans[0]?.scopeSpans[0]?.spans[0];
714
851
  if (!span)
715
852
  return payload;
716
- if (guard)
717
- span.attributes.push(...guardAttrs(guard));
853
+ if (guard) {
854
+ const attributes = guardAttrs(guard);
855
+ const mask = payloadMaskers.get(payload);
856
+ span.attributes.push(...mask ? attributes.map((attr) => maskAttribute(attr, mask)) : attributes);
857
+ }
718
858
  const timing = clientTiming ?? (guard?.clientRttMs !== void 0 ? { op: "guard", rttMs: guard.clientRttMs } : null);
719
859
  if (timing)
720
860
  span.attributes.push(...clientAttrs(timing));
@@ -750,6 +890,9 @@ var require_guard = __commonJS({
750
890
  };
751
891
  }
752
892
  var VALID_DECISIONS = /* @__PURE__ */ new Set(["ALLOW", "DENY", "REVIEW"]);
893
+ function isFailOpenReason(value) {
894
+ return value === "timeout" || value === "refused" || value === "error";
895
+ }
753
896
  exports.GUARD_STATUS_REFUSED = 410;
754
897
  async function evaluateGuard2(payload, endpoint, opts = {}) {
755
898
  if (!endpoint)
@@ -789,13 +932,17 @@ var require_guard = __commonJS({
789
932
  if (!body || !VALID_DECISIONS.has(body.decision) || !durationMsOk) {
790
933
  return failOpen2(Date.now() - start, "error");
791
934
  }
935
+ const failOpenReason = body.decision === "ALLOW" ? body.failOpenReason : void 0;
936
+ if (failOpenReason != null && !isFailOpenReason(failOpenReason))
937
+ return failOpen2(Date.now() - start, "error");
792
938
  const clientRttMs = Date.now() - start;
793
939
  return {
794
940
  decision: body.decision,
795
941
  reason: body.reason ?? null,
796
942
  userMessage: body.userMessage ?? null,
797
943
  durationMs: body.durationMs ?? clientRttMs,
798
- clientRttMs
944
+ clientRttMs,
945
+ ...isFailOpenReason(failOpenReason) ? { failOpenReason } : {}
799
946
  };
800
947
  } catch (err) {
801
948
  const name = err.name;
@@ -1644,7 +1791,7 @@ var import_core8 = __toESM(require_dist(), 1);
1644
1791
  var import_core5 = __toESM(require_dist(), 1);
1645
1792
 
1646
1793
  // src/core/version.ts
1647
- var ADAPTER_VERSION = "0.11.1";
1794
+ var ADAPTER_VERSION = "0.11.3-skax.0";
1648
1795
 
1649
1796
  // src/core/guard.ts
1650
1797
  var DEFAULT_TIMEOUT_MS = 100;
@@ -1696,7 +1843,12 @@ var BASH_CONTEXT_KEYS = /* @__PURE__ */ new Set([
1696
1843
  ]);
1697
1844
  var ATTR_POLICY = {
1698
1845
  skipRedactKeys: SKIP_REDACT_KEYS,
1699
- bashContextKeys: BASH_CONTEXT_KEYS
1846
+ bashContextKeys: BASH_CONTEXT_KEYS,
1847
+ outputForKey: (key2, value) => {
1848
+ if (key2 === "opencode.error" || key2 === "opencode.error_message") return value;
1849
+ if (!["opencode.tool_response", "opencode.tool_result", "opencode.output"].includes(key2)) return void 0;
1850
+ return value && typeof value === "object" && "output" in value && value.output !== void 0 ? value.output : value;
1851
+ }
1700
1852
  };
1701
1853
  function flattenFields(fields) {
1702
1854
  const out = [{ key: "ingest.type", value: { stringValue: "opencode" } }];
package/dist/plugin.js CHANGED
@@ -1,26 +1,26 @@
1
1
  import { createRequire as __pintaCreateRequire } from 'module'; const require = __pintaCreateRequire(import.meta.url);
2
- var Dt=Object.create;var Ae=Object.defineProperty;var It=Object.getOwnPropertyDescriptor;var At=Object.getOwnPropertyNames;var Mt=Object.getPrototypeOf,wt=Object.prototype.hasOwnProperty;var v=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,n)=>(typeof require<"u"?require:e)[n]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var T=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var kt=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of At(e))!wt.call(t,s)&&s!==n&&Ae(t,s,{get:()=>e[s],enumerable:!(r=It(e,s))||r.enumerable});return t};var D=(t,e,n)=>(n=t!=null?Dt(Mt(t)):{},kt(e||!t||!t.__esModule?Ae(n,"default",{value:t,enumerable:!0}):n,t));var Re=T(se=>{"use strict";Object.defineProperty(se,"__esModule",{value:!0});se.mysqlPasswordRanges=$t;var Rt=new Set(["mysql","mysqldump","mysqladmin","mysqlcheck","mysqlimport","mysqlshow","mariadb","mariadb-dump","mariadb-admin","mariadb-check","mariadb-import","mariadb-show"]),xt=new Set(["sh","bash","dash","zsh","ksh"]),jt=new Set(["-u","--user","-h","--host","-P","--port","-D","--database","-S","--socket","-e","--execute","--protocol","--default-character-set","--defaults-file","--defaults-extra-file","--login-path","--init-command","--ssl-ca","--ssl-capath","--ssl-cert","--ssl-key","--ssl-cipher"]),X=16;function Me(t,e,n=t.value.length){return{value:t.value.slice(e,n),ranges:t.ranges.slice(e,n)}}function G(t,e,n,r){t.value+=e.value.slice(n,r);for(let s=n;s<r;s++)t.ranges.push(e.ranges[s])}function we(t){if(t?.literal)return t.value.slice(t.value.lastIndexOf("/")+1).replace(/\.exe$/,"")}function Nt(t){let e=0;for(let n=0;n<=X;n++){for(;/^[A-Za-z_][A-Za-z0-9_]*=/.test(t[e]?.value??"");)e++;let r=we(t[e]);if(!r)return;if(["!","if","then","elif","else","while","until","do"].includes(r)){e++;continue}let s={env:["-u","--unset","-C","--chdir"],sudo:["-u","--user","-g","--group","-p","--prompt","-D","--chdir","-R","--chroot","-C","--close-from","-T","--command-timeout"],exec:["-a"],nice:["-n","--adjustment"],timeout:["-s","--signal","-k","--kill-after"]},i={env:["-i","--ignore-environment","-0","--null"],sudo:["-n","-E","-H","-S","-b","-k"],command:["-p"],exec:["-c","-l"],nohup:[],nice:[],time:["-p"],timeout:["--foreground","--preserve-status"]};if(!(r in i))return e;for(e++;t[e]?.value.startsWith("-");){let a=t[e++].value;if(a==="--")break;if(!i[r].includes(a)){if((s[r]??[]).includes(a)){if(!t[e++])return;continue}if(!(s[r]??[]).some(o=>o.startsWith("--")?a.startsWith(o+"="):a.startsWith(o)&&a.length>2)&&!(r==="nice"&&/^-\d+$/.test(a)))return}}if(r==="timeout"&&!/^\d+(?:\.\d+)?[smhd]?$/.test(t[e++]?.value??""))return}}function ke(t,e){let n=1,r="";for(let s=e;s<t.length;s++){let i=t[s];if(i==="\\"&&r!=="'"){s++;continue}if(r){i===r&&(r="");continue}if(i==="'"||i==='"')r=i;else if(i==="(")n++;else if(i===")"&&--n===0)return s}return t.length}function qt(t,e,n,r){let s={value:"",ranges:[],start:e,end:e,literal:!0},i="",a=e;for(;a<t.value.length;){let o=t.value[a];if(!i&&/[\s;|&()<>{}]/.test(o))break;if(o===i){i="",a++;continue}if(!i&&(o==="'"||o==='"')){i=o,a++;continue}if(o==="\\"&&i!=="'"){let u=t.value[a+1];if(u===`
3
- `){a+=2;continue}if(u&&(!i||/[$`"\\]/.test(u))){G(s,t,a+1,a+2),a+=2;continue}}if(i!=="'"&&t.value.startsWith("$(",a)){let u=ke(t.value,a+2);t.value[a+2]!=="("&&r<X&&x(Me(t,a+2,u),n,r+1),G(s,t,a,Math.min(u+1,t.value.length)),s.literal=!1,a=Math.min(u+1,t.value.length);continue}if(o==="`"&&i!=="'"){let u=a+1;for(;u<t.value.length&&t.value[u]!=="`";)u+=t.value[u]==="\\"?2:1;r<X&&x(Me(t,a+1,u),n,r+1),G(s,t,a,Math.min(u+1,t.value.length)),s.literal=!1,a=Math.min(u+1,t.value.length);continue}o==="$"&&i!=="'"&&(s.literal=!1),G(s,t,a,a+1),a++}return s.end=a,s}function Ct(t,e,n,r){let s=Nt(e);if(s===void 0)return;let i=we(e[s]);if(xt.has(i)&&r<X){for(let a=s+1;a<e.length;a++){let o=e[a].value;if(o==="--command"||/^-[a-zA-Z]*c[a-zA-Z]*$/.test(o)){let u=e[a+1];u&&x(u,n,r+1);return}if(!o.startsWith("-")||o==="--")return;(o==="-o"||o==="-O")&&a++}return}if(Rt.has(i))for(let a=s+1;a<e.length;a++){let o=e[a];if(o.value==="--")return;if(jt.has(o.value)){a++;continue}o.value.startsWith("-p")&&o.value.length>2&&n.push({start:t.ranges[o.start].start,end:t.ranges[o.end-1].end})}}function x(t,e,n=0){let r=[],s,i=[],a=0,o=()=>{Ct(t,r,e,n),r=[],s=void 0};for(;a<t.value.length;){let u=t.value[a];if(u===`
4
- `){o(),a++;for(let l of i.splice(0))for(;a<t.value.length;){let d=t.value.indexOf(`
5
- `,a),h=d<0?t.value.length:d,$=t.value.slice(a,h);if(a=d<0?h:h+1,(l.stripTabs?$.replace(/^\t+/,""):$)===l.delimiter)break}}else if(/\s/.test(u))a++;else if(u==="#"){let l=t.value.indexOf(`
6
- `,a);a=l<0?t.value.length:l}else if(t.value.startsWith("((",a))o(),a=Math.min(ke(t.value,a+1)+1,t.value.length);else if(/[;|&(){}]/.test(u))o(),a++;else if(u==="<"||u===">")r.at(-1)?.end===a&&/^\d+$/.test(r.at(-1).value)&&r.pop(),s=/^(?:<<<|<<-?|>>|<&|>&|[<>])/.exec(t.value.slice(a))?.[0]??u,a+=s.length;else{let l=qt(t,a,e,n);a=l.end,(s==="<<"||s==="<<-")&&i.push({delimiter:l.value,stripTabs:s==="<<-"}),s||r.push(l),s=void 0}}o()}function Bt(t,e,n){let r={value:"",ranges:[]};for(let s=e+1;s<n-1;s++){if(t.value[s]!=="\\"){G(r,t,s,s+1);continue}let i=s+(t.value[s+1]==="u"?6:2),a=JSON.parse(`"${t.value.slice(s,i)}"`);r.value+=a;for(let o=0;o<a.length;o++)r.ranges.push({start:t.ranges[s].start,end:t.ranges[i-1].end});s=i-1}return r}function $t(t){let e={value:t,ranges:Array.from({length:t.length},(r,s)=>({start:s,end:s+1}))},n=[];if(/^\s*[{[]/.test(t)){let r;try{r=JSON.parse(t)}catch{return x(e,n),n}if(r!==null&&typeof r=="object"){let s=/"(?:[^"\\]|\\.)*"/g,i;for(;i=s.exec(t);){let a=JSON.parse(i[0]);if(a!=="command"&&a!=="cmd")continue;let o=/^\s*:\s*/.exec(t.slice(s.lastIndex));if(!o)continue;let u=s.lastIndex+o[0].length;if(t[u]!=='"')continue;s.lastIndex=u;let l=s.exec(t);l?.index===u&&x(Bt(e,u,u+l[0].length),n)}}return n}return x(e,n),n}});var oe=T(m=>{"use strict";Object.defineProperty(m,"__esModule",{value:!0});m.PATTERNS=m.MAX_BYTES=void 0;m.truncateTo=xe;m.truncate=Ft;m.collectMatches=je;m.resolveOverlaps=Ne;m.applyMatches=qe;m.redact=Ut;var Gt=Re();m.MAX_BYTES=102400;function xe(t,e){let n=Buffer.from(t,"utf-8");return n.length<=e?t:`${n.subarray(0,Math.max(0,e)).toString("utf-8")}\u2026[TRUNCATED:${n.length}]`}function Ft(t){return xe(t,m.MAX_BYTES)}m.PATTERNS=[{type:"aws_access_key",regex:/AKIA[0-9A-Z]{16}/g},{type:"aws_secret_key",regex:/(?:aws[_-]?secret(?:[_-]?(?:access)?[_-]?key)?)\s*[:=]\s*["']?([A-Za-z0-9/+=]{40})(?![A-Za-z0-9/+=])/gi,captureGroup:1},{type:"gcp_service_account",regex:/\{[\s\S]{0,200}?"type"\s*:\s*"service_account"[\s\S]*?\}/g},{type:"github_token",regex:/gh[pousr]_[A-Za-z0-9]{36,}/g},{type:"gitlab_token",regex:/glpat-[A-Za-z0-9_-]{20}/g},{type:"slack_token",regex:/xox[abrsp]-[0-9A-Za-z-]{10,}/g},{type:"openai_key",regex:/sk-(?:proj-)?[A-Za-z0-9_-]{40,}/g},{type:"anthropic_key",regex:/sk-ant-[A-Za-z0-9_-]{50,}/g},{type:"stripe_key",regex:/(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g},{type:"jwt",regex:/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g},{type:"private_key_block",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g},{type:"bearer_token",regex:/bearer\s+([A-Za-z0-9._~+/=-]{12,})/gi,captureGroup:1},{type:"basic_auth",regex:/basic\s+([A-Za-z0-9+/=]{12,})/gi,captureGroup:1},{type:"db_url_password",regex:/\b(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|redis):\/\/[^:\s/]+:([^@\s]+)@/gi,captureGroup:1},{type:"cli_password_flag",regex:/(?:--password|--pass|--pwd)[=\s]([^\s'"]+)/g,captureGroup:1},{type:"cli_password_short",regex:/\s-p([^\s'"]+)/g,captureGroup:1,requireContext:"bash"},{type:"env_var_secret",regex:/^(?:export\s+)?([A-Z][A-Z0-9_]*(?:KEY|SECRET|TOKEN|PASSWORD|PASSWD|PWD|API_KEY)[A-Z0-9_]*)\s*=\s*["']?([^\s"'\n]+)/gm,captureGroup:2}];function je(t,e){let n=[];for(let r of m.PATTERNS){if(r.requireContext&&r.requireContext!==e.context)continue;if(r.type==="cli_password_short"){for(let{start:a,end:o}of(0,Gt.mysqlPasswordRanges)(t))n.push({start:a,end:o,replaceStart:a,replaceEnd:o,type:r.type,replacement:`-p[REDACTED:${r.type}]`});continue}let s=new RegExp(r.regex.source,r.regex.flags),i;for(;(i=s.exec(t))!==null;){let a=r.captureGroup??0,o=i[a];if(o===void 0){i.index===s.lastIndex&&s.lastIndex++;continue}let u=i.index,l=i.index+i[0].length,d=u+i[0].indexOf(o),h=d+o.length;n.push({start:u,end:l,replaceStart:d,replaceEnd:h,type:r.type}),i.index===s.lastIndex&&s.lastIndex++}}return n}function Ne(t){let e=[...t].sort((s,i)=>s.start!==i.start?s.start-i.start:i.end-i.start-(s.end-s.start)),n=[],r=-1;for(let s of e)s.start<r||(n.push(s),r=s.end);return n}function qe(t,e){let n=[...e].sort((s,i)=>i.replaceStart-s.replaceStart),r=t;for(let s of n)r=r.slice(0,s.replaceStart)+(s.replacement??`[REDACTED:${s.type}]`)+r.slice(s.replaceEnd);return r}function Ut(t,e={}){if(t.length===0)return t;let n=je(t,e);if(n.length===0)return t;let r=Ne(n);return qe(t,r)}});var ae=T(p=>{"use strict";var Vt=p&&p.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(p,"__esModule",{value:!0});p.MAX_SPAN_BYTES=void 0;p.ulidToTraceId=Ge;p.newSpanId=Fe;p.snakeCase=Yt;p.toOtlpValue=Ue;p.attrsFromRecord=Wt;p.guardAttrs=Ve;p.clientAttrs=Le;p.enforceSpanBudget=Xe;p.buildPayload=zt;p.attachGuard=Ye;p.mergeBatch=Zt;var Lt=Vt(v("crypto")),ie=oe(),Xt="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Ge(t){if(t.length!==26)throw new Error(`ulidToTraceId: expected 26 chars, got ${t.length}`);let e=0n;for(let r of t){let s=Xt.indexOf(r);if(s<0)throw new Error(`ulidToTraceId: invalid Crockford char "${r}"`);e=e<<5n|BigInt(s)}let n=(1n<<128n)-1n;return e&=n,e.toString(16).padStart(32,"0")}function Fe(){return Lt.default.randomBytes(8).toString("hex")}function Yt(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var Ce=new Set;function Y(t,e,n){let r=(0,ie.truncate)(e);if((n.skipRedactKeys??Ce).has(t))return r;let s=(n.bashContextKeys??Ce).has(t)?"bash":void 0;return(0,ie.redact)(r,{context:s})}function Ue(t,e,n={}){if(e==null)return null;switch(typeof e){case"string":return{stringValue:Y(t,e,n)};case"boolean":return{boolValue:e};case"number":return Number.isInteger(e)?{intValue:e}:{doubleValue:e};case"object":try{return{stringValue:Y(t,JSON.stringify(e),n)}}catch{return{stringValue:Y(t,String(e),n)}}default:return{stringValue:Y(t,String(e),n)}}}function Wt(t,e,n={}){let r=[];for(let[s,i]of Object.entries(t)){let a=`${e}.${s}`,o=Ue(a,i,n);o!==null&&r.push({key:a,value:o})}return r}function Ve(t){let e=[{key:"pinta.guard.decision",value:{stringValue:t.decision.toLowerCase()}},{key:"pinta.guard.duration_ms",value:{intValue:t.durationMs}}];return t.reason&&e.push({key:"pinta.guard.matched_rule",value:{stringValue:t.reason}}),t.failOpenReason&&e.push({key:"pinta.guard.fail_open_reason",value:{stringValue:t.failOpenReason}}),e}function Le(t){return[{key:"pinta.client.rtt_ms",value:Number.isInteger(t.rttMs)?{intValue:t.rttMs}:{doubleValue:t.rttMs}},{key:"pinta.client.op",value:{stringValue:t.op}}]}p.MAX_SPAN_BYTES=800*1024;function Be(t){let e=JSON.stringify(t);return e===void 0?0:Buffer.byteLength(e,"utf-8")}var $e=1024;function Xe(t,e=p.MAX_SPAN_BYTES){let n=Be(t);for(let r=0;r<100&&n>e;r++){let s=null,i=0;for(let u of t.attributes){if(!("stringValue"in u.value))continue;let l=Buffer.byteLength(u.value.stringValue,"utf-8");l>i&&(i=l,s=u.value)}if(s===null||i<=$e)break;let a=n-e,o=Math.max($e,i-a-64);s.stringValue=(0,ie.truncateTo)(s.stringValue,o),n=Be(t)}return t}function zt(t){let e=t.now??Date.now(),n=(BigInt(e)*1000000n).toString(),r=[...t.attributes],s={traceId:Ge(t.traceId),spanId:Fe(),name:t.spanName,kind:t.spanKind??1,startTimeUnixNano:n,endTimeUnixNano:n,attributes:r};Xe(s);let i={resourceSpans:[{resource:{attributes:t.resource},scopeSpans:[{scope:t.scope,spans:[s]}]}]};return Ye(i,t.guard,t.clientTiming)}function Ye(t,e,n){let r=t.resourceSpans[0]?.scopeSpans[0]?.spans[0];if(!r)return t;e&&r.attributes.push(...Ve(e));let s=n??(e?.clientRttMs!==void 0?{op:"guard",rttMs:e.clientRttMs}:null);return s&&r.attributes.push(...Le(s)),t}function Zt(t){let e=[];for(let n of t)e.push(...n.resourceSpans);return{resourceSpans:e}}});var We=T(P=>{"use strict";Object.defineProperty(P,"__esModule",{value:!0});P.GUARD_STATUS_REFUSED=P.GUARD_BUDGET_HEADER=void 0;P.evaluateGuard=Qt;var Kt=1e4,Ht="pinta-core";P.GUARD_BUDGET_HEADER="x-pinta-guard-budget-ms";function W(t,e){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:t,clientRttMs:t,failOpenReason:e}}var Jt=new Set(["ALLOW","DENY","REVIEW"]);P.GUARD_STATUS_REFUSED=410;async function Qt(t,e,n={}){if(!e||n.disabled)return null;let r=n.timeoutMs??Kt,s=Date.now(),i=new AbortController,a=setTimeout(()=>i.abort(),r);try{let o=await fetch(e,{method:"POST",headers:{"content-type":"application/json","user-agent":n.userAgent??Ht,"x-pinta-relay-token":n.token??"",...n.agentType?{"x-pinta-agent-type":n.agentType}:{},...Number.isFinite(r)&&r>0?{[P.GUARD_BUDGET_HEADER]:String(r)}:{}},body:JSON.stringify(t),signal:i.signal});if(o.status===P.GUARD_STATUS_REFUSED)return W(Date.now()-s,"refused");if(o.status!==200)return W(Date.now()-s,"error");let u=await o.json(),l=u?.durationMs===void 0||typeof u.durationMs=="number"&&Number.isFinite(u.durationMs);if(!u||!Jt.has(u.decision)||!l)return W(Date.now()-s,"error");let d=Date.now()-s;return{decision:u.decision,reason:u.reason??null,userMessage:u.userMessage??null,durationMs:u.durationMs??d,clientRttMs:d}}catch(o){let u=o.name,l=u==="AbortError"||u==="TimeoutError"?"timeout":"error";return W(Date.now()-s,l)}finally{clearTimeout(a)}}});var z=T(F=>{"use strict";var en=F&&F.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(F,"__esModule",{value:!0});F.atomicWriteFileSync=tn;var ze=en(v("fs"));function tn(t,e){let n=`${t}.${process.pid}.tmp`;ze.default.writeFileSync(n,e),ze.default.renameSync(n,t)}});var le=T(I=>{"use strict";var Ze=I&&I.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(I,"__esModule",{value:!0});I.MemoryRetryQueue=I.DiskRetryQueue=void 0;var y=Ze(v("fs")),Z=Ze(v("path")),nn=z(),K=1e3,rn=50,sn=5,ue=class{filePath;lockPath;logPrefix;constructor(e,n){this.filePath=Z.default.join(e,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=n}enqueue(e){try{y.default.mkdirSync(Z.default.dirname(this.filePath),{recursive:!0});let n=JSON.stringify({savedAt:new Date().toISOString(),payload:e})+`
7
- `;y.default.appendFileSync(this.filePath,n),this.trim()}catch(n){process.stderr.write(`[${this.logPrefix}] retry-queue enqueue failed: ${n}
8
- `)}}readAll(){try{let e=y.default.readFileSync(this.filePath,"utf-8"),n=[];for(let r of e.split(`
9
- `))if(r.trim())try{let s=JSON.parse(r);Array.isArray(s?.payload?.resourceSpans)&&n.push(s)}catch{}return n}catch{return[]}}rewrite(e){try{if(e.length===0){y.default.existsSync(this.filePath)&&y.default.unlinkSync(this.filePath);return}y.default.mkdirSync(Z.default.dirname(this.filePath),{recursive:!0}),(0,nn.atomicWriteFileSync)(this.filePath,e.map(n=>JSON.stringify(n)).join(`
2
+ var xt=Object.create;var xe=Object.defineProperty;var Nt=Object.getOwnPropertyDescriptor;var jt=Object.getOwnPropertyNames;var Ct=Object.getPrototypeOf,qt=Object.prototype.hasOwnProperty;var _=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,n)=>(typeof require<"u"?require:e)[n]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var O=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var Bt=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of jt(e))!qt.call(t,s)&&s!==n&&xe(t,s,{get:()=>e[s],enumerable:!(r=Nt(e,s))||r.enumerable});return t};var I=(t,e,n)=>(n=t!=null?xt(Ct(t)):{},Bt(e||!t||!t.__esModule?xe(n,"default",{value:t,enumerable:!0}):n,t));var qe=O(oe=>{"use strict";Object.defineProperty(oe,"__esModule",{value:!0});oe.mysqlPasswordRanges=Wt;var $t=new Set(["mysql","mysqldump","mysqladmin","mysqlcheck","mysqlimport","mysqlshow","mariadb","mariadb-dump","mariadb-admin","mariadb-check","mariadb-import","mariadb-show"]),Vt=new Set(["sh","bash","dash","zsh","ksh"]),Ft=new Set(["-u","--user","-h","--host","-P","--port","-D","--database","-S","--socket","-e","--execute","--protocol","--default-character-set","--defaults-file","--defaults-extra-file","--login-path","--init-command","--ssl-ca","--ssl-capath","--ssl-cert","--ssl-key","--ssl-cipher"]),z=16;function Ne(t,e,n=t.value.length){return{value:t.value.slice(e,n),ranges:t.ranges.slice(e,n)}}function F(t,e,n,r){t.value+=e.value.slice(n,r);for(let s=n;s<r;s++)t.ranges.push(e.ranges[s])}function je(t){if(t?.literal)return t.value.slice(t.value.lastIndexOf("/")+1).replace(/\.exe$/,"")}function Gt(t){let e=0;for(let n=0;n<=z;n++){for(;/^[A-Za-z_][A-Za-z0-9_]*=/.test(t[e]?.value??"");)e++;let r=je(t[e]);if(!r)return;if(["!","if","then","elif","else","while","until","do"].includes(r)){e++;continue}let s={env:["-u","--unset","-C","--chdir"],sudo:["-u","--user","-g","--group","-p","--prompt","-D","--chdir","-R","--chroot","-C","--close-from","-T","--command-timeout"],exec:["-a"],nice:["-n","--adjustment"],timeout:["-s","--signal","-k","--kill-after"]},a={env:["-i","--ignore-environment","-0","--null"],sudo:["-n","-E","-H","-S","-b","-k"],command:["-p"],exec:["-c","-l"],nohup:[],nice:[],time:["-p"],timeout:["--foreground","--preserve-status"]};if(!(r in a))return e;for(e++;t[e]?.value.startsWith("-");){let o=t[e++].value;if(o==="--")break;if(!a[r].includes(o)){if((s[r]??[]).includes(o)){if(!t[e++])return;continue}if(!(s[r]??[]).some(i=>i.startsWith("--")?o.startsWith(i+"="):o.startsWith(i)&&o.length>2)&&!(r==="nice"&&/^-\d+$/.test(o)))return}}if(r==="timeout"&&!/^\d+(?:\.\d+)?[smhd]?$/.test(t[e++]?.value??""))return}}function Ce(t,e){let n=1,r="";for(let s=e;s<t.length;s++){let a=t[s];if(a==="\\"&&r!=="'"){s++;continue}if(r){a===r&&(r="");continue}if(a==="'"||a==='"')r=a;else if(a==="(")n++;else if(a===")"&&--n===0)return s}return t.length}function Ut(t,e,n,r){let s={value:"",ranges:[],start:e,end:e,literal:!0},a="",o=e;for(;o<t.value.length;){let i=t.value[o];if(!a&&/[\s;|&()<>{}]/.test(i))break;if(i===a){a="",o++;continue}if(!a&&(i==="'"||i==='"')){a=i,o++;continue}if(i==="\\"&&a!=="'"){let u=t.value[o+1];if(u===`
3
+ `){o+=2;continue}if(u&&(!a||/[$`"\\]/.test(u))){F(s,t,o+1,o+2),o+=2;continue}}if(a!=="'"&&t.value.startsWith("$(",o)){let u=Ce(t.value,o+2);t.value[o+2]!=="("&&r<z&&j(Ne(t,o+2,u),n,r+1),F(s,t,o,Math.min(u+1,t.value.length)),s.literal=!1,o=Math.min(u+1,t.value.length);continue}if(i==="`"&&a!=="'"){let u=o+1;for(;u<t.value.length&&t.value[u]!=="`";)u+=t.value[u]==="\\"?2:1;r<z&&j(Ne(t,o+1,u),n,r+1),F(s,t,o,Math.min(u+1,t.value.length)),s.literal=!1,o=Math.min(u+1,t.value.length);continue}i==="$"&&a!=="'"&&(s.literal=!1),F(s,t,o,o+1),o++}return s.end=o,s}function Lt(t,e,n,r){let s=Gt(e);if(s===void 0)return;let a=je(e[s]);if(Vt.has(a)&&r<z){for(let o=s+1;o<e.length;o++){let i=e[o].value;if(i==="--command"||/^-[a-zA-Z]*c[a-zA-Z]*$/.test(i)){let u=e[o+1];u&&j(u,n,r+1);return}if(!i.startsWith("-")||i==="--")return;(i==="-o"||i==="-O")&&o++}return}if($t.has(a))for(let o=s+1;o<e.length;o++){let i=e[o];if(i.value==="--")return;if(Ft.has(i.value)){o++;continue}i.value.startsWith("-p")&&i.value.length>2&&n.push({start:t.ranges[i.start].start,end:t.ranges[i.end-1].end})}}function j(t,e,n=0){let r=[],s,a=[],o=0,i=()=>{Lt(t,r,e,n),r=[],s=void 0};for(;o<t.value.length;){let u=t.value[o];if(u===`
4
+ `){i(),o++;for(let l of a.splice(0))for(;o<t.value.length;){let f=t.value.indexOf(`
5
+ `,o),d=f<0?t.value.length:f,p=t.value.slice(o,d);if(o=f<0?d:d+1,(l.stripTabs?p.replace(/^\t+/,""):p)===l.delimiter)break}}else if(/\s/.test(u))o++;else if(u==="#"){let l=t.value.indexOf(`
6
+ `,o);o=l<0?t.value.length:l}else if(t.value.startsWith("((",o))i(),o=Math.min(Ce(t.value,o+1)+1,t.value.length);else if(/[;|&(){}]/.test(u))i(),o++;else if(u==="<"||u===">")r.at(-1)?.end===o&&/^\d+$/.test(r.at(-1).value)&&r.pop(),s=/^(?:<<<|<<-?|>>|<&|>&|[<>])/.exec(t.value.slice(o))?.[0]??u,o+=s.length;else{let l=Ut(t,o,e,n);o=l.end,(s==="<<"||s==="<<-")&&a.push({delimiter:l.value,stripTabs:s==="<<-"}),s||r.push(l),s=void 0}}i()}function Xt(t,e,n){let r={value:"",ranges:[]};for(let s=e+1;s<n-1;s++){if(t.value[s]!=="\\"){F(r,t,s,s+1);continue}let a=s+(t.value[s+1]==="u"?6:2),o=JSON.parse(`"${t.value.slice(s,a)}"`);r.value+=o;for(let i=0;i<o.length;i++)r.ranges.push({start:t.ranges[s].start,end:t.ranges[a-1].end});s=a-1}return r}function Wt(t){let e={value:t,ranges:Array.from({length:t.length},(r,s)=>({start:s,end:s+1}))},n=[];if(/^\s*[{[]/.test(t)){let r;try{r=JSON.parse(t)}catch{return j(e,n),n}if(r!==null&&typeof r=="object"){let s=/"(?:[^"\\]|\\.)*"/g,a;for(;a=s.exec(t);){let o=JSON.parse(a[0]);if(o!=="command"&&o!=="cmd"&&o!=="CommandLine")continue;let i=/^\s*:\s*/.exec(t.slice(s.lastIndex));if(!i)continue;let u=s.lastIndex+i[0].length;if(t[u]!=='"')continue;s.lastIndex=u;let l=s.exec(t);l?.index===u&&j(Xt(e,u,u+l[0].length),n)}}return n}return j(e,n),n}});var ue=O(y=>{"use strict";Object.defineProperty(y,"__esModule",{value:!0});y.PATTERNS=y.MAX_BYTES=void 0;y.truncateTo=Be;y.truncate=zt;y.collectMatches=$e;y.resolveOverlaps=ie;y.applyMatches=ae;y.createDetectedValueMasker=Kt;y.redact=Zt;var Yt=qe();y.MAX_BYTES=102400;function Be(t,e){let n=Buffer.from(t,"utf-8");return n.length<=e?t:`${n.subarray(0,Math.max(0,e)).toString("utf-8")}\u2026[TRUNCATED:${n.length}]`}function zt(t){return Be(t,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 $e(t,e){let n=[];for(let r of y.PATTERNS){if(r.requireContext&&r.requireContext!==e.context)continue;if(r.type==="cli_password_short"){for(let{start:o,end:i}of(0,Yt.mysqlPasswordRanges)(t))n.push({start:o,end:i,replaceStart:o,replaceEnd:i,type:r.type,replacement:`-p[REDACTED:${r.type}]`});continue}let s=new RegExp(r.regex.source,r.regex.flags),a;for(;(a=s.exec(t))!==null;){let o=r.captureGroup??0,i=a[o];if(i===void 0){a.index===s.lastIndex&&s.lastIndex++;continue}if(/^\[REDACTED(?::[^\]]+)?\]$/i.test(i))continue;let u=a.index,l=a.index+a[0].length,f=u+a[0].indexOf(i),d=f+i.length;n.push({start:u,end:l,replaceStart:f,replaceEnd:d,type:r.type}),a.index===s.lastIndex&&s.lastIndex++}}return n}function ie(t){let e=[...t].sort((r,s)=>r.replaceStart-s.replaceStart||s.replaceEnd-r.replaceEnd),n=[];for(let r of e){let s=n[n.length-1];s&&r.replaceStart<s.replaceEnd?(s.replaceEnd=Math.max(s.replaceEnd,r.replaceEnd),s.start=Math.min(s.start,r.start),s.end=Math.max(s.end,r.end)):n.push({...r})}return n}function ae(t,e){let n=[...e].sort((s,a)=>a.replaceStart-s.replaceStart),r=t;for(let s of n)r=r.slice(0,s.replaceStart)+(s.replacement??`[REDACTED:${s.type}]`)+r.slice(s.replaceEnd);return r}function Kt(t){let e=new Map;for(let o of t)o.value.length>0&&!e.has(o.value)&&e.set(o.value,o);let n=[...e.values()],r=n.flatMap(o=>{let i=JSON.stringify(o.value).slice(1,-1);return i===o.value?[o]:[o,{...o,value:i}]}),s=(o,i)=>{let u=[],l=[...o.matchAll(/\[(?:PINTA_)?REDACTED(?::[^\]]+)?\]/gi)];for(let f of i)for(let d=o.indexOf(f.value);d>=0;d=o.indexOf(f.value,d+1))l.some(p=>d>=p.index&&d+f.value.length<=p.index+p[0].length)||u.push({start:d,end:d+f.value.length,replaceStart:d,replaceEnd:d+f.value.length,type:f.type});return ae(o,ie(u))},a=o=>{if(n.length===0)return o;if(e.has(o))return s(o,n);let i=o.trimStart()[0];if(i==="{"||i==="["||i==='"'){let u=!1;try{JSON.parse(o),u=!0}catch(l){if(!(l instanceof SyntaxError))throw l}if(u)return o.replace(/"(?:\\.|[^"\\])*"|-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/gs,l=>{let f=l.startsWith('"'),d=f?JSON.parse(l):l,p=f?a(d):s(d,n);return p===d?l:JSON.stringify(p)})}return s(o,r)};return a}function Zt(t,e={}){if(t.length===0)return t;let n=$e(t,e);if(n.length===0)return t;let r=ie(n);return ae(t,r)}});var fe=O(h=>{"use strict";var Jt=h&&h.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(h,"__esModule",{value:!0});h.MAX_SPAN_BYTES=void 0;h.ulidToTraceId=Le;h.newSpanId=Xe;h.snakeCase=en;h.toOtlpValue=ze;h.attrsFromRecord=tn;h.guardAttrs=Ke;h.clientAttrs=Ze;h.enforceSpanBudget=Je;h.buildPayload=nn;h.attachGuard=He;h.mergeBatch=rn;var Ht=Jt(_("crypto")),M=ue(),Qt="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Le(t){if(t.length!==26)throw new Error(`ulidToTraceId: expected 26 chars, got ${t.length}`);let e=0n;for(let r of t){let s=Qt.indexOf(r);if(s<0)throw new Error(`ulidToTraceId: invalid Crockford char "${r}"`);e=e<<5n|BigInt(s)}let n=(1n<<128n)-1n;return e&=n,e.toString(16).padStart(32,"0")}function Xe(){return Ht.default.randomBytes(8).toString("hex")}function en(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var Ve=new Set,de=new WeakMap,We=new WeakMap,Ye=new WeakMap;function Fe(t){if(typeof t=="string")return t;try{return JSON.stringify(t)}catch(e){if(!(e instanceof TypeError))throw e;return String(t)}}function ce(t,e,n){let r=(n.bashContextKeys??Ve).has(t)?"bash":void 0,s=(n.skipRedactKeys??Ve).has(t)?[]:(0,M.collectMatches)(e,{context:r}),a={stringValue:(0,M.truncate)((0,M.applyMatches)(e,(0,M.resolveOverlaps)(s)))};return de.set(a,{original:e,detections:s.map(o=>({value:e.slice(o.replaceStart,o.replaceEnd),type:o.type}))}),a}function ze(t,e,n={}){if(e==null)return null;let r;switch(typeof e){case"string":r=ce(t,e,n);break;case"boolean":r={boolValue:e};break;case"number":r=Number.isInteger(e)?{intValue:e}:{doubleValue:e};break;case"object":{r=ce(t,Fe(e)??String(e),n);break}default:r=ce(t,String(e),n)}let s=Fe(n.outputForKey?.(t,e));return s!==void 0&&We.set(r,s),r}function tn(t,e,n={}){let r=[];for(let[s,a]of Object.entries(t)){let o=`${e}.${s}`,i=ze(o,a,n);i!==null&&r.push({key:o,value:i})}return r}function Ke(t){let e=[{key:"pinta.guard.decision",value:{stringValue:t.decision.toLowerCase()}},{key:"pinta.guard.duration_ms",value:{intValue:t.durationMs}}];return t.reason&&e.push({key:"pinta.guard.matched_rule",value:{stringValue:t.reason}}),t.failOpenReason&&e.push({key:"pinta.guard.fail_open_reason",value:{stringValue:t.failOpenReason}}),e}function Ze(t){return[{key:"pinta.client.rtt_ms",value:Number.isInteger(t.rttMs)?{intValue:t.rttMs}:{doubleValue:t.rttMs}},{key:"pinta.client.op",value:{stringValue:t.op}}]}h.MAX_SPAN_BYTES=800*1024;function Ge(t){let e=JSON.stringify(t);return e===void 0?0:Buffer.byteLength(e,"utf-8")}var Ue=1024;function Je(t,e=h.MAX_SPAN_BYTES){let n=Ge(t);for(let r=0;r<100&&n>e;r++){let s=null,a=0;for(let u of t.attributes){if(!("stringValue"in u.value))continue;let l=Buffer.byteLength(u.value.stringValue,"utf-8");l>a&&(a=l,s=u.value)}if(s===null||a<=Ue)break;let o=n-e,i=Math.max(Ue,a-o-64);s.stringValue=(0,M.truncateTo)(s.stringValue,i),n=Ge(t)}return t}function nn(t){let e=t.now??Date.now(),n=(BigInt(e)*1000000n).toString(),s=[...t.resource,...t.attributes].flatMap(d=>{let p=de.get(d.value);return p?[p]:[]}).flatMap(d=>d.detections),a=[...t.resource,...t.attributes].flatMap(d=>{let p=We.get(d.value);return p===void 0?[]:[p]}),o=new Set(s.filter(d=>{let p=(0,M.createDetectedValueMasker)([d]);return a.some(Y=>p(Y)!==Y)}).map(d=>d.value)),i=(0,M.createDetectedValueMasker)(s),u=t.attributes.map(d=>le(d,i)),l={traceId:Le(t.traceId),spanId:Xe(),name:i(t.spanName),kind:t.spanKind??1,startTimeUnixNano:n,endTimeUnixNano:n,attributes:u},f={resourceSpans:[{resource:{attributes:t.resource.map(d=>le(d,i))},scopeSpans:[{scope:{name:i(t.scope.name),version:i(t.scope.version)},spans:[l]}]}]};return s.length>0&&(Ye.set(f,i),u.push({key:"pinta.facts",value:{stringValue:JSON.stringify({items:[{origin:"attributes",values:s.filter(d=>!o.has(d.value))},{origin:"toolOutput",values:s.filter(d=>o.has(d.value))}].filter(d=>d.values.length>0).map(({origin:d,values:p})=>({category:"DATA_EXFILTRATION",source:"CORE_REDACT",path:"$",secrets:{kinds:["credential"],count:new Set(p.map(Y=>Y.value)).size,origins:[d],scannedFields:["attributes"],scanner:"core-tier1",truncated:!1,corroboration:["pattern"]}}))})}})),Je(l),He(f,t.guard,t.clientTiming)}function le(t,e){let n={key:e(t.key),value:{...t.value}},r=n.value;if("stringValue"in r){let s=de.get(t.value),a=e(s?.original??r.stringValue);r.stringValue=s?(0,M.truncate)(a):a}else if("intValue"in r||"doubleValue"in r){let s=String("intValue"in r?r.intValue:r.doubleValue),a=e(s);a!==s&&(n.value={stringValue:a})}return n}function He(t,e,n){let r=t.resourceSpans[0]?.scopeSpans[0]?.spans[0];if(!r)return t;if(e){let a=Ke(e),o=Ye.get(t);r.attributes.push(...o?a.map(i=>le(i,o)):a)}let s=n??(e?.clientRttMs!==void 0?{op:"guard",rttMs:e.clientRttMs}:null);return s&&r.attributes.push(...Ze(s)),t}function rn(t){let e=[];for(let n of t)e.push(...n.resourceSpans);return{resourceSpans:e}}});var et=O(b=>{"use strict";Object.defineProperty(b,"__esModule",{value:!0});b.GUARD_STATUS_REFUSED=b.GUARD_BUDGET_HEADER=void 0;b.evaluateGuard=un;var sn=1e4,on="pinta-core";b.GUARD_BUDGET_HEADER="x-pinta-guard-budget-ms";function G(t,e){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:t,clientRttMs:t,failOpenReason:e}}var an=new Set(["ALLOW","DENY","REVIEW"]);function Qe(t){return t==="timeout"||t==="refused"||t==="error"}b.GUARD_STATUS_REFUSED=410;async function un(t,e,n={}){if(!e||n.disabled)return null;let r=n.timeoutMs??sn,s=Date.now(),a=new AbortController,o=setTimeout(()=>a.abort(),r);try{let i=await fetch(e,{method:"POST",headers:{"content-type":"application/json","user-agent":n.userAgent??on,"x-pinta-relay-token":n.token??"",...n.agentType?{"x-pinta-agent-type":n.agentType}:{},...Number.isFinite(r)&&r>0?{[b.GUARD_BUDGET_HEADER]:String(r)}:{}},body:JSON.stringify(t),signal:a.signal});if(i.status===b.GUARD_STATUS_REFUSED)return G(Date.now()-s,"refused");if(i.status!==200)return G(Date.now()-s,"error");let u=await i.json(),l=u?.durationMs===void 0||typeof u.durationMs=="number"&&Number.isFinite(u.durationMs);if(!u||!an.has(u.decision)||!l)return G(Date.now()-s,"error");let f=u.decision==="ALLOW"?u.failOpenReason:void 0;if(f!=null&&!Qe(f))return G(Date.now()-s,"error");let d=Date.now()-s;return{decision:u.decision,reason:u.reason??null,userMessage:u.userMessage??null,durationMs:u.durationMs??d,clientRttMs:d,...Qe(f)?{failOpenReason:f}:{}}}catch(i){let u=i.name,l=u==="AbortError"||u==="TimeoutError"?"timeout":"error";return G(Date.now()-s,l)}finally{clearTimeout(o)}}});var K=O(U=>{"use strict";var cn=U&&U.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(U,"__esModule",{value:!0});U.atomicWriteFileSync=ln;var tt=cn(_("fs"));function ln(t,e){let n=`${t}.${process.pid}.tmp`;tt.default.writeFileSync(n,e),tt.default.renameSync(n,t)}});var he=O(A=>{"use strict";var nt=A&&A.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(A,"__esModule",{value:!0});A.MemoryRetryQueue=A.DiskRetryQueue=void 0;var v=nt(_("fs")),Z=nt(_("path")),dn=K(),J=1e3,fn=50,pn=5,pe=class{filePath;lockPath;logPrefix;constructor(e,n){this.filePath=Z.default.join(e,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=n}enqueue(e){try{v.default.mkdirSync(Z.default.dirname(this.filePath),{recursive:!0});let n=JSON.stringify({savedAt:new Date().toISOString(),payload:e})+`
7
+ `;v.default.appendFileSync(this.filePath,n),this.trim()}catch(n){process.stderr.write(`[${this.logPrefix}] retry-queue enqueue failed: ${n}
8
+ `)}}readAll(){try{let e=v.default.readFileSync(this.filePath,"utf-8"),n=[];for(let r of e.split(`
9
+ `))if(r.trim())try{let s=JSON.parse(r);Array.isArray(s?.payload?.resourceSpans)&&n.push(s)}catch{}return n}catch{return[]}}rewrite(e){try{if(e.length===0){v.default.existsSync(this.filePath)&&v.default.unlinkSync(this.filePath);return}v.default.mkdirSync(Z.default.dirname(this.filePath),{recursive:!0}),(0,dn.atomicWriteFileSync)(this.filePath,e.map(n=>JSON.stringify(n)).join(`
10
10
  `)+`
11
11
  `)}catch(n){process.stderr.write(`[${this.logPrefix}] retry-queue rewrite failed: ${n}
12
- `)}}tryAcquireLock(){let e=Date.now();try{y.default.mkdirSync(Z.default.dirname(this.lockPath),{recursive:!0})}catch(n){return process.stderr.write(`[${this.logPrefix}] retry-queue lock mkdir failed: ${n}
13
- `),!1}for(;Date.now()-e<rn;)try{let n=y.default.openSync(this.lockPath,"wx");return y.default.writeSync(n,String(process.pid)),y.default.closeSync(n),!0}catch(n){if(n?.code!=="EEXIST")return process.stderr.write(`[${this.logPrefix}] retry-queue lock open failed: ${n}
14
- `),!1;try{let i=y.default.statSync(this.lockPath);if(Date.now()-i.mtimeMs>3e4){y.default.unlinkSync(this.lockPath);continue}}catch{}let r=sn,s=Date.now()+r;for(;Date.now()<s;);}return!1}release(){try{y.default.unlinkSync(this.lockPath)}catch{}}trim(){let e=this.readAll();if(e.length<=K)return;let n=e.length-K;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${n} oldest entries
15
- `),this.rewrite(e.slice(n))}};I.DiskRetryQueue=ue;var ce=class{entries=[];enqueue(e){this.entries.push(e),this.entries.length>K&&this.entries.splice(0,this.entries.length-K)}drain(){let e=this.entries;return this.entries=[],e}get size(){return this.entries.length}};I.MemoryRetryQueue=ce});var tt=T(f=>{"use strict";Object.defineProperty(f,"__esModule",{value:!0});f.MemoryTransport=f.DiskTransport=f.MAX_POST_BYTES=void 0;f.parseHeadersEnv=Qe;f.envOptionsResolver=et;f.postOtlp=U;var Ke=le(),He=ae(),on=5e3;f.MAX_POST_BYTES=900*1024;function H(t){let e=JSON.stringify(t);return e===void 0?0:Buffer.byteLength(e,"utf-8")}function Je(t,e,n){let r=[],s=[],i=[],a=0;for(let o of t){let u=e(o);if(u>n){s.push(o);continue}i.length>0&&a+u>n&&(r.push(i),i=[],a=0),i.push(o),a+=u}return i.length>0&&r.push(i),{chunks:r,oversize:s}}function Qe(t){if(!t)return{};if(typeof t=="object")return{...t};let e={};for(let n of t.split(",")){let[r,...s]=n.split("=");r&&s.length>0&&(e[r.trim()]=s.join("=").trim())}return e}function et(){let t=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,e=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,n;return t?n=t.replace(/\/+$/,""):e&&(n=e.replace(/\/+$/,"")+"/v1/traces"),n?{endpoint:n,headers:Qe(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function U(t,e,n){let r=new AbortController,s=setTimeout(()=>r.abort(),on);try{let i=await fetch(e.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...e.headers},body:JSON.stringify(t),signal:r.signal});if(!i.ok){let a="";try{a=(await i.text()).slice(0,200)}catch{}let o=i.status===401||i.status===403?" \u2014 check OTEL_EXPORTER_OTLP_HEADERS (relay token)":i.status===404?" \u2014 check OTEL_EXPORTER_OTLP_TRACES_ENDPOINT path":i.status>=500?" \u2014 collector may be down":"";return process.stderr.write(`[${n}] OTLP POST ${i.status} ${e.endpoint}${o}${a?` body=${a}`:""}
16
- `),!1}return!0}catch(i){return process.stderr.write(`[${n}] OTLP POST failed: ${i.message??String(i)}
17
- `),!1}finally{clearTimeout(s)}}var de=class{queue;logPrefix;resolveOptions;constructor(e){this.queue=new Ke.DiskRetryQueue(e.pluginData,e.logPrefix),this.logPrefix=e.logPrefix,this.resolveOptions=e.resolveOptions??et}async send(e){let n=this.resolveOptions();if(!n||this.dropIfOversized(e))return;await U(e,n,this.logPrefix)||this.queue.enqueue(e)}async flush(){let e=this.resolveOptions();if(e&&this.queue.tryAcquireLock())try{let n=this.queue.readAll();if(n.length===0)return;let{chunks:r,oversize:s}=Je(n,o=>H(o.payload),f.MAX_POST_BYTES);s.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${s.length} oversized retry ${s.length===1?"entry":"entries"} (each > ${f.MAX_POST_BYTES} bytes \u2014 the backend caps the request body, so they can never be delivered)
18
- `);let i=[].concat(...r),a=0;for(let o of r){if(!await U((0,He.mergeBatch)(o.map(l=>l.payload)),e,this.logPrefix))break;a+=o.length}this.queue.rewrite(i.slice(a))}catch(n){process.stderr.write(`[${this.logPrefix}] flush failed: ${n?.message??String(n)}
19
- `)}finally{this.queue.release()}}dropIfOversized(e){let n=H(e);return n<=f.MAX_POST_BYTES?!1:(process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (${n} > ${f.MAX_POST_BYTES} bytes) \u2014 undeliverable, not queued
20
- `),!0)}};f.DiskTransport=de;var fe=class{queue=new Ke.MemoryRetryQueue;logPrefix;resolveOptions;constructor(e){this.logPrefix=e.logPrefix,this.resolveOptions=e.resolveOptions}async send(e){let n=this.resolveOptions();if(!n)return;if(H(e)>f.MAX_POST_BYTES){process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (> ${f.MAX_POST_BYTES} bytes) \u2014 undeliverable, not buffered
21
- `);return}await U(e,n,this.logPrefix)||this.queue.enqueue(e)}async flush(){let e=this.resolveOptions();if(!e)return;let n=this.queue.drain();if(n.length===0)return;let{chunks:r,oversize:s}=Je(n,H,f.MAX_POST_BYTES);s.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${s.length} oversized buffered ${s.length===1?"payload":"payloads"} (each > ${f.MAX_POST_BYTES} bytes \u2014 undeliverable)
22
- `);let i=[].concat(...r),a=0;for(let o of r){if(!await U((0,He.mergeBatch)(o),e,this.logPrefix))break;a+=o.length}for(let o of i.slice(a))this.queue.enqueue(o)}};f.MemoryTransport=fe});var me=T(k=>{"use strict";var he=k&&k.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(k,"__esModule",{value:!0});k.TraceManager=void 0;k.generateUlid=rt;var nt=he(v("fs")),an=he(v("path")),un=he(v("crypto")),cn=z(),pe="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function rt(){let t=Date.now(),e="",n=t;for(let i=0;i<10;i++)e=pe[n&31]+e,n=Math.floor(n/32);let r=un.default.randomBytes(10),s="";for(let i=0;i<10;i++)s+=pe[r[i]&31];for(;s.length<16;)s+=pe[0];return e+s}var ge=class{tracePath;constructor(e){this.tracePath=e}newTrace(){let e=rt();return this.save(e),e}currentTrace(){try{let e=nt.default.readFileSync(this.tracePath,"utf-8"),{traceId:n}=JSON.parse(e);if(n)return n}catch{}return this.newTrace()}save(e){try{nt.default.mkdirSync(an.default.dirname(this.tracePath),{recursive:!0}),(0,cn.atomicWriteFileSync)(this.tracePath,JSON.stringify({traceId:e}))}catch(n){process.stderr.write(`[pinta-core] trace persistence failed: ${n}
23
- `)}}};k.TraceManager=ge});var ut=T(A=>{"use strict";var ot=A&&A.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(A,"__esModule",{value:!0});A.MemorySessionTraceManager=A.DiskSessionTraceManager=void 0;var st=ot(v("fs")),ln=ot(v("path")),it=me(),dn=z(),at=200,ye=class{tracePath;maxSessions;constructor(e,n={}){this.tracePath=e,this.maxSessions=n.maxSessions??at}read(){try{let e=JSON.parse(st.default.readFileSync(this.tracePath,"utf-8"));if(e&&typeof e=="object"&&!("traceId"in e))return e}catch{}return{}}write(e){try{st.default.mkdirSync(ln.default.dirname(this.tracePath),{recursive:!0});let n=Object.entries(e),r=n.length>this.maxSessions?Object.fromEntries(n.slice(-this.maxSessions)):e;(0,dn.atomicWriteFileSync)(this.tracePath,JSON.stringify(r))}catch{}}newTrace(e){let n=e||"default",r=(0,it.generateUlid)(),s=this.read();return s[n]=r,this.write(s),r}currentTrace(e){let n=e||"default",r=this.read()[n];return r||this.newTrace(n)}};A.DiskSessionTraceManager=ye;var ve=class{map=new Map;maxSessions;constructor(e={}){this.maxSessions=e.maxSessions??at}newTrace(e){let n=e||"default",r=(0,it.generateUlid)();if(this.map.set(n,r),this.map.size>this.maxSessions){let s=this.map.keys().next().value;s!==void 0&&this.map.delete(s)}return r}currentTrace(e){let n=e||"default";return this.map.get(n)??this.newTrace(n)}};A.MemorySessionTraceManager=ve});var dt=T(R=>{"use strict";var _e=R&&R.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(R,"__esModule",{value:!0});R.envFilePath=gn;R.parseEnvFile=lt;R.loadEnvFile=hn;var fn=_e(v("node:fs")),pn=_e(v("node:os")),ct=_e(v("node:path"));function gn(t,e,n){let r=n?process.env[n]:void 0,s=r&&r.length>0?r:ct.default.join(pn.default.homedir(),t);return ct.default.join(s,e)}function lt(t){let e={};for(let n of t.split(`
24
- `)){let r=n.trim();if(!r||r.startsWith("#"))continue;let s=r.indexOf("=");if(s<0)continue;let i=r.slice(0,s).trim(),a=r.slice(s+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),i&&(e[i]=a)}return e}function hn(t){let e;try{e=fn.default.readFileSync(t,"utf-8")}catch{return}let n=lt(e);for(let[r,s]of Object.entries(n))process.env[r]===void 0&&(process.env[r]=s)}});var S=T(c=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});c.loadEnvFile=c.parseEnvFile=c.envFilePath=c.MemorySessionTraceManager=c.DiskSessionTraceManager=c.generateUlid=c.TraceManager=c.MAX_POST_BYTES=c.parseHeadersEnv=c.envOptionsResolver=c.postOtlp=c.MemoryTransport=c.DiskTransport=c.MemoryRetryQueue=c.DiskRetryQueue=c.GUARD_BUDGET_HEADER=c.GUARD_STATUS_REFUSED=c.evaluateGuard=c.MAX_SPAN_BYTES=c.enforceSpanBudget=c.mergeBatch=c.attachGuard=c.buildPayload=c.clientAttrs=c.guardAttrs=c.attrsFromRecord=c.toOtlpValue=c.snakeCase=c.newSpanId=c.ulidToTraceId=c.MAX_BYTES=c.PATTERNS=c.applyMatches=c.resolveOverlaps=c.collectMatches=c.truncateTo=c.truncate=c.redact=void 0;var M=oe();Object.defineProperty(c,"redact",{enumerable:!0,get:function(){return M.redact}});Object.defineProperty(c,"truncate",{enumerable:!0,get:function(){return M.truncate}});Object.defineProperty(c,"truncateTo",{enumerable:!0,get:function(){return M.truncateTo}});Object.defineProperty(c,"collectMatches",{enumerable:!0,get:function(){return M.collectMatches}});Object.defineProperty(c,"resolveOverlaps",{enumerable:!0,get:function(){return M.resolveOverlaps}});Object.defineProperty(c,"applyMatches",{enumerable:!0,get:function(){return M.applyMatches}});Object.defineProperty(c,"PATTERNS",{enumerable:!0,get:function(){return M.PATTERNS}});Object.defineProperty(c,"MAX_BYTES",{enumerable:!0,get:function(){return M.MAX_BYTES}});var _=ae();Object.defineProperty(c,"ulidToTraceId",{enumerable:!0,get:function(){return _.ulidToTraceId}});Object.defineProperty(c,"newSpanId",{enumerable:!0,get:function(){return _.newSpanId}});Object.defineProperty(c,"snakeCase",{enumerable:!0,get:function(){return _.snakeCase}});Object.defineProperty(c,"toOtlpValue",{enumerable:!0,get:function(){return _.toOtlpValue}});Object.defineProperty(c,"attrsFromRecord",{enumerable:!0,get:function(){return _.attrsFromRecord}});Object.defineProperty(c,"guardAttrs",{enumerable:!0,get:function(){return _.guardAttrs}});Object.defineProperty(c,"clientAttrs",{enumerable:!0,get:function(){return _.clientAttrs}});Object.defineProperty(c,"buildPayload",{enumerable:!0,get:function(){return _.buildPayload}});Object.defineProperty(c,"attachGuard",{enumerable:!0,get:function(){return _.attachGuard}});Object.defineProperty(c,"mergeBatch",{enumerable:!0,get:function(){return _.mergeBatch}});Object.defineProperty(c,"enforceSpanBudget",{enumerable:!0,get:function(){return _.enforceSpanBudget}});Object.defineProperty(c,"MAX_SPAN_BYTES",{enumerable:!0,get:function(){return _.MAX_SPAN_BYTES}});var Te=We();Object.defineProperty(c,"evaluateGuard",{enumerable:!0,get:function(){return Te.evaluateGuard}});Object.defineProperty(c,"GUARD_STATUS_REFUSED",{enumerable:!0,get:function(){return Te.GUARD_STATUS_REFUSED}});Object.defineProperty(c,"GUARD_BUDGET_HEADER",{enumerable:!0,get:function(){return Te.GUARD_BUDGET_HEADER}});var ft=le();Object.defineProperty(c,"DiskRetryQueue",{enumerable:!0,get:function(){return ft.DiskRetryQueue}});Object.defineProperty(c,"MemoryRetryQueue",{enumerable:!0,get:function(){return ft.MemoryRetryQueue}});var j=tt();Object.defineProperty(c,"DiskTransport",{enumerable:!0,get:function(){return j.DiskTransport}});Object.defineProperty(c,"MemoryTransport",{enumerable:!0,get:function(){return j.MemoryTransport}});Object.defineProperty(c,"postOtlp",{enumerable:!0,get:function(){return j.postOtlp}});Object.defineProperty(c,"envOptionsResolver",{enumerable:!0,get:function(){return j.envOptionsResolver}});Object.defineProperty(c,"parseHeadersEnv",{enumerable:!0,get:function(){return j.parseHeadersEnv}});Object.defineProperty(c,"MAX_POST_BYTES",{enumerable:!0,get:function(){return j.MAX_POST_BYTES}});var pt=me();Object.defineProperty(c,"TraceManager",{enumerable:!0,get:function(){return pt.TraceManager}});Object.defineProperty(c,"generateUlid",{enumerable:!0,get:function(){return pt.generateUlid}});var gt=ut();Object.defineProperty(c,"DiskSessionTraceManager",{enumerable:!0,get:function(){return gt.DiskSessionTraceManager}});Object.defineProperty(c,"MemorySessionTraceManager",{enumerable:!0,get:function(){return gt.MemorySessionTraceManager}});var Oe=dt();Object.defineProperty(c,"envFilePath",{enumerable:!0,get:function(){return Oe.envFilePath}});Object.defineProperty(c,"parseEnvFile",{enumerable:!0,get:function(){return Oe.parseEnvFile}});Object.defineProperty(c,"loadEnvFile",{enumerable:!0,get:function(){return Oe.loadEnvFile}})});var mt=D(S(),1);import yn from"node:fs";import Ee from"node:path";var V=D(S(),1);function mn(){return(0,V.envFilePath)(".config/opencode","pinta-opencode.env","OPENCODE_CONFIG_DIR")}function ht(t=mn()){(0,V.loadEnvFile)(t)}function Pe(...t){return t.find(e=>e)||void 0}function vn(t){let e=Pe(t.endpoint,process.env.PINTA_OPENCODE_ENDPOINT,process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT);if(e)return e.replace(/\/+$/,"");let n=process.env.OTEL_EXPORTER_OTLP_ENDPOINT;if(n)return n.replace(/\/+$/,"")+"/v1/traces"}var _n="opencode-ai";function Tn(){let t=Ee.dirname(process.execPath);for(let e=0;e<5;e++){try{let r=JSON.parse(yn.readFileSync(Ee.join(t,"package.json"),"utf8"));if(r.name===_n&&typeof r.version=="string"&&r.version)return r.version}catch{}let n=Ee.dirname(t);if(n===t)break;t=n}}function On(){let t=process.env.OPENCODE_VERSION?.trim();return t||Tn()}function yt(t={}){ht();let e=Pe(t.token,process.env.PINTA_OPENCODE_TOKEN),n=(0,mt.parseHeadersEnv)(t.headers??process.env.PINTA_OPENCODE_HEADERS??process.env.OTEL_EXPORTER_OTLP_HEADERS);e&&!Object.keys(n).some(s=>s.toLowerCase()==="x-pinta-relay-token")&&(n["x-pinta-relay-token"]=e);let r=t.guardTimeoutMs??(Number(process.env.PINTA_OPENCODE_GUARD_TIMEOUT_MS)||100);return{endpoint:vn(t),headers:n,guardEndpoint:Pe(t.guard,process.env.PINTA_OPENCODE_GUARD),relayToken:e,guardTimeoutMs:r,guardDisabled:process.env.PINTA_OPENCODE_GUARD_DISABLED==="1",serviceVersion:On()}}var N=D(S(),1),J=class extends N.MemoryTransport{constructor(n){super({logPrefix:"pinta-opencode",resolveOptions:()=>n.endpoint?{endpoint:n.endpoint,headers:n.headers}:null});this.config=n}deferred=new N.MemoryRetryQueue;defer(n){if(!this.config.endpoint)return;let r=Buffer.byteLength(JSON.stringify(n),"utf8");if(r>N.MAX_POST_BYTES){process.stderr.write(`[pinta-opencode] deferred payload exceeds POST budget (${r} bytes); dropped
25
- `);return}this.deferred.enqueue(n)}async flush(){await super.flush();for(let n of this.deferred.drain())await super.send(n)}};var Se=D(S(),1);var St=D(S(),1);var vt=D(S(),1);var Q="0.11.1";var En=100,Pn=`pinta-opencode/${Q}`;function _t(t,e,n={}){return(0,vt.evaluateGuard)(t,e,{timeoutMs:n.timeoutMs??En,token:n.token,disabled:n.disabled,userAgent:Pn})}var Pt=D(S(),1);import be from"os";var q=D(S(),1);var ee;function Sn(){if(ee===void 0)try{ee=be.userInfo().username}catch{ee=process.env.USER??process.env.LOGNAME??(typeof process.getuid=="function"?String(process.getuid()):"unknown")}return ee}var Tt=Q,bn=new Set(["opencode.hook","opencode.event_type","opencode.tool_name","opencode.session_id","opencode.sessionID","opencode.tool_use_id","opencode.cwd","opencode.agent","opencode.model","opencode.exit","opencode.truncated","opencode.title"]),Dn=new Set(["opencode.tool_input","opencode.tool_response"]),In={skipRedactKeys:bn,bashContextKeys:Dn};function An(t){let e=[{key:"ingest.type",value:{stringValue:"opencode"}}];return e.push(...(0,q.attrsFromRecord)(t,"opencode",In)),e}function Mn(t){return[{key:"service.name",value:{stringValue:"opencode"}},...t?[{key:"service.version",value:{stringValue:t}}]:[],{key:"telemetry.sdk.name",value:{stringValue:"pinta-opencode"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:Tt}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:Sn()}},{key:"host.name",value:{stringValue:be.hostname()}},{key:"host.arch",value:{stringValue:be.arch()}}]}function Ot(t){return(0,q.buildPayload)({traceId:t.traceId,spanName:t.name,attributes:An(t.fields),resource:Mn(t.serviceVersion),scope:{name:"pinta-opencode",version:Tt},now:t.now})}var C={messages:1024,requests:512,calls:2048,endedSessions:128,ttlMs:9e5},wn=new Set(["unknown","undefined","null","n/a","none","-","auto","default"]);function g(t){if(typeof t!="string")return;let e=t.trim();return e&&e.length<=1024?e:void 0}function w(t){let e=g(t);if(!(!e||e.startsWith("{")||e.startsWith("[")||wn.has(e.toLowerCase())))return e}function b(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function O(t,e,n){let r=b(t),s=r?w(r.modelID)??w(r.id):w(t);if(s)return{model:s,source:r?`${e}.${w(r.modelID)?"modelID":"id"}`:e,provider:w(r?.providerID??n)}}function E(...t){return JSON.stringify(t)}function B(...t){let e=t.map(g).filter(n=>n!==void 0);return e.every(n=>n===e[0])?e[0]:void 0}function De(t,e){let n=b(e.info),r=b(e.part);return typeof t=="string"&&t.startsWith("session.")?B(e.sessionID,n?.id):B(e.sessionID,n?.sessionID,r?.sessionID)}var L=class{constructor(e,n){this.limit=e;this.now=n}entries=new Map;get(e){let n=this.entries.get(e);if(n&&n.expires>this.now())return n.value;this.entries.delete(e)}set(e,n){this.entries.delete(e),this.entries.set(e,{value:n,expires:this.now()+C.ttlMs}),this.entries.size>this.limit&&this.entries.delete(this.entries.keys().next().value)}removeWhere(e){for(let[n,r]of this.entries)e(r.value)&&this.entries.delete(n)}clearSession(e){this.removeWhere(n=>n.sessionID===e)}},te=class{constructor(e=Date.now){this.now=e;this.messages=new L(C.messages,e),this.requests=new L(C.requests,e),this.calls=new L(C.calls,e)}messages;requests;calls;ended=new Map;chatMessage(e,n){let r=B(e.sessionID,n?.message?.sessionID);if(!r)return;this.ended.delete(r);let s=B(e.messageID,n?.message?.id);if(!s)return;let i=g(n?.message?.agent??e.agent),a=n?.message?.model!==void 0;this.requests.set(E(r,s,i??""),{sessionID:r,messageID:s,evidence:O(a?n.message?.model:e.model,a?"requested:chat.message.message.model":"requested:chat.message.model")})}chatParams(e){let n=B(e.sessionID,e.message?.sessionID),r=g(e.message?.id),s=g(e.agent);!n||!r||!s||this.ended.has(n)||this.requests.set(E(n,r,s),{sessionID:n,messageID:r,evidence:O(e.model,"requested:chat.params.model")})}fresh(e){return e===void 0||typeof e=="number"&&Number.isFinite(e)&&e>=this.now()-C.ttlMs}clearSession(e){this.messages.clearSession(e),this.requests.clearSession(e),this.calls.clearSession(e)}event(e,n){let r=De(e,n),s=b(n.info),i=b(n.part),a=["session.idle","session.deleted","session.error"].includes(e??"")||e==="session.status"&&b(n.status)?.type==="idle";if(r&&a?(this.clearSession(r),this.ended.delete(r),this.ended.set(r,!0),this.ended.size>C.endedSessions&&this.ended.delete(this.ended.keys().next().value)):r&&e==="session.created"&&(this.clearSession(r),this.ended.delete(r)),e==="message.updated"&&s){if(!B(n.sessionID,s.sessionID)&&(n.sessionID||s.sessionID))return;let o=g(s.id),u=g(s.agent),l=s.role,d=l==="assistant"?O(w(s.modelID),"reported:message.updated.info.modelID",s.providerID)??O(s.model,"reported:message.updated.info.model"):l==="user"?O(s.model,"requested:message.updated.info.model"):void 0;if(!d&&l==="user"&&!("model"in s)&&r&&o&&(d=this.requests.get(E(r,o,u??""))?.evidence),l==="user"&&"model"in s&&!d&&r&&o&&this.requests.set(E(r,o,u??""),{sessionID:r,messageID:o}),d&&(d={...d,agent:u,messageID:o}),r&&o&&!this.ended.has(r)&&this.fresh(b(s.time)?.created)){let h=this.messages.get(E(r,o)),$=h?.ambiguous||!!(l==="assistant"&&h?.evidence&&d&&(h.evidence.model!==d.model||h.evidence.provider!==d.provider||h.evidence.agent!==d.agent));this.messages.set(E(r,o),{sessionID:r,messageID:o,evidence:$?void 0:d,ambiguous:$})}return d}if(r&&e==="message.removed"){let o=g(n.messageID);this.messages.removeWhere(u=>u.sessionID===r&&u.messageID===o),this.requests.removeWhere(u=>u.sessionID===r&&u.messageID===o),this.calls.removeWhere(u=>u.sessionID===r&&u.messageID===o)}if(r&&e==="message.part.removed"){let o=g(n.partID);o&&this.calls.removeWhere(u=>u.sessionID===r&&u.partID===o)}if(e==="message.part.delta"){let o=g(n.messageID);return r&&o&&!this.ended.has(r)?this.messages.get(E(r,o))?.evidence:void 0}if(e==="message.part.updated"&&i){if(!r||this.ended.has(r)||!this.fresh(n.time))return;let o=g(i.messageID);if(!o)return;let u=g(i.callID);if(i.type==="tool"&&u){let l=E(r,u),d=this.calls.get(l);if(!d?.closed){let h=g(i.tool);this.calls.set(l,{sessionID:r,messageID:o,partID:g(i.id),tool:h,pinned:d?.pinned,ambiguous:d?.ambiguous||!!(d&&(d.messageID!==o||d.tool!==h))})}}return this.messages.get(E(r,o))?.evidence}return typeof e=="string"&&e.startsWith("session.")?O(s?.model,`selected:${e}.info.model`)??O(n.model,`selected:${e}.model`):O(n.model,"reported:event.model")??O(w(n.modelID),"reported:event.modelID",n.providerID)}tool(e,n){let r=O(w(e.modelID),"reported:tool.modelID",e.providerID)??O(e.model,"reported:tool.model",e.providerID),s=g(e.sessionID),i=g(e.callID);if(!s||!i)return r;let a=E(s,i),o=this.calls.get(a),u=r;if(!("model"in e)&&!("modelID"in e)&&o&&!o.closed&&!o.ambiguous&&!this.ended.has(s)&&(!o.tool||o.tool===e.tool)){let l=this.messages.get(E(s,o.messageID));l?.ambiguous||(u=o.pinned??l?.evidence),(e.agent&&u?.agent&&e.agent!==u.agent||e.messageID&&e.messageID!==o.messageID)&&(u=void 0)}return o&&!o.closed&&this.calls.set(a,{...o,pinned:n?void 0:u,closed:n}),u}beforeTool(e){return this.tool(e,!1)}afterTool(e){return this.tool(e,!0)}};function ne(t,e){let{model:n,model_source:r,...s}=t;return"model"in t&&n!==e?.model&&(s.model_raw=n),"model_source"in t&&(s.model_source_raw=r),e&&(s.model=e.model,s.model_source=e.source,e.provider&&("provider"in s&&s.provider!==e.provider&&(s.provider_raw=s.provider),s.provider=e.provider),s.agent===void 0&&(s.agent=e.agent),s.message_id===void 0&&(s.message_id=e.messageID)),s}var re=class{constructor(e,n,r){this.transport=e;this.trace=n;this.config=r}models=new te;build(e,n,r){let s=this.trace.currentTrace(n);return Ot({name:e,traceId:s,fields:r,serviceVersion:this.config.serviceVersion})}async send(e){await this.transport.send(e)}async emit(e,n,r){await this.send(this.build(e,n,r))}chatMessage(e,n){this.models.chatMessage(e,n)}chatParams(e){this.models.chatParams(e)}async lifecycle(e){let n=b(e.properties)??{},r=De(e.type,n),s=this.models.event(e.type,n);e.type==="session.idle"&&await this.transport.flush(),await this.emit(`opencode.event.${e.type??"unknown"}`,r,ne({hook:"event",event_type:e.type,session_id:r,cwd:process.cwd(),...n},s))}toolBeforePayload(e,n){return this.build("opencode.tool.before",e.sessionID,ne({...Et("tool.execute.before",e),tool_input:n},this.models.beforeTool(e)))}async toolBefore(e,n,r){await this.send((0,Pt.attachGuard)(this.toolBeforePayload(e,n),r))}toolAfterPayload(e,n){let r=n.metadata??{};return this.build("opencode.tool.after",e.sessionID,ne({...Et("tool.execute.after",e),tool_input:e.args,title:n.title,tool_response:n.content!==void 0?n:n.output,attachments:n.attachments,exit:r.exit,truncated:r.truncated},this.models.afterTool(e)))}async toolAfter(e,n){await this.send(this.toolAfterPayload(e,n))}};function Et(t,e){return{hook:t,tool_name:e.tool,session_id:e.sessionID,tool_use_id:e.callID,cwd:process.cwd(),...e.model!==void 0?{model:e.model}:{},...e.modelID!==void 0?{modelID:e.modelID}:{},...e.providerID!==void 0?{providerID:e.providerID}:{},...e.agent!==void 0?{agent:e.agent}:{},...e.messageID!==void 0?{message_id:e.messageID}:{}}}function bt(t,e){process.stderr.write(`[pinta-opencode] ${t}: ${e?.message??String(e)}
26
- `)}var kn="Pinta withheld this tool output because it violated an active policy.";function Ie(t,e){return async(...n)=>{try{await e(...n)}catch(r){bt(t,r)}}}var Rn=async(t,e)=>{let n=yt(e??{}),r=new J({endpoint:n.endpoint,headers:n.headers}),s=new Se.MemorySessionTraceManager,i=new re(r,s,n);async function a(o,u){let l=null;try{let d=u();l=await _t(d,n.guardEndpoint,{timeoutMs:n.guardTimeoutMs,token:n.relayToken,disabled:n.guardDisabled}),(0,St.attachGuard)(d,l),o==="tool.execute.after"&&l&&d.resourceSpans[0].scopeSpans[0].spans[0].attributes.push({key:"pinta.guard.target",value:{stringValue:"tool_output"}}),l?.decision==="DENY"?r.defer(d):await i.send(d)}catch(d){bt(o,d)}return l}return{"chat.message":Ie("chat.message",async(o,u)=>{s.newTrace(o?.sessionID),i.chatMessage(o,u)}),"chat.params":Ie("chat.params",async(o,u)=>{i.chatParams(o)}),event:Ie("event",async o=>{o?.event&&await i.lifecycle(o.event)}),"tool.execute.before":async(o,u)=>{let l=await a("tool.execute.before",()=>i.toolBeforePayload(o,u?.args));if(l?.decision==="DENY")throw new Error(l.userMessage??l.reason??"guard_deny")},"tool.execute.after":async(o,u)=>{if((await a("tool.execute.after",()=>i.toolAfterPayload(o,u)))?.decision==="DENY")throw new Error(kn)}}},pr=Rn;export{Rn as PintaOpencode,pr as default};
12
+ `)}}tryAcquireLock(){let e=Date.now();try{v.default.mkdirSync(Z.default.dirname(this.lockPath),{recursive:!0})}catch(n){return process.stderr.write(`[${this.logPrefix}] retry-queue lock mkdir failed: ${n}
13
+ `),!1}for(;Date.now()-e<fn;)try{let n=v.default.openSync(this.lockPath,"wx");return v.default.writeSync(n,String(process.pid)),v.default.closeSync(n),!0}catch(n){if(n?.code!=="EEXIST")return process.stderr.write(`[${this.logPrefix}] retry-queue lock open failed: ${n}
14
+ `),!1;try{let a=v.default.statSync(this.lockPath);if(Date.now()-a.mtimeMs>3e4){v.default.unlinkSync(this.lockPath);continue}}catch{}let r=pn,s=Date.now()+r;for(;Date.now()<s;);}return!1}release(){try{v.default.unlinkSync(this.lockPath)}catch{}}trim(){let e=this.readAll();if(e.length<=J)return;let n=e.length-J;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${n} oldest entries
15
+ `),this.rewrite(e.slice(n))}};A.DiskRetryQueue=pe;var ge=class{entries=[];enqueue(e){this.entries.push(e),this.entries.length>J&&this.entries.splice(0,this.entries.length-J)}drain(){let e=this.entries;return this.entries=[],e}get size(){return this.entries.length}};A.MemoryRetryQueue=ge});var ut=O(g=>{"use strict";Object.defineProperty(g,"__esModule",{value:!0});g.MemoryTransport=g.DiskTransport=g.MAX_POST_BYTES=void 0;g.parseHeadersEnv=it;g.envOptionsResolver=at;g.postOtlp=L;var rt=he(),st=fe(),gn=5e3;g.MAX_POST_BYTES=900*1024;function H(t){let e=JSON.stringify(t);return e===void 0?0:Buffer.byteLength(e,"utf-8")}function ot(t,e,n){let r=[],s=[],a=[],o=0;for(let i of t){let u=e(i);if(u>n){s.push(i);continue}a.length>0&&o+u>n&&(r.push(a),a=[],o=0),a.push(i),o+=u}return a.length>0&&r.push(a),{chunks:r,oversize:s}}function it(t){if(!t)return{};if(typeof t=="object")return{...t};let e={};for(let n of t.split(",")){let[r,...s]=n.split("=");r&&s.length>0&&(e[r.trim()]=s.join("=").trim())}return e}function at(){let t=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,e=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,n;return t?n=t.replace(/\/+$/,""):e&&(n=e.replace(/\/+$/,"")+"/v1/traces"),n?{endpoint:n,headers:it(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function L(t,e,n){let r=new AbortController,s=setTimeout(()=>r.abort(),gn);try{let a=await fetch(e.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...e.headers},body:JSON.stringify(t),signal:r.signal});if(!a.ok){let o="";try{o=(await a.text()).slice(0,200)}catch{}let i=a.status===401||a.status===403?" \u2014 check OTEL_EXPORTER_OTLP_HEADERS (relay token)":a.status===404?" \u2014 check OTEL_EXPORTER_OTLP_TRACES_ENDPOINT path":a.status>=500?" \u2014 collector may be down":"";return process.stderr.write(`[${n}] OTLP POST ${a.status} ${e.endpoint}${i}${o?` body=${o}`:""}
16
+ `),!1}return!0}catch(a){return process.stderr.write(`[${n}] OTLP POST failed: ${a.message??String(a)}
17
+ `),!1}finally{clearTimeout(s)}}var me=class{queue;logPrefix;resolveOptions;constructor(e){this.queue=new rt.DiskRetryQueue(e.pluginData,e.logPrefix),this.logPrefix=e.logPrefix,this.resolveOptions=e.resolveOptions??at}async send(e){let n=this.resolveOptions();if(!n||this.dropIfOversized(e))return;await L(e,n,this.logPrefix)||this.queue.enqueue(e)}async flush(){let e=this.resolveOptions();if(e&&this.queue.tryAcquireLock())try{let n=this.queue.readAll();if(n.length===0)return;let{chunks:r,oversize:s}=ot(n,i=>H(i.payload),g.MAX_POST_BYTES);s.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${s.length} oversized retry ${s.length===1?"entry":"entries"} (each > ${g.MAX_POST_BYTES} bytes \u2014 the backend caps the request body, so they can never be delivered)
18
+ `);let a=[].concat(...r),o=0;for(let i of r){if(!await L((0,st.mergeBatch)(i.map(l=>l.payload)),e,this.logPrefix))break;o+=i.length}this.queue.rewrite(a.slice(o))}catch(n){process.stderr.write(`[${this.logPrefix}] flush failed: ${n?.message??String(n)}
19
+ `)}finally{this.queue.release()}}dropIfOversized(e){let n=H(e);return n<=g.MAX_POST_BYTES?!1:(process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (${n} > ${g.MAX_POST_BYTES} bytes) \u2014 undeliverable, not queued
20
+ `),!0)}};g.DiskTransport=me;var ye=class{queue=new rt.MemoryRetryQueue;logPrefix;resolveOptions;constructor(e){this.logPrefix=e.logPrefix,this.resolveOptions=e.resolveOptions}async send(e){let n=this.resolveOptions();if(!n)return;if(H(e)>g.MAX_POST_BYTES){process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (> ${g.MAX_POST_BYTES} bytes) \u2014 undeliverable, not buffered
21
+ `);return}await L(e,n,this.logPrefix)||this.queue.enqueue(e)}async flush(){let e=this.resolveOptions();if(!e)return;let n=this.queue.drain();if(n.length===0)return;let{chunks:r,oversize:s}=ot(n,H,g.MAX_POST_BYTES);s.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${s.length} oversized buffered ${s.length===1?"payload":"payloads"} (each > ${g.MAX_POST_BYTES} bytes \u2014 undeliverable)
22
+ `);let a=[].concat(...r),o=0;for(let i of r){if(!await L((0,st.mergeBatch)(i),e,this.logPrefix))break;o+=i.length}for(let i of a.slice(o))this.queue.enqueue(i)}};g.MemoryTransport=ye});var Oe=O(x=>{"use strict";var Te=x&&x.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(x,"__esModule",{value:!0});x.TraceManager=void 0;x.generateUlid=lt;var ct=Te(_("fs")),hn=Te(_("path")),mn=Te(_("crypto")),yn=K(),ve="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function lt(){let t=Date.now(),e="",n=t;for(let a=0;a<10;a++)e=ve[n&31]+e,n=Math.floor(n/32);let r=mn.default.randomBytes(10),s="";for(let a=0;a<10;a++)s+=ve[r[a]&31];for(;s.length<16;)s+=ve[0];return e+s}var _e=class{tracePath;constructor(e){this.tracePath=e}newTrace(){let e=lt();return this.save(e),e}currentTrace(){try{let e=ct.default.readFileSync(this.tracePath,"utf-8"),{traceId:n}=JSON.parse(e);if(n)return n}catch{}return this.newTrace()}save(e){try{ct.default.mkdirSync(hn.default.dirname(this.tracePath),{recursive:!0}),(0,yn.atomicWriteFileSync)(this.tracePath,JSON.stringify({traceId:e}))}catch(n){process.stderr.write(`[pinta-core] trace persistence failed: ${n}
23
+ `)}}};x.TraceManager=_e});var ht=O(k=>{"use strict";var ft=k&&k.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(k,"__esModule",{value:!0});k.MemorySessionTraceManager=k.DiskSessionTraceManager=void 0;var dt=ft(_("fs")),vn=ft(_("path")),pt=Oe(),_n=K(),gt=200,Ee=class{tracePath;maxSessions;constructor(e,n={}){this.tracePath=e,this.maxSessions=n.maxSessions??gt}read(){try{let e=JSON.parse(dt.default.readFileSync(this.tracePath,"utf-8"));if(e&&typeof e=="object"&&!("traceId"in e))return e}catch{}return{}}write(e){try{dt.default.mkdirSync(vn.default.dirname(this.tracePath),{recursive:!0});let n=Object.entries(e),r=n.length>this.maxSessions?Object.fromEntries(n.slice(-this.maxSessions)):e;(0,_n.atomicWriteFileSync)(this.tracePath,JSON.stringify(r))}catch{}}newTrace(e){let n=e||"default",r=(0,pt.generateUlid)(),s=this.read();return s[n]=r,this.write(s),r}currentTrace(e){let n=e||"default",r=this.read()[n];return r||this.newTrace(n)}};k.DiskSessionTraceManager=Ee;var Se=class{map=new Map;maxSessions;constructor(e={}){this.maxSessions=e.maxSessions??gt}newTrace(e){let n=e||"default",r=(0,pt.generateUlid)();if(this.map.set(n,r),this.map.size>this.maxSessions){let s=this.map.keys().next().value;s!==void 0&&this.map.delete(s)}return r}currentTrace(e){let n=e||"default";return this.map.get(n)??this.newTrace(n)}};k.MemorySessionTraceManager=Se});var vt=O(N=>{"use strict";var be=N&&N.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(N,"__esModule",{value:!0});N.envFilePath=En;N.parseEnvFile=yt;N.loadEnvFile=Sn;var Tn=be(_("node:fs")),On=be(_("node:os")),mt=be(_("node:path"));function En(t,e,n){let r=n?process.env[n]:void 0,s=r&&r.length>0?r:mt.default.join(On.default.homedir(),t);return mt.default.join(s,e)}function yt(t){let e={};for(let n of t.split(`
24
+ `)){let r=n.trim();if(!r||r.startsWith("#"))continue;let s=r.indexOf("=");if(s<0)continue;let a=r.slice(0,s).trim(),o=r.slice(s+1).trim();(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),a&&(e[a]=o)}return e}function Sn(t){let e;try{e=Tn.default.readFileSync(t,"utf-8")}catch{return}let n=yt(e);for(let[r,s]of Object.entries(n))process.env[r]===void 0&&(process.env[r]=s)}});var P=O(c=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});c.loadEnvFile=c.parseEnvFile=c.envFilePath=c.MemorySessionTraceManager=c.DiskSessionTraceManager=c.generateUlid=c.TraceManager=c.MAX_POST_BYTES=c.parseHeadersEnv=c.envOptionsResolver=c.postOtlp=c.MemoryTransport=c.DiskTransport=c.MemoryRetryQueue=c.DiskRetryQueue=c.GUARD_BUDGET_HEADER=c.GUARD_STATUS_REFUSED=c.evaluateGuard=c.MAX_SPAN_BYTES=c.enforceSpanBudget=c.mergeBatch=c.attachGuard=c.buildPayload=c.clientAttrs=c.guardAttrs=c.attrsFromRecord=c.toOtlpValue=c.snakeCase=c.newSpanId=c.ulidToTraceId=c.MAX_BYTES=c.PATTERNS=c.applyMatches=c.resolveOverlaps=c.collectMatches=c.truncateTo=c.truncate=c.redact=void 0;var w=ue();Object.defineProperty(c,"redact",{enumerable:!0,get:function(){return w.redact}});Object.defineProperty(c,"truncate",{enumerable:!0,get:function(){return w.truncate}});Object.defineProperty(c,"truncateTo",{enumerable:!0,get:function(){return w.truncateTo}});Object.defineProperty(c,"collectMatches",{enumerable:!0,get:function(){return w.collectMatches}});Object.defineProperty(c,"resolveOverlaps",{enumerable:!0,get:function(){return w.resolveOverlaps}});Object.defineProperty(c,"applyMatches",{enumerable:!0,get:function(){return w.applyMatches}});Object.defineProperty(c,"PATTERNS",{enumerable:!0,get:function(){return w.PATTERNS}});Object.defineProperty(c,"MAX_BYTES",{enumerable:!0,get:function(){return w.MAX_BYTES}});var T=fe();Object.defineProperty(c,"ulidToTraceId",{enumerable:!0,get:function(){return T.ulidToTraceId}});Object.defineProperty(c,"newSpanId",{enumerable:!0,get:function(){return T.newSpanId}});Object.defineProperty(c,"snakeCase",{enumerable:!0,get:function(){return T.snakeCase}});Object.defineProperty(c,"toOtlpValue",{enumerable:!0,get:function(){return T.toOtlpValue}});Object.defineProperty(c,"attrsFromRecord",{enumerable:!0,get:function(){return T.attrsFromRecord}});Object.defineProperty(c,"guardAttrs",{enumerable:!0,get:function(){return T.guardAttrs}});Object.defineProperty(c,"clientAttrs",{enumerable:!0,get:function(){return T.clientAttrs}});Object.defineProperty(c,"buildPayload",{enumerable:!0,get:function(){return T.buildPayload}});Object.defineProperty(c,"attachGuard",{enumerable:!0,get:function(){return T.attachGuard}});Object.defineProperty(c,"mergeBatch",{enumerable:!0,get:function(){return T.mergeBatch}});Object.defineProperty(c,"enforceSpanBudget",{enumerable:!0,get:function(){return T.enforceSpanBudget}});Object.defineProperty(c,"MAX_SPAN_BYTES",{enumerable:!0,get:function(){return T.MAX_SPAN_BYTES}});var Pe=et();Object.defineProperty(c,"evaluateGuard",{enumerable:!0,get:function(){return Pe.evaluateGuard}});Object.defineProperty(c,"GUARD_STATUS_REFUSED",{enumerable:!0,get:function(){return Pe.GUARD_STATUS_REFUSED}});Object.defineProperty(c,"GUARD_BUDGET_HEADER",{enumerable:!0,get:function(){return Pe.GUARD_BUDGET_HEADER}});var _t=he();Object.defineProperty(c,"DiskRetryQueue",{enumerable:!0,get:function(){return _t.DiskRetryQueue}});Object.defineProperty(c,"MemoryRetryQueue",{enumerable:!0,get:function(){return _t.MemoryRetryQueue}});var C=ut();Object.defineProperty(c,"DiskTransport",{enumerable:!0,get:function(){return C.DiskTransport}});Object.defineProperty(c,"MemoryTransport",{enumerable:!0,get:function(){return C.MemoryTransport}});Object.defineProperty(c,"postOtlp",{enumerable:!0,get:function(){return C.postOtlp}});Object.defineProperty(c,"envOptionsResolver",{enumerable:!0,get:function(){return C.envOptionsResolver}});Object.defineProperty(c,"parseHeadersEnv",{enumerable:!0,get:function(){return C.parseHeadersEnv}});Object.defineProperty(c,"MAX_POST_BYTES",{enumerable:!0,get:function(){return C.MAX_POST_BYTES}});var Tt=Oe();Object.defineProperty(c,"TraceManager",{enumerable:!0,get:function(){return Tt.TraceManager}});Object.defineProperty(c,"generateUlid",{enumerable:!0,get:function(){return Tt.generateUlid}});var Ot=ht();Object.defineProperty(c,"DiskSessionTraceManager",{enumerable:!0,get:function(){return Ot.DiskSessionTraceManager}});Object.defineProperty(c,"MemorySessionTraceManager",{enumerable:!0,get:function(){return Ot.MemorySessionTraceManager}});var De=vt();Object.defineProperty(c,"envFilePath",{enumerable:!0,get:function(){return De.envFilePath}});Object.defineProperty(c,"parseEnvFile",{enumerable:!0,get:function(){return De.parseEnvFile}});Object.defineProperty(c,"loadEnvFile",{enumerable:!0,get:function(){return De.loadEnvFile}})});var St=I(P(),1);import Pn from"node:fs";import Ie from"node:path";var X=I(P(),1);function bn(){return(0,X.envFilePath)(".config/opencode","pinta-opencode.env","OPENCODE_CONFIG_DIR")}function Et(t=bn()){(0,X.loadEnvFile)(t)}function Me(...t){return t.find(e=>e)||void 0}function Dn(t){let e=Me(t.endpoint,process.env.PINTA_OPENCODE_ENDPOINT,process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT);if(e)return e.replace(/\/+$/,"");let n=process.env.OTEL_EXPORTER_OTLP_ENDPOINT;if(n)return n.replace(/\/+$/,"")+"/v1/traces"}var In="opencode-ai";function Mn(){let t=Ie.dirname(process.execPath);for(let e=0;e<5;e++){try{let r=JSON.parse(Pn.readFileSync(Ie.join(t,"package.json"),"utf8"));if(r.name===In&&typeof r.version=="string"&&r.version)return r.version}catch{}let n=Ie.dirname(t);if(n===t)break;t=n}}function An(){let t=process.env.OPENCODE_VERSION?.trim();return t||Mn()}function bt(t={}){Et();let e=Me(t.token,process.env.PINTA_OPENCODE_TOKEN),n=(0,St.parseHeadersEnv)(t.headers??process.env.PINTA_OPENCODE_HEADERS??process.env.OTEL_EXPORTER_OTLP_HEADERS);e&&!Object.keys(n).some(s=>s.toLowerCase()==="x-pinta-relay-token")&&(n["x-pinta-relay-token"]=e);let r=t.guardTimeoutMs??(Number(process.env.PINTA_OPENCODE_GUARD_TIMEOUT_MS)||100);return{endpoint:Dn(t),headers:n,guardEndpoint:Me(t.guard,process.env.PINTA_OPENCODE_GUARD),relayToken:e,guardTimeoutMs:r,guardDisabled:process.env.PINTA_OPENCODE_GUARD_DISABLED==="1",serviceVersion:An()}}var q=I(P(),1),Q=class extends q.MemoryTransport{constructor(n){super({logPrefix:"pinta-opencode",resolveOptions:()=>n.endpoint?{endpoint:n.endpoint,headers:n.headers}:null});this.config=n}deferred=new q.MemoryRetryQueue;defer(n){if(!this.config.endpoint)return;let r=Buffer.byteLength(JSON.stringify(n),"utf8");if(r>q.MAX_POST_BYTES){process.stderr.write(`[pinta-opencode] deferred payload exceeds POST budget (${r} bytes); dropped
25
+ `);return}this.deferred.enqueue(n)}async flush(){await super.flush();for(let n of this.deferred.drain())await super.send(n)}};var Ae=I(P(),1);var wt=I(P(),1);var Pt=I(P(),1);var ee="0.11.3-skax.0";var kn=100,wn=`pinta-opencode/${ee}`;function Dt(t,e,n={}){return(0,Pt.evaluateGuard)(t,e,{timeoutMs:n.timeoutMs??kn,token:n.token,disabled:n.disabled,userAgent:wn})}var kt=I(P(),1);import ke from"os";var B=I(P(),1);var te;function Rn(){if(te===void 0)try{te=ke.userInfo().username}catch{te=process.env.USER??process.env.LOGNAME??(typeof process.getuid=="function"?String(process.getuid()):"unknown")}return te}var It=ee,xn=new Set(["opencode.hook","opencode.event_type","opencode.tool_name","opencode.session_id","opencode.sessionID","opencode.tool_use_id","opencode.cwd","opencode.agent","opencode.model","opencode.exit","opencode.truncated","opencode.title"]),Nn=new Set(["opencode.tool_input","opencode.tool_response"]),jn={skipRedactKeys:xn,bashContextKeys:Nn,outputForKey:(t,e)=>{if(t==="opencode.error"||t==="opencode.error_message")return e;if(["opencode.tool_response","opencode.tool_result","opencode.output"].includes(t))return e&&typeof e=="object"&&"output"in e&&e.output!==void 0?e.output:e}};function Cn(t){let e=[{key:"ingest.type",value:{stringValue:"opencode"}}];return e.push(...(0,B.attrsFromRecord)(t,"opencode",jn)),e}function qn(t){return[{key:"service.name",value:{stringValue:"opencode"}},...t?[{key:"service.version",value:{stringValue:t}}]:[],{key:"telemetry.sdk.name",value:{stringValue:"pinta-opencode"}},{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:Rn()}},{key:"host.name",value:{stringValue:ke.hostname()}},{key:"host.arch",value:{stringValue:ke.arch()}}]}function Mt(t){return(0,B.buildPayload)({traceId:t.traceId,spanName:t.name,attributes:Cn(t.fields),resource:qn(t.serviceVersion),scope:{name:"pinta-opencode",version:It},now:t.now})}var $={messages:1024,requests:512,calls:2048,endedSessions:128,ttlMs:9e5},Bn=new Set(["unknown","undefined","null","n/a","none","-","auto","default"]);function m(t){if(typeof t!="string")return;let e=t.trim();return e&&e.length<=1024?e:void 0}function R(t){let e=m(t);if(!(!e||e.startsWith("{")||e.startsWith("[")||Bn.has(e.toLowerCase())))return e}function D(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function E(t,e,n){let r=D(t),s=r?R(r.modelID)??R(r.id):R(t);if(s)return{model:s,source:r?`${e}.${R(r.modelID)?"modelID":"id"}`:e,provider:R(r?.providerID??n)}}function S(...t){return JSON.stringify(t)}function V(...t){let e=t.map(m).filter(n=>n!==void 0);return e.every(n=>n===e[0])?e[0]:void 0}function we(t,e){let n=D(e.info),r=D(e.part);return typeof t=="string"&&t.startsWith("session.")?V(e.sessionID,n?.id):V(e.sessionID,n?.sessionID,r?.sessionID)}var W=class{constructor(e,n){this.limit=e;this.now=n}entries=new Map;get(e){let n=this.entries.get(e);if(n&&n.expires>this.now())return n.value;this.entries.delete(e)}set(e,n){this.entries.delete(e),this.entries.set(e,{value:n,expires:this.now()+$.ttlMs}),this.entries.size>this.limit&&this.entries.delete(this.entries.keys().next().value)}removeWhere(e){for(let[n,r]of this.entries)e(r.value)&&this.entries.delete(n)}clearSession(e){this.removeWhere(n=>n.sessionID===e)}},ne=class{constructor(e=Date.now){this.now=e;this.messages=new W($.messages,e),this.requests=new W($.requests,e),this.calls=new W($.calls,e)}messages;requests;calls;ended=new Map;chatMessage(e,n){let r=V(e.sessionID,n?.message?.sessionID);if(!r)return;this.ended.delete(r);let s=V(e.messageID,n?.message?.id);if(!s)return;let a=m(n?.message?.agent??e.agent),o=n?.message?.model!==void 0;this.requests.set(S(r,s,a??""),{sessionID:r,messageID:s,evidence:E(o?n.message?.model:e.model,o?"requested:chat.message.message.model":"requested:chat.message.model")})}chatParams(e){let n=V(e.sessionID,e.message?.sessionID),r=m(e.message?.id),s=m(e.agent);!n||!r||!s||this.ended.has(n)||this.requests.set(S(n,r,s),{sessionID:n,messageID:r,evidence:E(e.model,"requested:chat.params.model")})}fresh(e){return e===void 0||typeof e=="number"&&Number.isFinite(e)&&e>=this.now()-$.ttlMs}clearSession(e){this.messages.clearSession(e),this.requests.clearSession(e),this.calls.clearSession(e)}event(e,n){let r=we(e,n),s=D(n.info),a=D(n.part),o=["session.idle","session.deleted","session.error"].includes(e??"")||e==="session.status"&&D(n.status)?.type==="idle";if(r&&o?(this.clearSession(r),this.ended.delete(r),this.ended.set(r,!0),this.ended.size>$.endedSessions&&this.ended.delete(this.ended.keys().next().value)):r&&e==="session.created"&&(this.clearSession(r),this.ended.delete(r)),e==="message.updated"&&s){if(!V(n.sessionID,s.sessionID)&&(n.sessionID||s.sessionID))return;let i=m(s.id),u=m(s.agent),l=s.role,f=l==="assistant"?E(R(s.modelID),"reported:message.updated.info.modelID",s.providerID)??E(s.model,"reported:message.updated.info.model"):l==="user"?E(s.model,"requested:message.updated.info.model"):void 0;if(!f&&l==="user"&&!("model"in s)&&r&&i&&(f=this.requests.get(S(r,i,u??""))?.evidence),l==="user"&&"model"in s&&!f&&r&&i&&this.requests.set(S(r,i,u??""),{sessionID:r,messageID:i}),f&&(f={...f,agent:u,messageID:i}),r&&i&&!this.ended.has(r)&&this.fresh(D(s.time)?.created)){let d=this.messages.get(S(r,i)),p=d?.ambiguous||!!(l==="assistant"&&d?.evidence&&f&&(d.evidence.model!==f.model||d.evidence.provider!==f.provider||d.evidence.agent!==f.agent));this.messages.set(S(r,i),{sessionID:r,messageID:i,evidence:p?void 0:f,ambiguous:p})}return f}if(r&&e==="message.removed"){let i=m(n.messageID);this.messages.removeWhere(u=>u.sessionID===r&&u.messageID===i),this.requests.removeWhere(u=>u.sessionID===r&&u.messageID===i),this.calls.removeWhere(u=>u.sessionID===r&&u.messageID===i)}if(r&&e==="message.part.removed"){let i=m(n.partID);i&&this.calls.removeWhere(u=>u.sessionID===r&&u.partID===i)}if(e==="message.part.delta"){let i=m(n.messageID);return r&&i&&!this.ended.has(r)?this.messages.get(S(r,i))?.evidence:void 0}if(e==="message.part.updated"&&a){if(!r||this.ended.has(r)||!this.fresh(n.time))return;let i=m(a.messageID);if(!i)return;let u=m(a.callID);if(a.type==="tool"&&u){let l=S(r,u),f=this.calls.get(l);if(!f?.closed){let d=m(a.tool);this.calls.set(l,{sessionID:r,messageID:i,partID:m(a.id),tool:d,pinned:f?.pinned,ambiguous:f?.ambiguous||!!(f&&(f.messageID!==i||f.tool!==d))})}}return this.messages.get(S(r,i))?.evidence}return typeof e=="string"&&e.startsWith("session.")?E(s?.model,`selected:${e}.info.model`)??E(n.model,`selected:${e}.model`):E(n.model,"reported:event.model")??E(R(n.modelID),"reported:event.modelID",n.providerID)}tool(e,n){let r=E(R(e.modelID),"reported:tool.modelID",e.providerID)??E(e.model,"reported:tool.model",e.providerID),s=m(e.sessionID),a=m(e.callID);if(!s||!a)return r;let o=S(s,a),i=this.calls.get(o),u=r;if(!("model"in e)&&!("modelID"in e)&&i&&!i.closed&&!i.ambiguous&&!this.ended.has(s)&&(!i.tool||i.tool===e.tool)){let l=this.messages.get(S(s,i.messageID));l?.ambiguous||(u=i.pinned??l?.evidence),(e.agent&&u?.agent&&e.agent!==u.agent||e.messageID&&e.messageID!==i.messageID)&&(u=void 0)}return i&&!i.closed&&this.calls.set(o,{...i,pinned:n?void 0:u,closed:n}),u}beforeTool(e){return this.tool(e,!1)}afterTool(e){return this.tool(e,!0)}};function re(t,e){let{model:n,model_source:r,...s}=t;return"model"in t&&n!==e?.model&&(s.model_raw=n),"model_source"in t&&(s.model_source_raw=r),e&&(s.model=e.model,s.model_source=e.source,e.provider&&("provider"in s&&s.provider!==e.provider&&(s.provider_raw=s.provider),s.provider=e.provider),s.agent===void 0&&(s.agent=e.agent),s.message_id===void 0&&(s.message_id=e.messageID)),s}var se=class{constructor(e,n,r){this.transport=e;this.trace=n;this.config=r}models=new ne;build(e,n,r){let s=this.trace.currentTrace(n);return Mt({name:e,traceId:s,fields:r,serviceVersion:this.config.serviceVersion})}async send(e){await this.transport.send(e)}async emit(e,n,r){await this.send(this.build(e,n,r))}chatMessage(e,n){this.models.chatMessage(e,n)}chatParams(e){this.models.chatParams(e)}async lifecycle(e){let n=D(e.properties)??{},r=we(e.type,n),s=this.models.event(e.type,n);e.type==="session.idle"&&await this.transport.flush(),await this.emit(`opencode.event.${e.type??"unknown"}`,r,re({hook:"event",event_type:e.type,session_id:r,cwd:process.cwd(),...n},s))}toolBeforePayload(e,n){return this.build("opencode.tool.before",e.sessionID,re({...At("tool.execute.before",e),tool_input:n},this.models.beforeTool(e)))}async toolBefore(e,n,r){await this.send((0,kt.attachGuard)(this.toolBeforePayload(e,n),r))}toolAfterPayload(e,n){let r=n.metadata??{};return this.build("opencode.tool.after",e.sessionID,re({...At("tool.execute.after",e),tool_input:e.args,title:n.title,tool_response:n.content!==void 0?n:n.output,attachments:n.attachments,exit:r.exit,truncated:r.truncated},this.models.afterTool(e)))}async toolAfter(e,n){await this.send(this.toolAfterPayload(e,n))}};function At(t,e){return{hook:t,tool_name:e.tool,session_id:e.sessionID,tool_use_id:e.callID,cwd:process.cwd(),...e.model!==void 0?{model:e.model}:{},...e.modelID!==void 0?{modelID:e.modelID}:{},...e.providerID!==void 0?{providerID:e.providerID}:{},...e.agent!==void 0?{agent:e.agent}:{},...e.messageID!==void 0?{message_id:e.messageID}:{}}}function Rt(t,e){process.stderr.write(`[pinta-opencode] ${t}: ${e?.message??String(e)}
26
+ `)}var $n="Pinta withheld this tool output because it violated an active policy.";function Re(t,e){return async(...n)=>{try{await e(...n)}catch(r){Rt(t,r)}}}var Vn=async(t,e)=>{let n=bt(e??{}),r=new Q({endpoint:n.endpoint,headers:n.headers}),s=new Ae.MemorySessionTraceManager,a=new se(r,s,n);async function o(i,u){let l=null;try{let f=u();l=await Dt(f,n.guardEndpoint,{timeoutMs:n.guardTimeoutMs,token:n.relayToken,disabled:n.guardDisabled}),(0,wt.attachGuard)(f,l),i==="tool.execute.after"&&l&&f.resourceSpans[0].scopeSpans[0].spans[0].attributes.push({key:"pinta.guard.target",value:{stringValue:"tool_output"}}),l?.decision==="DENY"?r.defer(f):await a.send(f)}catch(f){Rt(i,f)}return l}return{"chat.message":Re("chat.message",async(i,u)=>{s.newTrace(i?.sessionID),a.chatMessage(i,u)}),"chat.params":Re("chat.params",async(i,u)=>{a.chatParams(i)}),event:Re("event",async i=>{i?.event&&await a.lifecycle(i.event)}),"tool.execute.before":async(i,u)=>{let l=await o("tool.execute.before",()=>a.toolBeforePayload(i,u?.args));if(l?.decision==="DENY")throw new Error(l.userMessage??l.reason??"guard_deny")},"tool.execute.after":async(i,u)=>{if((await o("tool.execute.after",()=>a.toolAfterPayload(i,u)))?.decision==="DENY")throw new Error($n)}}},Or=Vn;export{Vn as PintaOpencode,Or as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pinta-ai/pinta-opencode",
3
- "version": "0.11.1",
3
+ "version": "0.11.3-skax.0",
4
4
  "description": "OTLP forwarder + guard for opencode (in-process plugin)",
5
5
  "type": "module",
6
6
  "main": "dist/plugin.js",
@@ -36,7 +36,7 @@
36
36
  "prepublishOnly": "npm run build"
37
37
  },
38
38
  "devDependencies": {
39
- "@pinta-ai/core": "^0.9.1",
39
+ "@pinta-ai/core": "0.9.3-skax.0",
40
40
  "@types/node": "^22.0.0",
41
41
  "esbuild": "0.24.2",
42
42
  "typescript": "^5.7.0",