@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.
Files changed (45) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/dist/index.js +14 -71
  3. package/dist/index.mjs +15 -0
  4. package/dist/tools/doctor.js +4 -81
  5. package/dist/tools/install-hooks.js +3 -101
  6. package/package.json +17 -2
  7. package/dist/core/config.d.ts +0 -15
  8. package/dist/core/config.js +0 -19
  9. package/dist/core/config.js.map +0 -1
  10. package/dist/core/env-bridge.d.ts +0 -25
  11. package/dist/core/env-bridge.js +0 -43
  12. package/dist/core/env-bridge.js.map +0 -1
  13. package/dist/core/guard.d.ts +0 -14
  14. package/dist/core/guard.js +0 -53
  15. package/dist/core/guard.js.map +0 -1
  16. package/dist/core/otlp.d.ts +0 -55
  17. package/dist/core/otlp.js +0 -184
  18. package/dist/core/otlp.js.map +0 -1
  19. package/dist/core/redact.d.ts +0 -57
  20. package/dist/core/redact.js +0 -149
  21. package/dist/core/redact.js.map +0 -1
  22. package/dist/core/retry-queue.d.ts +0 -26
  23. package/dist/core/retry-queue.js +0 -127
  24. package/dist/core/retry-queue.js.map +0 -1
  25. package/dist/core/surface.d.ts +0 -21
  26. package/dist/core/surface.js +0 -13
  27. package/dist/core/surface.js.map +0 -1
  28. package/dist/core/trace.d.ts +0 -20
  29. package/dist/core/trace.js +0 -80
  30. package/dist/core/trace.js.map +0 -1
  31. package/dist/core/transport.d.ts +0 -18
  32. package/dist/core/transport.js +0 -127
  33. package/dist/core/transport.js.map +0 -1
  34. package/dist/core/types.d.ts +0 -49
  35. package/dist/core/types.js +0 -124
  36. package/dist/core/types.js.map +0 -1
  37. package/dist/env-file.d.ts +0 -4
  38. package/dist/env-file.js +0 -69
  39. package/dist/env-file.js.map +0 -1
  40. package/dist/index.d.ts +0 -1
  41. package/dist/index.js.map +0 -1
  42. package/dist/tools/doctor.d.ts +0 -1
  43. package/dist/tools/doctor.js.map +0 -1
  44. package/dist/tools/install-hooks.d.ts +0 -1
  45. package/dist/tools/install-hooks.js.map +0 -1
@@ -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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"}
@@ -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;
@@ -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
@@ -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"}
@@ -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
- }
@@ -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
@@ -1 +0,0 @@
1
- {"version":3,"file":"trace.js","sourceRoot":"","sources":["../../src/core/trace.ts"],"names":[],"mappings":"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"}
@@ -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
- }
@@ -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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"}
@@ -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;
@@ -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
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":";AAAA,4EAA4E;AAC5E,EAAE;AACF,6EAA6E;AAC7E,sEAAsE;AACtE,EAAE;AACF,8EAA8E;AAC9E,6EAA6E;AAC7E,uEAAuE;AACvE,6EAA6E;AAC7E,qEAAqE;AACrE,wFAAwF;AACxF,kFAAkF;AAClF,+EAA+E;AAC/E,wEAAwE;AACxE,yEAAyE;AACzE,8DAA8D;AAC9D,EAAE;AACF,kFAAkF;AAClF,6EAA6E;AAC7E,6EAA6E;;AAuB7E,8BAOC;AAGD,8BAEC;AAGD,4BAEC;AAGD,8BAEC;AAsCD,4BAIC;AAID,oCAEC;AAWD,wCAEC;AAyBD,gCAcC;AA3ID,SAAS,GAAG,CAAC,CAAU;IACrB,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,SAAS,CAAC,CAAW;IACnC,OAAO,CACL,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC;QACtB,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC;QACpB,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;QACf,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,SAAS,CAAC,CAC/C,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,SAAgB,SAAS,CAAC,CAAW;IACnC,OAAO,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAC/C,CAAC;AAED,+EAA+E;AAC/E,SAAgB,QAAQ,CAAC,CAAW;IAClC,OAAO,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAC7C,CAAC;AAED,4EAA4E;AAC5E,SAAgB,SAAS,CAAC,CAAW;IACnC,OAAO,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,SAAS,CAAC;AACnD,CAAC;AAoBD,MAAM,QAAQ,GAA8B;IAC1C,YAAY,EAAE,cAAc;IAC5B,UAAU,EAAE,YAAY;IACxB,gBAAgB,EAAE,kBAAkB;IACpC,mBAAmB,EAAE,kBAAkB;IACvC,UAAU,EAAE,YAAY;IACxB,WAAW,EAAE,aAAa;IAC1B,kBAAkB,EAAE,oBAAoB;IACxC,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,MAAM;IACjB,aAAa,EAAE,eAAe;IAC9B,YAAY,EAAE,cAAc;IAC5B,UAAU,EAAE,YAAY;IACxB,YAAY,EAAE,cAAc;IAC5B,iBAAiB,EAAE,mBAAmB;IACtC,aAAa,EAAE,eAAe;CAC/B,CAAC;AAEF,SAAgB,QAAQ,CAAC,CAAW;IAClC,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,OAAO,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,SAAS,CAAC;AAChD,CAAC;AAED;gFACgF;AAChF,SAAgB,YAAY,CAAC,IAAe;IAC1C,OAAO,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,mBAAmB,CAAC;AAC/D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC,CAAC;AAEnF,SAAgB,cAAc,CAAC,IAAwB;IACrD,OAAO,IAAI,KAAK,SAAS,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACxD,CAAC;AAoBD;;;;GAIG;AACH,SAAgB,UAAU,CAAC,IAAe,EAAE,MAAc;IACxD,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,kBAAkB,EAAE;gBAClB,aAAa,EAAE,YAAY;gBAC3B,kBAAkB,EAAE,MAAM;gBAC1B,wBAAwB,EAAE,MAAM;aACjC;SACF,CAAC,CAAC;IACL,CAAC;IACD,IAAI,IAAI,KAAK,mBAAmB,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -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;