@pinta-ai/pinta-opencode 0.7.0 → 0.8.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/dist/index.mjs +39 -13
- package/dist/plugin.js +13 -13
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1128,6 +1128,8 @@ var require_dist = __commonJS({
|
|
|
1128
1128
|
|
|
1129
1129
|
// src/config.ts
|
|
1130
1130
|
var import_core2 = __toESM(require_dist(), 1);
|
|
1131
|
+
import fs from "node:fs";
|
|
1132
|
+
import path from "node:path";
|
|
1131
1133
|
|
|
1132
1134
|
// src/env-file.ts
|
|
1133
1135
|
var import_core = __toESM(require_dist(), 1);
|
|
@@ -1153,6 +1155,28 @@ function resolveEndpoint(options) {
|
|
|
1153
1155
|
if (base) return base.replace(/\/+$/, "") + "/v1/traces";
|
|
1154
1156
|
return void 0;
|
|
1155
1157
|
}
|
|
1158
|
+
var OPENCODE_PACKAGE_NAME = "opencode-ai";
|
|
1159
|
+
function versionFromExecPath() {
|
|
1160
|
+
let dir = path.dirname(process.execPath);
|
|
1161
|
+
for (let i = 0; i < 5; i++) {
|
|
1162
|
+
try {
|
|
1163
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(dir, "package.json"), "utf8"));
|
|
1164
|
+
if (pkg.name === OPENCODE_PACKAGE_NAME && typeof pkg.version === "string" && pkg.version) {
|
|
1165
|
+
return pkg.version;
|
|
1166
|
+
}
|
|
1167
|
+
} catch {
|
|
1168
|
+
}
|
|
1169
|
+
const parent = path.dirname(dir);
|
|
1170
|
+
if (parent === dir) break;
|
|
1171
|
+
dir = parent;
|
|
1172
|
+
}
|
|
1173
|
+
return void 0;
|
|
1174
|
+
}
|
|
1175
|
+
function resolveServiceVersion() {
|
|
1176
|
+
const explicit = process.env.OPENCODE_VERSION?.trim();
|
|
1177
|
+
if (explicit) return explicit;
|
|
1178
|
+
return versionFromExecPath();
|
|
1179
|
+
}
|
|
1156
1180
|
function resolveConfig(options = {}) {
|
|
1157
1181
|
loadEnvFile();
|
|
1158
1182
|
const relayToken = firstSet(options.token, process.env.PINTA_OPENCODE_TOKEN);
|
|
@@ -1170,7 +1194,7 @@ function resolveConfig(options = {}) {
|
|
|
1170
1194
|
relayToken,
|
|
1171
1195
|
guardTimeoutMs,
|
|
1172
1196
|
guardDisabled: process.env.PINTA_OPENCODE_GUARD_DISABLED === "1",
|
|
1173
|
-
serviceVersion:
|
|
1197
|
+
serviceVersion: resolveServiceVersion()
|
|
1174
1198
|
};
|
|
1175
1199
|
}
|
|
1176
1200
|
|
|
@@ -1246,7 +1270,9 @@ function flattenFields(fields) {
|
|
|
1246
1270
|
function resourceAttrs(serviceVersion) {
|
|
1247
1271
|
return [
|
|
1248
1272
|
{ key: "service.name", value: { stringValue: "opencode" } },
|
|
1249
|
-
|
|
1273
|
+
// Omitted when unresolved — the absence is the honest signal, not "unknown".
|
|
1274
|
+
// A placeholder is indistinguishable from a real value downstream (PTA-347).
|
|
1275
|
+
...serviceVersion ? [{ key: "service.version", value: { stringValue: serviceVersion } }] : [],
|
|
1250
1276
|
{ key: "telemetry.sdk.name", value: { stringValue: "pinta-opencode" } },
|
|
1251
1277
|
{ key: "telemetry.sdk.language", value: { stringValue: "nodejs" } },
|
|
1252
1278
|
{ key: "telemetry.sdk.version", value: { stringValue: SDK_VERSION } },
|
|
@@ -1400,13 +1426,13 @@ var plugin_default = PintaOpencode;
|
|
|
1400
1426
|
// src/lifecycle/scanner.ts
|
|
1401
1427
|
import { opendir, stat as stat2 } from "node:fs/promises";
|
|
1402
1428
|
import { homedir } from "node:os";
|
|
1403
|
-
import
|
|
1429
|
+
import path3 from "node:path";
|
|
1404
1430
|
|
|
1405
1431
|
// src/lifecycle/snapshot.ts
|
|
1406
1432
|
import { execFile } from "node:child_process";
|
|
1407
1433
|
import { copyFile, mkdtemp, rm, stat } from "node:fs/promises";
|
|
1408
1434
|
import { tmpdir } from "node:os";
|
|
1409
|
-
import
|
|
1435
|
+
import path2 from "node:path";
|
|
1410
1436
|
import { promisify } from "node:util";
|
|
1411
1437
|
var execFileAsync = promisify(execFile);
|
|
1412
1438
|
var DEFAULT_STABLE_MS = 2e3;
|
|
@@ -1425,7 +1451,7 @@ async function sleep(ms) {
|
|
|
1425
1451
|
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
1426
1452
|
}
|
|
1427
1453
|
async function makeSnapshotDir(base) {
|
|
1428
|
-
return mkdtemp(
|
|
1454
|
+
return mkdtemp(path2.join(base, "pinta-opencode-snap-"));
|
|
1429
1455
|
}
|
|
1430
1456
|
async function backupViaCli(sqlite3Path, dbPath, outPath) {
|
|
1431
1457
|
const backupCmd = `.backup '${outPath.replace(/'/g, "''")}'`;
|
|
@@ -1433,7 +1459,7 @@ async function backupViaCli(sqlite3Path, dbPath, outPath) {
|
|
|
1433
1459
|
}
|
|
1434
1460
|
async function quiesceCopy(file, outDir, stableMs, maxRetries, deadlineMs) {
|
|
1435
1461
|
const dbPath = file.absPath;
|
|
1436
|
-
const outDbPath =
|
|
1462
|
+
const outDbPath = path2.join(outDir, path2.basename(dbPath));
|
|
1437
1463
|
const deadline = Date.now() + deadlineMs;
|
|
1438
1464
|
let lastErr;
|
|
1439
1465
|
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
@@ -1484,7 +1510,7 @@ async function snapshot(file, opts = {}) {
|
|
|
1484
1510
|
const outDir = await makeSnapshotDir(base);
|
|
1485
1511
|
try {
|
|
1486
1512
|
if (sqlite3Path) {
|
|
1487
|
-
const outPath =
|
|
1513
|
+
const outPath = path2.join(outDir, `${path2.basename(file.absPath)}.snapshot`);
|
|
1488
1514
|
try {
|
|
1489
1515
|
await backupViaCli(sqlite3Path, file.absPath, outPath);
|
|
1490
1516
|
return outPath;
|
|
@@ -1508,12 +1534,12 @@ function dataRoot() {
|
|
|
1508
1534
|
}
|
|
1509
1535
|
const xdg = process.env.XDG_DATA_HOME;
|
|
1510
1536
|
if (xdg && xdg.length > 0) {
|
|
1511
|
-
return
|
|
1537
|
+
return path3.join(xdg, "opencode");
|
|
1512
1538
|
}
|
|
1513
|
-
return
|
|
1539
|
+
return path3.join(homedir(), ".local", "share", "opencode");
|
|
1514
1540
|
}
|
|
1515
1541
|
function toPosixRelPath(root, absPath) {
|
|
1516
|
-
return
|
|
1542
|
+
return path3.relative(root, absPath).split(path3.sep).join("/");
|
|
1517
1543
|
}
|
|
1518
1544
|
function isExcluded(relPath) {
|
|
1519
1545
|
if (relPath === "auth.json") return true;
|
|
@@ -1529,9 +1555,9 @@ function semanticsFor(relPath) {
|
|
|
1529
1555
|
return relPath.endsWith(".db") ? "database" : "rewritten-doc";
|
|
1530
1556
|
}
|
|
1531
1557
|
function sessionIdFor(relPath) {
|
|
1532
|
-
const base =
|
|
1558
|
+
const base = path3.posix.basename(relPath);
|
|
1533
1559
|
if (!base.startsWith("ses_")) return void 0;
|
|
1534
|
-
const ext =
|
|
1560
|
+
const ext = path3.posix.extname(base);
|
|
1535
1561
|
return ext ? base.slice(0, -ext.length) : base;
|
|
1536
1562
|
}
|
|
1537
1563
|
function classify(relPath) {
|
|
@@ -1555,7 +1581,7 @@ async function* walkFiles(root, dir) {
|
|
|
1555
1581
|
}
|
|
1556
1582
|
try {
|
|
1557
1583
|
for await (const entry of entries) {
|
|
1558
|
-
const absPath =
|
|
1584
|
+
const absPath = path3.join(dir, entry.name);
|
|
1559
1585
|
const relPath = toPosixRelPath(root, absPath);
|
|
1560
1586
|
if (entry.isDirectory()) {
|
|
1561
1587
|
if (isExcludedDir(relPath)) continue;
|
package/dist/plugin.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { createRequire as __pintaCreateRequire } from 'module'; const require = __pintaCreateRequire(import.meta.url);
|
|
2
|
-
var
|
|
2
|
+
var tt=Object.create;var ue=Object.defineProperty;var rt=Object.getOwnPropertyDescriptor;var nt=Object.getOwnPropertyNames;var ot=Object.getPrototypeOf,st=Object.prototype.hasOwnProperty;var h=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var _=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var it=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of nt(e))!st.call(t,o)&&o!==r&&ue(t,o,{get:()=>e[o],enumerable:!(n=rt(e,o))||n.enumerable});return t};var E=(t,e,r)=>(r=t!=null?tt(ot(t)):{},it(e||!t||!t.__esModule?ue(r,"default",{value:t,enumerable:!0}):r,t));var F=_(p=>{"use strict";Object.defineProperty(p,"__esModule",{value:!0});p.PATTERNS=p.MAX_BYTES=void 0;p.truncateTo=ce;p.truncate=at;p.collectMatches=le;p.resolveOverlaps=de;p.applyMatches=fe;p.redact=ut;p.MAX_BYTES=102400;function ce(t,e){let r=Buffer.from(t,"utf-8");return r.length<=e?t:`${r.subarray(0,Math.max(0,e)).toString("utf-8")}\u2026[TRUNCATED:${r.length}]`}function at(t){return ce(t,p.MAX_BYTES)}p.PATTERNS=[{type:"aws_access_key",regex:/AKIA[0-9A-Z]{16}/g},{type:"aws_secret_key",regex:/(?:aws[_-]?secret(?:[_-]?(?:access)?[_-]?key)?)\s*[:=]\s*["']?([A-Za-z0-9/+=]{40})(?![A-Za-z0-9/+=])/gi,captureGroup:1},{type:"gcp_service_account",regex:/\{[\s\S]{0,200}?"type"\s*:\s*"service_account"[\s\S]*?\}/g},{type:"github_token",regex:/gh[pousr]_[A-Za-z0-9]{36,}/g},{type:"gitlab_token",regex:/glpat-[A-Za-z0-9_-]{20}/g},{type:"slack_token",regex:/xox[abrsp]-[0-9A-Za-z-]{10,}/g},{type:"openai_key",regex:/sk-(?:proj-)?[A-Za-z0-9_-]{40,}/g},{type:"anthropic_key",regex:/sk-ant-[A-Za-z0-9_-]{50,}/g},{type:"stripe_key",regex:/(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g},{type:"jwt",regex:/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g},{type:"private_key_block",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g},{type:"bearer_token",regex:/bearer\s+([A-Za-z0-9._~+/=-]{12,})/gi,captureGroup:1},{type:"basic_auth",regex:/basic\s+([A-Za-z0-9+/=]{12,})/gi,captureGroup:1},{type:"db_url_password",regex:/\b(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|redis):\/\/[^:\s/]+:([^@\s]+)@/gi,captureGroup:1},{type:"cli_password_flag",regex:/(?:--password|--pass|--pwd)[=\s]([^\s'"]+)/g,captureGroup:1},{type:"cli_password_short",regex:/\s-p([^\s'"]+)/g,captureGroup:1,requireContext:"bash"},{type:"env_var_secret",regex:/^(?:export\s+)?([A-Z][A-Z0-9_]*(?:KEY|SECRET|TOKEN|PASSWORD|PASSWD|PWD|API_KEY)[A-Z0-9_]*)\s*=\s*["']?([^\s"'\n]+)/gm,captureGroup:2}];function le(t,e){let r=[];for(let n of p.PATTERNS){if(n.requireContext&&n.requireContext!==e.context)continue;let o=new RegExp(n.regex.source,n.regex.flags),i;for(;(i=o.exec(t))!==null;){let u=n.captureGroup??0,a=i[u];if(a===void 0){i.index===o.lastIndex&&o.lastIndex++;continue}let c=i.index,d=i.index+i[0].length,P=c+i[0].indexOf(a),et=P+a.length;r.push({start:c,end:d,replaceStart:P,replaceEnd:et,type:n.type}),i.index===o.lastIndex&&o.lastIndex++}}return r}function de(t){let e=[...t].sort((o,i)=>o.start!==i.start?o.start-i.start:i.end-i.start-(o.end-o.start)),r=[],n=-1;for(let o of e)o.start<n||(r.push(o),n=o.end);return r}function fe(t,e){let r=[...e].sort((o,i)=>i.replaceStart-o.replaceStart),n=t;for(let o of r)n=n.slice(0,o.replaceStart)+`[REDACTED:${o.type}]`+n.slice(o.replaceEnd);return n}function ut(t,e={}){if(t.length===0)return t;let r=le(t,e);if(r.length===0)return t;let n=de(r);return fe(t,n)}});var V=_(f=>{"use strict";var ct=f&&f.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(f,"__esModule",{value:!0});f.MAX_SPAN_BYTES=void 0;f.ulidToTraceId=ye;f.newSpanId=_e;f.snakeCase=ft;f.toOtlpValue=me;f.attrsFromRecord=pt;f.guardAttrs=Oe;f.clientAttrs=Te;f.enforceSpanBudget=Pe;f.buildPayload=gt;f.mergeBatch=ht;var lt=ct(h("crypto")),$=F(),dt="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function ye(t){if(t.length!==26)throw new Error(`ulidToTraceId: expected 26 chars, got ${t.length}`);let e=0n;for(let n of t){let o=dt.indexOf(n);if(o<0)throw new Error(`ulidToTraceId: invalid Crockford char "${n}"`);e=e<<5n|BigInt(o)}let r=(1n<<128n)-1n;return e&=r,e.toString(16).padStart(32,"0")}function _e(){return lt.default.randomBytes(8).toString("hex")}function ft(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var pe=new Set;function R(t,e,r){let n=(0,$.truncate)(e);if((r.skipRedactKeys??pe).has(t))return n;let o=(r.bashContextKeys??pe).has(t)?"bash":void 0;return(0,$.redact)(n,{context:o})}function me(t,e,r={}){if(e==null)return null;switch(typeof e){case"string":return{stringValue:R(t,e,r)};case"boolean":return{boolValue:e};case"number":return Number.isInteger(e)?{intValue:e}:{doubleValue:e};case"object":try{return{stringValue:R(t,JSON.stringify(e),r)}}catch{return{stringValue:R(t,String(e),r)}}default:return{stringValue:R(t,String(e),r)}}}function pt(t,e,r={}){let n=[];for(let[o,i]of Object.entries(t)){let u=`${e}.${o}`,a=me(u,i,r);a!==null&&n.push({key:u,value:a})}return n}function Oe(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 Te(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}}]}f.MAX_SPAN_BYTES=800*1024;function ge(t){let e=JSON.stringify(t);return e===void 0?0:Buffer.byteLength(e,"utf-8")}var he=1024;function Pe(t,e=f.MAX_SPAN_BYTES){let r=ge(t);for(let n=0;n<100&&r>e;n++){let o=null,i=0;for(let c of t.attributes){if(!("stringValue"in c.value))continue;let d=Buffer.byteLength(c.value.stringValue,"utf-8");d>i&&(i=d,o=c.value)}if(o===null||i<=he)break;let u=r-e,a=Math.max(he,i-u-64);o.stringValue=(0,$.truncateTo)(o.stringValue,a),r=ge(t)}return t}function gt(t){let e=t.now??Date.now(),r=(BigInt(e)*1000000n).toString(),n=[...t.attributes];t.guard&&n.push(...Oe(t.guard));let o=t.clientTiming??(t.guard?.clientRttMs!==void 0?{op:"guard",rttMs:t.guard.clientRttMs}:null);o&&n.push(...Te(o));let i={traceId:ye(t.traceId),spanId:_e(),name:t.spanName,kind:t.spanKind??1,startTimeUnixNano:r,endTimeUnixNano:r,attributes:n};return Pe(i),{resourceSpans:[{resource:{attributes:t.resource},scopeSpans:[{scope:t.scope,spans:[i]}]}]}}function ht(t){let e=[];for(let r of t)e.push(...r.resourceSpans);return{resourceSpans:e}}});var ve=_(G=>{"use strict";Object.defineProperty(G,"__esModule",{value:!0});G.evaluateGuard=Ot;var yt=1e4,_t="pinta-core";function L(t,e){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:t,clientRttMs:t,failOpenReason:e}}var mt=new Set(["ALLOW","DENY","REVIEW"]);async function Ot(t,e,r={}){if(!e||r.disabled)return null;let n=r.timeoutMs??yt,o=Date.now(),i=new AbortController,u=setTimeout(()=>i.abort(),n);try{let a=await fetch(e,{method:"POST",headers:{"content-type":"application/json","user-agent":r.userAgent??_t,"x-pinta-relay-token":r.token??""},body:JSON.stringify({input:t}),signal:i.signal});if(a.status!==200)return L(Date.now()-o,"error");let c=await a.json(),d=c?.durationMs===void 0||typeof c.durationMs=="number"&&Number.isFinite(c.durationMs);if(!c||!mt.has(c.decision)||!d)return L(Date.now()-o,"error");let P=Date.now()-o;return{decision:c.decision,reason:c.reason??null,userMessage:c.userMessage??null,durationMs:c.durationMs??P,clientRttMs:P}}catch(a){let c=a.name,d=c==="AbortError"||c==="TimeoutError"?"timeout":"error";return L(Date.now()-o,d)}finally{clearTimeout(u)}}});var I=_(w=>{"use strict";var Tt=w&&w.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(w,"__esModule",{value:!0});w.atomicWriteFileSync=Pt;var Se=Tt(h("fs"));function Pt(t,e){let r=`${t}.${process.pid}.tmp`;Se.default.writeFileSync(r,e),Se.default.renameSync(r,t)}});var z=_(m=>{"use strict";var be=m&&m.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(m,"__esModule",{value:!0});m.MemoryRetryQueue=m.DiskRetryQueue=void 0;var g=be(h("fs")),D=be(h("path")),vt=I(),j=1e3,St=50,bt=5,X=class{filePath;lockPath;logPrefix;constructor(e,r){this.filePath=D.default.join(e,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=r}enqueue(e){try{g.default.mkdirSync(D.default.dirname(this.filePath),{recursive:!0});let r=JSON.stringify({savedAt:new Date().toISOString(),payload:e})+`
|
|
3
3
|
`;g.default.appendFileSync(this.filePath,r),this.trim()}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue enqueue failed: ${r}
|
|
4
4
|
`)}}readAll(){try{let e=g.default.readFileSync(this.filePath,"utf-8"),r=[];for(let n of e.split(`
|
|
5
|
-
`))if(n.trim())try{let o=JSON.parse(n);Array.isArray(o?.payload?.resourceSpans)&&r.push(o)}catch{}return r}catch{return[]}}rewrite(e){try{if(e.length===0){g.default.existsSync(this.filePath)&&g.default.unlinkSync(this.filePath);return}g.default.mkdirSync(D.default.dirname(this.filePath),{recursive:!0}),(0,
|
|
5
|
+
`))if(n.trim())try{let o=JSON.parse(n);Array.isArray(o?.payload?.resourceSpans)&&r.push(o)}catch{}return r}catch{return[]}}rewrite(e){try{if(e.length===0){g.default.existsSync(this.filePath)&&g.default.unlinkSync(this.filePath);return}g.default.mkdirSync(D.default.dirname(this.filePath),{recursive:!0}),(0,vt.atomicWriteFileSync)(this.filePath,e.map(r=>JSON.stringify(r)).join(`
|
|
6
6
|
`)+`
|
|
7
7
|
`)}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue rewrite failed: ${r}
|
|
8
8
|
`)}}tryAcquireLock(){let e=Date.now();try{g.default.mkdirSync(D.default.dirname(this.lockPath),{recursive:!0})}catch(r){return process.stderr.write(`[${this.logPrefix}] retry-queue lock mkdir failed: ${r}
|
|
9
|
-
`),!1}for(;Date.now()-e<
|
|
10
|
-
`),!1;try{let i=g.default.statSync(this.lockPath);if(Date.now()-i.mtimeMs>3e4){g.default.unlinkSync(this.lockPath);continue}}catch{}let n=
|
|
11
|
-
`),this.rewrite(e.slice(r))}};m.DiskRetryQueue=X;var Y=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}};m.MemoryRetryQueue=Y});var
|
|
9
|
+
`),!1}for(;Date.now()-e<St;)try{let r=g.default.openSync(this.lockPath,"wx");return g.default.writeSync(r,String(process.pid)),g.default.closeSync(r),!0}catch(r){if(r?.code!=="EEXIST")return process.stderr.write(`[${this.logPrefix}] retry-queue lock open failed: ${r}
|
|
10
|
+
`),!1;try{let i=g.default.statSync(this.lockPath);if(Date.now()-i.mtimeMs>3e4){g.default.unlinkSync(this.lockPath);continue}}catch{}let n=bt,o=Date.now()+n;for(;Date.now()<o;);}return!1}release(){try{g.default.unlinkSync(this.lockPath)}catch{}}trim(){let e=this.readAll();if(e.length<=j)return;let r=e.length-j;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${r} oldest entries
|
|
11
|
+
`),this.rewrite(e.slice(r))}};m.DiskRetryQueue=X;var Y=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}};m.MemoryRetryQueue=Y});var xe=_(l=>{"use strict";Object.defineProperty(l,"__esModule",{value:!0});l.MemoryTransport=l.DiskTransport=l.MAX_POST_BYTES=void 0;l.parseHeadersEnv=we;l.envOptionsResolver=Me;l.postOtlp=M;var Ee=z(),Ae=V(),Et=5e3;l.MAX_POST_BYTES=900*1024;function N(t){let e=JSON.stringify(t);return e===void 0?0:Buffer.byteLength(e,"utf-8")}function ke(t,e,r){let n=[],o=[],i=[],u=0;for(let a of t){let c=e(a);if(c>r){o.push(a);continue}i.length>0&&u+c>r&&(n.push(i),i=[],u=0),i.push(a),u+=c}return i.length>0&&n.push(i),{chunks:n,oversize:o}}function we(t){if(!t)return{};if(typeof t=="object")return{...t};let e={};for(let r of t.split(",")){let[n,...o]=r.split("=");n&&o.length>0&&(e[n.trim()]=o.join("=").trim())}return e}function Me(){let t=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,e=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,r;return t?r=t.replace(/\/+$/,""):e&&(r=e.replace(/\/+$/,"")+"/v1/traces"),r?{endpoint:r,headers:we(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function M(t,e,r){let n=new AbortController,o=setTimeout(()=>n.abort(),Et);try{let i=await fetch(e.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...e.headers},body:JSON.stringify(t),signal:n.signal});if(!i.ok){let u="";try{u=(await i.text()).slice(0,200)}catch{}let a=i.status===401||i.status===403?" \u2014 check OTEL_EXPORTER_OTLP_HEADERS (relay token)":i.status===404?" \u2014 check OTEL_EXPORTER_OTLP_TRACES_ENDPOINT path":i.status>=500?" \u2014 collector may be down":"";return process.stderr.write(`[${r}] OTLP POST ${i.status} ${e.endpoint}${a}${u?` body=${u}`:""}
|
|
12
12
|
`),!1}return!0}catch(i){return process.stderr.write(`[${r}] OTLP POST failed: ${i.message??String(i)}
|
|
13
|
-
`),!1}finally{clearTimeout(o)}}var U=class{queue;logPrefix;resolveOptions;constructor(e){this.queue=new
|
|
14
|
-
`);let i=[].concat(...n),u=0;for(let a of n){if(!await M((0,
|
|
13
|
+
`),!1}finally{clearTimeout(o)}}var U=class{queue;logPrefix;resolveOptions;constructor(e){this.queue=new Ee.DiskRetryQueue(e.pluginData,e.logPrefix),this.logPrefix=e.logPrefix,this.resolveOptions=e.resolveOptions??Me}async send(e){let r=this.resolveOptions();if(!r||this.dropIfOversized(e))return;await M(e,r,this.logPrefix)||this.queue.enqueue(e)}async flush(){let e=this.resolveOptions();if(e&&this.queue.tryAcquireLock())try{let r=this.queue.readAll();if(r.length===0)return;let{chunks:n,oversize:o}=ke(r,a=>N(a.payload),l.MAX_POST_BYTES);o.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${o.length} oversized retry ${o.length===1?"entry":"entries"} (each > ${l.MAX_POST_BYTES} bytes \u2014 the backend caps the request body, so they can never be delivered)
|
|
14
|
+
`);let i=[].concat(...n),u=0;for(let a of n){if(!await M((0,Ae.mergeBatch)(a.map(d=>d.payload)),e,this.logPrefix))break;u+=a.length}this.queue.rewrite(i.slice(u))}catch(r){process.stderr.write(`[${this.logPrefix}] flush failed: ${r?.message??String(r)}
|
|
15
15
|
`)}finally{this.queue.release()}}dropIfOversized(e){let r=N(e);return r<=l.MAX_POST_BYTES?!1:(process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (${r} > ${l.MAX_POST_BYTES} bytes) \u2014 undeliverable, not queued
|
|
16
|
-
`),!0)}};l.DiskTransport=U;var
|
|
17
|
-
`);return}await M(e,r,this.logPrefix)||this.queue.enqueue(e)}async flush(){let e=this.resolveOptions();if(!e)return;let r=this.queue.drain();if(r.length===0)return;let{chunks:n,oversize:o}=
|
|
18
|
-
`);let i=[].concat(...n),u=0;for(let a of n){if(!await M((0,
|
|
19
|
-
`)}}};v.TraceManager=
|
|
20
|
-
`)){let n=r.trim();if(!n||n.startsWith("#"))continue;let o=n.indexOf("=");if(o<0)continue;let i=n.slice(0,o).trim(),u=n.slice(o+1).trim();(u.startsWith('"')&&u.endsWith('"')||u.startsWith("'")&&u.endsWith("'"))&&(u=u.slice(1,-1)),i&&(e[i]=u)}return e}function
|
|
21
|
-
`)}function
|
|
16
|
+
`),!0)}};l.DiskTransport=U;var K=class{queue=new Ee.MemoryRetryQueue;logPrefix;resolveOptions;constructor(e){this.logPrefix=e.logPrefix,this.resolveOptions=e.resolveOptions}async send(e){let r=this.resolveOptions();if(!r)return;if(N(e)>l.MAX_POST_BYTES){process.stderr.write(`[${this.logPrefix}] dropping oversized span payload (> ${l.MAX_POST_BYTES} bytes) \u2014 undeliverable, not buffered
|
|
17
|
+
`);return}await M(e,r,this.logPrefix)||this.queue.enqueue(e)}async flush(){let e=this.resolveOptions();if(!e)return;let r=this.queue.drain();if(r.length===0)return;let{chunks:n,oversize:o}=ke(r,N,l.MAX_POST_BYTES);o.length>0&&process.stderr.write(`[${this.logPrefix}] dropping ${o.length} oversized buffered ${o.length===1?"payload":"payloads"} (each > ${l.MAX_POST_BYTES} bytes \u2014 undeliverable)
|
|
18
|
+
`);let i=[].concat(...n),u=0;for(let a of n){if(!await M((0,Ae.mergeBatch)(a),e,this.logPrefix))break;u+=a.length}for(let a of i.slice(u))this.queue.enqueue(a)}};l.MemoryTransport=K});var H=_(v=>{"use strict";var W=v&&v.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(v,"__esModule",{value:!0});v.TraceManager=void 0;v.generateUlid=Ie;var Re=W(h("fs")),At=W(h("path")),kt=W(h("crypto")),wt=I(),Z="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Ie(){let t=Date.now(),e="",r=t;for(let i=0;i<10;i++)e=Z[r&31]+e,r=Math.floor(r/32);let n=kt.default.randomBytes(10),o="";for(let i=0;i<10;i++)o+=Z[n[i]&31];for(;o.length<16;)o+=Z[0];return e+o}var J=class{tracePath;constructor(e){this.tracePath=e}newTrace(){let e=Ie();return this.save(e),e}currentTrace(){try{let e=Re.default.readFileSync(this.tracePath,"utf-8"),{traceId:r}=JSON.parse(e);if(r)return r}catch{}return this.newTrace()}save(e){try{Re.default.mkdirSync(At.default.dirname(this.tracePath),{recursive:!0}),(0,wt.atomicWriteFileSync)(this.tracePath,JSON.stringify({traceId:e}))}catch(r){process.stderr.write(`[pinta-core] trace persistence failed: ${r}
|
|
19
|
+
`)}}};v.TraceManager=J});var qe=_(O=>{"use strict";var je=O&&O.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(O,"__esModule",{value:!0});O.MemorySessionTraceManager=O.DiskSessionTraceManager=void 0;var De=je(h("fs")),Mt=je(h("path")),Ne=H(),xt=I(),Be=200,Q=class{tracePath;maxSessions;constructor(e,r={}){this.tracePath=e,this.maxSessions=r.maxSessions??Be}read(){try{let e=JSON.parse(De.default.readFileSync(this.tracePath,"utf-8"));if(e&&typeof e=="object"&&!("traceId"in e))return e}catch{}return{}}write(e){try{De.default.mkdirSync(Mt.default.dirname(this.tracePath),{recursive:!0});let r=Object.entries(e),n=r.length>this.maxSessions?Object.fromEntries(r.slice(-this.maxSessions)):e;(0,xt.atomicWriteFileSync)(this.tracePath,JSON.stringify(n))}catch{}}newTrace(e){let r=e||"default",n=(0,Ne.generateUlid)(),o=this.read();return o[r]=n,this.write(o),n}currentTrace(e){let r=e||"default",n=this.read()[r];return n||this.newTrace(r)}};O.DiskSessionTraceManager=Q;var ee=class{map=new Map;maxSessions;constructor(e={}){this.maxSessions=e.maxSessions??Be}newTrace(e){let r=e||"default",n=(0,Ne.generateUlid)();if(this.map.set(r,n),this.map.size>this.maxSessions){let o=this.map.keys().next().value;o!==void 0&&this.map.delete(o)}return n}currentTrace(e){let r=e||"default";return this.map.get(r)??this.newTrace(r)}};O.MemorySessionTraceManager=ee});var $e=_(S=>{"use strict";var te=S&&S.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(S,"__esModule",{value:!0});S.envFilePath=Dt;S.parseEnvFile=Fe;S.loadEnvFile=jt;var Rt=te(h("node:fs")),It=te(h("node:os")),Ce=te(h("node:path"));function Dt(t,e,r){let n=r?process.env[r]:void 0,o=n&&n.length>0?n:Ce.default.join(It.default.homedir(),t);return Ce.default.join(o,e)}function Fe(t){let e={};for(let r of t.split(`
|
|
20
|
+
`)){let n=r.trim();if(!n||n.startsWith("#"))continue;let o=n.indexOf("=");if(o<0)continue;let i=n.slice(0,o).trim(),u=n.slice(o+1).trim();(u.startsWith('"')&&u.endsWith('"')||u.startsWith("'")&&u.endsWith("'"))&&(u=u.slice(1,-1)),i&&(e[i]=u)}return e}function jt(t){let e;try{e=Rt.default.readFileSync(t,"utf-8")}catch{return}let r=Fe(e);for(let[n,o]of Object.entries(r))process.env[n]===void 0&&(process.env[n]=o)}});var b=_(s=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0});s.loadEnvFile=s.parseEnvFile=s.envFilePath=s.MemorySessionTraceManager=s.DiskSessionTraceManager=s.generateUlid=s.TraceManager=s.MAX_POST_BYTES=s.parseHeadersEnv=s.envOptionsResolver=s.postOtlp=s.MemoryTransport=s.DiskTransport=s.MemoryRetryQueue=s.DiskRetryQueue=s.evaluateGuard=s.MAX_SPAN_BYTES=s.enforceSpanBudget=s.mergeBatch=s.buildPayload=s.clientAttrs=s.guardAttrs=s.attrsFromRecord=s.toOtlpValue=s.snakeCase=s.newSpanId=s.ulidToTraceId=s.MAX_BYTES=s.PATTERNS=s.applyMatches=s.resolveOverlaps=s.collectMatches=s.truncateTo=s.truncate=s.redact=void 0;var T=F();Object.defineProperty(s,"redact",{enumerable:!0,get:function(){return T.redact}});Object.defineProperty(s,"truncate",{enumerable:!0,get:function(){return T.truncate}});Object.defineProperty(s,"truncateTo",{enumerable:!0,get:function(){return T.truncateTo}});Object.defineProperty(s,"collectMatches",{enumerable:!0,get:function(){return T.collectMatches}});Object.defineProperty(s,"resolveOverlaps",{enumerable:!0,get:function(){return T.resolveOverlaps}});Object.defineProperty(s,"applyMatches",{enumerable:!0,get:function(){return T.applyMatches}});Object.defineProperty(s,"PATTERNS",{enumerable:!0,get:function(){return T.PATTERNS}});Object.defineProperty(s,"MAX_BYTES",{enumerable:!0,get:function(){return T.MAX_BYTES}});var y=V();Object.defineProperty(s,"ulidToTraceId",{enumerable:!0,get:function(){return y.ulidToTraceId}});Object.defineProperty(s,"newSpanId",{enumerable:!0,get:function(){return y.newSpanId}});Object.defineProperty(s,"snakeCase",{enumerable:!0,get:function(){return y.snakeCase}});Object.defineProperty(s,"toOtlpValue",{enumerable:!0,get:function(){return y.toOtlpValue}});Object.defineProperty(s,"attrsFromRecord",{enumerable:!0,get:function(){return y.attrsFromRecord}});Object.defineProperty(s,"guardAttrs",{enumerable:!0,get:function(){return y.guardAttrs}});Object.defineProperty(s,"clientAttrs",{enumerable:!0,get:function(){return y.clientAttrs}});Object.defineProperty(s,"buildPayload",{enumerable:!0,get:function(){return y.buildPayload}});Object.defineProperty(s,"mergeBatch",{enumerable:!0,get:function(){return y.mergeBatch}});Object.defineProperty(s,"enforceSpanBudget",{enumerable:!0,get:function(){return y.enforceSpanBudget}});Object.defineProperty(s,"MAX_SPAN_BYTES",{enumerable:!0,get:function(){return y.MAX_SPAN_BYTES}});var Nt=ve();Object.defineProperty(s,"evaluateGuard",{enumerable:!0,get:function(){return Nt.evaluateGuard}});var Ve=z();Object.defineProperty(s,"DiskRetryQueue",{enumerable:!0,get:function(){return Ve.DiskRetryQueue}});Object.defineProperty(s,"MemoryRetryQueue",{enumerable:!0,get:function(){return Ve.MemoryRetryQueue}});var A=xe();Object.defineProperty(s,"DiskTransport",{enumerable:!0,get:function(){return A.DiskTransport}});Object.defineProperty(s,"MemoryTransport",{enumerable:!0,get:function(){return A.MemoryTransport}});Object.defineProperty(s,"postOtlp",{enumerable:!0,get:function(){return A.postOtlp}});Object.defineProperty(s,"envOptionsResolver",{enumerable:!0,get:function(){return A.envOptionsResolver}});Object.defineProperty(s,"parseHeadersEnv",{enumerable:!0,get:function(){return A.parseHeadersEnv}});Object.defineProperty(s,"MAX_POST_BYTES",{enumerable:!0,get:function(){return A.MAX_POST_BYTES}});var Le=H();Object.defineProperty(s,"TraceManager",{enumerable:!0,get:function(){return Le.TraceManager}});Object.defineProperty(s,"generateUlid",{enumerable:!0,get:function(){return Le.generateUlid}});var Ge=qe();Object.defineProperty(s,"DiskSessionTraceManager",{enumerable:!0,get:function(){return Ge.DiskSessionTraceManager}});Object.defineProperty(s,"MemorySessionTraceManager",{enumerable:!0,get:function(){return Ge.MemorySessionTraceManager}});var re=$e();Object.defineProperty(s,"envFilePath",{enumerable:!0,get:function(){return re.envFilePath}});Object.defineProperty(s,"parseEnvFile",{enumerable:!0,get:function(){return re.parseEnvFile}});Object.defineProperty(s,"loadEnvFile",{enumerable:!0,get:function(){return re.loadEnvFile}})});var Ye=E(b(),1);import qt from"node:fs";import ne from"node:path";var x=E(b(),1);function Bt(){return(0,x.envFilePath)(".config/opencode","pinta-opencode.env","OPENCODE_CONFIG_DIR")}function Xe(t=Bt()){(0,x.loadEnvFile)(t)}function oe(...t){return t.find(e=>e)||void 0}function Ct(t){let e=oe(t.endpoint,process.env.PINTA_OPENCODE_ENDPOINT,process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT);if(e)return e.replace(/\/+$/,"");let r=process.env.OTEL_EXPORTER_OTLP_ENDPOINT;if(r)return r.replace(/\/+$/,"")+"/v1/traces"}var Ft="opencode-ai";function $t(){let t=ne.dirname(process.execPath);for(let e=0;e<5;e++){try{let n=JSON.parse(qt.readFileSync(ne.join(t,"package.json"),"utf8"));if(n.name===Ft&&typeof n.version=="string"&&n.version)return n.version}catch{}let r=ne.dirname(t);if(r===t)break;t=r}}function Vt(){let t=process.env.OPENCODE_VERSION?.trim();return t||$t()}function ze(t={}){Xe();let e=oe(t.token,process.env.PINTA_OPENCODE_TOKEN),r=(0,Ye.parseHeadersEnv)(t.headers??process.env.PINTA_OPENCODE_HEADERS??process.env.OTEL_EXPORTER_OTLP_HEADERS);e&&!Object.keys(r).some(o=>o.toLowerCase()==="x-pinta-relay-token")&&(r["x-pinta-relay-token"]=e);let n=t.guardTimeoutMs??(Number(process.env.PINTA_OPENCODE_GUARD_TIMEOUT_MS)||50);return{endpoint:Ct(t),headers:r,guardEndpoint:oe(t.guard,process.env.PINTA_OPENCODE_GUARD),relayToken:e,guardTimeoutMs:n,guardDisabled:process.env.PINTA_OPENCODE_GUARD_DISABLED==="1",serviceVersion:Vt()}}var Ue=E(b(),1),B=class extends Ue.MemoryTransport{constructor(e){super({logPrefix:"pinta-opencode",resolveOptions:()=>e.endpoint?{endpoint:e.endpoint,headers:e.headers}:null})}};var se=E(b(),1);var Ke=E(b(),1),Lt=50,Gt="pinta-opencode/0.7.0";function Ze(t,e,r={}){return(0,Ke.evaluateGuard)(t,e,{timeoutMs:r.timeoutMs??Lt,token:r.token,disabled:r.disabled,userAgent:Gt})}var k=E(b(),1);import ie from"os";var q;function Xt(){if(q===void 0)try{q=ie.userInfo().username}catch{q=process.env.USER??process.env.LOGNAME??(typeof process.getuid=="function"?String(process.getuid()):"unknown")}return q}var Je="0.7.0",Yt=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"]),zt=new Set(["opencode.tool_input","opencode.tool_response"]),Ut={skipRedactKeys:Yt,bashContextKeys:zt};function Kt(t){let e=[{key:"ingest.type",value:{stringValue:"opencode"}}];return e.push(...(0,k.attrsFromRecord)(t,"opencode",Ut)),e}function Zt(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:Je}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:Xt()}},{key:"host.name",value:{stringValue:ie.hostname()}},{key:"host.arch",value:{stringValue:ie.arch()}}]}function We(t){return(0,k.buildPayload)({traceId:t.traceId,spanName:t.name,attributes:Kt(t.fields),resource:Zt(t.serviceVersion),scope:{name:"pinta-opencode",version:Je},now:t.now,guard:t.guard})}var C=class{constructor(e,r,n){this.transport=e;this.trace=r;this.config=n}async emit(e,r,n,o){let i=this.trace.currentTrace(r),u=We({name:e,traceId:i,fields:n,guard:o,serviceVersion:this.config.serviceVersion});await this.transport.send(u)}async lifecycle(e){let r=e.properties??{},n=typeof r.sessionID=="string"?r.sessionID:void 0;await this.emit(`opencode.event.${e.type??"unknown"}`,n,{hook:"event",event_type:e.type,session_id:n,cwd:process.cwd(),...r}),e.type==="session.idle"&&await this.transport.flush()}async toolBefore(e,r,n){await this.emit("opencode.tool.before",e.sessionID,{...He("tool.execute.before",e),tool_input:r},n)}async toolAfter(e,r){let n=r.metadata??{};await this.emit("opencode.tool.after",e.sessionID,{...He("tool.execute.after",e),title:r.title,tool_response:r.output,exit:n.exit,truncated:n.truncated})}};function He(t,e){return{hook:t,tool_name:e.tool,session_id:e.sessionID,tool_use_id:e.callID,cwd:process.cwd()}}function Qe(t,e){process.stderr.write(`[pinta-opencode] ${t}: ${e?.message??String(e)}
|
|
21
|
+
`)}function ae(t,e){return async(...r)=>{try{await e(...r)}catch(n){Qe(t,n)}}}var Jt=async(t,e)=>{let r=ze(e??{}),n=new B({endpoint:r.endpoint,headers:r.headers}),o=new se.MemorySessionTraceManager,i=new C(n,o,r);async function u(a,c){let d=null;try{d=await Ze({spanId:a.sessionID,toolName:a.tool,method:"tool.execute.before",cwd:process.cwd(),toolInput:c,rawTextFields:{toolInput:Wt(c)}},r.guardEndpoint,{timeoutMs:r.guardTimeoutMs,token:r.relayToken,disabled:r.guardDisabled}),await i.toolBefore(a,c,d)}catch(P){Qe("tool.execute.before",P)}return d}return{"chat.message":ae("chat.message",async a=>{o.newTrace(a?.sessionID)}),event:ae("event",async a=>{a?.event&&await i.lifecycle(a.event)}),"tool.execute.before":async(a,c)=>{let d=await u(a,c?.args);if(d?.decision==="DENY")throw new Error(d.userMessage??d.reason??"guard_deny")},"tool.execute.after":ae("tool.execute.after",(a,c)=>i.toolAfter(a,c))}};function Wt(t){try{return typeof t=="string"?t:JSON.stringify(t)??""}catch{return String(t)}}var Ar=Jt;export{Jt as PintaOpencode,Ar as default};
|