@pinta-ai/pinta-cc 1.2.0 → 1.2.2
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/dist/core/env-bridge.d.ts +10 -1
- package/dist/core/env-bridge.js +18 -3
- package/dist/core/env-bridge.js.map +1 -1
- package/dist/core/guard.d.ts +13 -0
- package/dist/core/guard.js +41 -0
- package/dist/core/guard.js.map +1 -0
- package/dist/core/otlp.d.ts +2 -0
- package/dist/core/otlp.js +11 -1
- package/dist/core/otlp.js.map +1 -1
- package/dist/core/transport.js +32 -4
- package/dist/core/transport.js.map +1 -1
- package/dist/handlers/pre-tool-use.js +22 -1
- package/dist/handlers/pre-tool-use.js.map +1 -1
- package/package.json +1 -1
|
@@ -8,9 +8,18 @@
|
|
|
8
8
|
* canonical OTel env names so transport.ts (and any future OTel SDK adoption)
|
|
9
9
|
* can read them via the OTel-spec names.
|
|
10
10
|
*
|
|
11
|
+
* The user-facing `endpoint` is treated as a *full* OTLP/HTTP traces URL
|
|
12
|
+
* (e.g., `http://127.0.0.1:5147/v1/traces`), so we map it to
|
|
13
|
+
* `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` (signal-specific full URL per OTel
|
|
14
|
+
* spec) rather than `OTEL_EXPORTER_OTLP_ENDPOINT` (which is a base URL the
|
|
15
|
+
* SDK appends `/v1/traces` to). This way both the OTel SDK (when used) and
|
|
16
|
+
* pinta-cc's hand-written transport agree on the URL without any path
|
|
17
|
+
* manipulation downstream.
|
|
18
|
+
*
|
|
11
19
|
* Pinta Manager auto-injects `CLAUDE_PLUGIN_OPTION_*` via Claude Code's
|
|
12
20
|
* settings.json. OSS users fill them in via the `/plugin install` UI.
|
|
13
21
|
*
|
|
14
|
-
* Existing
|
|
22
|
+
* Existing OTEL_EXPORTER_OTLP_TRACES_ENDPOINT / HEADERS take precedence
|
|
23
|
+
* (explicit override).
|
|
15
24
|
*/
|
|
16
25
|
export declare function bridgeUserConfigToOtelEnv(): void;
|
package/dist/core/env-bridge.js
CHANGED
|
@@ -11,18 +11,33 @@ exports.bridgeUserConfigToOtelEnv = bridgeUserConfigToOtelEnv;
|
|
|
11
11
|
* canonical OTel env names so transport.ts (and any future OTel SDK adoption)
|
|
12
12
|
* can read them via the OTel-spec names.
|
|
13
13
|
*
|
|
14
|
+
* The user-facing `endpoint` is treated as a *full* OTLP/HTTP traces URL
|
|
15
|
+
* (e.g., `http://127.0.0.1:5147/v1/traces`), so we map it to
|
|
16
|
+
* `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` (signal-specific full URL per OTel
|
|
17
|
+
* spec) rather than `OTEL_EXPORTER_OTLP_ENDPOINT` (which is a base URL the
|
|
18
|
+
* SDK appends `/v1/traces` to). This way both the OTel SDK (when used) and
|
|
19
|
+
* pinta-cc's hand-written transport agree on the URL without any path
|
|
20
|
+
* manipulation downstream.
|
|
21
|
+
*
|
|
14
22
|
* Pinta Manager auto-injects `CLAUDE_PLUGIN_OPTION_*` via Claude Code's
|
|
15
23
|
* settings.json. OSS users fill them in via the `/plugin install` UI.
|
|
16
24
|
*
|
|
17
|
-
* Existing
|
|
25
|
+
* Existing OTEL_EXPORTER_OTLP_TRACES_ENDPOINT / HEADERS take precedence
|
|
26
|
+
* (explicit override).
|
|
18
27
|
*/
|
|
19
28
|
function bridgeUserConfigToOtelEnv() {
|
|
20
|
-
if (process.env.CLAUDE_PLUGIN_OPTION_ENDPOINT &&
|
|
21
|
-
process.env.
|
|
29
|
+
if (process.env.CLAUDE_PLUGIN_OPTION_ENDPOINT &&
|
|
30
|
+
!process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) {
|
|
31
|
+
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT =
|
|
32
|
+
process.env.CLAUDE_PLUGIN_OPTION_ENDPOINT;
|
|
22
33
|
}
|
|
23
34
|
if (process.env.CLAUDE_PLUGIN_OPTION_API_KEY && !process.env.OTEL_EXPORTER_OTLP_HEADERS) {
|
|
24
35
|
process.env.OTEL_EXPORTER_OTLP_HEADERS =
|
|
25
36
|
`x-pinta-relay-token=${process.env.CLAUDE_PLUGIN_OPTION_API_KEY}`;
|
|
26
37
|
}
|
|
38
|
+
// Expose for guard.ts (~/guard/evaluate auth header)
|
|
39
|
+
if (!process.env.PINTA_RELAY_TOKEN && process.env.CLAUDE_PLUGIN_OPTION_API_KEY) {
|
|
40
|
+
process.env.PINTA_RELAY_TOKEN = process.env.CLAUDE_PLUGIN_OPTION_API_KEY;
|
|
41
|
+
}
|
|
27
42
|
}
|
|
28
43
|
//# sourceMappingURL=env-bridge.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env-bridge.js","sourceRoot":"","sources":["../../src/core/env-bridge.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"env-bridge.js","sourceRoot":"","sources":["../../src/core/env-bridge.ts"],"names":[],"mappings":";;AAwBA,8DAgBC;AAxCD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,yBAAyB;IACvC,IACE,OAAO,CAAC,GAAG,CAAC,6BAA6B;QACzC,CAAC,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAC/C,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,kCAAkC;YAC5C,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC;IAC9C,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,CAAC;QACxF,OAAO,CAAC,GAAG,CAAC,0BAA0B;YACpC,uBAAuB,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,CAAC;IACtE,CAAC;IACD,qDAAqD;IACrD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,CAAC;QAC/E,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC;IAC3E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface GuardInput {
|
|
2
|
+
spanId: string;
|
|
3
|
+
toolName?: string;
|
|
4
|
+
toolInput?: unknown;
|
|
5
|
+
rawTextFields?: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
export interface GuardResult {
|
|
8
|
+
decision: 'ALLOW' | 'DENY' | 'REVIEW';
|
|
9
|
+
reason: string | null;
|
|
10
|
+
durationMs: number;
|
|
11
|
+
failOpenReason?: 'timeout' | 'refused' | 'error';
|
|
12
|
+
}
|
|
13
|
+
export declare function evaluateGuard(input: GuardInput, endpoint: string | undefined): Promise<GuardResult | null>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.evaluateGuard = evaluateGuard;
|
|
4
|
+
const TIMEOUT_MS = 50;
|
|
5
|
+
function sleep(ms) {
|
|
6
|
+
return new Promise((_, reject) => setTimeout(() => {
|
|
7
|
+
const err = new Error('Guard request timed out');
|
|
8
|
+
err.name = 'TimeoutError';
|
|
9
|
+
reject(err);
|
|
10
|
+
}, ms));
|
|
11
|
+
}
|
|
12
|
+
async function evaluateGuard(input, endpoint) {
|
|
13
|
+
if (!endpoint)
|
|
14
|
+
return null;
|
|
15
|
+
if (process.env.PINTA_GUARD_DISABLED === '1')
|
|
16
|
+
return null;
|
|
17
|
+
const start = Date.now();
|
|
18
|
+
try {
|
|
19
|
+
const res = await Promise.race([
|
|
20
|
+
fetch(endpoint, {
|
|
21
|
+
method: 'POST',
|
|
22
|
+
headers: {
|
|
23
|
+
'content-type': 'application/json',
|
|
24
|
+
'x-pinta-relay-token': process.env.PINTA_RELAY_TOKEN ?? '',
|
|
25
|
+
},
|
|
26
|
+
body: JSON.stringify({ input }),
|
|
27
|
+
}),
|
|
28
|
+
sleep(TIMEOUT_MS),
|
|
29
|
+
]);
|
|
30
|
+
if (res.status !== 200) {
|
|
31
|
+
return { decision: 'ALLOW', reason: null, durationMs: Date.now() - start, failOpenReason: 'error' };
|
|
32
|
+
}
|
|
33
|
+
const body = (await res.json());
|
|
34
|
+
return { decision: body.decision, reason: body.reason, durationMs: body.durationMs ?? (Date.now() - start) };
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
const reason = err.name === 'TimeoutError' ? 'timeout' : 'error';
|
|
38
|
+
return { decision: 'ALLOW', reason: null, durationMs: Date.now() - start, failOpenReason: reason };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/core/guard.ts"],"names":[],"mappings":";;AA0BA,sCA4BC;AAxCD,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACjD,GAAG,CAAC,IAAI,GAAG,cAAc,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,CAAC;IACd,CAAC,EAAE,EAAE,CAAC,CACP,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,aAAa,CACjC,KAAiB,EACjB,QAA4B;IAE5B,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAC7B,KAAK,CAAC,QAAQ,EAAE;gBACd,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,qBAAqB,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE;iBAC3D;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;aAChC,CAAC;YACF,KAAK,CAAC,UAAU,CAAC;SAClB,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC;QACtG,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsF,CAAC;QACrH,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;IAC/G,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAmC,GAAa,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;QAC3G,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC;IACrG,CAAC;AACH,CAAC"}
|
package/dist/core/otlp.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BaseEvent } from "./types.js";
|
|
2
|
+
import type { GuardResult } from "./guard.js";
|
|
2
3
|
export interface OtlpAttribute {
|
|
3
4
|
key: string;
|
|
4
5
|
value: {
|
|
@@ -48,6 +49,7 @@ export declare function buildOtlpPayload(args: {
|
|
|
48
49
|
event: BaseEvent;
|
|
49
50
|
traceId: string;
|
|
50
51
|
now?: number;
|
|
52
|
+
guard?: GuardResult | null;
|
|
51
53
|
}): OtlpPayload;
|
|
52
54
|
/**
|
|
53
55
|
* Combine multiple per-hook payloads into a single OTLP payload by
|
package/dist/core/otlp.js
CHANGED
|
@@ -177,6 +177,16 @@ function resourceAttrs() {
|
|
|
177
177
|
function buildOtlpPayload(args) {
|
|
178
178
|
const ts = args.now ?? Date.now();
|
|
179
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
|
+
}
|
|
180
190
|
const span = {
|
|
181
191
|
traceId: ulidToTraceId(args.traceId),
|
|
182
192
|
spanId: newSpanId(),
|
|
@@ -184,7 +194,7 @@ function buildOtlpPayload(args) {
|
|
|
184
194
|
kind: 1, // SPAN_KIND_INTERNAL
|
|
185
195
|
startTimeUnixNano: tsNano,
|
|
186
196
|
endTimeUnixNano: tsNano,
|
|
187
|
-
attributes:
|
|
197
|
+
attributes: attrs,
|
|
188
198
|
};
|
|
189
199
|
return {
|
|
190
200
|
resourceSpans: [
|
package/dist/core/otlp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"otlp.js","sourceRoot":"","sources":["../../src/core/otlp.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"otlp.js","sourceRoot":"","sources":["../../src/core/otlp.ts"],"names":[],"mappings":"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"}
|
package/dist/core/transport.js
CHANGED
|
@@ -16,11 +16,24 @@ function parseHeadersEnv(raw) {
|
|
|
16
16
|
return out;
|
|
17
17
|
}
|
|
18
18
|
function getOptions() {
|
|
19
|
-
|
|
19
|
+
// OTLP/HTTP spec: TRACES_ENDPOINT is the full URL (no append by exporter);
|
|
20
|
+
// ENDPOINT is a base URL the SDK appends /v1/traces to. We treat the
|
|
21
|
+
// value as a full URL — env-bridge maps CLAUDE_PLUGIN_OPTION_ENDPOINT to
|
|
22
|
+
// TRACES_ENDPOINT specifically. For OSS users who set ENDPOINT directly,
|
|
23
|
+
// assume base URL and append /v1/traces.
|
|
24
|
+
const tracesEndpoint = process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;
|
|
25
|
+
const baseEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
26
|
+
let endpoint;
|
|
27
|
+
if (tracesEndpoint) {
|
|
28
|
+
endpoint = tracesEndpoint.replace(/\/+$/, "");
|
|
29
|
+
}
|
|
30
|
+
else if (baseEndpoint) {
|
|
31
|
+
endpoint = baseEndpoint.replace(/\/+$/, "") + "/v1/traces";
|
|
32
|
+
}
|
|
20
33
|
if (!endpoint)
|
|
21
34
|
return null;
|
|
22
35
|
return {
|
|
23
|
-
endpoint
|
|
36
|
+
endpoint,
|
|
24
37
|
headers: parseHeadersEnv(process.env.OTEL_EXPORTER_OTLP_HEADERS),
|
|
25
38
|
};
|
|
26
39
|
}
|
|
@@ -69,7 +82,8 @@ class Transport {
|
|
|
69
82
|
const ctrl = new AbortController();
|
|
70
83
|
const timer = setTimeout(() => ctrl.abort(), TIMEOUT_MS);
|
|
71
84
|
try {
|
|
72
|
-
|
|
85
|
+
// opts.endpoint is the full traces URL — no path append.
|
|
86
|
+
const res = await fetch(opts.endpoint, {
|
|
73
87
|
method: "POST",
|
|
74
88
|
headers: {
|
|
75
89
|
"Content-Type": "application/json",
|
|
@@ -79,7 +93,21 @@ class Transport {
|
|
|
79
93
|
signal: ctrl.signal,
|
|
80
94
|
});
|
|
81
95
|
if (!res.ok) {
|
|
82
|
-
|
|
96
|
+
let body = "";
|
|
97
|
+
try {
|
|
98
|
+
body = (await res.text()).slice(0, 200);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
/* ignore */
|
|
102
|
+
}
|
|
103
|
+
const hint = res.status === 401 || res.status === 403
|
|
104
|
+
? " — check OTEL_EXPORTER_OTLP_HEADERS (relay token)"
|
|
105
|
+
: res.status === 404
|
|
106
|
+
? " — check OTEL_EXPORTER_OTLP_TRACES_ENDPOINT path"
|
|
107
|
+
: res.status >= 500
|
|
108
|
+
? " — collector may be down"
|
|
109
|
+
: "";
|
|
110
|
+
process.stderr.write(`[pinta-cc] OTLP POST ${res.status} ${opts.endpoint}${hint}${body ? ` body=${body}` : ""}\n`);
|
|
83
111
|
return false;
|
|
84
112
|
}
|
|
85
113
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/core/transport.ts"],"names":[],"mappings":";;;AAAA,qDAA8C;AAE9C,uCAAuC;AAGvC,MAAM,UAAU,GAAG,IAAI,CAAC;AAOxB,SAAS,eAAe,CAAC,GAAuB;IAC9C,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,MAAM,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAClE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,UAAU;IACjB,MAAM,
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/core/transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,12 +4,33 @@ exports.handlePreToolUse = handlePreToolUse;
|
|
|
4
4
|
const transport_js_1 = require("../core/transport.js");
|
|
5
5
|
const trace_js_1 = require("../core/trace.js");
|
|
6
6
|
const otlp_js_1 = require("../core/otlp.js");
|
|
7
|
+
const guard_js_1 = require("../core/guard.js");
|
|
7
8
|
async function handlePreToolUse(event, config) {
|
|
9
|
+
const guardEndpoint = process.env.PINTA_GUARD_ENDPOINT;
|
|
10
|
+
const rawToolInput = typeof event.tool_input === 'string'
|
|
11
|
+
? event.tool_input
|
|
12
|
+
: JSON.stringify(event.tool_input);
|
|
13
|
+
const guard = await (0, guard_js_1.evaluateGuard)({
|
|
14
|
+
spanId: event.session_id ?? 'unknown',
|
|
15
|
+
toolName: event.tool_name,
|
|
16
|
+
toolInput: event.tool_input,
|
|
17
|
+
rawTextFields: { toolInput: rawToolInput },
|
|
18
|
+
}, guardEndpoint);
|
|
8
19
|
const transport = new transport_js_1.Transport(config);
|
|
9
20
|
await transport.flush();
|
|
10
21
|
const traceId = new trace_js_1.TraceManager(config).currentTrace();
|
|
11
|
-
const payload = (0, otlp_js_1.buildOtlpPayload)({ event, traceId });
|
|
22
|
+
const payload = (0, otlp_js_1.buildOtlpPayload)({ event, traceId, guard });
|
|
12
23
|
await transport.send(payload);
|
|
24
|
+
if (guard?.decision === 'DENY') {
|
|
25
|
+
const out = {
|
|
26
|
+
hookSpecificOutput: {
|
|
27
|
+
hookEventName: 'PreToolUse',
|
|
28
|
+
permissionDecision: 'deny',
|
|
29
|
+
permissionDecisionReason: guard.reason ?? 'guard_deny',
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
process.stdout.write(JSON.stringify(out) + '\n');
|
|
33
|
+
}
|
|
13
34
|
return 0;
|
|
14
35
|
}
|
|
15
36
|
//# sourceMappingURL=pre-tool-use.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pre-tool-use.js","sourceRoot":"","sources":["../../src/handlers/pre-tool-use.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"pre-tool-use.js","sourceRoot":"","sources":["../../src/handlers/pre-tool-use.ts"],"names":[],"mappings":";;AAOA,4CAmCC;AAxCD,uDAAiD;AACjD,+CAAgD;AAChD,6CAAmD;AACnD,+CAAiD;AAE1C,KAAK,UAAU,gBAAgB,CACpC,KAAsB,EACtB,MAAmB;IAEnB,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IACvD,MAAM,YAAY,GAAG,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;QACvD,CAAC,CAAC,KAAK,CAAC,UAAU;QAClB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,MAAM,IAAA,wBAAa,EAC/B;QACE,MAAM,EAAE,KAAK,CAAC,UAAU,IAAI,SAAS;QACrC,QAAQ,EAAE,KAAK,CAAC,SAAS;QACzB,SAAS,EAAE,KAAK,CAAC,UAAU;QAC3B,aAAa,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE;KAC3C,EACD,aAAa,CACd,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IACxB,MAAM,OAAO,GAAG,IAAI,uBAAY,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,CAAC;IACxD,MAAM,OAAO,GAAG,IAAA,0BAAgB,EAAC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5D,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAE9B,IAAI,KAAK,EAAE,QAAQ,KAAK,MAAM,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG;YACV,kBAAkB,EAAE;gBAClB,aAAa,EAAE,YAAY;gBAC3B,kBAAkB,EAAE,MAAe;gBACnC,wBAAwB,EAAE,KAAK,CAAC,MAAM,IAAI,YAAY;aACvD;SACF,CAAC;QACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|