@pinta-ai/pinta-cc 1.2.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 (61) hide show
  1. package/.claude-plugin/marketplace.json +20 -0
  2. package/.claude-plugin/plugin.json +20 -0
  3. package/CHANGELOG.md +42 -0
  4. package/LICENSE +136 -0
  5. package/README.md +200 -0
  6. package/dist/core/config.d.ts +13 -0
  7. package/dist/core/config.js +22 -0
  8. package/dist/core/config.js.map +1 -0
  9. package/dist/core/env-bridge.d.ts +16 -0
  10. package/dist/core/env-bridge.js +28 -0
  11. package/dist/core/env-bridge.js.map +1 -0
  12. package/dist/core/identity.d.ts +1 -0
  13. package/dist/core/identity.js +3 -0
  14. package/dist/core/identity.js.map +1 -0
  15. package/dist/core/otlp.d.ts +57 -0
  16. package/dist/core/otlp.js +214 -0
  17. package/dist/core/otlp.js.map +1 -0
  18. package/dist/core/redact.d.ts +57 -0
  19. package/dist/core/redact.js +149 -0
  20. package/dist/core/redact.js.map +1 -0
  21. package/dist/core/retry-queue.d.ts +26 -0
  22. package/dist/core/retry-queue.js +127 -0
  23. package/dist/core/retry-queue.js.map +1 -0
  24. package/dist/core/trace.d.ts +10 -0
  25. package/dist/core/trace.js +61 -0
  26. package/dist/core/trace.js.map +1 -0
  27. package/dist/core/transport.d.ts +18 -0
  28. package/dist/core/transport.js +97 -0
  29. package/dist/core/transport.js.map +1 -0
  30. package/dist/core/types.d.ts +65 -0
  31. package/dist/core/types.js +39 -0
  32. package/dist/core/types.js.map +1 -0
  33. package/dist/handlers/default.d.ts +6 -0
  34. package/dist/handlers/default.js +11 -0
  35. package/dist/handlers/default.js.map +1 -0
  36. package/dist/handlers/permission.d.ts +3 -0
  37. package/dist/handlers/permission.js +15 -0
  38. package/dist/handlers/permission.js.map +1 -0
  39. package/dist/handlers/post-tool-use.d.ts +3 -0
  40. package/dist/handlers/post-tool-use.js +15 -0
  41. package/dist/handlers/post-tool-use.js.map +1 -0
  42. package/dist/handlers/pre-tool-use.d.ts +3 -0
  43. package/dist/handlers/pre-tool-use.js +15 -0
  44. package/dist/handlers/pre-tool-use.js.map +1 -0
  45. package/dist/handlers/session.d.ts +3 -0
  46. package/dist/handlers/session.js +15 -0
  47. package/dist/handlers/session.js.map +1 -0
  48. package/dist/handlers/stop.d.ts +3 -0
  49. package/dist/handlers/stop.js +15 -0
  50. package/dist/handlers/stop.js.map +1 -0
  51. package/dist/handlers/subagent.d.ts +3 -0
  52. package/dist/handlers/subagent.js +15 -0
  53. package/dist/handlers/subagent.js.map +1 -0
  54. package/dist/handlers/user-prompt.d.ts +3 -0
  55. package/dist/handlers/user-prompt.js +15 -0
  56. package/dist/handlers/user-prompt.js.map +1 -0
  57. package/dist/index.d.ts +1 -0
  58. package/dist/index.js +65 -0
  59. package/dist/index.js.map +1 -0
  60. package/hooks/hooks.json +18 -0
  61. package/package.json +37 -0
@@ -0,0 +1,61 @@
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
+ /** UserPromptSubmit 시 새 traceId 생성 및 저장 */
37
+ newTrace() {
38
+ const traceId = generateUlid();
39
+ this.save(traceId);
40
+ return traceId;
41
+ }
42
+ /** 현재 traceId 반환. 없으면 새로 생성 */
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
@@ -0,0 +1 @@
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,MAAmB;QAC7B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IACpC,CAAC;IAED,2CAA2C;IAC3C,QAAQ;QACN,MAAM,OAAO,GAAG,YAAY,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,+BAA+B;IAC/B,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"}
@@ -0,0 +1,18 @@
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
+ }
@@ -0,0 +1,97 @@
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
+ const endpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
20
+ if (!endpoint)
21
+ return null;
22
+ return {
23
+ endpoint: endpoint.replace(/\/+$/, ""),
24
+ headers: parseHeadersEnv(process.env.OTEL_EXPORTER_OTLP_HEADERS),
25
+ };
26
+ }
27
+ class Transport {
28
+ queue;
29
+ constructor(config) {
30
+ this.queue = new retry_queue_js_1.RetryQueue(config.pluginData);
31
+ }
32
+ /**
33
+ * POST a single payload. On any failure, enqueue it for the next hook to retry.
34
+ * Silent disable when no endpoint is configured.
35
+ */
36
+ async send(payload) {
37
+ const opts = getOptions();
38
+ if (!opts)
39
+ return; // Silent disable when no endpoint configured
40
+ const ok = await this.post(payload, opts);
41
+ if (!ok)
42
+ this.queue.enqueue(payload);
43
+ }
44
+ /**
45
+ * Best-effort drain. Acquires the lock, reads the queue, attempts a single
46
+ * batched POST. On failure, leaves the queue untouched.
47
+ * Silent disable when no endpoint is configured.
48
+ */
49
+ async flush() {
50
+ const opts = getOptions();
51
+ if (!opts)
52
+ return;
53
+ if (!this.queue.tryAcquireLock())
54
+ return;
55
+ try {
56
+ const entries = this.queue.readAll();
57
+ if (entries.length === 0)
58
+ return;
59
+ const merged = (0, otlp_js_1.mergeBatch)(entries.map((e) => e.payload));
60
+ const ok = await this.post(merged, opts);
61
+ if (ok)
62
+ this.queue.rewrite([]);
63
+ }
64
+ finally {
65
+ this.queue.release();
66
+ }
67
+ }
68
+ async post(payload, opts) {
69
+ const ctrl = new AbortController();
70
+ const timer = setTimeout(() => ctrl.abort(), TIMEOUT_MS);
71
+ try {
72
+ const res = await fetch(`${opts.endpoint}/traces`, {
73
+ method: "POST",
74
+ headers: {
75
+ "Content-Type": "application/json",
76
+ ...opts.headers,
77
+ },
78
+ body: JSON.stringify(payload),
79
+ signal: ctrl.signal,
80
+ });
81
+ if (!res.ok) {
82
+ process.stderr.write(`[pinta-cc] OTLP POST ${res.status}\n`);
83
+ return false;
84
+ }
85
+ return true;
86
+ }
87
+ catch (err) {
88
+ process.stderr.write(`[pinta-cc] OTLP POST failed: ${err.message ?? String(err)}\n`);
89
+ return false;
90
+ }
91
+ finally {
92
+ clearTimeout(timer);
93
+ }
94
+ }
95
+ }
96
+ exports.Transport = Transport;
97
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/core/transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ export interface BaseEvent {
2
+ session_id: string;
3
+ transcript_path: string;
4
+ cwd: string;
5
+ permission_mode?: string;
6
+ hook_event_name: string;
7
+ [key: string]: unknown;
8
+ }
9
+ export interface PreToolUseEvent extends BaseEvent {
10
+ hook_event_name: "PreToolUse";
11
+ tool_name: string;
12
+ tool_input: Record<string, unknown>;
13
+ tool_use_id: string;
14
+ }
15
+ export interface PostToolUseEvent extends BaseEvent {
16
+ hook_event_name: "PostToolUse";
17
+ tool_name: string;
18
+ tool_input: Record<string, unknown>;
19
+ tool_response: unknown;
20
+ tool_use_id: string;
21
+ }
22
+ export interface PostToolUseFailureEvent extends BaseEvent {
23
+ hook_event_name: "PostToolUseFailure";
24
+ tool_name: string;
25
+ tool_input: Record<string, unknown>;
26
+ tool_use_id: string;
27
+ error?: string;
28
+ is_interrupt?: boolean;
29
+ }
30
+ export interface UserPromptSubmitEvent extends BaseEvent {
31
+ hook_event_name: "UserPromptSubmit";
32
+ prompt: string;
33
+ }
34
+ export interface SessionEvent extends BaseEvent {
35
+ hook_event_name: "SessionStart" | "SessionEnd";
36
+ }
37
+ export interface SubagentEvent extends BaseEvent {
38
+ hook_event_name: "SubagentStart" | "SubagentStop";
39
+ agent_id?: string;
40
+ agent_type?: string;
41
+ }
42
+ export interface StopEvent extends BaseEvent {
43
+ hook_event_name: "Stop";
44
+ stop_hook_active?: boolean;
45
+ }
46
+ export interface PermissionEvent extends BaseEvent {
47
+ hook_event_name: "PermissionRequest" | "PermissionDenied";
48
+ tool_name?: string;
49
+ tool_input?: Record<string, unknown>;
50
+ }
51
+ export declare function isPreToolUseEvent(event: BaseEvent): event is PreToolUseEvent;
52
+ export declare function isPostToolUseEvent(event: BaseEvent): event is PostToolUseEvent | PostToolUseFailureEvent;
53
+ export declare function isUserPromptSubmitEvent(event: BaseEvent): event is UserPromptSubmitEvent;
54
+ export declare function isSessionEvent(event: BaseEvent): event is SessionEvent;
55
+ export declare function isSubagentEvent(event: BaseEvent): event is SubagentEvent;
56
+ export declare function isStopEvent(event: BaseEvent): event is StopEvent;
57
+ export declare function isPermissionEvent(event: BaseEvent): event is PermissionEvent;
58
+ export declare function isSkippedHook(event: BaseEvent): boolean;
59
+ export interface HookBlockOutput {
60
+ hookSpecificOutput: {
61
+ hookEventName: "PreToolUse";
62
+ permissionDecision: "deny";
63
+ permissionDecisionReason: string;
64
+ };
65
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ // --- Claude Code hook event types ---
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.isPreToolUseEvent = isPreToolUseEvent;
5
+ exports.isPostToolUseEvent = isPostToolUseEvent;
6
+ exports.isUserPromptSubmitEvent = isUserPromptSubmitEvent;
7
+ exports.isSessionEvent = isSessionEvent;
8
+ exports.isSubagentEvent = isSubagentEvent;
9
+ exports.isStopEvent = isStopEvent;
10
+ exports.isPermissionEvent = isPermissionEvent;
11
+ exports.isSkippedHook = isSkippedHook;
12
+ // --- Type guards ---
13
+ function isPreToolUseEvent(event) {
14
+ return event.hook_event_name === "PreToolUse";
15
+ }
16
+ function isPostToolUseEvent(event) {
17
+ return (event.hook_event_name === "PostToolUse" || event.hook_event_name === "PostToolUseFailure");
18
+ }
19
+ function isUserPromptSubmitEvent(event) {
20
+ return event.hook_event_name === "UserPromptSubmit";
21
+ }
22
+ function isSessionEvent(event) {
23
+ return event.hook_event_name === "SessionStart" || event.hook_event_name === "SessionEnd";
24
+ }
25
+ function isSubagentEvent(event) {
26
+ return event.hook_event_name === "SubagentStart" || event.hook_event_name === "SubagentStop";
27
+ }
28
+ function isStopEvent(event) {
29
+ return event.hook_event_name === "Stop";
30
+ }
31
+ function isPermissionEvent(event) {
32
+ return (event.hook_event_name === "PermissionRequest" || event.hook_event_name === "PermissionDenied");
33
+ }
34
+ // --- Skip-list (route to default no-op handler) ---
35
+ const SKIP_HOOKS = new Set(["Notification", "TaskCreated", "TaskCompleted"]);
36
+ function isSkippedHook(event) {
37
+ return SKIP_HOOKS.has(event.hook_event_name);
38
+ }
39
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":";AAAA,uCAAuC;;AAgEvC,8CAEC;AAED,gDAMC;AAED,0DAEC;AAED,wCAEC;AAED,0CAEC;AAED,kCAEC;AAED,8CAIC;AAKD,sCAEC;AAzCD,sBAAsB;AAEtB,SAAgB,iBAAiB,CAAC,KAAgB;IAChD,OAAO,KAAK,CAAC,eAAe,KAAK,YAAY,CAAC;AAChD,CAAC;AAED,SAAgB,kBAAkB,CAChC,KAAgB;IAEhB,OAAO,CACL,KAAK,CAAC,eAAe,KAAK,aAAa,IAAI,KAAK,CAAC,eAAe,KAAK,oBAAoB,CAC1F,CAAC;AACJ,CAAC;AAED,SAAgB,uBAAuB,CAAC,KAAgB;IACtD,OAAO,KAAK,CAAC,eAAe,KAAK,kBAAkB,CAAC;AACtD,CAAC;AAED,SAAgB,cAAc,CAAC,KAAgB;IAC7C,OAAO,KAAK,CAAC,eAAe,KAAK,cAAc,IAAI,KAAK,CAAC,eAAe,KAAK,YAAY,CAAC;AAC5F,CAAC;AAED,SAAgB,eAAe,CAAC,KAAgB;IAC9C,OAAO,KAAK,CAAC,eAAe,KAAK,eAAe,IAAI,KAAK,CAAC,eAAe,KAAK,cAAc,CAAC;AAC/F,CAAC;AAED,SAAgB,WAAW,CAAC,KAAgB;IAC1C,OAAO,KAAK,CAAC,eAAe,KAAK,MAAM,CAAC;AAC1C,CAAC;AAED,SAAgB,iBAAiB,CAAC,KAAgB;IAChD,OAAO,CACL,KAAK,CAAC,eAAe,KAAK,mBAAmB,IAAI,KAAK,CAAC,eAAe,KAAK,kBAAkB,CAC9F,CAAC;AACJ,CAAC;AAED,qDAAqD;AAErD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC,CAAC;AAC7E,SAAgB,aAAa,CAAC,KAAgB;IAC5C,OAAO,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { BaseEvent } from "../core/types.js";
2
+ /**
3
+ * Catch-all for hooks we explicitly skip (Notification, TaskCreated, TaskCompleted)
4
+ * and any future hook event we have not yet routed. Exits 0 silently.
5
+ */
6
+ export declare function handleDefault(_event: BaseEvent): Promise<number>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleDefault = handleDefault;
4
+ /**
5
+ * Catch-all for hooks we explicitly skip (Notification, TaskCreated, TaskCompleted)
6
+ * and any future hook event we have not yet routed. Exits 0 silently.
7
+ */
8
+ async function handleDefault(_event) {
9
+ return 0;
10
+ }
11
+ //# sourceMappingURL=default.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default.js","sourceRoot":"","sources":["../../src/handlers/default.ts"],"names":[],"mappings":";;AAMA,sCAEC;AAND;;;GAGG;AACI,KAAK,UAAU,aAAa,CAAC,MAAiB;IACnD,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PintaConfig } from "../core/config.js";
2
+ import type { PermissionEvent } from "../core/types.js";
3
+ export declare function handlePermission(event: PermissionEvent, config: PintaConfig): Promise<number>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handlePermission = handlePermission;
4
+ const transport_js_1 = require("../core/transport.js");
5
+ const trace_js_1 = require("../core/trace.js");
6
+ const otlp_js_1 = require("../core/otlp.js");
7
+ async function handlePermission(event, config) {
8
+ const transport = new transport_js_1.Transport(config);
9
+ await transport.flush();
10
+ const traceId = new trace_js_1.TraceManager(config).currentTrace();
11
+ const payload = (0, otlp_js_1.buildOtlpPayload)({ event, traceId });
12
+ await transport.send(payload);
13
+ return 0;
14
+ }
15
+ //# sourceMappingURL=permission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission.js","sourceRoot":"","sources":["../../src/handlers/permission.ts"],"names":[],"mappings":";;AAMA,4CAWC;AAfD,uDAAiD;AACjD,+CAAgD;AAChD,6CAAmD;AAE5C,KAAK,UAAU,gBAAgB,CACpC,KAAsB,EACtB,MAAmB;IAEnB,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IAExB,MAAM,OAAO,GAAG,IAAI,uBAAY,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,CAAC;IACxD,MAAM,OAAO,GAAG,IAAA,0BAAgB,EAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IACrD,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PintaConfig } from "../core/config.js";
2
+ import type { PostToolUseEvent, PostToolUseFailureEvent } from "../core/types.js";
3
+ export declare function handlePostToolUse(event: PostToolUseEvent | PostToolUseFailureEvent, config: PintaConfig): Promise<number>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handlePostToolUse = handlePostToolUse;
4
+ const transport_js_1 = require("../core/transport.js");
5
+ const trace_js_1 = require("../core/trace.js");
6
+ const otlp_js_1 = require("../core/otlp.js");
7
+ async function handlePostToolUse(event, config) {
8
+ const transport = new transport_js_1.Transport(config);
9
+ await transport.flush();
10
+ const traceId = new trace_js_1.TraceManager(config).currentTrace();
11
+ const payload = (0, otlp_js_1.buildOtlpPayload)({ event, traceId });
12
+ await transport.send(payload);
13
+ return 0;
14
+ }
15
+ //# sourceMappingURL=post-tool-use.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post-tool-use.js","sourceRoot":"","sources":["../../src/handlers/post-tool-use.ts"],"names":[],"mappings":";;AAMA,8CAWC;AAfD,uDAAiD;AACjD,+CAAgD;AAChD,6CAAmD;AAE5C,KAAK,UAAU,iBAAiB,CACrC,KAAiD,EACjD,MAAmB;IAEnB,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IAExB,MAAM,OAAO,GAAG,IAAI,uBAAY,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,CAAC;IACxD,MAAM,OAAO,GAAG,IAAA,0BAAgB,EAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IACrD,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PintaConfig } from "../core/config.js";
2
+ import type { PreToolUseEvent } from "../core/types.js";
3
+ export declare function handlePreToolUse(event: PreToolUseEvent, config: PintaConfig): Promise<number>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handlePreToolUse = handlePreToolUse;
4
+ const transport_js_1 = require("../core/transport.js");
5
+ const trace_js_1 = require("../core/trace.js");
6
+ const otlp_js_1 = require("../core/otlp.js");
7
+ async function handlePreToolUse(event, config) {
8
+ const transport = new transport_js_1.Transport(config);
9
+ await transport.flush();
10
+ const traceId = new trace_js_1.TraceManager(config).currentTrace();
11
+ const payload = (0, otlp_js_1.buildOtlpPayload)({ event, traceId });
12
+ await transport.send(payload);
13
+ return 0;
14
+ }
15
+ //# sourceMappingURL=pre-tool-use.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre-tool-use.js","sourceRoot":"","sources":["../../src/handlers/pre-tool-use.ts"],"names":[],"mappings":";;AAMA,4CAWC;AAfD,uDAAiD;AACjD,+CAAgD;AAChD,6CAAmD;AAE5C,KAAK,UAAU,gBAAgB,CACpC,KAAsB,EACtB,MAAmB;IAEnB,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IAExB,MAAM,OAAO,GAAG,IAAI,uBAAY,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,CAAC;IACxD,MAAM,OAAO,GAAG,IAAA,0BAAgB,EAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IACrD,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PintaConfig } from "../core/config.js";
2
+ import type { SessionEvent } from "../core/types.js";
3
+ export declare function handleSession(event: SessionEvent, config: PintaConfig): Promise<number>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleSession = handleSession;
4
+ const transport_js_1 = require("../core/transport.js");
5
+ const trace_js_1 = require("../core/trace.js");
6
+ const otlp_js_1 = require("../core/otlp.js");
7
+ async function handleSession(event, config) {
8
+ const transport = new transport_js_1.Transport(config);
9
+ await transport.flush();
10
+ const traceId = new trace_js_1.TraceManager(config).currentTrace();
11
+ const payload = (0, otlp_js_1.buildOtlpPayload)({ event, traceId });
12
+ await transport.send(payload);
13
+ return 0;
14
+ }
15
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/handlers/session.ts"],"names":[],"mappings":";;AAMA,sCAWC;AAfD,uDAAiD;AACjD,+CAAgD;AAChD,6CAAmD;AAE5C,KAAK,UAAU,aAAa,CACjC,KAAmB,EACnB,MAAmB;IAEnB,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IAExB,MAAM,OAAO,GAAG,IAAI,uBAAY,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,CAAC;IACxD,MAAM,OAAO,GAAG,IAAA,0BAAgB,EAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IACrD,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PintaConfig } from "../core/config.js";
2
+ import type { StopEvent } from "../core/types.js";
3
+ export declare function handleStop(event: StopEvent, config: PintaConfig): Promise<number>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleStop = handleStop;
4
+ const transport_js_1 = require("../core/transport.js");
5
+ const trace_js_1 = require("../core/trace.js");
6
+ const otlp_js_1 = require("../core/otlp.js");
7
+ async function handleStop(event, config) {
8
+ const transport = new transport_js_1.Transport(config);
9
+ await transport.flush();
10
+ const traceId = new trace_js_1.TraceManager(config).currentTrace();
11
+ const payload = (0, otlp_js_1.buildOtlpPayload)({ event, traceId });
12
+ await transport.send(payload);
13
+ return 0;
14
+ }
15
+ //# sourceMappingURL=stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/handlers/stop.ts"],"names":[],"mappings":";;AAMA,gCAWC;AAfD,uDAAiD;AACjD,+CAAgD;AAChD,6CAAmD;AAE5C,KAAK,UAAU,UAAU,CAC9B,KAAgB,EAChB,MAAmB;IAEnB,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IAExB,MAAM,OAAO,GAAG,IAAI,uBAAY,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,CAAC;IACxD,MAAM,OAAO,GAAG,IAAA,0BAAgB,EAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IACrD,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PintaConfig } from "../core/config.js";
2
+ import type { SubagentEvent } from "../core/types.js";
3
+ export declare function handleSubagent(event: SubagentEvent, config: PintaConfig): Promise<number>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleSubagent = handleSubagent;
4
+ const transport_js_1 = require("../core/transport.js");
5
+ const trace_js_1 = require("../core/trace.js");
6
+ const otlp_js_1 = require("../core/otlp.js");
7
+ async function handleSubagent(event, config) {
8
+ const transport = new transport_js_1.Transport(config);
9
+ await transport.flush();
10
+ const traceId = new trace_js_1.TraceManager(config).currentTrace();
11
+ const payload = (0, otlp_js_1.buildOtlpPayload)({ event, traceId });
12
+ await transport.send(payload);
13
+ return 0;
14
+ }
15
+ //# sourceMappingURL=subagent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent.js","sourceRoot":"","sources":["../../src/handlers/subagent.ts"],"names":[],"mappings":";;AAMA,wCAWC;AAfD,uDAAiD;AACjD,+CAAgD;AAChD,6CAAmD;AAE5C,KAAK,UAAU,cAAc,CAClC,KAAoB,EACpB,MAAmB;IAEnB,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IAExB,MAAM,OAAO,GAAG,IAAI,uBAAY,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,CAAC;IACxD,MAAM,OAAO,GAAG,IAAA,0BAAgB,EAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IACrD,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PintaConfig } from "../core/config.js";
2
+ import type { UserPromptSubmitEvent } from "../core/types.js";
3
+ export declare function handleUserPrompt(event: UserPromptSubmitEvent, config: PintaConfig): Promise<number>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleUserPrompt = handleUserPrompt;
4
+ const transport_js_1 = require("../core/transport.js");
5
+ const trace_js_1 = require("../core/trace.js");
6
+ const otlp_js_1 = require("../core/otlp.js");
7
+ async function handleUserPrompt(event, config) {
8
+ const transport = new transport_js_1.Transport(config);
9
+ await transport.flush();
10
+ const traceId = new trace_js_1.TraceManager(config).newTrace(); // NEW trace per user turn
11
+ const payload = (0, otlp_js_1.buildOtlpPayload)({ event, traceId });
12
+ await transport.send(payload);
13
+ return 0;
14
+ }
15
+ //# sourceMappingURL=user-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-prompt.js","sourceRoot":"","sources":["../../src/handlers/user-prompt.ts"],"names":[],"mappings":";;AAMA,4CAWC;AAfD,uDAAiD;AACjD,+CAAgD;AAChD,6CAAmD;AAE5C,KAAK,UAAU,gBAAgB,CACpC,KAA4B,EAC5B,MAAmB;IAEnB,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IAExB,MAAM,OAAO,GAAG,IAAI,uBAAY,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,0BAA0B;IAC/E,MAAM,OAAO,GAAG,IAAA,0BAAgB,EAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IACrD,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const env_bridge_js_1 = require("./core/env-bridge.js");
4
+ const config_js_1 = require("./core/config.js");
5
+ const types_js_1 = require("./core/types.js");
6
+ const pre_tool_use_js_1 = require("./handlers/pre-tool-use.js");
7
+ const post_tool_use_js_1 = require("./handlers/post-tool-use.js");
8
+ const user_prompt_js_1 = require("./handlers/user-prompt.js");
9
+ const session_js_1 = require("./handlers/session.js");
10
+ const subagent_js_1 = require("./handlers/subagent.js");
11
+ const stop_js_1 = require("./handlers/stop.js");
12
+ const permission_js_1 = require("./handlers/permission.js");
13
+ const default_js_1 = require("./handlers/default.js");
14
+ async function readStdin() {
15
+ const chunks = [];
16
+ for await (const chunk of process.stdin) {
17
+ chunks.push(chunk);
18
+ }
19
+ return Buffer.concat(chunks).toString("utf-8");
20
+ }
21
+ async function main() {
22
+ // Bridge CLAUDE_PLUGIN_OPTION_* → OTEL_EXPORTER_OTLP_* FIRST before any other logic.
23
+ // Explicit OTel env vars take precedence over the bridge.
24
+ (0, env_bridge_js_1.bridgeUserConfigToOtelEnv)();
25
+ let exitCode = 0;
26
+ try {
27
+ const config = (0, config_js_1.loadConfig)();
28
+ const raw = await readStdin();
29
+ const event = JSON.parse(raw);
30
+ if ((0, types_js_1.isSkippedHook)(event)) {
31
+ exitCode = await (0, default_js_1.handleDefault)(event);
32
+ }
33
+ else if ((0, types_js_1.isPreToolUseEvent)(event)) {
34
+ exitCode = await (0, pre_tool_use_js_1.handlePreToolUse)(event, config);
35
+ }
36
+ else if ((0, types_js_1.isPostToolUseEvent)(event)) {
37
+ exitCode = await (0, post_tool_use_js_1.handlePostToolUse)(event, config);
38
+ }
39
+ else if ((0, types_js_1.isUserPromptSubmitEvent)(event)) {
40
+ exitCode = await (0, user_prompt_js_1.handleUserPrompt)(event, config);
41
+ }
42
+ else if ((0, types_js_1.isSessionEvent)(event)) {
43
+ exitCode = await (0, session_js_1.handleSession)(event, config);
44
+ }
45
+ else if ((0, types_js_1.isSubagentEvent)(event)) {
46
+ exitCode = await (0, subagent_js_1.handleSubagent)(event, config);
47
+ }
48
+ else if ((0, types_js_1.isStopEvent)(event)) {
49
+ exitCode = await (0, stop_js_1.handleStop)(event, config);
50
+ }
51
+ else if ((0, types_js_1.isPermissionEvent)(event)) {
52
+ exitCode = await (0, permission_js_1.handlePermission)(event, config);
53
+ }
54
+ else {
55
+ exitCode = await (0, default_js_1.handleDefault)(event);
56
+ }
57
+ }
58
+ catch (err) {
59
+ process.stderr.write(`[pinta-cc] error: ${err}\n`);
60
+ exitCode = 0; // top-level catch-all stays fail-open per spec §6
61
+ }
62
+ process.exit(exitCode);
63
+ }
64
+ main();
65
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,wDAAiE;AACjE,gDAA8C;AAC9C,8CASyB;AAEzB,gEAA8D;AAC9D,kEAAgE;AAChE,8DAA6D;AAC7D,sDAAsD;AACtD,wDAAwD;AACxD,gDAAgD;AAChD,4DAA4D;AAC5D,sDAAsD;AAEtD,KAAK,UAAU,SAAS;IACtB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACjD,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,qFAAqF;IACrF,0DAA0D;IAC1D,IAAA,yCAAyB,GAAE,CAAC;IAE5B,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,sBAAU,GAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAc,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEzC,IAAI,IAAA,wBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;YACzB,QAAQ,GAAG,MAAM,IAAA,0BAAa,EAAC,KAAK,CAAC,CAAC;QACxC,CAAC;aAAM,IAAI,IAAA,4BAAiB,EAAC,KAAK,CAAC,EAAE,CAAC;YACpC,QAAQ,GAAG,MAAM,IAAA,kCAAgB,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACnD,CAAC;aAAM,IAAI,IAAA,6BAAkB,EAAC,KAAK,CAAC,EAAE,CAAC;YACrC,QAAQ,GAAG,MAAM,IAAA,oCAAiB,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACpD,CAAC;aAAM,IAAI,IAAA,kCAAuB,EAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,QAAQ,GAAG,MAAM,IAAA,iCAAgB,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACnD,CAAC;aAAM,IAAI,IAAA,yBAAc,EAAC,KAAK,CAAC,EAAE,CAAC;YACjC,QAAQ,GAAG,MAAM,IAAA,0BAAa,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAChD,CAAC;aAAM,IAAI,IAAA,0BAAe,EAAC,KAAK,CAAC,EAAE,CAAC;YAClC,QAAQ,GAAG,MAAM,IAAA,4BAAc,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;aAAM,IAAI,IAAA,sBAAW,EAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,QAAQ,GAAG,MAAM,IAAA,oBAAU,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC7C,CAAC;aAAM,IAAI,IAAA,4BAAiB,EAAC,KAAK,CAAC,EAAE,CAAC;YACpC,QAAQ,GAAG,MAAM,IAAA,gCAAgB,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,MAAM,IAAA,0BAAa,EAAC,KAAK,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;QACnD,QAAQ,GAAG,CAAC,CAAC,CAAC,kDAAkD;IAClE,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACzB,CAAC;AAED,IAAI,EAAE,CAAC"}
@@ -0,0 +1,18 @@
1
+ {
2
+ "hooks": {
3
+ "PreToolUse": [{ "hooks": [{ "type": "command", "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" }] }],
4
+ "PostToolUse": [{ "hooks": [{ "type": "command", "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" }] }],
5
+ "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" }] }],
6
+ "SessionStart": [{ "hooks": [{ "type": "command", "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" }] }],
7
+ "SessionEnd": [{ "hooks": [{ "type": "command", "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" }] }],
8
+ "PostToolUseFailure": [{ "hooks": [{ "type": "command", "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" }] }],
9
+ "PermissionRequest": [{ "hooks": [{ "type": "command", "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" }] }],
10
+ "PermissionDenied": [{ "hooks": [{ "type": "command", "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" }] }],
11
+ "Notification": [{ "hooks": [{ "type": "command", "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" }] }],
12
+ "SubagentStart": [{ "hooks": [{ "type": "command", "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" }] }],
13
+ "SubagentStop": [{ "hooks": [{ "type": "command", "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" }] }],
14
+ "Stop": [{ "hooks": [{ "type": "command", "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" }] }],
15
+ "TaskCreated": [{ "hooks": [{ "type": "command", "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" }] }],
16
+ "TaskCompleted": [{ "hooks": [{ "type": "command", "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" }] }]
17
+ }
18
+ }
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@pinta-ai/pinta-cc",
3
+ "version": "1.2.0",
4
+ "description": "Generic OTLP forwarder for Claude Code hook events",
5
+ "main": "dist/index.js",
6
+ "license": "PolyForm-Noncommercial-1.0.0",
7
+ "files": [
8
+ "dist",
9
+ ".claude-plugin",
10
+ "hooks",
11
+ "LICENSE",
12
+ "README.md",
13
+ "CHANGELOG.md"
14
+ ],
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/awarecorp/pinta-cc.git"
18
+ },
19
+ "homepage": "https://github.com/awarecorp/pinta-cc#readme",
20
+ "bugs": {
21
+ "url": "https://github.com/awarecorp/pinta-cc/issues"
22
+ },
23
+ "scripts": {
24
+ "build": "tsc",
25
+ "dev": "tsc --watch",
26
+ "test": "vitest run",
27
+ "test:watch": "vitest",
28
+ "mock-server": "npx tsx tools/mock-server.ts",
29
+ "prepublishOnly": "npm run build"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^22.0.0",
33
+ "tsx": "^4.0.0",
34
+ "typescript": "^5.7.0",
35
+ "vitest": "^2.1.0"
36
+ }
37
+ }