@pinta-ai/pinta-codex 1.2.4 → 1.4.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 (51) hide show
  1. package/.codex-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +31 -0
  3. package/dist/index.js +15 -53
  4. package/package.json +14 -6
  5. package/dist/core/config.d.ts +0 -12
  6. package/dist/core/config.js +0 -125
  7. package/dist/core/config.js.map +0 -1
  8. package/dist/core/guard.d.ts +0 -13
  9. package/dist/core/guard.js +0 -41
  10. package/dist/core/guard.js.map +0 -1
  11. package/dist/core/identity.d.ts +0 -1
  12. package/dist/core/identity.js +0 -3
  13. package/dist/core/identity.js.map +0 -1
  14. package/dist/core/otlp.d.ts +0 -59
  15. package/dist/core/otlp.js +0 -192
  16. package/dist/core/otlp.js.map +0 -1
  17. package/dist/core/redact.d.ts +0 -57
  18. package/dist/core/redact.js +0 -149
  19. package/dist/core/redact.js.map +0 -1
  20. package/dist/core/retry-queue.d.ts +0 -26
  21. package/dist/core/retry-queue.js +0 -127
  22. package/dist/core/retry-queue.js.map +0 -1
  23. package/dist/core/trace.d.ts +0 -10
  24. package/dist/core/trace.js +0 -61
  25. package/dist/core/trace.js.map +0 -1
  26. package/dist/core/transport.d.ts +0 -10
  27. package/dist/core/transport.js +0 -83
  28. package/dist/core/transport.js.map +0 -1
  29. package/dist/core/types.d.ts +0 -48
  30. package/dist/core/types.js +0 -45
  31. package/dist/core/types.js.map +0 -1
  32. package/dist/handlers/default.d.ts +0 -6
  33. package/dist/handlers/default.js +0 -11
  34. package/dist/handlers/default.js.map +0 -1
  35. package/dist/handlers/post-tool-use.d.ts +0 -3
  36. package/dist/handlers/post-tool-use.js +0 -15
  37. package/dist/handlers/post-tool-use.js.map +0 -1
  38. package/dist/handlers/pre-tool-use.d.ts +0 -3
  39. package/dist/handlers/pre-tool-use.js +0 -38
  40. package/dist/handlers/pre-tool-use.js.map +0 -1
  41. package/dist/handlers/session.d.ts +0 -3
  42. package/dist/handlers/session.js +0 -15
  43. package/dist/handlers/session.js.map +0 -1
  44. package/dist/handlers/stop.d.ts +0 -3
  45. package/dist/handlers/stop.js +0 -15
  46. package/dist/handlers/stop.js.map +0 -1
  47. package/dist/handlers/user-prompt.d.ts +0 -3
  48. package/dist/handlers/user-prompt.js +0 -15
  49. package/dist/handlers/user-prompt.js.map +0 -1
  50. package/dist/index.d.ts +0 -1
  51. package/dist/index.js.map +0 -1
package/dist/core/otlp.js DELETED
@@ -1,192 +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.ulidToTraceId = ulidToTraceId;
7
- exports.newSpanId = newSpanId;
8
- exports.buildOtlpPayload = buildOtlpPayload;
9
- exports.mergeBatch = mergeBatch;
10
- const crypto_1 = __importDefault(require("crypto"));
11
- const os_1 = __importDefault(require("os"));
12
- const redact_js_1 = require("./redact.js");
13
- const PLUGIN_VERSION = "1.2.0"; // keep in sync with .codex-plugin/plugin.json
14
- /**
15
- * Resolve the Codex CLI version from an explicit env if present.
16
- * Hooks run as short-lived processes, so we keep this intentionally simple.
17
- */
18
- let cachedCliVersion = null;
19
- function getCodexVersion() {
20
- if (cachedCliVersion !== null)
21
- return cachedCliVersion;
22
- cachedCliVersion = process.env.CODEX_CLI_VERSION || "unknown";
23
- return cachedCliVersion;
24
- }
25
- const CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
26
- /**
27
- * Convert a 26-char Crockford ULID into 32 lowercase hex chars (16 bytes)
28
- * suitable for an OTLP traceId. Decoding is straightforward because each
29
- * Crockford char carries 5 bits and 26 chars = 130 bits; we keep the low
30
- * 128 bits (the spec already pads timestamp+randomness into 128 bits).
31
- */
32
- function ulidToTraceId(ulid) {
33
- if (ulid.length !== 26) {
34
- throw new Error(`ulidToTraceId: expected 26 chars, got ${ulid.length}`);
35
- }
36
- // Decode to a BigInt then to 16-byte big-endian buffer.
37
- let n = 0n;
38
- for (const ch of ulid) {
39
- const idx = CROCKFORD.indexOf(ch);
40
- if (idx < 0)
41
- throw new Error(`ulidToTraceId: invalid Crockford char "${ch}"`);
42
- n = (n << 5n) | BigInt(idx);
43
- }
44
- // Mask to 128 bits (drop the top 2 bits of the 130-bit decode).
45
- const mask = (1n << 128n) - 1n;
46
- n &= mask;
47
- // Render as 32 hex chars, lowercase.
48
- return n.toString(16).padStart(32, "0");
49
- }
50
- /** Generate a fresh 16-hex-char (8-byte) span ID. */
51
- function newSpanId() {
52
- return crypto_1.default.randomBytes(8).toString("hex");
53
- }
54
- /**
55
- * Attribute keys for which redaction (Tier 1) is skipped. Truncation (Tier 3)
56
- * still applies. These are identifiers, enums, or our own resource attrs that
57
- * are known-safe and where false-positive masking would hurt more than help.
58
- */
59
- const SKIP_REDACT_KEYS = new Set([
60
- "codex.hook",
61
- "codex.tool_name",
62
- "codex.tool_use_id",
63
- "codex.session_id",
64
- "codex.transcript_path",
65
- "codex.cwd",
66
- "codex.permission_mode",
67
- ]);
68
- function maybeRedactString(key, raw) {
69
- // Spec §3: truncate first, then redact.
70
- const truncated = (0, redact_js_1.truncate)(raw);
71
- if (SKIP_REDACT_KEYS.has(key))
72
- return truncated;
73
- // Bash context only applies when this key may carry shell command text.
74
- // flattenEvent emits codex.tool_input as a single JSON-stringified attribute
75
- // (no nested flattening today), so strict equality matches actual behavior.
76
- // If nested flattening is ever added, re-evaluate to avoid extending bash
77
- // context to unrelated nested keys (e.g. codex.tool_input.file_path).
78
- const context = key === "codex.tool_input" || key === "codex.tool_response"
79
- ? "bash"
80
- : undefined;
81
- return (0, redact_js_1.redact)(truncated, { context });
82
- }
83
- /** Convert a JS value into an OTLP attribute value. Returns null to omit. */
84
- function toOtlpValue(key, v) {
85
- if (v === null || v === undefined)
86
- return null;
87
- switch (typeof v) {
88
- case "string":
89
- return { stringValue: maybeRedactString(key, v) };
90
- case "boolean":
91
- return { boolValue: v };
92
- case "number":
93
- if (Number.isInteger(v))
94
- return { intValue: v };
95
- return { doubleValue: v };
96
- case "object":
97
- try {
98
- return { stringValue: maybeRedactString(key, JSON.stringify(v)) };
99
- }
100
- catch {
101
- return { stringValue: maybeRedactString(key, String(v)) };
102
- }
103
- default:
104
- return { stringValue: maybeRedactString(key, String(v)) };
105
- }
106
- }
107
- function snakeCase(hookEventName) {
108
- // "PreToolUse" → "pre_tool_use"
109
- return hookEventName
110
- .replace(/([a-z0-9])([A-Z])/g, "$1_$2")
111
- .replace(/([A-Z])([A-Z][a-z])/g, "$1_$2")
112
- .toLowerCase();
113
- }
114
- function flattenEvent(event) {
115
- const out = [];
116
- // Discriminator first so the Pinta backend's detectIngestType hits it cheaply.
117
- out.push({ key: "ingest.type", value: { stringValue: "codex" } });
118
- // Always set codex.hook explicitly so server queries have a canonical key
119
- // regardless of incoming field name.
120
- out.push({ key: "codex.hook", value: { stringValue: event.hook_event_name } });
121
- for (const [k, v] of Object.entries(event)) {
122
- if (k === "hook_event_name")
123
- continue; // covered by codex.hook above
124
- const key = `codex.${k}`;
125
- const value = toOtlpValue(key, v);
126
- if (value === null)
127
- continue;
128
- out.push({ key, value });
129
- }
130
- return out;
131
- }
132
- function resourceAttrs() {
133
- return [
134
- { key: "service.name", value: { stringValue: "codex" } },
135
- { key: "service.version", value: { stringValue: getCodexVersion() } },
136
- { key: "telemetry.sdk.name", value: { stringValue: "pinta-codex" } },
137
- { key: "telemetry.sdk.language", value: { stringValue: "nodejs" } },
138
- { key: "telemetry.sdk.version", value: { stringValue: PLUGIN_VERSION } },
139
- { key: "process.pid", value: { intValue: process.pid } },
140
- { key: "process.owner", value: { stringValue: os_1.default.userInfo().username } },
141
- { key: "host.name", value: { stringValue: os_1.default.hostname() } },
142
- { key: "host.arch", value: { stringValue: os_1.default.arch() } },
143
- ];
144
- }
145
- function buildOtlpPayload(args) {
146
- const ts = args.now ?? Date.now();
147
- const tsNano = (BigInt(ts) * 1000000n).toString();
148
- const attrs = flattenEvent(args.event);
149
- if (args.guard) {
150
- attrs.push({ key: 'pinta.guard.decision', value: { stringValue: args.guard.decision.toLowerCase() } }, { key: 'pinta.guard.duration_ms', value: { intValue: args.guard.durationMs } });
151
- if (args.guard.reason) {
152
- attrs.push({ key: 'pinta.guard.matched_rule', value: { stringValue: args.guard.reason } });
153
- }
154
- if (args.guard.failOpenReason) {
155
- attrs.push({ key: 'pinta.guard.fail_open_reason', value: { stringValue: args.guard.failOpenReason } });
156
- }
157
- }
158
- const span = {
159
- traceId: ulidToTraceId(args.traceId),
160
- spanId: newSpanId(),
161
- name: `codex.${snakeCase(args.event.hook_event_name)}`,
162
- kind: 1, // SPAN_KIND_INTERNAL
163
- startTimeUnixNano: tsNano,
164
- endTimeUnixNano: tsNano,
165
- attributes: attrs,
166
- };
167
- return {
168
- resourceSpans: [
169
- {
170
- resource: { attributes: resourceAttrs() },
171
- scopeSpans: [
172
- {
173
- scope: { name: "pinta-codex", version: PLUGIN_VERSION },
174
- spans: [span],
175
- },
176
- ],
177
- },
178
- ],
179
- };
180
- }
181
- /**
182
- * Combine multiple per-hook payloads into a single OTLP payload by
183
- * concatenating their resourceSpans arrays. The Pinta backend's parser
184
- * iterates over resourceSpans natively.
185
- */
186
- function mergeBatch(payloads) {
187
- const out = [];
188
- for (const p of payloads)
189
- out.push(...p.resourceSpans);
190
- return { resourceSpans: out };
191
- }
192
- //# sourceMappingURL=otlp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"otlp.js","sourceRoot":"","sources":["../../src/core/otlp.ts"],"names":[],"mappings":"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"}
@@ -1,57 +0,0 @@
1
- export interface RedactOptions {
2
- /**
3
- * Optional context hint that enables context-gated patterns. Currently
4
- * only "bash" enables `cli_password_short` (-p<pass>) since matching it
5
- * outside Bash command text is too noisy.
6
- */
7
- context?: "bash";
8
- }
9
- /** Tier 3 cap: per-string byte limit before truncation. */
10
- export declare const MAX_BYTES = 102400;
11
- /**
12
- * Truncate input by UTF-8 byte length. Appends `…[TRUNCATED:<origByteLen>]`
13
- * to indicate elision. Returns input unchanged when within cap.
14
- *
15
- * Uses Buffer for accurate byte counting; slices on byte boundary then
16
- * decodes — may produce a U+FFFD if the boundary lands mid-codepoint, which
17
- * is acceptable for telemetry.
18
- */
19
- export declare function truncate(input: string): string;
20
- export interface Pattern {
21
- /** Token type printed inside `[REDACTED:<type>]`. */
22
- type: string;
23
- /** Regex with global flag (`g`). Multiline (`m`) for line-anchored ones. */
24
- regex: RegExp;
25
- /**
26
- * Capture group index whose substring is replaced. 0 (default) = whole match.
27
- * Use a positive group when the pattern brackets context that should be
28
- * preserved (e.g. `postgres://user:<pwd>@` keeps the URL shape intact).
29
- */
30
- captureGroup?: number;
31
- /**
32
- * If set, this pattern only applies when `RedactOptions.context` equals
33
- * the listed value. Used for false-positive-prone shapes.
34
- */
35
- requireContext?: "bash";
36
- }
37
- export declare const PATTERNS: ReadonlyArray<Pattern>;
38
- interface Match {
39
- start: number;
40
- end: number;
41
- replaceStart: number;
42
- replaceEnd: number;
43
- type: string;
44
- }
45
- export declare function collectMatches(input: string, opts: RedactOptions): Match[];
46
- export declare function resolveOverlaps(matches: Match[]): Match[];
47
- export declare function applyMatches(input: string, matches: Match[]): string;
48
- /**
49
- * Mask high-confidence secret patterns in `input`. Returns a new string with
50
- * matched substrings replaced by `[REDACTED:<type>]`.
51
- *
52
- * - `opts.context = "bash"` enables context-gated patterns.
53
- * - Truncation is NOT applied here — see `truncate()`. The caller decides
54
- * the order (spec §3 Tier 3: truncate first, then redact).
55
- */
56
- export declare function redact(input: string, opts?: RedactOptions): string;
57
- export {};
@@ -1,149 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PATTERNS = exports.MAX_BYTES = void 0;
4
- exports.truncate = truncate;
5
- exports.collectMatches = collectMatches;
6
- exports.resolveOverlaps = resolveOverlaps;
7
- exports.applyMatches = applyMatches;
8
- exports.redact = redact;
9
- /** Tier 3 cap: per-string byte limit before truncation. */
10
- exports.MAX_BYTES = 102400;
11
- /**
12
- * Truncate input by UTF-8 byte length. Appends `…[TRUNCATED:<origByteLen>]`
13
- * to indicate elision. Returns input unchanged when within cap.
14
- *
15
- * Uses Buffer for accurate byte counting; slices on byte boundary then
16
- * decodes — may produce a U+FFFD if the boundary lands mid-codepoint, which
17
- * is acceptable for telemetry.
18
- */
19
- function truncate(input) {
20
- const buf = Buffer.from(input, "utf-8");
21
- if (buf.length <= exports.MAX_BYTES)
22
- return input;
23
- const head = buf.subarray(0, exports.MAX_BYTES).toString("utf-8");
24
- return `${head}…[TRUNCATED:${buf.length}]`;
25
- }
26
- exports.PATTERNS = [
27
- { type: "aws_access_key", regex: /AKIA[0-9A-Z]{16}/g },
28
- {
29
- type: "aws_secret_key",
30
- // Context word `aws_secret`/`AWS_SECRET` (with optional separator) followed
31
- // by an assignment-ish character then a 40-char base64-ish blob.
32
- regex: /(?:aws[_-]?secret(?:[_-]?(?:access)?[_-]?key)?)\s*[:=]\s*["']?([A-Za-z0-9/+=]{40})(?![A-Za-z0-9/+=])/gi,
33
- captureGroup: 1,
34
- },
35
- {
36
- type: "gcp_service_account",
37
- // Whole JSON blob starting with the service-account discriminator.
38
- regex: /\{[\s\S]{0,200}?"type"\s*:\s*"service_account"[\s\S]*?\}/g,
39
- },
40
- { type: "github_token", regex: /gh[pousr]_[A-Za-z0-9]{36,}/g },
41
- { type: "gitlab_token", regex: /glpat-[A-Za-z0-9_-]{20}/g },
42
- { type: "slack_token", regex: /xox[abrsp]-[0-9A-Za-z-]{10,}/g },
43
- { type: "openai_key", regex: /sk-(?:proj-)?[A-Za-z0-9_-]{40,}/g },
44
- { type: "anthropic_key", regex: /sk-ant-[A-Za-z0-9_-]{50,}/g },
45
- { type: "stripe_key", regex: /(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}/g },
46
- {
47
- type: "jwt",
48
- regex: /eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g,
49
- },
50
- {
51
- type: "private_key_block",
52
- regex: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,
53
- },
54
- { type: "bearer_token", regex: /bearer\s+([A-Za-z0-9._~+/=-]{12,})/gi, captureGroup: 1 },
55
- { type: "basic_auth", regex: /basic\s+([A-Za-z0-9+/=]{12,})/gi, captureGroup: 1 },
56
- {
57
- type: "db_url_password",
58
- regex: /\b(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|redis):\/\/[^:\s/]+:([^@\s]+)@/gi,
59
- captureGroup: 1,
60
- },
61
- {
62
- type: "cli_password_flag",
63
- regex: /(?:--password|--pass|--pwd)[=\s]([^\s'"]+)/g,
64
- captureGroup: 1,
65
- },
66
- {
67
- type: "cli_password_short",
68
- // mysql -p<pass>; only on bash context.
69
- regex: /\s-p([^\s'"]+)/g,
70
- captureGroup: 1,
71
- requireContext: "bash",
72
- },
73
- {
74
- type: "env_var_secret",
75
- // Known false positive: trailing `[A-Z0-9_]*` is greedy, so names like
76
- // `OPENAI_API_KEY_DESCRIPTION=Used` still match. Acceptable for Bronze.
77
- regex: /^(?:export\s+)?([A-Z][A-Z0-9_]*(?:KEY|SECRET|TOKEN|PASSWORD|PASSWD|PWD|API_KEY)[A-Z0-9_]*)\s*=\s*["']?([^\s"'\n]+)/gm,
78
- captureGroup: 2,
79
- },
80
- ];
81
- function collectMatches(input, opts) {
82
- const out = [];
83
- for (const pattern of exports.PATTERNS) {
84
- if (pattern.requireContext && pattern.requireContext !== opts.context)
85
- continue;
86
- const re = new RegExp(pattern.regex.source, pattern.regex.flags);
87
- let m;
88
- while ((m = re.exec(input)) !== null) {
89
- const cg = pattern.captureGroup ?? 0;
90
- const captured = m[cg];
91
- if (captured === undefined) {
92
- if (m.index === re.lastIndex)
93
- re.lastIndex++;
94
- continue;
95
- }
96
- const start = m.index;
97
- const end = m.index + m[0].length;
98
- const replaceStart = start + m[0].indexOf(captured);
99
- const replaceEnd = replaceStart + captured.length;
100
- out.push({ start, end, replaceStart, replaceEnd, type: pattern.type });
101
- if (m.index === re.lastIndex)
102
- re.lastIndex++; // guard against zero-length
103
- }
104
- }
105
- return out;
106
- }
107
- function resolveOverlaps(matches) {
108
- const sorted = [...matches].sort((a, b) => {
109
- if (a.start !== b.start)
110
- return a.start - b.start;
111
- return (b.end - b.start) - (a.end - a.start); // longer whole-match wins on tie
112
- });
113
- const kept = [];
114
- let lastEnd = -1;
115
- for (const m of sorted) {
116
- if (m.start < lastEnd)
117
- continue; // overlapping later match dropped
118
- kept.push(m);
119
- lastEnd = m.end;
120
- }
121
- return kept;
122
- }
123
- function applyMatches(input, matches) {
124
- // Apply right-to-left so earlier indices remain valid.
125
- const sorted = [...matches].sort((a, b) => b.replaceStart - a.replaceStart);
126
- let out = input;
127
- for (const m of sorted) {
128
- out = out.slice(0, m.replaceStart) + `[REDACTED:${m.type}]` + out.slice(m.replaceEnd);
129
- }
130
- return out;
131
- }
132
- /**
133
- * Mask high-confidence secret patterns in `input`. Returns a new string with
134
- * matched substrings replaced by `[REDACTED:<type>]`.
135
- *
136
- * - `opts.context = "bash"` enables context-gated patterns.
137
- * - Truncation is NOT applied here — see `truncate()`. The caller decides
138
- * the order (spec §3 Tier 3: truncate first, then redact).
139
- */
140
- function redact(input, opts = {}) {
141
- if (input.length === 0)
142
- return input;
143
- const all = collectMatches(input, opts);
144
- if (all.length === 0)
145
- return input;
146
- const kept = resolveOverlaps(all);
147
- return applyMatches(input, kept);
148
- }
149
- //# sourceMappingURL=redact.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/core/redact.ts"],"names":[],"mappings":"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"}
@@ -1,26 +0,0 @@
1
- import type { OtlpPayload } from "./otlp.js";
2
- export interface QueueEntry {
3
- savedAt: string;
4
- payload: OtlpPayload;
5
- }
6
- export declare class RetryQueue {
7
- private filePath;
8
- private lockPath;
9
- constructor(pluginData: string);
10
- /** Append a single payload. Best-effort: any IO error is swallowed (logged to stderr). */
11
- enqueue(payload: OtlpPayload): void;
12
- /**
13
- * Read all entries oldest-first. Returns [] if the file does not exist or is unreadable.
14
- * Does NOT delete the file — callers handle persistence via `rewrite`.
15
- */
16
- readAll(): QueueEntry[];
17
- /** Replace the queue with the given entries (or delete the file when empty). */
18
- rewrite(entries: QueueEntry[]): void;
19
- /**
20
- * Try to acquire the lock for ~LOCK_TIMEOUT_MS. Returns true on success.
21
- * Caller MUST call `release()` if true is returned.
22
- */
23
- tryAcquireLock(): boolean;
24
- release(): void;
25
- private trim;
26
- }
@@ -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-codex] 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-codex] 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-codex] 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-codex] 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,10 +0,0 @@
1
- import type { PintaCodexConfig } from "./config.js";
2
- export declare class TraceManager {
3
- private tracePath;
4
- constructor(config: PintaCodexConfig);
5
- /** Start a new trace for each user prompt hook. */
6
- newTrace(): string;
7
- /** Return the current trace id, creating one when needed. */
8
- currentTrace(): string;
9
- private save;
10
- }
@@ -1,61 +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
- // 10 chars timestamp (48-bit ms)
14
- let ts = "";
15
- let t = now;
16
- for (let i = 0; i < 10; i++) {
17
- ts = CROCKFORD[t & 31] + ts;
18
- t = Math.floor(t / 32);
19
- }
20
- // 16 chars randomness (80-bit)
21
- const rand = crypto_1.default.randomBytes(10);
22
- let r = "";
23
- for (let i = 0; i < 10; i++) {
24
- r += CROCKFORD[rand[i] & 31];
25
- }
26
- // pad to 16 chars
27
- while (r.length < 16)
28
- r += CROCKFORD[0];
29
- return ts + r;
30
- }
31
- class TraceManager {
32
- tracePath;
33
- constructor(config) {
34
- this.tracePath = config.tracePath;
35
- }
36
- /** Start a new trace for each user prompt hook. */
37
- newTrace() {
38
- const traceId = generateUlid();
39
- this.save(traceId);
40
- return traceId;
41
- }
42
- /** Return the current trace id, creating one when needed. */
43
- currentTrace() {
44
- try {
45
- const data = fs_1.default.readFileSync(this.tracePath, "utf-8");
46
- const { traceId } = JSON.parse(data);
47
- if (traceId)
48
- return traceId;
49
- }
50
- catch {
51
- // no trace file yet
52
- }
53
- return this.newTrace();
54
- }
55
- save(traceId) {
56
- fs_1.default.mkdirSync(path_1.default.dirname(this.tracePath), { recursive: true });
57
- fs_1.default.writeFileSync(this.tracePath, JSON.stringify({ traceId }));
58
- }
59
- }
60
- exports.TraceManager = TraceManager;
61
- //# sourceMappingURL=trace.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"trace.js","sourceRoot":"","sources":["../../src/core/trace.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,gDAAwB;AACxB,oDAA4B;AAG5B,MAAM,SAAS,GAAG,kCAAkC,CAAC;AAErD,SAAS,YAAY;IACnB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,iCAAiC;IACjC,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,IAAI,CAAC,GAAG,GAAG,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,EAAE,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;QAC5B,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACzB,CAAC;IACD,+BAA+B;IAC/B,MAAM,IAAI,GAAG,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACpC,IAAI,CAAC,GAAG,EAAE,CAAC;IACX,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/B,CAAC;IACD,kBAAkB;IAClB,OAAO,CAAC,CAAC,MAAM,GAAG,EAAE;QAAE,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC;IACxC,OAAO,EAAE,GAAG,CAAC,CAAC;AAChB,CAAC;AAED,MAAa,YAAY;IACf,SAAS,CAAS;IAE1B,YAAY,MAAwB;QAClC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IACpC,CAAC;IAED,mDAAmD;IACnD,QAAQ;QACN,MAAM,OAAO,GAAG,YAAY,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,6DAA6D;IAC7D,YAAY;QACV,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,YAAE,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACtD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,OAAO;gBAAE,OAAO,OAAO,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,oBAAoB;QACtB,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAEO,IAAI,CAAC,OAAe;QAC1B,YAAE,CAAC,SAAS,CAAC,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,YAAE,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IAChE,CAAC;CACF;AA9BD,oCA8BC"}