@pinta-ai/pinta-cc 1.4.1 → 1.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/.claude-plugin/plugin.json +1 -1
- package/dist/index.js +14 -71
- package/package.json +9 -2
- package/dist/core/config.d.ts +0 -13
- package/dist/core/config.js +0 -22
- 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 -51
- package/dist/core/guard.js.map +0 -1
- package/dist/core/identity.d.ts +0 -1
- package/dist/core/identity.js +0 -3
- package/dist/core/identity.js.map +0 -1
- package/dist/core/otlp.d.ts +0 -59
- package/dist/core/otlp.js +0 -224
- 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/trace.d.ts +0 -10
- package/dist/core/trace.js +0 -61
- package/dist/core/trace.js.map +0 -1
- package/dist/core/transport.d.ts +0 -18
- package/dist/core/transport.js +0 -125
- package/dist/core/transport.js.map +0 -1
- package/dist/core/types.d.ts +0 -65
- package/dist/core/types.js +0 -39
- package/dist/core/types.js.map +0 -1
- package/dist/env-file.d.ts +0 -9
- package/dist/env-file.js +0 -85
- package/dist/env-file.js.map +0 -1
- package/dist/handlers/default.d.ts +0 -6
- package/dist/handlers/default.js +0 -11
- package/dist/handlers/default.js.map +0 -1
- package/dist/handlers/permission.d.ts +0 -3
- package/dist/handlers/permission.js +0 -15
- package/dist/handlers/permission.js.map +0 -1
- package/dist/handlers/post-tool-use.d.ts +0 -3
- package/dist/handlers/post-tool-use.js +0 -15
- package/dist/handlers/post-tool-use.js.map +0 -1
- package/dist/handlers/pre-tool-use.d.ts +0 -3
- package/dist/handlers/pre-tool-use.js +0 -40
- package/dist/handlers/pre-tool-use.js.map +0 -1
- package/dist/handlers/session.d.ts +0 -3
- package/dist/handlers/session.js +0 -15
- package/dist/handlers/session.js.map +0 -1
- package/dist/handlers/stop.d.ts +0 -3
- package/dist/handlers/stop.js +0 -15
- package/dist/handlers/stop.js.map +0 -1
- package/dist/handlers/subagent.d.ts +0 -3
- package/dist/handlers/subagent.js +0 -15
- package/dist/handlers/subagent.js.map +0 -1
- package/dist/handlers/user-prompt.d.ts +0 -3
- package/dist/handlers/user-prompt.js +0 -15
- package/dist/handlers/user-prompt.js.map +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js.map +0 -1
package/dist/core/otlp.js
DELETED
|
@@ -1,224 +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 fs_1 = __importDefault(require("fs"));
|
|
12
|
-
const os_1 = __importDefault(require("os"));
|
|
13
|
-
const path_1 = __importDefault(require("path"));
|
|
14
|
-
const redact_js_1 = require("./redact.js");
|
|
15
|
-
const PLUGIN_VERSION = "1.4.1"; // keep in sync with .claude-plugin/plugin.json
|
|
16
|
-
/**
|
|
17
|
-
* Resolve the Claude Code CLI version by walking up from the binary path
|
|
18
|
-
* (CLAUDE_CODE_EXECPATH) until we find the `@anthropic-ai/claude-code`
|
|
19
|
-
* package.json. Different install layouts (npm global, pnpm, bundled) put
|
|
20
|
-
* the binary at different depths, so we can't hard-code "..".
|
|
21
|
-
*
|
|
22
|
-
* Cached at module scope — one read per hook process.
|
|
23
|
-
* Falls back to "unknown" on any failure so a missing CLI never fails the hook.
|
|
24
|
-
*/
|
|
25
|
-
let cachedCliVersion = null;
|
|
26
|
-
function getClaudeCodeVersion() {
|
|
27
|
-
if (cachedCliVersion !== null)
|
|
28
|
-
return cachedCliVersion;
|
|
29
|
-
cachedCliVersion = resolveClaudeCodeVersion() ?? "unknown";
|
|
30
|
-
return cachedCliVersion;
|
|
31
|
-
}
|
|
32
|
-
const MAX_WALK_DEPTH = 6;
|
|
33
|
-
function resolveClaudeCodeVersion() {
|
|
34
|
-
const execPath = process.env.CLAUDE_CODE_EXECPATH;
|
|
35
|
-
if (!execPath)
|
|
36
|
-
return null;
|
|
37
|
-
let dir = path_1.default.dirname(execPath);
|
|
38
|
-
const root = path_1.default.parse(dir).root;
|
|
39
|
-
for (let i = 0; i < MAX_WALK_DEPTH && dir !== root; i++) {
|
|
40
|
-
const pkgPath = path_1.default.join(dir, "package.json");
|
|
41
|
-
try {
|
|
42
|
-
const raw = fs_1.default.readFileSync(pkgPath, "utf-8");
|
|
43
|
-
const parsed = JSON.parse(raw);
|
|
44
|
-
if (typeof parsed.name === "string" &&
|
|
45
|
-
parsed.name.startsWith("@anthropic-ai/claude-code") &&
|
|
46
|
-
typeof parsed.version === "string") {
|
|
47
|
-
return parsed.version;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
// keep walking
|
|
52
|
-
}
|
|
53
|
-
dir = path_1.default.dirname(dir);
|
|
54
|
-
}
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
const CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
58
|
-
/**
|
|
59
|
-
* Convert a 26-char Crockford ULID into 32 lowercase hex chars (16 bytes)
|
|
60
|
-
* suitable for an OTLP traceId. Decoding is straightforward because each
|
|
61
|
-
* Crockford char carries 5 bits and 26 chars = 130 bits; we keep the low
|
|
62
|
-
* 128 bits (the spec already pads timestamp+randomness into 128 bits).
|
|
63
|
-
*/
|
|
64
|
-
function ulidToTraceId(ulid) {
|
|
65
|
-
if (ulid.length !== 26) {
|
|
66
|
-
throw new Error(`ulidToTraceId: expected 26 chars, got ${ulid.length}`);
|
|
67
|
-
}
|
|
68
|
-
// Decode to a BigInt then to 16-byte big-endian buffer.
|
|
69
|
-
let n = 0n;
|
|
70
|
-
for (const ch of ulid) {
|
|
71
|
-
const idx = CROCKFORD.indexOf(ch);
|
|
72
|
-
if (idx < 0)
|
|
73
|
-
throw new Error(`ulidToTraceId: invalid Crockford char "${ch}"`);
|
|
74
|
-
n = (n << 5n) | BigInt(idx);
|
|
75
|
-
}
|
|
76
|
-
// Mask to 128 bits (drop the top 2 bits of the 130-bit decode).
|
|
77
|
-
const mask = (1n << 128n) - 1n;
|
|
78
|
-
n &= mask;
|
|
79
|
-
// Render as 32 hex chars, lowercase.
|
|
80
|
-
return n.toString(16).padStart(32, "0");
|
|
81
|
-
}
|
|
82
|
-
/** Generate a fresh 16-hex-char (8-byte) span ID. */
|
|
83
|
-
function newSpanId() {
|
|
84
|
-
return crypto_1.default.randomBytes(8).toString("hex");
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Attribute keys for which redaction (Tier 1) is skipped. Truncation (Tier 3)
|
|
88
|
-
* still applies. These are identifiers, enums, or our own resource attrs that
|
|
89
|
-
* are known-safe and where false-positive masking would hurt more than help.
|
|
90
|
-
*/
|
|
91
|
-
const SKIP_REDACT_KEYS = new Set([
|
|
92
|
-
"cc.hook",
|
|
93
|
-
"cc.tool_name",
|
|
94
|
-
"cc.tool_use_id",
|
|
95
|
-
"cc.session_id",
|
|
96
|
-
"cc.transcript_path",
|
|
97
|
-
"cc.cwd",
|
|
98
|
-
"cc.permission_mode",
|
|
99
|
-
]);
|
|
100
|
-
function maybeRedactString(key, raw) {
|
|
101
|
-
// Spec §3: truncate first, then redact.
|
|
102
|
-
const truncated = (0, redact_js_1.truncate)(raw);
|
|
103
|
-
if (SKIP_REDACT_KEYS.has(key))
|
|
104
|
-
return truncated;
|
|
105
|
-
// Bash context only applies when this key may carry shell command text.
|
|
106
|
-
// flattenEvent emits cc.tool_input as a single JSON-stringified attribute
|
|
107
|
-
// (no nested flattening today), so strict equality matches actual behavior.
|
|
108
|
-
// If nested flattening is ever added, re-evaluate to avoid extending bash
|
|
109
|
-
// context to unrelated nested keys (e.g. cc.tool_input.file_path).
|
|
110
|
-
const context = key === "cc.tool_input" || key === "cc.tool_response"
|
|
111
|
-
? "bash"
|
|
112
|
-
: undefined;
|
|
113
|
-
return (0, redact_js_1.redact)(truncated, { context });
|
|
114
|
-
}
|
|
115
|
-
/** Convert a JS value into an OTLP attribute value. Returns null to omit. */
|
|
116
|
-
function toOtlpValue(key, v) {
|
|
117
|
-
if (v === null || v === undefined)
|
|
118
|
-
return null;
|
|
119
|
-
switch (typeof v) {
|
|
120
|
-
case "string":
|
|
121
|
-
return { stringValue: maybeRedactString(key, v) };
|
|
122
|
-
case "boolean":
|
|
123
|
-
return { boolValue: v };
|
|
124
|
-
case "number":
|
|
125
|
-
if (Number.isInteger(v))
|
|
126
|
-
return { intValue: v };
|
|
127
|
-
return { doubleValue: v };
|
|
128
|
-
case "object":
|
|
129
|
-
try {
|
|
130
|
-
return { stringValue: maybeRedactString(key, JSON.stringify(v)) };
|
|
131
|
-
}
|
|
132
|
-
catch {
|
|
133
|
-
return { stringValue: maybeRedactString(key, String(v)) };
|
|
134
|
-
}
|
|
135
|
-
default:
|
|
136
|
-
return { stringValue: maybeRedactString(key, String(v)) };
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
function snakeCase(hookEventName) {
|
|
140
|
-
// "PreToolUse" → "pre_tool_use"
|
|
141
|
-
return hookEventName
|
|
142
|
-
.replace(/([a-z0-9])([A-Z])/g, "$1_$2")
|
|
143
|
-
.replace(/([A-Z])([A-Z][a-z])/g, "$1_$2")
|
|
144
|
-
.toLowerCase();
|
|
145
|
-
}
|
|
146
|
-
function flattenEvent(event) {
|
|
147
|
-
const out = [];
|
|
148
|
-
// Discriminator first so aware-backend's detectIngestType hits it cheaply.
|
|
149
|
-
out.push({ key: "ingest.type", value: { stringValue: "cc" } });
|
|
150
|
-
// Always set cc.hook explicitly so server queries have a canonical key
|
|
151
|
-
// regardless of incoming field name.
|
|
152
|
-
out.push({ key: "cc.hook", value: { stringValue: event.hook_event_name } });
|
|
153
|
-
for (const [k, v] of Object.entries(event)) {
|
|
154
|
-
if (k === "hook_event_name")
|
|
155
|
-
continue; // covered by cc.hook above
|
|
156
|
-
const key = `cc.${k}`;
|
|
157
|
-
const value = toOtlpValue(key, v);
|
|
158
|
-
if (value === null)
|
|
159
|
-
continue;
|
|
160
|
-
out.push({ key, value });
|
|
161
|
-
}
|
|
162
|
-
return out;
|
|
163
|
-
}
|
|
164
|
-
function resourceAttrs() {
|
|
165
|
-
return [
|
|
166
|
-
{ key: "service.name", value: { stringValue: "claude-code" } },
|
|
167
|
-
{ key: "service.version", value: { stringValue: getClaudeCodeVersion() } },
|
|
168
|
-
{ key: "telemetry.sdk.name", value: { stringValue: "pinta-cc" } },
|
|
169
|
-
{ key: "telemetry.sdk.language", value: { stringValue: "nodejs" } },
|
|
170
|
-
{ key: "telemetry.sdk.version", value: { stringValue: PLUGIN_VERSION } },
|
|
171
|
-
{ key: "process.pid", value: { intValue: process.pid } },
|
|
172
|
-
{ key: "process.owner", value: { stringValue: os_1.default.userInfo().username } },
|
|
173
|
-
{ key: "host.name", value: { stringValue: os_1.default.hostname() } },
|
|
174
|
-
{ key: "host.arch", value: { stringValue: os_1.default.arch() } },
|
|
175
|
-
];
|
|
176
|
-
}
|
|
177
|
-
function buildOtlpPayload(args) {
|
|
178
|
-
const ts = args.now ?? Date.now();
|
|
179
|
-
const tsNano = (BigInt(ts) * 1000000n).toString();
|
|
180
|
-
const attrs = flattenEvent(args.event);
|
|
181
|
-
if (args.guard) {
|
|
182
|
-
attrs.push({ key: 'pinta.guard.decision', value: { stringValue: args.guard.decision.toLowerCase() } }, { key: 'pinta.guard.duration_ms', value: { intValue: args.guard.durationMs } });
|
|
183
|
-
if (args.guard.reason) {
|
|
184
|
-
attrs.push({ key: 'pinta.guard.matched_rule', value: { stringValue: args.guard.reason } });
|
|
185
|
-
}
|
|
186
|
-
if (args.guard.failOpenReason) {
|
|
187
|
-
attrs.push({ key: 'pinta.guard.fail_open_reason', value: { stringValue: args.guard.failOpenReason } });
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
const span = {
|
|
191
|
-
traceId: ulidToTraceId(args.traceId),
|
|
192
|
-
spanId: newSpanId(),
|
|
193
|
-
name: `cc.${snakeCase(args.event.hook_event_name)}`,
|
|
194
|
-
kind: 1, // SPAN_KIND_INTERNAL
|
|
195
|
-
startTimeUnixNano: tsNano,
|
|
196
|
-
endTimeUnixNano: tsNano,
|
|
197
|
-
attributes: attrs,
|
|
198
|
-
};
|
|
199
|
-
return {
|
|
200
|
-
resourceSpans: [
|
|
201
|
-
{
|
|
202
|
-
resource: { attributes: resourceAttrs() },
|
|
203
|
-
scopeSpans: [
|
|
204
|
-
{
|
|
205
|
-
scope: { name: "pinta-cc", version: PLUGIN_VERSION },
|
|
206
|
-
spans: [span],
|
|
207
|
-
},
|
|
208
|
-
],
|
|
209
|
-
},
|
|
210
|
-
],
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Combine multiple per-hook payloads into a single OTLP payload by
|
|
215
|
-
* concatenating their resourceSpans arrays. aware-backend's parser
|
|
216
|
-
* iterates over resourceSpans natively.
|
|
217
|
-
*/
|
|
218
|
-
function mergeBatch(payloads) {
|
|
219
|
-
const out = [];
|
|
220
|
-
for (const p of payloads)
|
|
221
|
-
out.push(...p.resourceSpans);
|
|
222
|
-
return { resourceSpans: out };
|
|
223
|
-
}
|
|
224
|
-
//# sourceMappingURL=otlp.js.map
|
package/dist/core/otlp.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"otlp.js","sourceRoot":"","sources":["../../src/core/otlp.ts"],"names":[],"mappings":"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"}
|
package/dist/core/redact.d.ts
DELETED
|
@@ -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 {};
|
package/dist/core/redact.js
DELETED
|
@@ -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
|
package/dist/core/redact.js.map
DELETED
|
@@ -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
|
-
}
|
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-cc] 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-cc] 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-cc] 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-cc] 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/trace.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { PintaConfig } from "./config.js";
|
|
2
|
-
export declare class TraceManager {
|
|
3
|
-
private tracePath;
|
|
4
|
-
constructor(config: PintaConfig);
|
|
5
|
-
/** UserPromptSubmit 시 새 traceId 생성 및 저장 */
|
|
6
|
-
newTrace(): string;
|
|
7
|
-
/** 현재 traceId 반환. 없으면 새로 생성 */
|
|
8
|
-
currentTrace(): string;
|
|
9
|
-
private save;
|
|
10
|
-
}
|