@pinta-ai/pinta-copilot 0.3.1 → 0.5.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 +44 -0
- package/dist/index.js +14 -71
- package/dist/index.mjs +15 -0
- package/dist/tools/doctor.js +4 -81
- package/dist/tools/install-hooks.js +3 -101
- package/package.json +17 -2
- package/dist/core/config.d.ts +0 -15
- package/dist/core/config.js +0 -19
- package/dist/core/config.js.map +0 -1
- package/dist/core/env-bridge.d.ts +0 -25
- package/dist/core/env-bridge.js +0 -43
- package/dist/core/env-bridge.js.map +0 -1
- package/dist/core/guard.d.ts +0 -14
- package/dist/core/guard.js +0 -53
- package/dist/core/guard.js.map +0 -1
- package/dist/core/otlp.d.ts +0 -55
- package/dist/core/otlp.js +0 -184
- package/dist/core/otlp.js.map +0 -1
- package/dist/core/redact.d.ts +0 -57
- package/dist/core/redact.js +0 -149
- package/dist/core/redact.js.map +0 -1
- package/dist/core/retry-queue.d.ts +0 -26
- package/dist/core/retry-queue.js +0 -127
- package/dist/core/retry-queue.js.map +0 -1
- package/dist/core/surface.d.ts +0 -21
- package/dist/core/surface.js +0 -13
- package/dist/core/surface.js.map +0 -1
- package/dist/core/trace.d.ts +0 -20
- package/dist/core/trace.js +0 -80
- package/dist/core/trace.js.map +0 -1
- package/dist/core/transport.d.ts +0 -18
- package/dist/core/transport.js +0 -127
- package/dist/core/transport.js.map +0 -1
- package/dist/core/types.d.ts +0 -49
- package/dist/core/types.js +0 -124
- package/dist/core/types.js.map +0 -1
- package/dist/env-file.d.ts +0 -4
- package/dist/env-file.js +0 -69
- package/dist/env-file.js.map +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js.map +0 -1
- package/dist/tools/doctor.d.ts +0 -1
- package/dist/tools/doctor.js.map +0 -1
- package/dist/tools/install-hooks.d.ts +0 -1
- package/dist/tools/install-hooks.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,50 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to pinta-copilot are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.4.0] - 2026-07-12
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **Shared core extraction.** The duplicated low-level utilities (otlp,
|
|
10
|
+
transport, retry-queue, redact, guard, session trace) now come from the
|
|
11
|
+
private `@pinta-ai/core` package; `src/core/*.ts` keeps only thin bindings
|
|
12
|
+
plus the copilot-specific bits (event flattening, surface detection, the
|
|
13
|
+
`envFilePath` override). Core is a devDependency, bundled into `dist/` by
|
|
14
|
+
esbuild at build time, so npmjs consumers never need private-registry access
|
|
15
|
+
and there is no runtime dependency on it.
|
|
16
|
+
- `@pinta-ai/core` bumped `^0.2.0` → `^0.3.0`. The upgrade is additive; no
|
|
17
|
+
adaptor source change was needed.
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- `pinta.client.rtt_ms` / `pinta.client.op` span attributes on guarded spans.
|
|
22
|
+
`buildOtlpPayload` already forwards its `guard` result into core's
|
|
23
|
+
`buildPayload`, and core `0.3.0` derives the client-call timing from the
|
|
24
|
+
`GuardResult.clientRttMs` it now measures. The manager can only time its own
|
|
25
|
+
handler, so `clientRttMs - durationMs` gives it the transport overhead.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- `package-lock.json` resolved `@pinta-ai/core` as a local link to
|
|
30
|
+
`../pinta-core` while `package.json` declared a version range. `npm ci` did
|
|
31
|
+
not error on the mismatch — it created a dangling symlink to a dev-machine-only
|
|
32
|
+
path and the build then failed `TS2307: Cannot find module '@pinta-ai/core'`,
|
|
33
|
+
breaking pr-validate, build-dist and publish. The lock now pins core's
|
|
34
|
+
GitHub Packages tarball with its integrity hash.
|
|
35
|
+
- `npm publish` would have failed `ENEEDAUTH`: the committed `.npmrc` pointed
|
|
36
|
+
npmjs auth at `${NPM_TOKEN}`, but no such secret exists, so it expanded to an
|
|
37
|
+
empty token instead of falling through to OIDC trusted publishing. The npmjs
|
|
38
|
+
`_authToken` line is gone and `setup-node`'s `registry-url` is back;
|
|
39
|
+
`NODE_AUTH_TOKEN` is now scoped to the `npm ci` step so it is not sent to
|
|
40
|
+
npmjs during publish.
|
|
41
|
+
- `npm` pinned to `11.18.0` in the publish workflow. `npm@latest` is now 12.x,
|
|
42
|
+
which requires node >=22.22 and aborts the node-20 publish job with
|
|
43
|
+
`EBADENGINE`.
|
|
44
|
+
- `tests/core/guard.test.ts` asserted the core `0.2.0` `GuardResult` shape with
|
|
45
|
+
an exhaustive `toEqual` and broke once `clientRttMs` was added. It now matches
|
|
46
|
+
that field by type, since it is a measured wall-clock rather than a value
|
|
47
|
+
echoed from the response body.
|
|
48
|
+
|
|
5
49
|
## [0.2.0] - 2026-06-16
|
|
6
50
|
|
|
7
51
|
### Changed
|
package/dist/index.js
CHANGED
|
@@ -1,71 +1,14 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
(0,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
async function readStdin() {
|
|
16
|
-
const chunks = [];
|
|
17
|
-
for await (const chunk of process.stdin)
|
|
18
|
-
chunks.push(chunk);
|
|
19
|
-
return Buffer.concat(chunks).toString("utf-8");
|
|
20
|
-
}
|
|
21
|
-
async function main() {
|
|
22
|
-
// ⚠️ CLI preToolUse hooks are FAIL-CLOSED: a non-zero exit / crash / timeout
|
|
23
|
-
// DENIES the tool — and a crashing hook bricks the whole agent (report_intent
|
|
24
|
-
// / ask_user get blocked too, verified §9.6). Therefore this process MUST
|
|
25
|
-
// exit 0 on every path. All work is wrapped; the catch-all stays exit 0.
|
|
26
|
-
try {
|
|
27
|
-
const config = (0, config_js_1.loadConfig)();
|
|
28
|
-
const surface = (0, surface_js_1.detectSurface)();
|
|
29
|
-
const raw = await readStdin();
|
|
30
|
-
const event = JSON.parse(raw);
|
|
31
|
-
const kind = (0, types_js_1.classify)(event);
|
|
32
|
-
const sid = (0, types_js_1.sessionId)(event);
|
|
33
|
-
const transport = new transport_js_1.Transport(config);
|
|
34
|
-
await transport.flush(); // drain retry queue first
|
|
35
|
-
const trace = new trace_js_1.TraceManager(config);
|
|
36
|
-
// UserPromptSubmit starts a new per-turn trace; everything else reuses it.
|
|
37
|
-
const traceId = kind === "UserPromptSubmit" ? trace.newTrace(sid) : trace.currentTrace(sid);
|
|
38
|
-
// Guard runs on the two tool-gating events (PreToolUse: all surfaces;
|
|
39
|
-
// PermissionRequest: CLI-only). Internal agent tools (report_intent,
|
|
40
|
-
// ask_user) are telemetry-only — never guarded (would brick the turn).
|
|
41
|
-
const toolNm = (0, types_js_1.toolName)(event);
|
|
42
|
-
let guard = null;
|
|
43
|
-
if ((0, types_js_1.isGuardEvent)(kind) && !(0, types_js_1.isInternalTool)(toolNm)) {
|
|
44
|
-
const ti = (0, types_js_1.toolInput)(event);
|
|
45
|
-
guard = await (0, guard_js_1.evaluateGuard)({
|
|
46
|
-
spanId: sid ?? "unknown",
|
|
47
|
-
toolName: toolNm,
|
|
48
|
-
toolInput: ti,
|
|
49
|
-
rawTextFields: {
|
|
50
|
-
toolInput: typeof ti === "string" ? ti : JSON.stringify(ti ?? null),
|
|
51
|
-
},
|
|
52
|
-
}, process.env.PINTA_GUARD_ENDPOINT);
|
|
53
|
-
}
|
|
54
|
-
// Telemetry: one span per event (Bronze flattening, copilot.* prefix).
|
|
55
|
-
const payload = (0, otlp_js_1.buildOtlpPayload)({ event, traceId, surface, guard });
|
|
56
|
-
await transport.send(payload);
|
|
57
|
-
// Enforcement: emit a deny decision in the format the firing event expects.
|
|
58
|
-
if (guard?.decision === "DENY") {
|
|
59
|
-
const out = (0, types_js_1.formatDeny)(kind, guard.userMessage ?? guard.reason ?? "guard_deny");
|
|
60
|
-
if (out)
|
|
61
|
-
process.stdout.write(out + "\n");
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
catch (err) {
|
|
65
|
-
process.stderr.write(`[pinta-copilot] error: ${err}\n`);
|
|
66
|
-
// fail-open by design — never block a tool because the adapter crashed.
|
|
67
|
-
}
|
|
68
|
-
process.exit(0);
|
|
69
|
-
}
|
|
70
|
-
main();
|
|
71
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
"use strict";var Qe=Object.create;var se=Object.defineProperty;var We=Object.getOwnPropertyDescriptor;var et=Object.getOwnPropertyNames;var tt=Object.getPrototypeOf,rt=Object.prototype.hasOwnProperty;var f=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var nt=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of et(t))!rt.call(e,o)&&o!==r&&se(e,o,{get:()=>t[o],enumerable:!(n=We(t,o))||n.enumerable});return e};var _=(e,t,r)=>(r=e!=null?Qe(tt(e)):{},nt(t||!e||!e.__esModule?se(r,"default",{value:e,enumerable:!0}):r,e));var G=f(c=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});c.PATTERNS=c.MAX_BYTES=void 0;c.truncate=ot;c.collectMatches=ie;c.resolveOverlaps=ae;c.applyMatches=ue;c.redact=st;c.MAX_BYTES=102400;function ot(e){let t=Buffer.from(e,"utf-8");return t.length<=c.MAX_BYTES?e:`${t.subarray(0,c.MAX_BYTES).toString("utf-8")}\u2026[TRUNCATED:${t.length}]`}c.PATTERNS=[{type:"aws_access_key",regex:/AKIA[0-9A-Z]{16}/g},{type:"aws_secret_key",regex:/(?:aws[_-]?secret(?:[_-]?(?:access)?[_-]?key)?)\s*[:=]\s*["']?([A-Za-z0-9/+=]{40})(?![A-Za-z0-9/+=])/gi,captureGroup:1},{type:"gcp_service_account",regex:/\{[\s\S]{0,200}?"type"\s*:\s*"service_account"[\s\S]*?\}/g},{type:"github_token",regex:/gh[pousr]_[A-Za-z0-9]{36,}/g},{type:"gitlab_token",regex:/glpat-[A-Za-z0-9_-]{20}/g},{type:"slack_token",regex:/xox[abrsp]-[0-9A-Za-z-]{10,}/g},{type:"openai_key",regex:/sk-(?:proj-)?[A-Za-z0-9_-]{40,}/g},{type:"anthropic_key",regex:/sk-ant-[A-Za-z0-9_-]{50,}/g},{type:"stripe_key",regex:/(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g},{type:"jwt",regex:/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g},{type:"private_key_block",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g},{type:"bearer_token",regex:/bearer\s+([A-Za-z0-9._~+/=-]{12,})/gi,captureGroup:1},{type:"basic_auth",regex:/basic\s+([A-Za-z0-9+/=]{12,})/gi,captureGroup:1},{type:"db_url_password",regex:/\b(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|redis):\/\/[^:\s/]+:([^@\s]+)@/gi,captureGroup:1},{type:"cli_password_flag",regex:/(?:--password|--pass|--pwd)[=\s]([^\s'"]+)/g,captureGroup:1},{type:"cli_password_short",regex:/\s-p([^\s'"]+)/g,captureGroup:1,requireContext:"bash"},{type:"env_var_secret",regex:/^(?:export\s+)?([A-Z][A-Z0-9_]*(?:KEY|SECRET|TOKEN|PASSWORD|PASSWD|PWD|API_KEY)[A-Z0-9_]*)\s*=\s*["']?([^\s"'\n]+)/gm,captureGroup:2}];function ie(e,t){let r=[];for(let n of c.PATTERNS){if(n.requireContext&&n.requireContext!==t.context)continue;let o=new RegExp(n.regex.source,n.regex.flags),i;for(;(i=o.exec(e))!==null;){let a=n.captureGroup??0,u=i[a];if(u===void 0){i.index===o.lastIndex&&o.lastIndex++;continue}let R=i.index,I=i.index+i[0].length,h=R+i[0].indexOf(u),U=h+u.length;r.push({start:R,end:I,replaceStart:h,replaceEnd:U,type:n.type}),i.index===o.lastIndex&&o.lastIndex++}}return r}function ae(e){let t=[...e].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 t)o.start<n||(r.push(o),n=o.end);return r}function ue(e,t){let r=[...t].sort((o,i)=>i.replaceStart-o.replaceStart),n=e;for(let o of r)n=n.slice(0,o.replaceStart)+`[REDACTED:${o.type}]`+n.slice(o.replaceEnd);return n}function st(e,t={}){if(e.length===0)return e;let r=ie(e,t);if(r.length===0)return e;let n=ae(r);return ue(e,n)}});var V=f(p=>{"use strict";var it=p&&p.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(p,"__esModule",{value:!0});p.ulidToTraceId=pe;p.newSpanId=fe;p.snakeCase=ct;p.toOtlpValue=de;p.attrsFromRecord=lt;p.guardAttrs=ge;p.clientAttrs=he;p.buildPayload=pt;p.mergeBatch=ft;var at=it(require("crypto")),ce=G(),ut="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function pe(e){if(e.length!==26)throw new Error(`ulidToTraceId: expected 26 chars, got ${e.length}`);let t=0n;for(let n of e){let o=ut.indexOf(n);if(o<0)throw new Error(`ulidToTraceId: invalid Crockford char "${n}"`);t=t<<5n|BigInt(o)}let r=(1n<<128n)-1n;return t&=r,t.toString(16).padStart(32,"0")}function fe(){return at.default.randomBytes(8).toString("hex")}function ct(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var le=new Set;function x(e,t,r){let n=(0,ce.truncate)(t);if((r.skipRedactKeys??le).has(e))return n;let o=(r.bashContextKeys??le).has(e)?"bash":void 0;return(0,ce.redact)(n,{context:o})}function de(e,t,r={}){if(t==null)return null;switch(typeof t){case"string":return{stringValue:x(e,t,r)};case"boolean":return{boolValue:t};case"number":return Number.isInteger(t)?{intValue:t}:{doubleValue:t};case"object":try{return{stringValue:x(e,JSON.stringify(t),r)}}catch{return{stringValue:x(e,String(t),r)}}default:return{stringValue:x(e,String(t),r)}}}function lt(e,t,r={}){let n=[];for(let[o,i]of Object.entries(e)){let a=`${t}.${o}`,u=de(a,i,r);u!==null&&n.push({key:a,value:u})}return n}function ge(e){let t=[{key:"pinta.guard.decision",value:{stringValue:e.decision.toLowerCase()}},{key:"pinta.guard.duration_ms",value:{intValue:e.durationMs}}];return e.reason&&t.push({key:"pinta.guard.matched_rule",value:{stringValue:e.reason}}),e.failOpenReason&&t.push({key:"pinta.guard.fail_open_reason",value:{stringValue:e.failOpenReason}}),t}function he(e){return[{key:"pinta.client.rtt_ms",value:Number.isInteger(e.rttMs)?{intValue:e.rttMs}:{doubleValue:e.rttMs}},{key:"pinta.client.op",value:{stringValue:e.op}}]}function pt(e){let t=e.now??Date.now(),r=(BigInt(t)*1000000n).toString(),n=[...e.attributes];e.guard&&n.push(...ge(e.guard));let o=e.clientTiming??(e.guard?.clientRttMs!==void 0?{op:"guard",rttMs:e.guard.clientRttMs}:null);o&&n.push(...he(o));let i={traceId:pe(e.traceId),spanId:fe(),name:e.spanName,kind:e.spanKind??1,startTimeUnixNano:r,endTimeUnixNano:r,attributes:n};return{resourceSpans:[{resource:{attributes:e.resource},scopeSpans:[{scope:e.scope,spans:[i]}]}]}}function ft(e){let t=[];for(let r of e)t.push(...r.resourceSpans);return{resourceSpans:t}}});var ye=f($=>{"use strict";Object.defineProperty($,"__esModule",{value:!0});$.evaluateGuard=_t;var dt=1e4,gt="pinta-core";function _e(e,t){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:e,clientRttMs:e,failOpenReason:t}}function ht(e){return new Promise((t,r)=>setTimeout(()=>{let n=new Error("Guard request timed out");n.name="TimeoutError",r(n)},e))}async function _t(e,t,r={}){if(!t||r.disabled)return null;let n=r.timeoutMs??dt,o=Date.now();try{let i=await Promise.race([fetch(t,{method:"POST",headers:{"content-type":"application/json","user-agent":r.userAgent??gt,"x-pinta-relay-token":r.token??""},body:JSON.stringify({input:e})}),ht(n)]);if(i.status!==200)return _e(Date.now()-o,"error");let a=await i.json(),u=Date.now()-o;return{decision:a.decision,reason:a.reason,userMessage:a.userMessage??null,durationMs:a.durationMs??u,clientRttMs:u}}catch(i){let a=i.name==="TimeoutError"?"timeout":"error";return _e(Date.now()-o,a)}}});var Z=f(y=>{"use strict";var me=y&&y.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(y,"__esModule",{value:!0});y.MemoryRetryQueue=y.DiskRetryQueue=void 0;var l=me(require("fs")),M=me(require("path")),N=1e3,yt=50,mt=5,K=class{filePath;lockPath;logPrefix;constructor(t,r){this.filePath=M.default.join(t,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=r}enqueue(t){try{l.default.mkdirSync(M.default.dirname(this.filePath),{recursive:!0});let r=JSON.stringify({savedAt:new Date().toISOString(),payload:t})+`
|
|
2
|
+
`;l.default.appendFileSync(this.filePath,r),this.trim()}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue enqueue failed: ${r}
|
|
3
|
+
`)}}readAll(){try{let t=l.default.readFileSync(this.filePath,"utf-8"),r=[];for(let n of t.split(`
|
|
4
|
+
`))if(n.trim())try{r.push(JSON.parse(n))}catch{}return r}catch{return[]}}rewrite(t){try{if(t.length===0){l.default.existsSync(this.filePath)&&l.default.unlinkSync(this.filePath);return}l.default.mkdirSync(M.default.dirname(this.filePath),{recursive:!0}),l.default.writeFileSync(this.filePath,t.map(r=>JSON.stringify(r)).join(`
|
|
5
|
+
`)+`
|
|
6
|
+
`)}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue rewrite failed: ${r}
|
|
7
|
+
`)}}tryAcquireLock(){let t=Date.now();for(l.default.mkdirSync(M.default.dirname(this.lockPath),{recursive:!0});Date.now()-t<yt;)try{let r=l.default.openSync(this.lockPath,"wx");return l.default.writeSync(r,String(process.pid)),l.default.closeSync(r),!0}catch(r){if(r?.code!=="EEXIST")return process.stderr.write(`[${this.logPrefix}] retry-queue lock open failed: ${r}
|
|
8
|
+
`),!1;try{let i=l.default.statSync(this.lockPath);if(Date.now()-i.mtimeMs>3e4){l.default.unlinkSync(this.lockPath);continue}}catch{}let n=mt,o=Date.now()+n;for(;Date.now()<o;);}return!1}release(){try{l.default.unlinkSync(this.lockPath)}catch{}}trim(){let t=this.readAll();if(t.length<=N)return;let r=t.length-N;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${r} oldest entries
|
|
9
|
+
`),this.rewrite(t.slice(r))}};y.DiskRetryQueue=K;var B=class{entries=[];enqueue(t){this.entries.push(t),this.entries.length>N&&this.entries.splice(0,this.entries.length-N)}drain(){let t=this.entries;return this.entries=[],t}get size(){return this.entries.length}};y.MemoryRetryQueue=B});var ve=f(d=>{"use strict";Object.defineProperty(d,"__esModule",{value:!0});d.MemoryTransport=d.DiskTransport=void 0;d.parseHeadersEnv=Te;d.envOptionsResolver=Se;d.postOtlp=k;var Pe=Z(),Oe=V(),Pt=5e3;function Te(e){if(!e)return{};if(typeof e=="object")return{...e};let t={};for(let r of e.split(",")){let[n,...o]=r.split("=");n&&o.length>0&&(t[n.trim()]=o.join("=").trim())}return t}function Se(){let e=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,t=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,r;return e?r=e.replace(/\/+$/,""):t&&(r=t.replace(/\/+$/,"")+"/v1/traces"),r?{endpoint:r,headers:Te(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function k(e,t,r){let n=new AbortController,o=setTimeout(()=>n.abort(),Pt);try{let i=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify(e),signal:n.signal});if(!i.ok){let a="";try{a=(await i.text()).slice(0,200)}catch{}let u=i.status===401||i.status===403?" \u2014 check OTEL_EXPORTER_OTLP_HEADERS (relay token)":i.status===404?" \u2014 check OTEL_EXPORTER_OTLP_TRACES_ENDPOINT path":i.status>=500?" \u2014 collector may be down":"";return process.stderr.write(`[${r}] OTLP POST ${i.status} ${t.endpoint}${u}${a?` body=${a}`:""}
|
|
10
|
+
`),!1}return!0}catch(i){return process.stderr.write(`[${r}] OTLP POST failed: ${i.message??String(i)}
|
|
11
|
+
`),!1}finally{clearTimeout(o)}}var X=class{queue;logPrefix;resolveOptions;constructor(t){this.queue=new Pe.DiskRetryQueue(t.pluginData,t.logPrefix),this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions??Se}async send(t){let r=this.resolveOptions();if(!r)return;await k(t,r,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(t&&this.queue.tryAcquireLock())try{let r=this.queue.readAll();if(r.length===0)return;let n=(0,Oe.mergeBatch)(r.map(i=>i.payload));await k(n,t,this.logPrefix)&&this.queue.rewrite([])}finally{this.queue.release()}}};d.DiskTransport=X;var J=class{queue=new Pe.MemoryRetryQueue;logPrefix;resolveOptions;constructor(t){this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions}async send(t){let r=this.resolveOptions();if(!r)return;await k(t,r,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(!t)return;let r=this.queue.drain();if(r.length===0)return;let n=(0,Oe.mergeBatch)(r);if(!await k(n,t,this.logPrefix))for(let i of r)this.queue.enqueue(i)}};d.MemoryTransport=J});var W=f(O=>{"use strict";var Q=O&&O.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(O,"__esModule",{value:!0});O.TraceManager=void 0;O.generateUlid=Ee;var Y=Q(require("fs")),Ot=Q(require("path")),Tt=Q(require("crypto")),H="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Ee(){let e=Date.now(),t="",r=e;for(let i=0;i<10;i++)t=H[r&31]+t,r=Math.floor(r/32);let n=Tt.default.randomBytes(10),o="";for(let i=0;i<10;i++)o+=H[n[i]&31];for(;o.length<16;)o+=H[0];return t+o}var z=class{tracePath;constructor(t){this.tracePath=t}newTrace(){let t=Ee();return this.save(t),t}currentTrace(){try{let t=Y.default.readFileSync(this.tracePath,"utf-8"),{traceId:r}=JSON.parse(t);if(r)return r}catch{}return this.newTrace()}save(t){Y.default.mkdirSync(Ot.default.dirname(this.tracePath),{recursive:!0}),Y.default.writeFileSync(this.tracePath,JSON.stringify({traceId:t}))}};O.TraceManager=z});var Ae=f(m=>{"use strict";var be=m&&m.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(m,"__esModule",{value:!0});m.MemorySessionTraceManager=m.DiskSessionTraceManager=void 0;var ee=be(require("fs")),St=be(require("path")),ke=W(),we=200,te=class{tracePath;maxSessions;constructor(t,r={}){this.tracePath=t,this.maxSessions=r.maxSessions??we}read(){try{let t=JSON.parse(ee.default.readFileSync(this.tracePath,"utf-8"));if(t&&typeof t=="object"&&!("traceId"in t))return t}catch{}return{}}write(t){try{ee.default.mkdirSync(St.default.dirname(this.tracePath),{recursive:!0});let r=Object.entries(t),n=r.length>this.maxSessions?Object.fromEntries(r.slice(-this.maxSessions)):t;ee.default.writeFileSync(this.tracePath,JSON.stringify(n))}catch{}}newTrace(t){let r=t||"default",n=(0,ke.generateUlid)(),o=this.read();return o[r]=n,this.write(o),n}currentTrace(t){let r=t||"default",n=this.read()[r];return n||this.newTrace(r)}};m.DiskSessionTraceManager=te;var re=class{map=new Map;maxSessions;constructor(t={}){this.maxSessions=t.maxSessions??we}newTrace(t){let r=t||"default",n=(0,ke.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(t){let r=t||"default";return this.map.get(r)??this.newTrace(r)}};m.MemorySessionTraceManager=re});var xe=f(T=>{"use strict";var ne=T&&T.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(T,"__esModule",{value:!0});T.envFilePath=bt;T.parseEnvFile=Ie;T.loadEnvFile=kt;var vt=ne(require("node:fs")),Et=ne(require("node:os")),Re=ne(require("node:path"));function bt(e,t,r){let n=r?process.env[r]:void 0,o=n&&n.length>0?n:Re.default.join(Et.default.homedir(),e);return Re.default.join(o,t)}function Ie(e){let t={};for(let r of e.split(`
|
|
12
|
+
`)){let n=r.trim();if(!n||n.startsWith("#"))continue;let o=n.indexOf("=");if(o<0)continue;let i=n.slice(0,o).trim(),a=n.slice(o+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),i&&(t[i]=a)}return t}function kt(e){let t;try{t=vt.default.readFileSync(e,"utf-8")}catch{return}let r=Ie(t);for(let[n,o]of Object.entries(r))process.env[n]===void 0&&(process.env[n]=o)}});var b=f(s=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0});s.loadEnvFile=s.parseEnvFile=s.envFilePath=s.MemorySessionTraceManager=s.DiskSessionTraceManager=s.generateUlid=s.TraceManager=s.parseHeadersEnv=s.envOptionsResolver=s.postOtlp=s.MemoryTransport=s.DiskTransport=s.MemoryRetryQueue=s.DiskRetryQueue=s.evaluateGuard=s.mergeBatch=s.buildPayload=s.clientAttrs=s.guardAttrs=s.attrsFromRecord=s.toOtlpValue=s.snakeCase=s.newSpanId=s.ulidToTraceId=s.MAX_BYTES=s.PATTERNS=s.applyMatches=s.resolveOverlaps=s.collectMatches=s.truncate=s.redact=void 0;var S=G();Object.defineProperty(s,"redact",{enumerable:!0,get:function(){return S.redact}});Object.defineProperty(s,"truncate",{enumerable:!0,get:function(){return S.truncate}});Object.defineProperty(s,"collectMatches",{enumerable:!0,get:function(){return S.collectMatches}});Object.defineProperty(s,"resolveOverlaps",{enumerable:!0,get:function(){return S.resolveOverlaps}});Object.defineProperty(s,"applyMatches",{enumerable:!0,get:function(){return S.applyMatches}});Object.defineProperty(s,"PATTERNS",{enumerable:!0,get:function(){return S.PATTERNS}});Object.defineProperty(s,"MAX_BYTES",{enumerable:!0,get:function(){return S.MAX_BYTES}});var g=V();Object.defineProperty(s,"ulidToTraceId",{enumerable:!0,get:function(){return g.ulidToTraceId}});Object.defineProperty(s,"newSpanId",{enumerable:!0,get:function(){return g.newSpanId}});Object.defineProperty(s,"snakeCase",{enumerable:!0,get:function(){return g.snakeCase}});Object.defineProperty(s,"toOtlpValue",{enumerable:!0,get:function(){return g.toOtlpValue}});Object.defineProperty(s,"attrsFromRecord",{enumerable:!0,get:function(){return g.attrsFromRecord}});Object.defineProperty(s,"guardAttrs",{enumerable:!0,get:function(){return g.guardAttrs}});Object.defineProperty(s,"clientAttrs",{enumerable:!0,get:function(){return g.clientAttrs}});Object.defineProperty(s,"buildPayload",{enumerable:!0,get:function(){return g.buildPayload}});Object.defineProperty(s,"mergeBatch",{enumerable:!0,get:function(){return g.mergeBatch}});var wt=ye();Object.defineProperty(s,"evaluateGuard",{enumerable:!0,get:function(){return wt.evaluateGuard}});var Me=Z();Object.defineProperty(s,"DiskRetryQueue",{enumerable:!0,get:function(){return Me.DiskRetryQueue}});Object.defineProperty(s,"MemoryRetryQueue",{enumerable:!0,get:function(){return Me.MemoryRetryQueue}});var w=ve();Object.defineProperty(s,"DiskTransport",{enumerable:!0,get:function(){return w.DiskTransport}});Object.defineProperty(s,"MemoryTransport",{enumerable:!0,get:function(){return w.MemoryTransport}});Object.defineProperty(s,"postOtlp",{enumerable:!0,get:function(){return w.postOtlp}});Object.defineProperty(s,"envOptionsResolver",{enumerable:!0,get:function(){return w.envOptionsResolver}});Object.defineProperty(s,"parseHeadersEnv",{enumerable:!0,get:function(){return w.parseHeadersEnv}});var Ne=W();Object.defineProperty(s,"TraceManager",{enumerable:!0,get:function(){return Ne.TraceManager}});Object.defineProperty(s,"generateUlid",{enumerable:!0,get:function(){return Ne.generateUlid}});var De=Ae();Object.defineProperty(s,"DiskSessionTraceManager",{enumerable:!0,get:function(){return De.DiskSessionTraceManager}});Object.defineProperty(s,"MemorySessionTraceManager",{enumerable:!0,get:function(){return De.MemorySessionTraceManager}});var oe=xe();Object.defineProperty(s,"envFilePath",{enumerable:!0,get:function(){return oe.envFilePath}});Object.defineProperty(s,"parseEnvFile",{enumerable:!0,get:function(){return oe.parseEnvFile}});Object.defineProperty(s,"loadEnvFile",{enumerable:!0,get:function(){return oe.loadEnvFile}})});var A=_(b());function At(){return(0,A.envFilePath)(".copilot","pinta-copilot.env","COPILOT_HOME")}function je(e=At()){(0,A.loadEnvFile)(e)}var Ce=_(require("os")),D=_(require("path"));function Rt(){return process.env.COPILOT_HOME||D.default.join(Ce.default.homedir(),".copilot")}function qe(){let e=process.env.COPILOT_PLUGIN_DATA||D.default.join(Rt(),"pinta-copilot-data");return{pluginData:e,tracePath:D.default.join(e,"trace.json")}}function Le(e=process.env){return e.COPILOT_AGENT_JOB_ID||e.COPILOT_AGENT_SESSION_ID||e.COPILOT_AGENT_PROMPT?"cloud":e.ELECTRON_RUN_AS_NODE||e.VSCODE_IPC_HOOK||e.VSCODE_PID?"ext":"cli"}function v(e){return typeof e=="string"?e:void 0}function j(e){return v(e.hook_event_name)??v(e.hookEventName)??v(e.hookName)??(process.env.PINTA_COPILOT_EVENT||void 0)}function Fe(e){return v(e.session_id)??v(e.sessionId)}function Ue(e){return v(e.tool_name)??v(e.toolName)}function Ge(e){return e.tool_input??e.toolArgs??e.toolInput}var It={sessionstart:"SessionStart",sessionend:"SessionEnd",userpromptsubmit:"UserPromptSubmit",userpromptsubmitted:"UserPromptSubmit",pretooluse:"PreToolUse",posttooluse:"PostToolUse",posttoolusefailure:"PostToolUseFailure",stop:"Stop",agentstop:"Stop",subagentstart:"SubagentStart",subagentstop:"SubagentStop",precompact:"PreCompact",notification:"Notification",permissionrequest:"PermissionRequest",erroroccurred:"ErrorOccurred"};function Ve(e){let t=j(e);return t?It[t.toLowerCase()]??"Unknown":"Unknown"}function $e(e){return e==="PreToolUse"||e==="PermissionRequest"}var xt=new Set(["report_intent","ask_user"]);function Ke(e){return e!==void 0&&xt.has(e)}function Be(e,t){return e==="PreToolUse"?JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:t}}):e==="PermissionRequest"?JSON.stringify({behavior:"deny",message:t}):null}var q=_(b());function Mt(){let e=process.env.COPILOT_PLUGIN_OPTION_ENDPOINT||process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,t=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,r;return e?r=e.replace(/\/+$/,""):t&&(r=t.replace(/\/+$/,"")+"/v1/traces"),r?{endpoint:r,headers:(0,q.parseHeadersEnv)(process.env.COPILOT_PLUGIN_OPTION_HEADERS||process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}var C=class extends q.DiskTransport{constructor(t){super({pluginData:t.pluginData,logPrefix:"pinta-copilot",resolveOptions:Mt})}};var Ze=_(b()),L=class extends Ze.DiskSessionTraceManager{constructor(t){super(t.tracePath)}};var F=_(require("os")),E=_(b());var Xe="0.5.0";function Nt(){return process.env.COPILOT_CLI_VERSION||"unknown"}var Dt=new Set(["copilot.hook","copilot.tool_name","copilot.toolName","copilot.tool_use_id","copilot.toolUseId","copilot.session_id","copilot.sessionId","copilot.transcript_path","copilot.transcriptPath","copilot.cwd","copilot.permission_mode","copilot.surface","copilot.agent_id","copilot.agent_type","copilot.agent_name","copilot.agent_display_name","copilot.stop_reason","copilot.notification_type"]),jt=new Set(["copilot.tool_input","copilot.toolInput","copilot.tool_response","copilot.tool_result"]),Ct={skipRedactKeys:Dt,bashContextKeys:jt},qt=new Set(["hook_event_name","hookEventName","hookName"]);function Lt(e,t){let r=Object.fromEntries(Object.entries(e).filter(([n])=>!qt.has(n)));return[{key:"ingest.type",value:{stringValue:"copilot"}},{key:"copilot.hook",value:{stringValue:j(e)??"unknown"}},{key:"copilot.surface",value:{stringValue:t}},...(0,E.attrsFromRecord)(r,"copilot",Ct)]}function Ft(){return[{key:"service.name",value:{stringValue:"copilot"}},{key:"service.version",value:{stringValue:Nt()}},{key:"telemetry.sdk.name",value:{stringValue:"pinta-copilot"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:Xe}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:F.default.userInfo().username}},{key:"host.name",value:{stringValue:F.default.hostname()}},{key:"host.arch",value:{stringValue:F.default.arch()}}]}function Je(e){return(0,E.buildPayload)({traceId:e.traceId,spanName:`copilot.${(0,E.snakeCase)(j(e.event)??"unknown")}`,attributes:Lt(e.event,e.surface),resource:Ft(),scope:{name:"pinta-copilot",version:Xe},now:e.now,guard:e.guard})}var Ye=_(b());function Ut(){return Number(process.env.PINTA_GUARD_TIMEOUT_MS)||50}var Gt="pinta-copilot/0.5.0";function He(e,t){return(0,Ye.evaluateGuard)(e,t,{timeoutMs:Ut(),token:process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:Gt})}async function Vt(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function ze(){try{let e=qe(),t=Le(),r=await Vt(),n=JSON.parse(r),o=Ve(n),i=Fe(n),a=new C(e);await a.flush();let u=new L(e),R=o==="UserPromptSubmit"?u.newTrace(i):u.currentTrace(i),I=Ue(n),h=null;if($e(o)&&!Ke(I)){let P=Ge(n);h=await He({spanId:i??"unknown",toolName:I,toolInput:P,rawTextFields:{toolInput:typeof P=="string"?P:JSON.stringify(P??null)}},process.env.PINTA_GUARD_ENDPOINT)}let U=Je({event:n,traceId:R,surface:t,guard:h});if(await a.send(U),h?.decision==="DENY"){let P=Be(o,h.userMessage??h.reason??"guard_deny");P&&process.stdout.write(P+`
|
|
13
|
+
`)}}catch(e){process.stderr.write(`[pinta-copilot] error: ${e}
|
|
14
|
+
`)}return 0}je();async function $t(){let e=await ze();process.exit(e)}$t();
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import{createRequire as __pintaCreateRequire}from 'node:module';const require=__pintaCreateRequire(import.meta.url);
|
|
2
|
+
var dt=Object.create;var fe=Object.defineProperty;var mt=Object.getOwnPropertyDescriptor;var gt=Object.getOwnPropertyNames;var ht=Object.getPrototypeOf,yt=Object.prototype.hasOwnProperty;var d=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var m=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var _t=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of gt(t))!yt.call(e,o)&&o!==r&&fe(e,o,{get:()=>t[o],enumerable:!(n=mt(t,o))||n.enumerable});return e};var I=(e,t,r)=>(r=e!=null?dt(ht(e)):{},_t(t||!e||!e.__esModule?fe(r,"default",{value:e,enumerable:!0}):r,e));var $=m(c=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});c.PATTERNS=c.MAX_BYTES=void 0;c.truncate=Pt;c.collectMatches=de;c.resolveOverlaps=me;c.applyMatches=ge;c.redact=St;c.MAX_BYTES=102400;function Pt(e){let t=Buffer.from(e,"utf-8");return t.length<=c.MAX_BYTES?e:`${t.subarray(0,c.MAX_BYTES).toString("utf-8")}\u2026[TRUNCATED:${t.length}]`}c.PATTERNS=[{type:"aws_access_key",regex:/AKIA[0-9A-Z]{16}/g},{type:"aws_secret_key",regex:/(?:aws[_-]?secret(?:[_-]?(?:access)?[_-]?key)?)\s*[:=]\s*["']?([A-Za-z0-9/+=]{40})(?![A-Za-z0-9/+=])/gi,captureGroup:1},{type:"gcp_service_account",regex:/\{[\s\S]{0,200}?"type"\s*:\s*"service_account"[\s\S]*?\}/g},{type:"github_token",regex:/gh[pousr]_[A-Za-z0-9]{36,}/g},{type:"gitlab_token",regex:/glpat-[A-Za-z0-9_-]{20}/g},{type:"slack_token",regex:/xox[abrsp]-[0-9A-Za-z-]{10,}/g},{type:"openai_key",regex:/sk-(?:proj-)?[A-Za-z0-9_-]{40,}/g},{type:"anthropic_key",regex:/sk-ant-[A-Za-z0-9_-]{50,}/g},{type:"stripe_key",regex:/(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g},{type:"jwt",regex:/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g},{type:"private_key_block",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g},{type:"bearer_token",regex:/bearer\s+([A-Za-z0-9._~+/=-]{12,})/gi,captureGroup:1},{type:"basic_auth",regex:/basic\s+([A-Za-z0-9+/=]{12,})/gi,captureGroup:1},{type:"db_url_password",regex:/\b(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|redis):\/\/[^:\s/]+:([^@\s]+)@/gi,captureGroup:1},{type:"cli_password_flag",regex:/(?:--password|--pass|--pwd)[=\s]([^\s'"]+)/g,captureGroup:1},{type:"cli_password_short",regex:/\s-p([^\s'"]+)/g,captureGroup:1,requireContext:"bash"},{type:"env_var_secret",regex:/^(?:export\s+)?([A-Z][A-Z0-9_]*(?:KEY|SECRET|TOKEN|PASSWORD|PASSWD|PWD|API_KEY)[A-Z0-9_]*)\s*=\s*["']?([^\s"'\n]+)/gm,captureGroup:2}];function de(e,t){let r=[];for(let n of c.PATTERNS){if(n.requireContext&&n.requireContext!==t.context)continue;let o=new RegExp(n.regex.source,n.regex.flags),s;for(;(s=o.exec(e))!==null;){let a=n.captureGroup??0,u=s[a];if(u===void 0){s.index===o.lastIndex&&o.lastIndex++;continue}let p=s.index,b=s.index+s[0].length,y=p+s[0].indexOf(u),U=y+u.length;r.push({start:p,end:b,replaceStart:y,replaceEnd:U,type:n.type}),s.index===o.lastIndex&&o.lastIndex++}}return r}function me(e){let t=[...e].sort((o,s)=>o.start!==s.start?o.start-s.start:s.end-s.start-(o.end-o.start)),r=[],n=-1;for(let o of t)o.start<n||(r.push(o),n=o.end);return r}function ge(e,t){let r=[...t].sort((o,s)=>s.replaceStart-o.replaceStart),n=e;for(let o of r)n=n.slice(0,o.replaceStart)+`[REDACTED:${o.type}]`+n.slice(o.replaceEnd);return n}function St(e,t={}){if(e.length===0)return e;let r=de(e,t);if(r.length===0)return e;let n=me(r);return ge(e,n)}});var G=m(f=>{"use strict";var Ot=f&&f.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(f,"__esModule",{value:!0});f.ulidToTraceId=_e;f.newSpanId=Pe;f.snakeCase=Et;f.toOtlpValue=Se;f.attrsFromRecord=wt;f.guardAttrs=Oe;f.clientAttrs=Te;f.buildPayload=bt;f.mergeBatch=kt;var Tt=Ot(d("crypto")),he=$(),vt="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function _e(e){if(e.length!==26)throw new Error(`ulidToTraceId: expected 26 chars, got ${e.length}`);let t=0n;for(let n of e){let o=vt.indexOf(n);if(o<0)throw new Error(`ulidToTraceId: invalid Crockford char "${n}"`);t=t<<5n|BigInt(o)}let r=(1n<<128n)-1n;return t&=r,t.toString(16).padStart(32,"0")}function Pe(){return Tt.default.randomBytes(8).toString("hex")}function Et(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}var ye=new Set;function M(e,t,r){let n=(0,he.truncate)(t);if((r.skipRedactKeys??ye).has(e))return n;let o=(r.bashContextKeys??ye).has(e)?"bash":void 0;return(0,he.redact)(n,{context:o})}function Se(e,t,r={}){if(t==null)return null;switch(typeof t){case"string":return{stringValue:M(e,t,r)};case"boolean":return{boolValue:t};case"number":return Number.isInteger(t)?{intValue:t}:{doubleValue:t};case"object":try{return{stringValue:M(e,JSON.stringify(t),r)}}catch{return{stringValue:M(e,String(t),r)}}default:return{stringValue:M(e,String(t),r)}}}function wt(e,t,r={}){let n=[];for(let[o,s]of Object.entries(e)){let a=`${t}.${o}`,u=Se(a,s,r);u!==null&&n.push({key:a,value:u})}return n}function Oe(e){let t=[{key:"pinta.guard.decision",value:{stringValue:e.decision.toLowerCase()}},{key:"pinta.guard.duration_ms",value:{intValue:e.durationMs}}];return e.reason&&t.push({key:"pinta.guard.matched_rule",value:{stringValue:e.reason}}),e.failOpenReason&&t.push({key:"pinta.guard.fail_open_reason",value:{stringValue:e.failOpenReason}}),t}function Te(e){return[{key:"pinta.client.rtt_ms",value:Number.isInteger(e.rttMs)?{intValue:e.rttMs}:{doubleValue:e.rttMs}},{key:"pinta.client.op",value:{stringValue:e.op}}]}function bt(e){let t=e.now??Date.now(),r=(BigInt(t)*1000000n).toString(),n=[...e.attributes];e.guard&&n.push(...Oe(e.guard));let o=e.clientTiming??(e.guard?.clientRttMs!==void 0?{op:"guard",rttMs:e.guard.clientRttMs}:null);o&&n.push(...Te(o));let s={traceId:_e(e.traceId),spanId:Pe(),name:e.spanName,kind:e.spanKind??1,startTimeUnixNano:r,endTimeUnixNano:r,attributes:n};return{resourceSpans:[{resource:{attributes:e.resource},scopeSpans:[{scope:e.scope,spans:[s]}]}]}}function kt(e){let t=[];for(let r of e)t.push(...r.resourceSpans);return{resourceSpans:t}}});var Ee=m(V=>{"use strict";Object.defineProperty(V,"__esModule",{value:!0});V.evaluateGuard=At;var It=1e4,xt="pinta-core";function ve(e,t){return{decision:"ALLOW",reason:null,userMessage:null,durationMs:e,clientRttMs:e,failOpenReason:t}}function Rt(e){return new Promise((t,r)=>setTimeout(()=>{let n=new Error("Guard request timed out");n.name="TimeoutError",r(n)},e))}async function At(e,t,r={}){if(!t||r.disabled)return null;let n=r.timeoutMs??It,o=Date.now();try{let s=await Promise.race([fetch(t,{method:"POST",headers:{"content-type":"application/json","user-agent":r.userAgent??xt,"x-pinta-relay-token":r.token??""},body:JSON.stringify({input:e})}),Rt(n)]);if(s.status!==200)return ve(Date.now()-o,"error");let a=await s.json(),u=Date.now()-o;return{decision:a.decision,reason:a.reason,userMessage:a.userMessage??null,durationMs:a.durationMs??u,clientRttMs:u}}catch(s){let a=s.name==="TimeoutError"?"timeout":"error";return ve(Date.now()-o,a)}}});var Z=m(_=>{"use strict";var we=_&&_.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0});_.MemoryRetryQueue=_.DiskRetryQueue=void 0;var l=we(d("fs")),D=we(d("path")),N=1e3,Mt=50,Dt=5,B=class{filePath;lockPath;logPrefix;constructor(t,r){this.filePath=D.default.join(t,"failed-spans.jsonl"),this.lockPath=this.filePath+".lock",this.logPrefix=r}enqueue(t){try{l.default.mkdirSync(D.default.dirname(this.filePath),{recursive:!0});let r=JSON.stringify({savedAt:new Date().toISOString(),payload:t})+`
|
|
3
|
+
`;l.default.appendFileSync(this.filePath,r),this.trim()}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue enqueue failed: ${r}
|
|
4
|
+
`)}}readAll(){try{let t=l.default.readFileSync(this.filePath,"utf-8"),r=[];for(let n of t.split(`
|
|
5
|
+
`))if(n.trim())try{r.push(JSON.parse(n))}catch{}return r}catch{return[]}}rewrite(t){try{if(t.length===0){l.default.existsSync(this.filePath)&&l.default.unlinkSync(this.filePath);return}l.default.mkdirSync(D.default.dirname(this.filePath),{recursive:!0}),l.default.writeFileSync(this.filePath,t.map(r=>JSON.stringify(r)).join(`
|
|
6
|
+
`)+`
|
|
7
|
+
`)}catch(r){process.stderr.write(`[${this.logPrefix}] retry-queue rewrite failed: ${r}
|
|
8
|
+
`)}}tryAcquireLock(){let t=Date.now();for(l.default.mkdirSync(D.default.dirname(this.lockPath),{recursive:!0});Date.now()-t<Mt;)try{let r=l.default.openSync(this.lockPath,"wx");return l.default.writeSync(r,String(process.pid)),l.default.closeSync(r),!0}catch(r){if(r?.code!=="EEXIST")return process.stderr.write(`[${this.logPrefix}] retry-queue lock open failed: ${r}
|
|
9
|
+
`),!1;try{let s=l.default.statSync(this.lockPath);if(Date.now()-s.mtimeMs>3e4){l.default.unlinkSync(this.lockPath);continue}}catch{}let n=Dt,o=Date.now()+n;for(;Date.now()<o;);}return!1}release(){try{l.default.unlinkSync(this.lockPath)}catch{}}trim(){let t=this.readAll();if(t.length<=N)return;let r=t.length-N;process.stderr.write(`[${this.logPrefix}] retry-queue full, dropping ${r} oldest entries
|
|
10
|
+
`),this.rewrite(t.slice(r))}};_.DiskRetryQueue=B;var K=class{entries=[];enqueue(t){this.entries.push(t),this.entries.length>N&&this.entries.splice(0,this.entries.length-N)}drain(){let t=this.entries;return this.entries=[],t}get size(){return this.entries.length}};_.MemoryRetryQueue=K});var Re=m(g=>{"use strict";Object.defineProperty(g,"__esModule",{value:!0});g.MemoryTransport=g.DiskTransport=void 0;g.parseHeadersEnv=Ie;g.envOptionsResolver=xe;g.postOtlp=x;var be=Z(),ke=G(),Nt=5e3;function Ie(e){if(!e)return{};if(typeof e=="object")return{...e};let t={};for(let r of e.split(",")){let[n,...o]=r.split("=");n&&o.length>0&&(t[n.trim()]=o.join("=").trim())}return t}function xe(){let e=process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,t=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,r;return e?r=e.replace(/\/+$/,""):t&&(r=t.replace(/\/+$/,"")+"/v1/traces"),r?{endpoint:r,headers:Ie(process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}async function x(e,t,r){let n=new AbortController,o=setTimeout(()=>n.abort(),Nt);try{let s=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify(e),signal:n.signal});if(!s.ok){let a="";try{a=(await s.text()).slice(0,200)}catch{}let u=s.status===401||s.status===403?" \u2014 check OTEL_EXPORTER_OTLP_HEADERS (relay token)":s.status===404?" \u2014 check OTEL_EXPORTER_OTLP_TRACES_ENDPOINT path":s.status>=500?" \u2014 collector may be down":"";return process.stderr.write(`[${r}] OTLP POST ${s.status} ${t.endpoint}${u}${a?` body=${a}`:""}
|
|
11
|
+
`),!1}return!0}catch(s){return process.stderr.write(`[${r}] OTLP POST failed: ${s.message??String(s)}
|
|
12
|
+
`),!1}finally{clearTimeout(o)}}var X=class{queue;logPrefix;resolveOptions;constructor(t){this.queue=new be.DiskRetryQueue(t.pluginData,t.logPrefix),this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions??xe}async send(t){let r=this.resolveOptions();if(!r)return;await x(t,r,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(t&&this.queue.tryAcquireLock())try{let r=this.queue.readAll();if(r.length===0)return;let n=(0,ke.mergeBatch)(r.map(s=>s.payload));await x(n,t,this.logPrefix)&&this.queue.rewrite([])}finally{this.queue.release()}}};g.DiskTransport=X;var z=class{queue=new be.MemoryRetryQueue;logPrefix;resolveOptions;constructor(t){this.logPrefix=t.logPrefix,this.resolveOptions=t.resolveOptions}async send(t){let r=this.resolveOptions();if(!r)return;await x(t,r,this.logPrefix)||this.queue.enqueue(t)}async flush(){let t=this.resolveOptions();if(!t)return;let r=this.queue.drain();if(r.length===0)return;let n=(0,ke.mergeBatch)(r);if(!await x(n,t,this.logPrefix))for(let s of r)this.queue.enqueue(s)}};g.MemoryTransport=z});var W=m(O=>{"use strict";var Q=O&&O.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(O,"__esModule",{value:!0});O.TraceManager=void 0;O.generateUlid=Ae;var H=Q(d("fs")),jt=Q(d("path")),Ct=Q(d("crypto")),J="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Ae(){let e=Date.now(),t="",r=e;for(let s=0;s<10;s++)t=J[r&31]+t,r=Math.floor(r/32);let n=Ct.default.randomBytes(10),o="";for(let s=0;s<10;s++)o+=J[n[s]&31];for(;o.length<16;)o+=J[0];return t+o}var Y=class{tracePath;constructor(t){this.tracePath=t}newTrace(){let t=Ae();return this.save(t),t}currentTrace(){try{let t=H.default.readFileSync(this.tracePath,"utf-8"),{traceId:r}=JSON.parse(t);if(r)return r}catch{}return this.newTrace()}save(t){H.default.mkdirSync(jt.default.dirname(this.tracePath),{recursive:!0}),H.default.writeFileSync(this.tracePath,JSON.stringify({traceId:t}))}};O.TraceManager=Y});var je=m(P=>{"use strict";var Me=P&&P.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(P,"__esModule",{value:!0});P.MemorySessionTraceManager=P.DiskSessionTraceManager=void 0;var ee=Me(d("fs")),qt=Me(d("path")),De=W(),Ne=200,te=class{tracePath;maxSessions;constructor(t,r={}){this.tracePath=t,this.maxSessions=r.maxSessions??Ne}read(){try{let t=JSON.parse(ee.default.readFileSync(this.tracePath,"utf-8"));if(t&&typeof t=="object"&&!("traceId"in t))return t}catch{}return{}}write(t){try{ee.default.mkdirSync(qt.default.dirname(this.tracePath),{recursive:!0});let r=Object.entries(t),n=r.length>this.maxSessions?Object.fromEntries(r.slice(-this.maxSessions)):t;ee.default.writeFileSync(this.tracePath,JSON.stringify(n))}catch{}}newTrace(t){let r=t||"default",n=(0,De.generateUlid)(),o=this.read();return o[r]=n,this.write(o),n}currentTrace(t){let r=t||"default",n=this.read()[r];return n||this.newTrace(r)}};P.DiskSessionTraceManager=te;var re=class{map=new Map;maxSessions;constructor(t={}){this.maxSessions=t.maxSessions??Ne}newTrace(t){let r=t||"default",n=(0,De.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(t){let r=t||"default";return this.map.get(r)??this.newTrace(r)}};P.MemorySessionTraceManager=re});var Fe=m(T=>{"use strict";var ne=T&&T.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(T,"__esModule",{value:!0});T.envFilePath=Ut;T.parseEnvFile=qe;T.loadEnvFile=$t;var Ft=ne(d("node:fs")),Lt=ne(d("node:os")),Ce=ne(d("node:path"));function Ut(e,t,r){let n=r?process.env[r]:void 0,o=n&&n.length>0?n:Ce.default.join(Lt.default.homedir(),e);return Ce.default.join(o,t)}function qe(e){let t={};for(let r of e.split(`
|
|
13
|
+
`)){let n=r.trim();if(!n||n.startsWith("#"))continue;let o=n.indexOf("=");if(o<0)continue;let s=n.slice(0,o).trim(),a=n.slice(o+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),s&&(t[s]=a)}return t}function $t(e){let t;try{t=Ft.default.readFileSync(e,"utf-8")}catch{return}let r=qe(t);for(let[n,o]of Object.entries(r))process.env[n]===void 0&&(process.env[n]=o)}});var k=m(i=>{"use strict";Object.defineProperty(i,"__esModule",{value:!0});i.loadEnvFile=i.parseEnvFile=i.envFilePath=i.MemorySessionTraceManager=i.DiskSessionTraceManager=i.generateUlid=i.TraceManager=i.parseHeadersEnv=i.envOptionsResolver=i.postOtlp=i.MemoryTransport=i.DiskTransport=i.MemoryRetryQueue=i.DiskRetryQueue=i.evaluateGuard=i.mergeBatch=i.buildPayload=i.clientAttrs=i.guardAttrs=i.attrsFromRecord=i.toOtlpValue=i.snakeCase=i.newSpanId=i.ulidToTraceId=i.MAX_BYTES=i.PATTERNS=i.applyMatches=i.resolveOverlaps=i.collectMatches=i.truncate=i.redact=void 0;var v=$();Object.defineProperty(i,"redact",{enumerable:!0,get:function(){return v.redact}});Object.defineProperty(i,"truncate",{enumerable:!0,get:function(){return v.truncate}});Object.defineProperty(i,"collectMatches",{enumerable:!0,get:function(){return v.collectMatches}});Object.defineProperty(i,"resolveOverlaps",{enumerable:!0,get:function(){return v.resolveOverlaps}});Object.defineProperty(i,"applyMatches",{enumerable:!0,get:function(){return v.applyMatches}});Object.defineProperty(i,"PATTERNS",{enumerable:!0,get:function(){return v.PATTERNS}});Object.defineProperty(i,"MAX_BYTES",{enumerable:!0,get:function(){return v.MAX_BYTES}});var h=G();Object.defineProperty(i,"ulidToTraceId",{enumerable:!0,get:function(){return h.ulidToTraceId}});Object.defineProperty(i,"newSpanId",{enumerable:!0,get:function(){return h.newSpanId}});Object.defineProperty(i,"snakeCase",{enumerable:!0,get:function(){return h.snakeCase}});Object.defineProperty(i,"toOtlpValue",{enumerable:!0,get:function(){return h.toOtlpValue}});Object.defineProperty(i,"attrsFromRecord",{enumerable:!0,get:function(){return h.attrsFromRecord}});Object.defineProperty(i,"guardAttrs",{enumerable:!0,get:function(){return h.guardAttrs}});Object.defineProperty(i,"clientAttrs",{enumerable:!0,get:function(){return h.clientAttrs}});Object.defineProperty(i,"buildPayload",{enumerable:!0,get:function(){return h.buildPayload}});Object.defineProperty(i,"mergeBatch",{enumerable:!0,get:function(){return h.mergeBatch}});var Gt=Ee();Object.defineProperty(i,"evaluateGuard",{enumerable:!0,get:function(){return Gt.evaluateGuard}});var Le=Z();Object.defineProperty(i,"DiskRetryQueue",{enumerable:!0,get:function(){return Le.DiskRetryQueue}});Object.defineProperty(i,"MemoryRetryQueue",{enumerable:!0,get:function(){return Le.MemoryRetryQueue}});var R=Re();Object.defineProperty(i,"DiskTransport",{enumerable:!0,get:function(){return R.DiskTransport}});Object.defineProperty(i,"MemoryTransport",{enumerable:!0,get:function(){return R.MemoryTransport}});Object.defineProperty(i,"postOtlp",{enumerable:!0,get:function(){return R.postOtlp}});Object.defineProperty(i,"envOptionsResolver",{enumerable:!0,get:function(){return R.envOptionsResolver}});Object.defineProperty(i,"parseHeadersEnv",{enumerable:!0,get:function(){return R.parseHeadersEnv}});var Ue=W();Object.defineProperty(i,"TraceManager",{enumerable:!0,get:function(){return Ue.TraceManager}});Object.defineProperty(i,"generateUlid",{enumerable:!0,get:function(){return Ue.generateUlid}});var $e=je();Object.defineProperty(i,"DiskSessionTraceManager",{enumerable:!0,get:function(){return $e.DiskSessionTraceManager}});Object.defineProperty(i,"MemorySessionTraceManager",{enumerable:!0,get:function(){return $e.MemorySessionTraceManager}});var oe=Fe();Object.defineProperty(i,"envFilePath",{enumerable:!0,get:function(){return oe.envFilePath}});Object.defineProperty(i,"parseEnvFile",{enumerable:!0,get:function(){return oe.parseEnvFile}});Object.defineProperty(i,"loadEnvFile",{enumerable:!0,get:function(){return oe.loadEnvFile}})});import{realpathSync as Ir}from"node:fs";import{pathToFileURL as xr}from"node:url";var A=I(k());function Vt(){return(0,A.envFilePath)(".copilot","pinta-copilot.env","COPILOT_HOME")}function Ge(e=Vt()){(0,A.loadEnvFile)(e)}import Bt from"os";import se from"path";function ie(){return process.env.COPILOT_HOME||se.join(Bt.homedir(),".copilot")}function Ve(){let e=process.env.COPILOT_PLUGIN_DATA||se.join(ie(),"pinta-copilot-data");return{pluginData:e,tracePath:se.join(e,"trace.json")}}function Be(e=process.env){return e.COPILOT_AGENT_JOB_ID||e.COPILOT_AGENT_SESSION_ID||e.COPILOT_AGENT_PROMPT?"cloud":e.ELECTRON_RUN_AS_NODE||e.VSCODE_IPC_HOOK||e.VSCODE_PID?"ext":"cli"}function E(e){return typeof e=="string"?e:void 0}function j(e){return E(e.hook_event_name)??E(e.hookEventName)??E(e.hookName)??(process.env.PINTA_COPILOT_EVENT||void 0)}function Ke(e){return E(e.session_id)??E(e.sessionId)}function Ze(e){return E(e.tool_name)??E(e.toolName)}function Xe(e){return e.tool_input??e.toolArgs??e.toolInput}var Kt={sessionstart:"SessionStart",sessionend:"SessionEnd",userpromptsubmit:"UserPromptSubmit",userpromptsubmitted:"UserPromptSubmit",pretooluse:"PreToolUse",posttooluse:"PostToolUse",posttoolusefailure:"PostToolUseFailure",stop:"Stop",agentstop:"Stop",subagentstart:"SubagentStart",subagentstop:"SubagentStop",precompact:"PreCompact",notification:"Notification",permissionrequest:"PermissionRequest",erroroccurred:"ErrorOccurred"};function ze(e){let t=j(e);return t?Kt[t.toLowerCase()]??"Unknown":"Unknown"}function He(e){return e==="PreToolUse"||e==="PermissionRequest"}var Zt=new Set(["report_intent","ask_user"]);function Je(e){return e!==void 0&&Zt.has(e)}function Ye(e,t){return e==="PreToolUse"?JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:t}}):e==="PermissionRequest"?JSON.stringify({behavior:"deny",message:t}):null}var q=I(k());function Xt(){let e=process.env.COPILOT_PLUGIN_OPTION_ENDPOINT||process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,t=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,r;return e?r=e.replace(/\/+$/,""):t&&(r=t.replace(/\/+$/,"")+"/v1/traces"),r?{endpoint:r,headers:(0,q.parseHeadersEnv)(process.env.COPILOT_PLUGIN_OPTION_HEADERS||process.env.OTEL_EXPORTER_OTLP_HEADERS)}:null}var C=class extends q.DiskTransport{constructor(t){super({pluginData:t.pluginData,logPrefix:"pinta-copilot",resolveOptions:Xt})}};var Qe=I(k()),F=class extends Qe.DiskSessionTraceManager{constructor(t){super(t.tracePath)}};var w=I(k());import ae from"os";var We="0.5.0";function zt(){return process.env.COPILOT_CLI_VERSION||"unknown"}var Ht=new Set(["copilot.hook","copilot.tool_name","copilot.toolName","copilot.tool_use_id","copilot.toolUseId","copilot.session_id","copilot.sessionId","copilot.transcript_path","copilot.transcriptPath","copilot.cwd","copilot.permission_mode","copilot.surface","copilot.agent_id","copilot.agent_type","copilot.agent_name","copilot.agent_display_name","copilot.stop_reason","copilot.notification_type"]),Jt=new Set(["copilot.tool_input","copilot.toolInput","copilot.tool_response","copilot.tool_result"]),Yt={skipRedactKeys:Ht,bashContextKeys:Jt},Qt=new Set(["hook_event_name","hookEventName","hookName"]);function Wt(e,t){let r=Object.fromEntries(Object.entries(e).filter(([n])=>!Qt.has(n)));return[{key:"ingest.type",value:{stringValue:"copilot"}},{key:"copilot.hook",value:{stringValue:j(e)??"unknown"}},{key:"copilot.surface",value:{stringValue:t}},...(0,w.attrsFromRecord)(r,"copilot",Yt)]}function er(){return[{key:"service.name",value:{stringValue:"copilot"}},{key:"service.version",value:{stringValue:zt()}},{key:"telemetry.sdk.name",value:{stringValue:"pinta-copilot"}},{key:"telemetry.sdk.language",value:{stringValue:"nodejs"}},{key:"telemetry.sdk.version",value:{stringValue:We}},{key:"process.pid",value:{intValue:process.pid}},{key:"process.owner",value:{stringValue:ae.userInfo().username}},{key:"host.name",value:{stringValue:ae.hostname()}},{key:"host.arch",value:{stringValue:ae.arch()}}]}function et(e){return(0,w.buildPayload)({traceId:e.traceId,spanName:`copilot.${(0,w.snakeCase)(j(e.event)??"unknown")}`,attributes:Wt(e.event,e.surface),resource:er(),scope:{name:"pinta-copilot",version:We},now:e.now,guard:e.guard})}var tt=I(k());function tr(){return Number(process.env.PINTA_GUARD_TIMEOUT_MS)||50}var rr="pinta-copilot/0.5.0";function rt(e,t){return(0,tt.evaluateGuard)(e,t,{timeoutMs:tr(),token:process.env.PINTA_RELAY_TOKEN??"",disabled:process.env.PINTA_GUARD_DISABLED==="1",userAgent:rr})}async function nr(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function nt(){try{let e=Ve(),t=Be(),r=await nr(),n=JSON.parse(r),o=ze(n),s=Ke(n),a=new C(e);await a.flush();let u=new F(e),p=o==="UserPromptSubmit"?u.newTrace(s):u.currentTrace(s),b=Ze(n),y=null;if(He(o)&&!Je(b)){let S=Xe(n);y=await rt({spanId:s??"unknown",toolName:b,toolInput:S,rawTextFields:{toolInput:typeof S=="string"?S:JSON.stringify(S??null)}},process.env.PINTA_GUARD_ENDPOINT)}let U=et({event:n,traceId:p,surface:t,guard:y});if(await a.send(U),y?.decision==="DENY"){let S=Ye(o,y.userMessage??y.reason??"guard_deny");S&&process.stdout.write(S+`
|
|
14
|
+
`)}}catch(e){process.stderr.write(`[pinta-copilot] error: ${e}
|
|
15
|
+
`)}return 0}import{opendir as gr,stat as hr}from"node:fs/promises";import L from"node:path";import{spawn as st}from"node:child_process";import{copyFile as ue,mkdtemp as or,rm as pn,stat as sr}from"node:fs/promises";import ir from"node:os";import ce from"node:path";var ar=2e3,ur=250,ot=3,le;function cr(){return le||(le=new Promise(e=>{let t=st("sqlite3",["-version"],{stdio:"ignore"});t.once("error",()=>e(!1)),t.once("exit",r=>e(r===0))})),le}function lr(e){return`'${e.replace(/'/g,"''")}'`}async function pr(e,t){let r=`.backup ${lr(t)}`;await new Promise((n,o)=>{let s=st("sqlite3",[e,r],{stdio:["ignore","ignore","pipe"]}),a="";s.stderr?.on("data",u=>{a+=u.toString()}),s.once("error",o),s.once("exit",u=>{u===0?n():o(new Error(`sqlite3 .backup exited ${u}: ${a.trim()}`))})})}async function pe(e){try{return await sr(e)}catch{return}}function it(e,t){return e===void 0||t===void 0?e===void 0&&t===void 0:e.size===t.size&&e.mtimeMs===t.mtimeMs}function at(e){return{wal:`${e}-wal`,shm:`${e}-shm`}}async function fr(e){let{wal:t,shm:r}=at(e),n=[e,t,r],o=Date.now(),s=await Promise.all(n.map(async a=>({path:a,st:await pe(a)})));for(;;){if(Date.now()-o>=ar)return s;await new Promise(p=>setTimeout(p,ur));let a=await Promise.all(n.map(async p=>({path:p,st:await pe(p)})));a.every((p,b)=>it(p.st,s[b].st))||(o=Date.now()),s=a}}async function dr(e,t){let{wal:r,shm:n}=at(e),o=await fr(e);if(await ue(e,t),o.find(u=>u.path===r)?.st!==void 0&&await ue(r,`${t}-wal`),o.find(u=>u.path===n)?.st!==void 0&&await ue(n,`${t}-shm`),!(await Promise.all([e,r,n].map(async u=>({path:u,st:await pe(u)})))).every((u,p)=>it(u.st,o[p].st)))throw new Error(`snapshot: ${e} changed during quiesce-copy (torn-read guard)`)}async function mr(e,t){let r;for(let n=1;n<=ot;n++)try{await dr(e,t);return}catch(o){r=o}throw new Error(`snapshot: quiesce-copy of ${e} failed after ${ot} attempts: ${String(r)}`)}async function ut(e,t={}){let r=t.tmpDirBase??ir.tmpdir(),n=await or(ce.join(r,"pinta-copilot-snapshot-")),o=ce.join(n,ce.basename(e.absPath));if(await cr())try{return await pr(e.absPath,o),o}catch{}return await mr(e.absPath,o),o}var yr="pinta-copilot",ct="events.jsonl",lt="session.db",_r="rewind-snapshots/backups/";function Pr(){return L.join(ie(),"session-state")}function Sr(e,t){return L.relative(e,t).split(L.sep).join("/")}function Or(e){return e.endsWith(".db-wal")||e.endsWith(".db-shm")}function Tr(e){let[t]=e.split("/");return!t||t===e?{}:{sessionId:t}}function vr(e,t){let r=e.split("/").length===2;return r&&t===ct?"append-log":r&&t===lt?"database":"rewritten-doc"}function Er(e){let t=e.split("/"),r=t[t.length-1]??"";return t.length===2&&(r===ct||r===lt)?"session-log":e.includes(_r)?"other":"meta"}async function pt(){return[Pr()]}async function*ft(e,t){let r;try{r=await gr(t)}catch{return}try{for await(let n of r){let o=L.join(t,n.name);n.isDirectory()?yield*ft(e,o):n.isFile()&&(yield{absPath:o,relPath:Sr(e,o)})}}catch{return}}async function*wr(e){let[t]=await pt(),r=e.since?.getTime();for await(let{absPath:n,relPath:o}of ft(t,t)){let s=o.split("/"),a=s[s.length-1]??"";if(Or(a))continue;let u;try{u=await hr(n)}catch{continue}r!==void 0&&u.mtime.getTime()<=r||(yield{relPath:o,absPath:n,size:u.size,mtime:u.mtime,...Tr(o),semantics:vr(o,a)})}}async function br(e){return ut(e)}var kr={id:yr,roots:pt,scan:wr,classify:Er,snapshot:br};Ge();function Rr(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===xr(Ir(e)).href}catch{return!1}}async function Ar(){let e=await nt();process.exit(e)}Rr()&&Ar();export{kr as lifecycle};
|
package/dist/tools/doctor.js
CHANGED
|
@@ -1,81 +1,4 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
/**
|
|
7
|
-
* doctor — read-only health check for a pinta-copilot install.
|
|
8
|
-
*
|
|
9
|
-
* node dist/tools/doctor.js (or: npm run doctor)
|
|
10
|
-
*
|
|
11
|
-
* Verifies the hook file, env file / OTel endpoint, and the built adapter.
|
|
12
|
-
* Exits 1 if anything required is missing; 0 if healthy.
|
|
13
|
-
*/
|
|
14
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
15
|
-
const node_os_1 = __importDefault(require("node:os"));
|
|
16
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
17
|
-
const surface_js_1 = require("../core/surface.js");
|
|
18
|
-
function copilotHome() {
|
|
19
|
-
return process.env.COPILOT_HOME || node_path_1.default.join(node_os_1.default.homedir(), ".copilot");
|
|
20
|
-
}
|
|
21
|
-
const checks = [];
|
|
22
|
-
function check(required, ok, label, detail) {
|
|
23
|
-
checks.push({ ok, label, detail, required });
|
|
24
|
-
}
|
|
25
|
-
const home = copilotHome();
|
|
26
|
-
const hookFile = node_path_1.default.join(home, "hooks", "pinta-copilot.json");
|
|
27
|
-
const envFile = node_path_1.default.join(home, "pinta-copilot.env");
|
|
28
|
-
const adapter = node_path_1.default.join(node_path_1.default.dirname(node_path_1.default.resolve(process.argv[1])), "..", "index.js");
|
|
29
|
-
// 1. adapter built
|
|
30
|
-
check(true, node_fs_1.default.existsSync(adapter), "adapter built (dist/index.js)", adapter);
|
|
31
|
-
// 2. hook file installed + points at this adapter
|
|
32
|
-
let hookOk = false;
|
|
33
|
-
let hookDetail = `${hookFile} (missing — run \`npm run install-hooks\`)`;
|
|
34
|
-
try {
|
|
35
|
-
const j = JSON.parse(node_fs_1.default.readFileSync(hookFile, "utf-8"));
|
|
36
|
-
const cmd = j?.hooks?.PreToolUse?.[0]?.command ?? "";
|
|
37
|
-
const events = Object.keys(j?.hooks ?? {}).length;
|
|
38
|
-
hookOk = cmd.includes("index.js");
|
|
39
|
-
hookDetail = `${hookFile} (${events} events)`;
|
|
40
|
-
}
|
|
41
|
-
catch {
|
|
42
|
-
/* missing */
|
|
43
|
-
}
|
|
44
|
-
check(true, hookOk, "hook file installed", hookDetail);
|
|
45
|
-
// 3. env file (optional) + OTel endpoint configured (required for telemetry)
|
|
46
|
-
const hasEnvFile = node_fs_1.default.existsSync(envFile);
|
|
47
|
-
check(false, hasEnvFile, "env file present", hasEnvFile ? envFile : `${envFile} (none — config may come from process.env)`);
|
|
48
|
-
let endpoint = process.env.COPILOT_PLUGIN_OPTION_ENDPOINT ||
|
|
49
|
-
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||
|
|
50
|
-
process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
51
|
-
if (!endpoint && hasEnvFile) {
|
|
52
|
-
const m = node_fs_1.default
|
|
53
|
-
.readFileSync(envFile, "utf-8")
|
|
54
|
-
.match(/(?:COPILOT_PLUGIN_OPTION_ENDPOINT|OTEL_EXPORTER_OTLP_(?:TRACES_)?ENDPOINT)=(.+)/);
|
|
55
|
-
if (m)
|
|
56
|
-
endpoint = m[1].trim();
|
|
57
|
-
}
|
|
58
|
-
check(true, Boolean(endpoint), "traces endpoint configured", endpoint || "(unset — spans will be dropped)");
|
|
59
|
-
// 4. guard endpoint (optional)
|
|
60
|
-
let guardEp = process.env.PINTA_GUARD_ENDPOINT;
|
|
61
|
-
if (!guardEp && hasEnvFile) {
|
|
62
|
-
const m = node_fs_1.default.readFileSync(envFile, "utf-8").match(/PINTA_GUARD_ENDPOINT=(.+)/);
|
|
63
|
-
if (m)
|
|
64
|
-
guardEp = m[1].trim();
|
|
65
|
-
}
|
|
66
|
-
check(false, Boolean(guardEp), "guard endpoint (optional)", guardEp || "(none — telemetry only, no allow/deny)");
|
|
67
|
-
// --- report ---
|
|
68
|
-
let failed = 0;
|
|
69
|
-
for (const c of checks) {
|
|
70
|
-
const mark = c.ok ? "✅" : c.required ? "❌" : "⚠️ ";
|
|
71
|
-
if (!c.ok && c.required)
|
|
72
|
-
failed++;
|
|
73
|
-
// eslint-disable-next-line no-console
|
|
74
|
-
console.log(`${mark} ${c.label}${c.detail ? ` — ${c.detail}` : ""}`);
|
|
75
|
-
}
|
|
76
|
-
// eslint-disable-next-line no-console
|
|
77
|
-
console.log(`\nsurface (this shell): ${(0, surface_js_1.detectSurface)()}`);
|
|
78
|
-
// eslint-disable-next-line no-console
|
|
79
|
-
console.log(failed === 0 ? "\nhealthy ✅" : `\n${failed} required check(s) failed ❌`);
|
|
80
|
-
process.exit(failed === 0 ? 0 : 1);
|
|
81
|
-
//# sourceMappingURL=doctor.js.map
|
|
1
|
+
"use strict";var k=Object.create;var _=Object.defineProperty;var L=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,R=Object.prototype.hasOwnProperty;var j=(e,o,n,l)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of C(o))!R.call(e,r)&&r!==n&&_(e,r,{get:()=>o[r],enumerable:!(l=L(o,r))||l.enumerable});return e};var a=(e,o,n)=>(n=e!=null?k(x(e)):{},j(o||!e||!e.__esModule?_(n,"default",{value:e,enumerable:!0}):n,e));var s=a(require("node:fs")),t=a(require("node:path"));function P(e=process.env){return e.COPILOT_AGENT_JOB_ID||e.COPILOT_AGENT_SESSION_ID||e.COPILOT_AGENT_PROMPT?"cloud":e.ELECTRON_RUN_AS_NODE||e.VSCODE_IPC_HOOK||e.VSCODE_PID?"ext":"cli"}var T=a(require("os")),E=a(require("path"));function m(){return process.env.COPILOT_HOME||E.default.join(T.default.homedir(),".copilot")}var h=[];function c(e,o,n,l){h.push({ok:o,label:n,detail:l,required:e})}function I(e,o){let n=s.default.readFileSync(e,"utf-8").match(o);return n?n[1].trim():void 0}var g=m(),u=t.default.join(g,"hooks","pinta-copilot.json"),i=t.default.join(g,"pinta-copilot.env"),N=t.default.join(t.default.dirname(t.default.resolve(process.argv[1])),"..","index.js");c(!0,s.default.existsSync(N),"adapter built (dist/index.js)",N);var D=!1,S=`${u} (missing \u2014 run \`npm run install-hooks\`)`;try{let e=JSON.parse(s.default.readFileSync(u,"utf-8")),o=e?.hooks?.PreToolUse?.[0]?.command??"",n=Object.keys(e?.hooks??{}).length;D=o.includes("index.js"),S=`${u} (${n} events)`}catch{}c(!0,D,"hook file installed",S);var p=s.default.existsSync(i);c(!1,p,"env file present",p?i:`${i} (none \u2014 config may come from process.env)`);var O=process.env.COPILOT_PLUGIN_OPTION_ENDPOINT||process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT||process.env.OTEL_EXPORTER_OTLP_ENDPOINT;!O&&p&&(O=I(i,/(?:COPILOT_PLUGIN_OPTION_ENDPOINT|OTEL_EXPORTER_OTLP_(?:TRACES_)?ENDPOINT)=(.+)/));c(!0,!!O,"traces endpoint configured",O||"(unset \u2014 spans will be dropped)");var d=process.env.PINTA_GUARD_ENDPOINT;!d&&p&&(d=I(i,/PINTA_GUARD_ENDPOINT=(.+)/));c(!1,!!d,"guard endpoint (optional)",d||"(none \u2014 telemetry only, no allow/deny)");var f=0;for(let e of h){let o=e.ok?"\u2705":e.required?"\u274C":"\u26A0\uFE0F ";!e.ok&&e.required&&f++,console.log(`${o} ${e.label}${e.detail?` \u2014 ${e.detail}`:""}`)}console.log(`
|
|
2
|
+
surface (this shell): ${P()}`);console.log(f===0?`
|
|
3
|
+
healthy \u2705`:`
|
|
4
|
+
${f} required check(s) failed \u274C`);process.exit(f===0?0:1);
|
|
@@ -1,101 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
/**
|
|
7
|
-
* install-hooks — write the user-level Copilot hook file that points every
|
|
8
|
-
* event at this adapter's `dist/index.js` (D4: direct hook-file install,
|
|
9
|
-
* plugin auto-discovery channel unused).
|
|
10
|
-
*
|
|
11
|
-
* Target: `$COPILOT_HOME/hooks/pinta-copilot.json` (default `~/.copilot/hooks/`).
|
|
12
|
-
* One file fires on BOTH the Copilot CLI and the VS Code extension — no VS Code
|
|
13
|
-
* setting required (`chat.useClaudeHooks` default works, §9.7). Add the same
|
|
14
|
-
* file under a repo's `.github/hooks/` for cloud/repo-scoped runs (out of scope
|
|
15
|
-
* for now).
|
|
16
|
-
*
|
|
17
|
-
* Idempotent: re-running rewrites our file in place. `--uninstall` removes it.
|
|
18
|
-
* Absolute paths are baked in at install time because user-level hooks don't
|
|
19
|
-
* receive `${COPILOT_PLUGIN_ROOT}` substitution.
|
|
20
|
-
*
|
|
21
|
-
* Usage:
|
|
22
|
-
* node dist/tools/install-hooks.js [--dry-run] [--uninstall]
|
|
23
|
-
*/
|
|
24
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
25
|
-
const node_os_1 = __importDefault(require("node:os"));
|
|
26
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
27
|
-
const HOOK_FILE = "pinta-copilot.json";
|
|
28
|
-
// Every event routes to the single adapter binary; it branches internally
|
|
29
|
-
// (telemetry for all; guard deny on PreToolUse + permissionRequest).
|
|
30
|
-
const EVENTS = [
|
|
31
|
-
"SessionStart",
|
|
32
|
-
"SessionEnd",
|
|
33
|
-
"UserPromptSubmit",
|
|
34
|
-
"PreToolUse",
|
|
35
|
-
"PostToolUse",
|
|
36
|
-
"PostToolUseFailure",
|
|
37
|
-
"Stop",
|
|
38
|
-
"SubagentStart",
|
|
39
|
-
"SubagentStop",
|
|
40
|
-
"PreCompact",
|
|
41
|
-
"Notification",
|
|
42
|
-
"permissionRequest",
|
|
43
|
-
];
|
|
44
|
-
function copilotHome() {
|
|
45
|
-
return process.env.COPILOT_HOME || node_path_1.default.join(node_os_1.default.homedir(), ".copilot");
|
|
46
|
-
}
|
|
47
|
-
function hooksDir() {
|
|
48
|
-
return node_path_1.default.join(copilotHome(), "hooks");
|
|
49
|
-
}
|
|
50
|
-
/** Absolute path to dist/index.js. This script runs as dist/tools/install-hooks.js,
|
|
51
|
-
* so resolve relative to the invoked script path (CJS/ESM agnostic). */
|
|
52
|
-
function adapterEntry() {
|
|
53
|
-
const here = node_path_1.default.dirname(node_path_1.default.resolve(process.argv[1])); // .../dist/tools
|
|
54
|
-
return node_path_1.default.join(here, "..", "index.js"); // .../dist/index.js
|
|
55
|
-
}
|
|
56
|
-
function buildHooksFile() {
|
|
57
|
-
const cmd = `${process.execPath} ${adapterEntry()}`;
|
|
58
|
-
const hooks = {};
|
|
59
|
-
for (const ev of EVENTS) {
|
|
60
|
-
// Stamp the registered event name into env as a fail-safe discriminator —
|
|
61
|
-
// some payloads (CLI subagentStart) omit any hook-name field entirely.
|
|
62
|
-
hooks[ev] = [{ type: "command", command: cmd, env: { PINTA_COPILOT_EVENT: ev } }];
|
|
63
|
-
}
|
|
64
|
-
return JSON.stringify({
|
|
65
|
-
version: 1,
|
|
66
|
-
_note: "Managed by @pinta-ai/pinta-copilot install-hooks. Do not edit by hand.",
|
|
67
|
-
hooks,
|
|
68
|
-
}, null, 2) + "\n";
|
|
69
|
-
}
|
|
70
|
-
function main() {
|
|
71
|
-
const args = process.argv.slice(2);
|
|
72
|
-
const dryRun = args.includes("--dry-run");
|
|
73
|
-
const uninstall = args.includes("--uninstall");
|
|
74
|
-
const target = node_path_1.default.join(hooksDir(), HOOK_FILE);
|
|
75
|
-
if (uninstall) {
|
|
76
|
-
if (node_fs_1.default.existsSync(target)) {
|
|
77
|
-
if (!dryRun)
|
|
78
|
-
node_fs_1.default.rmSync(target);
|
|
79
|
-
console.log(`${dryRun ? "[dry-run] would remove" : "removed"}: ${target}`);
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
console.log(`nothing to remove: ${target}`);
|
|
83
|
-
}
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
const content = buildHooksFile();
|
|
87
|
-
if (node_fs_1.default.existsSync(target) && node_fs_1.default.readFileSync(target, "utf-8") === content) {
|
|
88
|
-
console.log(`already up to date: ${target}`);
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
if (dryRun) {
|
|
92
|
-
console.log(`[dry-run] would write: ${target}\n${content}`);
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
node_fs_1.default.mkdirSync(hooksDir(), { recursive: true });
|
|
96
|
-
node_fs_1.default.writeFileSync(target, content);
|
|
97
|
-
console.log(`installed: ${target}`);
|
|
98
|
-
console.log("→ restart the Copilot CLI / reload the VS Code window to load hooks.");
|
|
99
|
-
}
|
|
100
|
-
main();
|
|
101
|
-
//# sourceMappingURL=install-hooks.js.map
|
|
1
|
+
"use strict";var m=Object.create;var a=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var S=Object.getPrototypeOf,h=Object.prototype.hasOwnProperty;var y=(o,n,e,t)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of f(n))!h.call(o,r)&&r!==e&&a(o,r,{get:()=>n[r],enumerable:!(t=g(n,r))||t.enumerable});return o};var c=(o,n,e)=>(e=o!=null?m(S(o)):{},y(n||!o||!o.__esModule?a(e,"default",{value:o,enumerable:!0}):e,o));var i=c(require("node:fs")),s=c(require("node:path"));var l=c(require("os")),u=c(require("path"));function p(){return process.env.COPILOT_HOME||u.default.join(l.default.homedir(),".copilot")}var P="pinta-copilot.json",v=["SessionStart","SessionEnd","UserPromptSubmit","PreToolUse","PostToolUse","PostToolUseFailure","Stop","SubagentStart","SubagentStop","PreCompact","Notification","permissionRequest"];function d(){return s.default.join(p(),"hooks")}function C(){let o=s.default.dirname(s.default.resolve(process.argv[1]));return s.default.join(o,"..","index.js")}function O(){let o=`${process.execPath} ${C()}`,n={};for(let e of v)n[e]=[{type:"command",command:o,env:{PINTA_COPILOT_EVENT:e}}];return JSON.stringify({version:1,_note:"Managed by @pinta-ai/pinta-copilot install-hooks. Do not edit by hand.",hooks:n},null,2)+`
|
|
2
|
+
`}function T(){let o=process.argv.slice(2),n=o.includes("--dry-run"),e=o.includes("--uninstall"),t=s.default.join(d(),P);if(e){i.default.existsSync(t)?(n||i.default.rmSync(t),console.log(`${n?"[dry-run] would remove":"removed"}: ${t}`)):console.log(`nothing to remove: ${t}`);return}let r=O();if(i.default.existsSync(t)&&i.default.readFileSync(t,"utf-8")===r){console.log(`already up to date: ${t}`);return}if(n){console.log(`[dry-run] would write: ${t}
|
|
3
|
+
${r}`);return}i.default.mkdirSync(d(),{recursive:!0}),i.default.writeFileSync(t,r),console.log(`installed: ${t}`),console.log("\u2192 restart the Copilot CLI / reload the VS Code window to load hooks.")}T();
|
package/package.json
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pinta-ai/pinta-copilot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Generic OTLP forwarder + guard for GitHub Copilot hook events (CLI + VS Code extension)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"import": "./dist/index.mjs",
|
|
9
|
+
"require": "./dist/index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
6
12
|
"license": "PolyForm-Noncommercial-1.0.0",
|
|
7
13
|
"files": [
|
|
8
14
|
"dist",
|
|
@@ -20,10 +26,13 @@
|
|
|
20
26
|
},
|
|
21
27
|
"scripts": {
|
|
22
28
|
"bump": "node scripts/bump.mjs",
|
|
23
|
-
"build": "tsc",
|
|
29
|
+
"build": "tsc --noEmit && npm run build:cjs && npm run build:esm",
|
|
30
|
+
"build:cjs": "esbuild src/index.ts src/tools/doctor.ts src/tools/install-hooks.ts --bundle --platform=node --format=cjs --target=node18 --minify --outbase=src --outdir=dist",
|
|
31
|
+
"build:esm": "esbuild src/index.mts --bundle --platform=node --format=esm --target=node18 --minify --banner:js=\"import{createRequire as __pintaCreateRequire}from 'node:module';const require=__pintaCreateRequire(import.meta.url);\" --outfile=dist/index.mjs",
|
|
24
32
|
"dev": "tsc --watch",
|
|
25
33
|
"test": "vitest run",
|
|
26
34
|
"test:watch": "vitest",
|
|
35
|
+
"smoke:import": "node scripts/smoke-import.mjs",
|
|
27
36
|
"mock-server": "npx tsx tools/mock-server.ts",
|
|
28
37
|
"install-hooks": "node dist/tools/install-hooks.js",
|
|
29
38
|
"uninstall-hooks": "node dist/tools/install-hooks.js --uninstall",
|
|
@@ -31,9 +40,15 @@
|
|
|
31
40
|
"prepublishOnly": "npm run build"
|
|
32
41
|
},
|
|
33
42
|
"devDependencies": {
|
|
43
|
+
"@pinta-ai/core": "^0.3.0",
|
|
34
44
|
"@types/node": "^22.0.0",
|
|
45
|
+
"esbuild": "^0.24.0",
|
|
35
46
|
"tsx": "^4.0.0",
|
|
36
47
|
"typescript": "^5.7.0",
|
|
37
48
|
"vitest": "^2.1.0"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"registry": "https://registry.npmjs.org",
|
|
52
|
+
"access": "public"
|
|
38
53
|
}
|
|
39
54
|
}
|
package/dist/core/config.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Runtime config. Endpoint/headers come from OTEL_EXPORTER_OTLP_* env vars
|
|
3
|
-
* (loaded from ~/.copilot/pinta-copilot.env at startup) — not in this struct.
|
|
4
|
-
*
|
|
5
|
-
* pinta-copilot is installed as a direct hook file (D4), so the data dir
|
|
6
|
-
* (trace + retry-queue) must be a STABLE location independent of cwd —
|
|
7
|
-
* otherwise the per-turn trace written by UserPromptSubmit can't be read back
|
|
8
|
-
* by the following PreToolUse if cwd differs. We anchor it under the Copilot
|
|
9
|
-
* home (`$COPILOT_HOME` or `~/.copilot`).
|
|
10
|
-
*/
|
|
11
|
-
export interface PintaConfig {
|
|
12
|
-
pluginData: string;
|
|
13
|
-
tracePath: string;
|
|
14
|
-
}
|
|
15
|
-
export declare function loadConfig(): PintaConfig;
|
package/dist/core/config.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.loadConfig = loadConfig;
|
|
7
|
-
const os_1 = __importDefault(require("os"));
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
function copilotHome() {
|
|
10
|
-
return process.env.COPILOT_HOME || path_1.default.join(os_1.default.homedir(), ".copilot");
|
|
11
|
-
}
|
|
12
|
-
function loadConfig() {
|
|
13
|
-
const pluginData = process.env.COPILOT_PLUGIN_DATA || path_1.default.join(copilotHome(), "pinta-copilot-data");
|
|
14
|
-
return {
|
|
15
|
-
pluginData,
|
|
16
|
-
tracePath: path_1.default.join(pluginData, "trace.json"),
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=config.js.map
|
package/dist/core/config.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":";;;;;AAsBA,gCAOC;AA7BD,4CAAoB;AACpB,gDAAwB;AAiBxB,SAAS,WAAW;IAClB,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AACzE,CAAC;AAED,SAAgB,UAAU;IACxB,MAAM,UAAU,GACd,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,oBAAoB,CAAC,CAAC;IACpF,OAAO;QACL,UAAU;QACV,SAAS,EAAE,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC;KAC/C,CAAC;AACJ,CAAC"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bridge Claude Code's userConfig env vars (CLAUDE_PLUGIN_OPTION_*) to the
|
|
3
|
-
* OTel SDK standard env vars (OTEL_EXPORTER_OTLP_*).
|
|
4
|
-
*
|
|
5
|
-
* Claude Code maps each plugin.json `userConfig.<key>` to a corresponding
|
|
6
|
-
* `CLAUDE_PLUGIN_OPTION_<KEY>` env var on hook spawn. We keep the user-
|
|
7
|
-
* facing names friendly (`endpoint`, `api_key`) and translate them into the
|
|
8
|
-
* canonical OTel env names so transport.ts (and any future OTel SDK adoption)
|
|
9
|
-
* can read them via the OTel-spec names.
|
|
10
|
-
*
|
|
11
|
-
* The user-facing `endpoint` is treated as a *full* OTLP/HTTP traces URL
|
|
12
|
-
* (e.g., `http://127.0.0.1:5147/v1/traces`), so we map it to
|
|
13
|
-
* `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` (signal-specific full URL per OTel
|
|
14
|
-
* spec) rather than `OTEL_EXPORTER_OTLP_ENDPOINT` (which is a base URL the
|
|
15
|
-
* SDK appends `/v1/traces` to). This way both the OTel SDK (when used) and
|
|
16
|
-
* pinta-cc's hand-written transport agree on the URL without any path
|
|
17
|
-
* manipulation downstream.
|
|
18
|
-
*
|
|
19
|
-
* Pinta Manager auto-injects `CLAUDE_PLUGIN_OPTION_*` via Claude Code's
|
|
20
|
-
* settings.json. OSS users fill them in via the `/plugin install` UI.
|
|
21
|
-
*
|
|
22
|
-
* Existing OTEL_EXPORTER_OTLP_TRACES_ENDPOINT / HEADERS take precedence
|
|
23
|
-
* (explicit override).
|
|
24
|
-
*/
|
|
25
|
-
export declare function bridgeUserConfigToOtelEnv(): void;
|