@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/dist/core/retry-queue.js
DELETED
|
@@ -1,127 +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.RetryQueue = void 0;
|
|
7
|
-
const fs_1 = __importDefault(require("fs"));
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const MAX_ENTRIES = 1000;
|
|
10
|
-
const LOCK_TIMEOUT_MS = 50;
|
|
11
|
-
const LOCK_POLL_MS = 5;
|
|
12
|
-
class RetryQueue {
|
|
13
|
-
filePath;
|
|
14
|
-
lockPath;
|
|
15
|
-
constructor(pluginData) {
|
|
16
|
-
this.filePath = path_1.default.join(pluginData, "failed-spans.jsonl");
|
|
17
|
-
this.lockPath = this.filePath + ".lock";
|
|
18
|
-
}
|
|
19
|
-
/** Append a single payload. Best-effort: any IO error is swallowed (logged to stderr). */
|
|
20
|
-
enqueue(payload) {
|
|
21
|
-
try {
|
|
22
|
-
fs_1.default.mkdirSync(path_1.default.dirname(this.filePath), { recursive: true });
|
|
23
|
-
const line = JSON.stringify({ savedAt: new Date().toISOString(), payload }) + "\n";
|
|
24
|
-
fs_1.default.appendFileSync(this.filePath, line);
|
|
25
|
-
this.trim();
|
|
26
|
-
}
|
|
27
|
-
catch (err) {
|
|
28
|
-
process.stderr.write(`[pinta-copilot] retry-queue enqueue failed: ${err}\n`);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Read all entries oldest-first. Returns [] if the file does not exist or is unreadable.
|
|
33
|
-
* Does NOT delete the file — callers handle persistence via `rewrite`.
|
|
34
|
-
*/
|
|
35
|
-
readAll() {
|
|
36
|
-
try {
|
|
37
|
-
const raw = fs_1.default.readFileSync(this.filePath, "utf-8");
|
|
38
|
-
const out = [];
|
|
39
|
-
for (const line of raw.split("\n")) {
|
|
40
|
-
if (!line.trim())
|
|
41
|
-
continue;
|
|
42
|
-
try {
|
|
43
|
-
out.push(JSON.parse(line));
|
|
44
|
-
}
|
|
45
|
-
catch {
|
|
46
|
-
// skip malformed line
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return out;
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
return [];
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
/** Replace the queue with the given entries (or delete the file when empty). */
|
|
56
|
-
rewrite(entries) {
|
|
57
|
-
try {
|
|
58
|
-
if (entries.length === 0) {
|
|
59
|
-
if (fs_1.default.existsSync(this.filePath))
|
|
60
|
-
fs_1.default.unlinkSync(this.filePath);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
fs_1.default.mkdirSync(path_1.default.dirname(this.filePath), { recursive: true });
|
|
64
|
-
fs_1.default.writeFileSync(this.filePath, entries.map((e) => JSON.stringify(e)).join("\n") + "\n");
|
|
65
|
-
}
|
|
66
|
-
catch (err) {
|
|
67
|
-
process.stderr.write(`[pinta-copilot] retry-queue rewrite failed: ${err}\n`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Try to acquire the lock for ~LOCK_TIMEOUT_MS. Returns true on success.
|
|
72
|
-
* Caller MUST call `release()` if true is returned.
|
|
73
|
-
*/
|
|
74
|
-
tryAcquireLock() {
|
|
75
|
-
const start = Date.now();
|
|
76
|
-
fs_1.default.mkdirSync(path_1.default.dirname(this.lockPath), { recursive: true });
|
|
77
|
-
while (Date.now() - start < LOCK_TIMEOUT_MS) {
|
|
78
|
-
try {
|
|
79
|
-
const fd = fs_1.default.openSync(this.lockPath, "wx");
|
|
80
|
-
fs_1.default.writeSync(fd, String(process.pid));
|
|
81
|
-
fs_1.default.closeSync(fd);
|
|
82
|
-
return true;
|
|
83
|
-
}
|
|
84
|
-
catch (err) {
|
|
85
|
-
if (err?.code !== "EEXIST") {
|
|
86
|
-
process.stderr.write(`[pinta-copilot] retry-queue lock open failed: ${err}\n`);
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
// Stale lock detection: if mtime is older than 30s, drop it.
|
|
90
|
-
try {
|
|
91
|
-
const st = fs_1.default.statSync(this.lockPath);
|
|
92
|
-
if (Date.now() - st.mtimeMs > 30_000) {
|
|
93
|
-
fs_1.default.unlinkSync(this.lockPath);
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
/* ignore */
|
|
99
|
-
}
|
|
100
|
-
const wait = LOCK_POLL_MS;
|
|
101
|
-
const end = Date.now() + wait;
|
|
102
|
-
while (Date.now() < end) {
|
|
103
|
-
/* spin briefly; sync only because hooks are short-lived */
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return false;
|
|
108
|
-
}
|
|
109
|
-
release() {
|
|
110
|
-
try {
|
|
111
|
-
fs_1.default.unlinkSync(this.lockPath);
|
|
112
|
-
}
|
|
113
|
-
catch {
|
|
114
|
-
/* already gone */
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
trim() {
|
|
118
|
-
const entries = this.readAll();
|
|
119
|
-
if (entries.length <= MAX_ENTRIES)
|
|
120
|
-
return;
|
|
121
|
-
const drop = entries.length - MAX_ENTRIES;
|
|
122
|
-
process.stderr.write(`[pinta-copilot] retry-queue full, dropping ${drop} oldest entries\n`);
|
|
123
|
-
this.rewrite(entries.slice(drop));
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
exports.RetryQueue = RetryQueue;
|
|
127
|
-
//# sourceMappingURL=retry-queue.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"retry-queue.js","sourceRoot":"","sources":["../../src/core/retry-queue.ts"],"names":[],"mappings":"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"}
|
package/dist/core/surface.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Runtime surface detection — which GitHub Copilot host spawned this hook.
|
|
3
|
-
*
|
|
4
|
-
* A single `pinta-copilot` adapter / a single `~/.copilot/hooks/` file fires
|
|
5
|
-
* across three surfaces (BACKGROUND_RESEARCH §9, D11/D14). We label every span
|
|
6
|
-
* with `copilot.surface` so the backend can distinguish them. The hook is a
|
|
7
|
-
* spawned child process, so we read the inherited `process.env`.
|
|
8
|
-
*
|
|
9
|
-
* Detection is empirically validated (2026-06-08, KU9):
|
|
10
|
-
* - cloud: Copilot cloud agent injects `COPILOT_AGENT_*`.
|
|
11
|
-
* - ext : the VS Code extension host sets `ELECTRON_RUN_AS_NODE` /
|
|
12
|
-
* `VSCODE_PID` / `VSCODE_IPC_HOOK` on its node children.
|
|
13
|
-
* - cli : neither.
|
|
14
|
-
*
|
|
15
|
-
* ⚠️ `TERM_PROGRAM` is deliberately NOT used: VS Code's *integrated terminal*
|
|
16
|
-
* sets `TERM_PROGRAM=vscode` for a standalone CLI run (would misclassify as
|
|
17
|
-
* ext), and a real ext host inherits whatever launched VS Code (e.g. ghostty)
|
|
18
|
-
* — unreliable in both directions. `ELECTRON_RUN_AS_NODE` is the robust signal.
|
|
19
|
-
*/
|
|
20
|
-
export type Surface = "cli" | "cloud" | "ext";
|
|
21
|
-
export declare function detectSurface(env?: NodeJS.ProcessEnv): Surface;
|
package/dist/core/surface.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.detectSurface = detectSurface;
|
|
4
|
-
function detectSurface(env = process.env) {
|
|
5
|
-
if (env.COPILOT_AGENT_JOB_ID || env.COPILOT_AGENT_SESSION_ID || env.COPILOT_AGENT_PROMPT) {
|
|
6
|
-
return "cloud";
|
|
7
|
-
}
|
|
8
|
-
if (env.ELECTRON_RUN_AS_NODE || env.VSCODE_IPC_HOOK || env.VSCODE_PID) {
|
|
9
|
-
return "ext";
|
|
10
|
-
}
|
|
11
|
-
return "cli";
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=surface.js.map
|
package/dist/core/surface.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"surface.js","sourceRoot":"","sources":["../../src/core/surface.ts"],"names":[],"mappings":";;AAqBA,sCAQC;AARD,SAAgB,aAAa,CAAC,MAAyB,OAAO,CAAC,GAAG;IAChE,IAAI,GAAG,CAAC,oBAAoB,IAAI,GAAG,CAAC,wBAAwB,IAAI,GAAG,CAAC,oBAAoB,EAAE,CAAC;QACzF,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,GAAG,CAAC,oBAAoB,IAAI,GAAG,CAAC,eAAe,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QACtE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/core/trace.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { PintaConfig } from "./config.js";
|
|
2
|
-
/**
|
|
3
|
-
* Per-turn trace correlation, keyed by `session_id`.
|
|
4
|
-
*
|
|
5
|
-
* `UserPromptSubmit` starts a new ULID trace for its session; subsequent hooks
|
|
6
|
-
* in the same turn reuse it. Keying by session_id (not a single global file)
|
|
7
|
-
* is required because CLI and the VS Code extension can run concurrently and
|
|
8
|
-
* each emits its own session — verified that `session_id` is stable across a
|
|
9
|
-
* turn on both surfaces (H10). The store is a `{ [sessionId]: traceId }` map.
|
|
10
|
-
*/
|
|
11
|
-
export declare class TraceManager {
|
|
12
|
-
private tracePath;
|
|
13
|
-
constructor(config: PintaConfig);
|
|
14
|
-
private readMap;
|
|
15
|
-
private writeMap;
|
|
16
|
-
/** Start (and persist) a new trace for this session. */
|
|
17
|
-
newTrace(sessionId?: string): string;
|
|
18
|
-
/** Current trace for this session; create one if none exists yet. */
|
|
19
|
-
currentTrace(sessionId?: string): string;
|
|
20
|
-
}
|
package/dist/core/trace.js
DELETED
|
@@ -1,80 +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.TraceManager = void 0;
|
|
7
|
-
const fs_1 = __importDefault(require("fs"));
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const crypto_1 = __importDefault(require("crypto"));
|
|
10
|
-
const CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
11
|
-
function generateUlid() {
|
|
12
|
-
const now = Date.now();
|
|
13
|
-
let ts = "";
|
|
14
|
-
let t = now;
|
|
15
|
-
for (let i = 0; i < 10; i++) {
|
|
16
|
-
ts = CROCKFORD[t & 31] + ts;
|
|
17
|
-
t = Math.floor(t / 32);
|
|
18
|
-
}
|
|
19
|
-
const rand = crypto_1.default.randomBytes(10);
|
|
20
|
-
let r = "";
|
|
21
|
-
for (let i = 0; i < 10; i++)
|
|
22
|
-
r += CROCKFORD[rand[i] & 31];
|
|
23
|
-
while (r.length < 16)
|
|
24
|
-
r += CROCKFORD[0];
|
|
25
|
-
return ts + r;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Per-turn trace correlation, keyed by `session_id`.
|
|
29
|
-
*
|
|
30
|
-
* `UserPromptSubmit` starts a new ULID trace for its session; subsequent hooks
|
|
31
|
-
* in the same turn reuse it. Keying by session_id (not a single global file)
|
|
32
|
-
* is required because CLI and the VS Code extension can run concurrently and
|
|
33
|
-
* each emits its own session — verified that `session_id` is stable across a
|
|
34
|
-
* turn on both surfaces (H10). The store is a `{ [sessionId]: traceId }` map.
|
|
35
|
-
*/
|
|
36
|
-
class TraceManager {
|
|
37
|
-
tracePath;
|
|
38
|
-
constructor(config) {
|
|
39
|
-
this.tracePath = config.tracePath;
|
|
40
|
-
}
|
|
41
|
-
readMap() {
|
|
42
|
-
try {
|
|
43
|
-
const data = JSON.parse(fs_1.default.readFileSync(this.tracePath, "utf-8"));
|
|
44
|
-
// Back-compat: a bare { traceId } file → treat as no sessions.
|
|
45
|
-
if (data && typeof data === "object" && !("traceId" in data)) {
|
|
46
|
-
return data;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
catch {
|
|
50
|
-
// no/invalid file
|
|
51
|
-
}
|
|
52
|
-
return {};
|
|
53
|
-
}
|
|
54
|
-
writeMap(map) {
|
|
55
|
-
fs_1.default.mkdirSync(path_1.default.dirname(this.tracePath), { recursive: true });
|
|
56
|
-
// Cap stored sessions to avoid unbounded growth (keep most recent ~200).
|
|
57
|
-
const entries = Object.entries(map);
|
|
58
|
-
const capped = entries.length > 200 ? Object.fromEntries(entries.slice(-200)) : map;
|
|
59
|
-
fs_1.default.writeFileSync(this.tracePath, JSON.stringify(capped));
|
|
60
|
-
}
|
|
61
|
-
/** Start (and persist) a new trace for this session. */
|
|
62
|
-
newTrace(sessionId) {
|
|
63
|
-
const traceId = generateUlid();
|
|
64
|
-
const key = sessionId || "default";
|
|
65
|
-
const map = this.readMap();
|
|
66
|
-
map[key] = traceId;
|
|
67
|
-
this.writeMap(map);
|
|
68
|
-
return traceId;
|
|
69
|
-
}
|
|
70
|
-
/** Current trace for this session; create one if none exists yet. */
|
|
71
|
-
currentTrace(sessionId) {
|
|
72
|
-
const key = sessionId || "default";
|
|
73
|
-
const existing = this.readMap()[key];
|
|
74
|
-
if (existing)
|
|
75
|
-
return existing;
|
|
76
|
-
return this.newTrace(sessionId);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
exports.TraceManager = TraceManager;
|
|
80
|
-
//# sourceMappingURL=trace.js.map
|
package/dist/core/trace.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../src/core/trace.ts"],"names":[],"mappings":"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"}
|
package/dist/core/transport.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { OtlpPayload } from "./otlp.js";
|
|
2
|
-
import type { PintaConfig } from "./config.js";
|
|
3
|
-
export declare class Transport {
|
|
4
|
-
private queue;
|
|
5
|
-
constructor(config: PintaConfig);
|
|
6
|
-
/**
|
|
7
|
-
* POST a single payload. On any failure, enqueue it for the next hook to retry.
|
|
8
|
-
* Silent disable when no endpoint is configured.
|
|
9
|
-
*/
|
|
10
|
-
send(payload: OtlpPayload): Promise<void>;
|
|
11
|
-
/**
|
|
12
|
-
* Best-effort drain. Acquires the lock, reads the queue, attempts a single
|
|
13
|
-
* batched POST. On failure, leaves the queue untouched.
|
|
14
|
-
* Silent disable when no endpoint is configured.
|
|
15
|
-
*/
|
|
16
|
-
flush(): Promise<void>;
|
|
17
|
-
private post;
|
|
18
|
-
}
|
package/dist/core/transport.js
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Transport = void 0;
|
|
4
|
-
const retry_queue_js_1 = require("./retry-queue.js");
|
|
5
|
-
const otlp_js_1 = require("./otlp.js");
|
|
6
|
-
const TIMEOUT_MS = 5000;
|
|
7
|
-
function parseHeadersEnv(raw) {
|
|
8
|
-
if (!raw)
|
|
9
|
-
return {};
|
|
10
|
-
const out = {};
|
|
11
|
-
for (const pair of raw.split(",")) {
|
|
12
|
-
const [k, ...rest] = pair.split("=");
|
|
13
|
-
if (k && rest.length > 0)
|
|
14
|
-
out[k.trim()] = rest.join("=").trim();
|
|
15
|
-
}
|
|
16
|
-
return out;
|
|
17
|
-
}
|
|
18
|
-
function getOptions() {
|
|
19
|
-
// Config is namespaced to COPILOT_PLUGIN_OPTION_* so it never collides with
|
|
20
|
-
// Copilot's own native OTel feature, which reads the standard
|
|
21
|
-
// OTEL_EXPORTER_OTLP_* vars. COPILOT_PLUGIN_OPTION_ENDPOINT is the full
|
|
22
|
-
// traces URL. OTEL_EXPORTER_OTLP_* are honored as a lower-priority fallback
|
|
23
|
-
// for OSS users who prefer the standard names. (ENDPOINT, without /v1/traces,
|
|
24
|
-
// is a base URL we append to.)
|
|
25
|
-
const fullEndpoint = process.env.COPILOT_PLUGIN_OPTION_ENDPOINT ||
|
|
26
|
-
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;
|
|
27
|
-
const baseEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
28
|
-
let endpoint;
|
|
29
|
-
if (fullEndpoint) {
|
|
30
|
-
endpoint = fullEndpoint.replace(/\/+$/, "");
|
|
31
|
-
}
|
|
32
|
-
else if (baseEndpoint) {
|
|
33
|
-
endpoint = baseEndpoint.replace(/\/+$/, "") + "/v1/traces";
|
|
34
|
-
}
|
|
35
|
-
if (!endpoint)
|
|
36
|
-
return null;
|
|
37
|
-
return {
|
|
38
|
-
endpoint,
|
|
39
|
-
headers: parseHeadersEnv(process.env.COPILOT_PLUGIN_OPTION_HEADERS || process.env.OTEL_EXPORTER_OTLP_HEADERS),
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
class Transport {
|
|
43
|
-
queue;
|
|
44
|
-
constructor(config) {
|
|
45
|
-
this.queue = new retry_queue_js_1.RetryQueue(config.pluginData);
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* POST a single payload. On any failure, enqueue it for the next hook to retry.
|
|
49
|
-
* Silent disable when no endpoint is configured.
|
|
50
|
-
*/
|
|
51
|
-
async send(payload) {
|
|
52
|
-
const opts = getOptions();
|
|
53
|
-
if (!opts)
|
|
54
|
-
return; // Silent disable when no endpoint configured
|
|
55
|
-
const ok = await this.post(payload, opts);
|
|
56
|
-
if (!ok)
|
|
57
|
-
this.queue.enqueue(payload);
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Best-effort drain. Acquires the lock, reads the queue, attempts a single
|
|
61
|
-
* batched POST. On failure, leaves the queue untouched.
|
|
62
|
-
* Silent disable when no endpoint is configured.
|
|
63
|
-
*/
|
|
64
|
-
async flush() {
|
|
65
|
-
const opts = getOptions();
|
|
66
|
-
if (!opts)
|
|
67
|
-
return;
|
|
68
|
-
if (!this.queue.tryAcquireLock())
|
|
69
|
-
return;
|
|
70
|
-
try {
|
|
71
|
-
const entries = this.queue.readAll();
|
|
72
|
-
if (entries.length === 0)
|
|
73
|
-
return;
|
|
74
|
-
const merged = (0, otlp_js_1.mergeBatch)(entries.map((e) => e.payload));
|
|
75
|
-
const ok = await this.post(merged, opts);
|
|
76
|
-
if (ok)
|
|
77
|
-
this.queue.rewrite([]);
|
|
78
|
-
}
|
|
79
|
-
finally {
|
|
80
|
-
this.queue.release();
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
async post(payload, opts) {
|
|
84
|
-
const ctrl = new AbortController();
|
|
85
|
-
const timer = setTimeout(() => ctrl.abort(), TIMEOUT_MS);
|
|
86
|
-
try {
|
|
87
|
-
// opts.endpoint is the full traces URL — no path append.
|
|
88
|
-
const res = await fetch(opts.endpoint, {
|
|
89
|
-
method: "POST",
|
|
90
|
-
headers: {
|
|
91
|
-
"Content-Type": "application/json",
|
|
92
|
-
...opts.headers,
|
|
93
|
-
},
|
|
94
|
-
body: JSON.stringify(payload),
|
|
95
|
-
signal: ctrl.signal,
|
|
96
|
-
});
|
|
97
|
-
if (!res.ok) {
|
|
98
|
-
let body = "";
|
|
99
|
-
try {
|
|
100
|
-
body = (await res.text()).slice(0, 200);
|
|
101
|
-
}
|
|
102
|
-
catch {
|
|
103
|
-
/* ignore */
|
|
104
|
-
}
|
|
105
|
-
const hint = res.status === 401 || res.status === 403
|
|
106
|
-
? " — check OTEL_EXPORTER_OTLP_HEADERS (relay token)"
|
|
107
|
-
: res.status === 404
|
|
108
|
-
? " — check OTEL_EXPORTER_OTLP_TRACES_ENDPOINT path"
|
|
109
|
-
: res.status >= 500
|
|
110
|
-
? " — collector may be down"
|
|
111
|
-
: "";
|
|
112
|
-
process.stderr.write(`[pinta-copilot] OTLP POST ${res.status} ${opts.endpoint}${hint}${body ? ` body=${body}` : ""}\n`);
|
|
113
|
-
return false;
|
|
114
|
-
}
|
|
115
|
-
return true;
|
|
116
|
-
}
|
|
117
|
-
catch (err) {
|
|
118
|
-
process.stderr.write(`[pinta-copilot] OTLP POST failed: ${err.message ?? String(err)}\n`);
|
|
119
|
-
return false;
|
|
120
|
-
}
|
|
121
|
-
finally {
|
|
122
|
-
clearTimeout(timer);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
exports.Transport = Transport;
|
|
127
|
-
//# sourceMappingURL=transport.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/core/transport.ts"],"names":[],"mappings":"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"}
|
package/dist/core/types.d.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
export interface RawEvent {
|
|
2
|
-
[key: string]: unknown;
|
|
3
|
-
}
|
|
4
|
-
/**
|
|
5
|
-
* Resolve the hook event name. Copilot is inconsistent across surfaces/events:
|
|
6
|
-
* - snake `hook_event_name` (CLI/ext most events)
|
|
7
|
-
* - camel `hookEventName`
|
|
8
|
-
* - `hookName` (CLI permissionRequest)
|
|
9
|
-
* - NONE AT ALL — CLI `subagentStart` ships only camelCase agent fields with
|
|
10
|
-
* no event-name key (verified 2026-06-08, real adapter e2e).
|
|
11
|
-
*
|
|
12
|
-
* Final fallback: `PINTA_COPILOT_EVENT`, which `install-hooks` stamps into each
|
|
13
|
-
* hook entry's `env` block (Copilot passes hook `env` through to the process —
|
|
14
|
-
* H4). So we always know the event even when the payload omits it. The payload
|
|
15
|
-
* discriminator wins when present.
|
|
16
|
-
*/
|
|
17
|
-
export declare function eventName(e: RawEvent): string | undefined;
|
|
18
|
-
/** session id — `session_id` (CLI/ext) or `sessionId` (permissionRequest camel). */
|
|
19
|
-
export declare function sessionId(e: RawEvent): string | undefined;
|
|
20
|
-
/** tool name — `tool_name` (snake) or `toolName` (camel/permissionRequest). */
|
|
21
|
-
export declare function toolName(e: RawEvent): string | undefined;
|
|
22
|
-
/** tool input — `tool_input` (snake) / `toolArgs` / `toolInput` (camel). */
|
|
23
|
-
export declare function toolInput(e: RawEvent): unknown;
|
|
24
|
-
export type EventKind = "SessionStart" | "SessionEnd" | "UserPromptSubmit" | "PreToolUse" | "PostToolUse" | "PostToolUseFailure" | "Stop" | "SubagentStart" | "SubagentStop" | "PreCompact" | "Notification" | "PermissionRequest" | "ErrorOccurred" | "Unknown";
|
|
25
|
-
export declare function classify(e: RawEvent): EventKind;
|
|
26
|
-
/** Guard runs on the two tool-gating events. PreToolUse fires on all surfaces;
|
|
27
|
-
* PermissionRequest is CLI-only (ext has no such event → entry is ignored). */
|
|
28
|
-
export declare function isGuardEvent(kind: EventKind): boolean;
|
|
29
|
-
export declare function isInternalTool(name: string | undefined): boolean;
|
|
30
|
-
/** preToolUse decision-control — honored by CLI, ext, and cloud. */
|
|
31
|
-
export interface PreToolUseDenyOutput {
|
|
32
|
-
hookSpecificOutput: {
|
|
33
|
-
hookEventName: "PreToolUse";
|
|
34
|
-
permissionDecision: "deny";
|
|
35
|
-
permissionDecisionReason: string;
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
/** permissionRequest decision-control — CLI permission service only. */
|
|
39
|
-
export interface PermissionRequestDenyOutput {
|
|
40
|
-
behavior: "deny";
|
|
41
|
-
message: string;
|
|
42
|
-
interrupt?: boolean;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Render the deny decision in the format the firing event expects, or null if
|
|
46
|
-
* the event isn't a gating event. preToolUse uses `permissionDecision`; the CLI
|
|
47
|
-
* permission service uses `behavior`/`message`.
|
|
48
|
-
*/
|
|
49
|
-
export declare function formatDeny(kind: EventKind, reason: string): string | null;
|
package/dist/core/types.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// --- GitHub Copilot hook event types (CLI + VS Code extension + cloud) ---
|
|
3
|
-
//
|
|
4
|
-
// One stdin/stdout contract is shared by all three surfaces, but the payload
|
|
5
|
-
// SHAPE differs (verified 2026-06-08, BACKGROUND_RESEARCH §9.6/§9.7):
|
|
6
|
-
//
|
|
7
|
-
// • CLI : snake_case, discriminator `hook_event_name`; PostToolUse carries
|
|
8
|
-
// `tool_result` (structured); NO `tool_use_id`; `transcript_path`
|
|
9
|
-
// only on Stop; SessionStart has `initial_prompt`; Stop has
|
|
10
|
-
// `stop_reason`; subagent uses `agent_name`/`agent_display_name`.
|
|
11
|
-
// permissionRequest is a DIFFERENT schema: camelCase with
|
|
12
|
-
// discriminator `hookName` + `toolName`/`toolInput`/`permissionSuggestions`.
|
|
13
|
-
// • ext : snake_case, `hook_event_name`; Claude-Code-shaped — `tool_response`,
|
|
14
|
-
// `tool_use_id` present, `transcript_path` on every event, Stop has
|
|
15
|
-
// `stop_hook_active`, subagent uses `agent_id`/`agent_type`,
|
|
16
|
-
// SessionStart has `model`. Does NOT fire permissionRequest /
|
|
17
|
-
// SessionEnd / PostToolUseFailure / ErrorOccurred.
|
|
18
|
-
//
|
|
19
|
-
// Span building uses Bronze flattening (every top-level field → `copilot.<key>`),
|
|
20
|
-
// so we do NOT enumerate every field. We only normalize the handful used for
|
|
21
|
-
// routing / guard / trace, absorbing both casings + both discriminator keys.
|
|
22
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
-
exports.eventName = eventName;
|
|
24
|
-
exports.sessionId = sessionId;
|
|
25
|
-
exports.toolName = toolName;
|
|
26
|
-
exports.toolInput = toolInput;
|
|
27
|
-
exports.classify = classify;
|
|
28
|
-
exports.isGuardEvent = isGuardEvent;
|
|
29
|
-
exports.isInternalTool = isInternalTool;
|
|
30
|
-
exports.formatDeny = formatDeny;
|
|
31
|
-
function str(v) {
|
|
32
|
-
return typeof v === "string" ? v : undefined;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Resolve the hook event name. Copilot is inconsistent across surfaces/events:
|
|
36
|
-
* - snake `hook_event_name` (CLI/ext most events)
|
|
37
|
-
* - camel `hookEventName`
|
|
38
|
-
* - `hookName` (CLI permissionRequest)
|
|
39
|
-
* - NONE AT ALL — CLI `subagentStart` ships only camelCase agent fields with
|
|
40
|
-
* no event-name key (verified 2026-06-08, real adapter e2e).
|
|
41
|
-
*
|
|
42
|
-
* Final fallback: `PINTA_COPILOT_EVENT`, which `install-hooks` stamps into each
|
|
43
|
-
* hook entry's `env` block (Copilot passes hook `env` through to the process —
|
|
44
|
-
* H4). So we always know the event even when the payload omits it. The payload
|
|
45
|
-
* discriminator wins when present.
|
|
46
|
-
*/
|
|
47
|
-
function eventName(e) {
|
|
48
|
-
return (str(e.hook_event_name) ??
|
|
49
|
-
str(e.hookEventName) ??
|
|
50
|
-
str(e.hookName) ??
|
|
51
|
-
(process.env.PINTA_COPILOT_EVENT || undefined));
|
|
52
|
-
}
|
|
53
|
-
/** session id — `session_id` (CLI/ext) or `sessionId` (permissionRequest camel). */
|
|
54
|
-
function sessionId(e) {
|
|
55
|
-
return str(e.session_id) ?? str(e.sessionId);
|
|
56
|
-
}
|
|
57
|
-
/** tool name — `tool_name` (snake) or `toolName` (camel/permissionRequest). */
|
|
58
|
-
function toolName(e) {
|
|
59
|
-
return str(e.tool_name) ?? str(e.toolName);
|
|
60
|
-
}
|
|
61
|
-
/** tool input — `tool_input` (snake) / `toolArgs` / `toolInput` (camel). */
|
|
62
|
-
function toolInput(e) {
|
|
63
|
-
return e.tool_input ?? e.toolArgs ?? e.toolInput;
|
|
64
|
-
}
|
|
65
|
-
const KIND_MAP = {
|
|
66
|
-
sessionstart: "SessionStart",
|
|
67
|
-
sessionend: "SessionEnd",
|
|
68
|
-
userpromptsubmit: "UserPromptSubmit",
|
|
69
|
-
userpromptsubmitted: "UserPromptSubmit",
|
|
70
|
-
pretooluse: "PreToolUse",
|
|
71
|
-
posttooluse: "PostToolUse",
|
|
72
|
-
posttoolusefailure: "PostToolUseFailure",
|
|
73
|
-
stop: "Stop",
|
|
74
|
-
agentstop: "Stop",
|
|
75
|
-
subagentstart: "SubagentStart",
|
|
76
|
-
subagentstop: "SubagentStop",
|
|
77
|
-
precompact: "PreCompact",
|
|
78
|
-
notification: "Notification",
|
|
79
|
-
permissionrequest: "PermissionRequest",
|
|
80
|
-
erroroccurred: "ErrorOccurred",
|
|
81
|
-
};
|
|
82
|
-
function classify(e) {
|
|
83
|
-
const n = eventName(e);
|
|
84
|
-
if (!n)
|
|
85
|
-
return "Unknown";
|
|
86
|
-
return KIND_MAP[n.toLowerCase()] ?? "Unknown";
|
|
87
|
-
}
|
|
88
|
-
/** Guard runs on the two tool-gating events. PreToolUse fires on all surfaces;
|
|
89
|
-
* PermissionRequest is CLI-only (ext has no such event → entry is ignored). */
|
|
90
|
-
function isGuardEvent(kind) {
|
|
91
|
-
return kind === "PreToolUse" || kind === "PermissionRequest";
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Internal agent tools that are NOT subject to guard enforcement — they get
|
|
95
|
-
* telemetry only (decision: per user policy 2026-06-08). `report_intent` and
|
|
96
|
-
* `ask_user` are the agent's own control tools, not user-facing actions;
|
|
97
|
-
* denying them would brick the turn without security benefit (they also fire
|
|
98
|
-
* preToolUse, observed in §9.6). The span is still emitted; guard is skipped.
|
|
99
|
-
*/
|
|
100
|
-
const INTERNAL_TOOLS = new Set(["report_intent", "ask_user"]);
|
|
101
|
-
function isInternalTool(name) {
|
|
102
|
-
return name !== undefined && INTERNAL_TOOLS.has(name);
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Render the deny decision in the format the firing event expects, or null if
|
|
106
|
-
* the event isn't a gating event. preToolUse uses `permissionDecision`; the CLI
|
|
107
|
-
* permission service uses `behavior`/`message`.
|
|
108
|
-
*/
|
|
109
|
-
function formatDeny(kind, reason) {
|
|
110
|
-
if (kind === "PreToolUse") {
|
|
111
|
-
return JSON.stringify({
|
|
112
|
-
hookSpecificOutput: {
|
|
113
|
-
hookEventName: "PreToolUse",
|
|
114
|
-
permissionDecision: "deny",
|
|
115
|
-
permissionDecisionReason: reason,
|
|
116
|
-
},
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
if (kind === "PermissionRequest") {
|
|
120
|
-
return JSON.stringify({ behavior: "deny", message: reason });
|
|
121
|
-
}
|
|
122
|
-
return null;
|
|
123
|
-
}
|
|
124
|
-
//# sourceMappingURL=types.js.map
|
package/dist/core/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
package/dist/env-file.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export declare function envFilePath(): string;
|
|
2
|
-
export declare function parseEnvFile(content: string): Record<string, string>;
|
|
3
|
-
/** Load the env file (if present) and merge only-unset keys into process.env. */
|
|
4
|
-
export declare function loadEnvFile(filePath?: string): void;
|