@raindrop-ai/claude-code 0.0.18 → 0.0.19
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/cli.js +354 -54
- package/dist/index.cjs +334 -36
- package/dist/index.d.cts +19 -9
- package/dist/index.d.ts +19 -9
- package/dist/index.js +334 -36
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -45,6 +45,10 @@ type IdentifyInput = {
|
|
|
45
45
|
userId: string;
|
|
46
46
|
traits?: Record<string, unknown>;
|
|
47
47
|
};
|
|
48
|
+
type EventUsage = {
|
|
49
|
+
promptTokens?: number;
|
|
50
|
+
completionTokens?: number;
|
|
51
|
+
};
|
|
48
52
|
type Patch = {
|
|
49
53
|
eventName?: string;
|
|
50
54
|
userId?: string;
|
|
@@ -52,7 +56,10 @@ type Patch = {
|
|
|
52
56
|
input?: string;
|
|
53
57
|
output?: string;
|
|
54
58
|
model?: string;
|
|
59
|
+
usage?: EventUsage;
|
|
60
|
+
error?: unknown;
|
|
55
61
|
properties?: Record<string, unknown>;
|
|
62
|
+
featureFlags?: Record<string, string>;
|
|
56
63
|
attachments?: Attachment[];
|
|
57
64
|
isPending?: boolean;
|
|
58
65
|
timestamp?: string;
|
|
@@ -149,12 +156,7 @@ declare class EventShipper$1 {
|
|
|
149
156
|
*/
|
|
150
157
|
private requestOpts;
|
|
151
158
|
patch(eventId: string, patch: Patch): Promise<void>;
|
|
152
|
-
finish(eventId: string, patch:
|
|
153
|
-
output?: string;
|
|
154
|
-
model?: string;
|
|
155
|
-
properties?: Record<string, unknown>;
|
|
156
|
-
userId?: string;
|
|
157
|
-
}): Promise<void>;
|
|
159
|
+
finish(eventId: string, patch: Pick<Patch, "output" | "model" | "usage" | "error" | "properties" | "featureFlags" | "userId">): Promise<void>;
|
|
158
160
|
flush(): Promise<void>;
|
|
159
161
|
shutdown(): Promise<void>;
|
|
160
162
|
trackSignal(signal: SignalInput): Promise<void>;
|
|
@@ -327,6 +329,9 @@ declare class TraceShipper$1 {
|
|
|
327
329
|
spanIdB64: string;
|
|
328
330
|
};
|
|
329
331
|
eventId: string;
|
|
332
|
+
userId?: string;
|
|
333
|
+
convoId?: string;
|
|
334
|
+
eventName?: string;
|
|
330
335
|
operationId?: string;
|
|
331
336
|
attributes?: Array<OtlpKeyValue | undefined>;
|
|
332
337
|
startTimeUnixNano?: string;
|
|
@@ -345,6 +350,9 @@ declare class TraceShipper$1 {
|
|
|
345
350
|
spanIdB64: string;
|
|
346
351
|
};
|
|
347
352
|
eventId: string;
|
|
353
|
+
userId?: string;
|
|
354
|
+
convoId?: string;
|
|
355
|
+
eventName?: string;
|
|
348
356
|
startTimeUnixNano: string;
|
|
349
357
|
endTimeUnixNano: string;
|
|
350
358
|
attributes?: Array<OtlpKeyValue | undefined>;
|
|
@@ -525,7 +533,7 @@ declare function mapHookToRaindrop(payload: HookPayload, config: MapperConfig, e
|
|
|
525
533
|
declare function extractAppendSystemPrompt(args: string[]): string | undefined;
|
|
526
534
|
|
|
527
535
|
declare const PACKAGE_NAME = "@raindrop-ai/claude-code";
|
|
528
|
-
declare const PACKAGE_VERSION
|
|
536
|
+
declare const PACKAGE_VERSION: string;
|
|
529
537
|
|
|
530
538
|
/** A tool call extracted from an assistant message content block. */
|
|
531
539
|
interface LLMToolCall {
|
|
@@ -619,9 +627,11 @@ interface LocalDebuggerResult {
|
|
|
619
627
|
declare function detectLocalDebugger(debug: boolean): Promise<LocalDebuggerResult>;
|
|
620
628
|
/**
|
|
621
629
|
* Mirror an event payload to the local debugger's track_partial endpoint.
|
|
622
|
-
*
|
|
630
|
+
* Must be awaited: Claude Code hooks call process.exit as soon as handleHook
|
|
631
|
+
* returns, so a fire-and-forget fetch is killed before it leaves the socket.
|
|
632
|
+
* Errors are swallowed — observability must never fail the hook.
|
|
623
633
|
*/
|
|
624
|
-
declare function mirrorEventToLocalDebugger(baseUrl: string, payload: Record<string, unknown>, debug: boolean): void
|
|
634
|
+
declare function mirrorEventToLocalDebugger(baseUrl: string, payload: Record<string, unknown>, debug: boolean): Promise<void>;
|
|
625
635
|
|
|
626
636
|
interface ResolvedSignal {
|
|
627
637
|
description: string;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// ../core/dist/chunk-
|
|
1
|
+
// ../core/dist/chunk-5PSWD267.js
|
|
2
2
|
function getCrypto() {
|
|
3
3
|
const c = globalThis.crypto;
|
|
4
4
|
return c;
|
|
@@ -42,6 +42,20 @@ function base64Encode(bytes) {
|
|
|
42
42
|
}
|
|
43
43
|
return out;
|
|
44
44
|
}
|
|
45
|
+
var HANDOFF_ATTRIBUTE_SUFFIXES = {
|
|
46
|
+
mode: "raindrop.handoff.mode",
|
|
47
|
+
childEventId: "raindrop.handoff.childEventId",
|
|
48
|
+
parentEventId: "raindrop.handoff.parentEventId",
|
|
49
|
+
parentSpanId: "raindrop.handoff.parentSpanId",
|
|
50
|
+
name: "raindrop.handoff.name",
|
|
51
|
+
terminal: "raindrop.handoff.terminal",
|
|
52
|
+
agentRole: "raindrop.agent.role"
|
|
53
|
+
};
|
|
54
|
+
var HANDOFF_TERMINAL_PROPERTY_KEY = HANDOFF_ATTRIBUTE_SUFFIXES.terminal;
|
|
55
|
+
var TRACEPARENT_HEADER = "traceparent";
|
|
56
|
+
var BAGGAGE_HEADER = "baggage";
|
|
57
|
+
var HANDOFF_HEADER = "x-raindrop-handoff";
|
|
58
|
+
var UNRESOLVED_CARRIER_WARNING = `[raindrop] resume: headers were supplied but no hand-off carrier was found on them (searched ${HANDOFF_HEADER}, ${TRACEPARENT_HEADER}, ${BAGGAGE_HEADER}). This run reports as an UNLINKED event, and the launcher that dispatched it will stay on "queued" forever because nothing ever references its child. Passing headers means a parent handed off, so no carrier on them is almost certainly a defect: a gateway or proxy stripping ${HANDOFF_HEADER}, a middleware overwriting ${BAGGAGE_HEADER}, a request forwarded without its headers, or a hand-built carrier whose field names do not match. Send every header the launcher's dispatch returned. Logged once per process; pass no headers for a directly-invoked sub-agent to silence it.`;
|
|
45
59
|
function runWithTracingSuppressed(fn) {
|
|
46
60
|
const hook = globalThis.RAINDROP_SUPPRESS_TRACING;
|
|
47
61
|
if (typeof hook !== "function") return fn();
|
|
@@ -332,26 +346,29 @@ function resolveLocalDebuggerBaseUrl(baseUrl) {
|
|
|
332
346
|
if (shouldAutoEnableLocalWorkshop()) return DEFAULT_LOCAL_WORKSHOP_URL;
|
|
333
347
|
return null;
|
|
334
348
|
}
|
|
349
|
+
var LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS = 2e3;
|
|
335
350
|
function mirrorTraceExportToLocalDebugger(body, options = {}) {
|
|
336
351
|
var _a;
|
|
337
352
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
338
|
-
if (!baseUrl) return;
|
|
339
|
-
|
|
353
|
+
if (!baseUrl) return Promise.resolve();
|
|
354
|
+
return postJson(`${baseUrl}traces`, body, {}, {
|
|
340
355
|
maxAttempts: 1,
|
|
341
356
|
debug: (_a = options.debug) != null ? _a : false,
|
|
342
|
-
sdkName: options.sdkName
|
|
357
|
+
sdkName: options.sdkName,
|
|
358
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
343
359
|
}).catch(() => {
|
|
344
360
|
});
|
|
345
361
|
}
|
|
346
362
|
function mirrorPartialEventToLocalDebugger(event, options = {}) {
|
|
347
363
|
var _a;
|
|
348
364
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
349
|
-
if (!baseUrl) return;
|
|
365
|
+
if (!baseUrl) return Promise.resolve();
|
|
350
366
|
const headers = options.writeKey ? { Authorization: `Bearer ${options.writeKey}` } : {};
|
|
351
|
-
|
|
367
|
+
return postJson(`${baseUrl}events/track_partial`, event, headers, {
|
|
352
368
|
maxAttempts: 1,
|
|
353
369
|
debug: (_a = options.debug) != null ? _a : false,
|
|
354
|
-
sdkName: options.sdkName
|
|
370
|
+
sdkName: options.sdkName,
|
|
371
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
355
372
|
}).catch(() => {
|
|
356
373
|
});
|
|
357
374
|
}
|
|
@@ -377,16 +394,52 @@ function projectIdHeaders(projectId) {
|
|
|
377
394
|
var SHUTDOWN_DEADLINE_MS = 1e4;
|
|
378
395
|
var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
379
396
|
function mergePatches(target, source) {
|
|
380
|
-
var _a, _b, _c, _d;
|
|
397
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
381
398
|
const out = { ...target, ...source };
|
|
382
399
|
if (target.properties || source.properties) {
|
|
383
400
|
out.properties = { ...(_a = target.properties) != null ? _a : {}, ...(_b = source.properties) != null ? _b : {} };
|
|
384
401
|
}
|
|
402
|
+
if (target.usage || source.usage) {
|
|
403
|
+
out.usage = { ...(_c = target.usage) != null ? _c : {} };
|
|
404
|
+
if (((_d = source.usage) == null ? void 0 : _d.promptTokens) !== void 0) {
|
|
405
|
+
out.usage.promptTokens = source.usage.promptTokens;
|
|
406
|
+
}
|
|
407
|
+
if (((_e = source.usage) == null ? void 0 : _e.completionTokens) !== void 0) {
|
|
408
|
+
out.usage.completionTokens = source.usage.completionTokens;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
if (source.error === void 0) {
|
|
412
|
+
out.error = target.error;
|
|
413
|
+
}
|
|
414
|
+
if (target.featureFlags || source.featureFlags) {
|
|
415
|
+
out.featureFlags = { ...(_f = target.featureFlags) != null ? _f : {}, ...(_g = source.featureFlags) != null ? _g : {} };
|
|
416
|
+
}
|
|
385
417
|
if (target.attachments || source.attachments) {
|
|
386
|
-
out.attachments = [...(
|
|
418
|
+
out.attachments = [...(_h = target.attachments) != null ? _h : [], ...(_i = source.attachments) != null ? _i : []];
|
|
387
419
|
}
|
|
388
420
|
return out;
|
|
389
421
|
}
|
|
422
|
+
function isErrorLike(value) {
|
|
423
|
+
return value !== null && typeof value === "object";
|
|
424
|
+
}
|
|
425
|
+
function eventTelemetryProperties(patch) {
|
|
426
|
+
var _a, _b;
|
|
427
|
+
const properties = {};
|
|
428
|
+
if (((_a = patch.usage) == null ? void 0 : _a.promptTokens) !== void 0 && Number.isFinite(patch.usage.promptTokens)) {
|
|
429
|
+
properties["ai.usage.prompt_tokens"] = patch.usage.promptTokens;
|
|
430
|
+
}
|
|
431
|
+
if (((_b = patch.usage) == null ? void 0 : _b.completionTokens) !== void 0 && Number.isFinite(patch.usage.completionTokens)) {
|
|
432
|
+
properties["ai.usage.completion_tokens"] = patch.usage.completionTokens;
|
|
433
|
+
}
|
|
434
|
+
if (patch.error !== void 0 && patch.error !== null) {
|
|
435
|
+
const constructorName = patch.error instanceof Error && patch.error.constructor !== Error ? patch.error.constructor.name : void 0;
|
|
436
|
+
const errorType = patch.error instanceof Error ? patch.error.name && patch.error.name !== "Error" ? patch.error.name : constructorName || patch.error.name || "Error" : isErrorLike(patch.error) && typeof patch.error.name === "string" && patch.error.name.length > 0 ? patch.error.name : "Error";
|
|
437
|
+
const errorMessage = patch.error instanceof Error ? patch.error.message : isErrorLike(patch.error) && typeof patch.error.message === "string" ? patch.error.message : String(patch.error);
|
|
438
|
+
properties["error.type"] = errorType;
|
|
439
|
+
properties["error.message"] = errorMessage;
|
|
440
|
+
}
|
|
441
|
+
return properties;
|
|
442
|
+
}
|
|
390
443
|
var EventShipper = class {
|
|
391
444
|
constructor(opts) {
|
|
392
445
|
this.buffers = /* @__PURE__ */ new Map();
|
|
@@ -635,6 +688,11 @@ var EventShipper = class {
|
|
|
635
688
|
return;
|
|
636
689
|
}
|
|
637
690
|
const { wizardSession, ...restProperties } = (_e = accumulated.properties) != null ? _e : {};
|
|
691
|
+
let telemetryProperties = {};
|
|
692
|
+
try {
|
|
693
|
+
telemetryProperties = eventTelemetryProperties(accumulated);
|
|
694
|
+
} catch (e) {
|
|
695
|
+
}
|
|
638
696
|
const convoId = (_f = accumulated.convoId) != null ? _f : sticky.convoId;
|
|
639
697
|
const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
|
|
640
698
|
const payload = {
|
|
@@ -644,15 +702,17 @@ var EventShipper = class {
|
|
|
644
702
|
timestamp: (_i = accumulated.timestamp) != null ? _i : (/* @__PURE__ */ new Date()).toISOString(),
|
|
645
703
|
ai_data: {
|
|
646
704
|
input: accumulated.input,
|
|
647
|
-
output: accumulated.output,
|
|
705
|
+
output: accumulated.error !== void 0 && accumulated.error !== null ? void 0 : accumulated.output,
|
|
648
706
|
model: accumulated.model,
|
|
649
707
|
convo_id: convoId
|
|
650
708
|
},
|
|
651
709
|
properties: {
|
|
652
710
|
...restProperties,
|
|
711
|
+
...telemetryProperties,
|
|
653
712
|
...wizardSession ? { "raindrop.wizardSession": wizardSession } : {},
|
|
654
713
|
$context: this.context
|
|
655
714
|
},
|
|
715
|
+
...accumulated.featureFlags && Object.keys(accumulated.featureFlags).length > 0 ? { feature_flags: accumulated.featureFlags } : {},
|
|
656
716
|
attachments: accumulated.attachments,
|
|
657
717
|
is_pending: isPending
|
|
658
718
|
};
|
|
@@ -676,29 +736,30 @@ var EventShipper = class {
|
|
|
676
736
|
endpoint: url
|
|
677
737
|
});
|
|
678
738
|
}
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
});
|
|
686
|
-
}
|
|
739
|
+
const mirror = this.localDebuggerUrl ? mirrorPartialEventToLocalDebugger(payload, {
|
|
740
|
+
baseUrl: this.localDebuggerUrl,
|
|
741
|
+
writeKey: this.writeKey,
|
|
742
|
+
debug: this.debug,
|
|
743
|
+
sdkName: this.sdkName
|
|
744
|
+
}) : void 0;
|
|
687
745
|
if (!this.writeKey) {
|
|
688
746
|
if (!isPending) this.sticky.delete(eventId);
|
|
747
|
+
if (mirror) await mirror;
|
|
689
748
|
return;
|
|
690
749
|
}
|
|
691
750
|
const opts = this.requestOpts();
|
|
692
751
|
if (!opts) {
|
|
693
752
|
this.warnShutdownDrop(`track_partial ${eventId}`);
|
|
694
753
|
if (!isPending) this.sticky.delete(eventId);
|
|
754
|
+
if (mirror) await mirror;
|
|
695
755
|
return;
|
|
696
756
|
}
|
|
697
757
|
const p = postJson(url, payload, this.requestHeaders(), opts);
|
|
698
|
-
|
|
758
|
+
const combined = mirror ? Promise.all([mirror, p]).then(() => void 0) : p;
|
|
759
|
+
this.inFlight.add(combined);
|
|
699
760
|
try {
|
|
700
761
|
try {
|
|
701
|
-
await
|
|
762
|
+
await combined;
|
|
702
763
|
if (this.debug) {
|
|
703
764
|
console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
|
|
704
765
|
}
|
|
@@ -710,13 +771,156 @@ var EventShipper = class {
|
|
|
710
771
|
);
|
|
711
772
|
}
|
|
712
773
|
} finally {
|
|
713
|
-
this.inFlight.delete(
|
|
774
|
+
this.inFlight.delete(combined);
|
|
714
775
|
}
|
|
715
776
|
if (!isPending) {
|
|
716
777
|
this.sticky.delete(eventId);
|
|
717
778
|
}
|
|
718
779
|
}
|
|
719
780
|
};
|
|
781
|
+
var MODEL_USAGE_ATTRIBUTES = {
|
|
782
|
+
usageSource: "raindrop.usage.source",
|
|
783
|
+
providerName: "gen_ai.provider.name",
|
|
784
|
+
requestModel: "gen_ai.request.model",
|
|
785
|
+
responseModel: "gen_ai.response.model",
|
|
786
|
+
inputTokens: "gen_ai.usage.input_tokens",
|
|
787
|
+
outputTokens: "gen_ai.usage.output_tokens",
|
|
788
|
+
reasoningTokens: "gen_ai.usage.reasoning_tokens",
|
|
789
|
+
cacheReadInputTokens: "gen_ai.usage.cache_read_input_tokens",
|
|
790
|
+
cacheWriteInputTokens: "gen_ai.usage.cache_write_input_tokens",
|
|
791
|
+
providerReportedCost: "gen_ai.usage.provider_reported_cost",
|
|
792
|
+
nonCachedInputTokens: "raindrop.usage.input_tokens.non_cached",
|
|
793
|
+
nonReasoningOutputTokens: "raindrop.usage.output_tokens.non_reasoning",
|
|
794
|
+
totalOutputTokens: "raindrop.usage.output_tokens.total",
|
|
795
|
+
reasoningOutputTokens: "raindrop.usage.output_tokens.reasoning",
|
|
796
|
+
cacheReadTokens: "raindrop.usage.input_tokens.cache_read",
|
|
797
|
+
cacheWriteTokens: "raindrop.usage.input_tokens.cache_write"
|
|
798
|
+
};
|
|
799
|
+
var MODEL_PROVIDER_NAMES = [
|
|
800
|
+
["google.vertex.anthropic", "google-vertex"],
|
|
801
|
+
["google.vertex_ai", "google-vertex"],
|
|
802
|
+
["google.vertex", "google-vertex"],
|
|
803
|
+
["gcp.vertex_ai", "google-vertex"],
|
|
804
|
+
["gcp.gemini", "google"],
|
|
805
|
+
["google_vertexai", "google-vertex"],
|
|
806
|
+
["vertex.anthropic", "google-vertex"],
|
|
807
|
+
["amazon-bedrock", "amazon-bedrock"],
|
|
808
|
+
["aws.bedrock", "amazon-bedrock"],
|
|
809
|
+
["bedrock", "amazon-bedrock"],
|
|
810
|
+
["anthropic", "anthropic"],
|
|
811
|
+
["openai", "openai"],
|
|
812
|
+
["google", "google"],
|
|
813
|
+
["az.ai.openai", "azure"],
|
|
814
|
+
["azure", "azure"],
|
|
815
|
+
["openrouter", "openrouter"]
|
|
816
|
+
];
|
|
817
|
+
function canonicalModelProvider(provider) {
|
|
818
|
+
var _a;
|
|
819
|
+
const normalizedProvider = provider.trim().toLowerCase();
|
|
820
|
+
if (normalizedProvider === "gateway") return "vercel";
|
|
821
|
+
const match = MODEL_PROVIDER_NAMES.find(
|
|
822
|
+
([family]) => normalizedProvider === family || normalizedProvider.startsWith(`${family}.`)
|
|
823
|
+
);
|
|
824
|
+
return (_a = match == null ? void 0 : match[1]) != null ? _a : normalizedProvider;
|
|
825
|
+
}
|
|
826
|
+
var STRING_ALIASES = {
|
|
827
|
+
[MODEL_USAGE_ATTRIBUTES.requestModel]: ["ai.model.id", "ai.model"]
|
|
828
|
+
};
|
|
829
|
+
var NUMBER_ALIASES = {
|
|
830
|
+
[MODEL_USAGE_ATTRIBUTES.inputTokens]: [
|
|
831
|
+
"gen_ai.usage.prompt_tokens",
|
|
832
|
+
"ai.usage.prompt_tokens",
|
|
833
|
+
"ai.usage.promptTokens",
|
|
834
|
+
"ai.usage.input_tokens",
|
|
835
|
+
"ai.usage.inputTokens"
|
|
836
|
+
],
|
|
837
|
+
[MODEL_USAGE_ATTRIBUTES.outputTokens]: [
|
|
838
|
+
"gen_ai.usage.completion_tokens",
|
|
839
|
+
"ai.usage.completion_tokens",
|
|
840
|
+
"ai.usage.completionTokens",
|
|
841
|
+
"ai.usage.output_tokens",
|
|
842
|
+
"ai.usage.outputTokens"
|
|
843
|
+
],
|
|
844
|
+
[MODEL_USAGE_ATTRIBUTES.reasoningTokens]: [
|
|
845
|
+
"gen_ai.usage.reasoning.output_tokens",
|
|
846
|
+
"ai.usage.reasoningTokens",
|
|
847
|
+
"ai.usage.thoughts_tokens"
|
|
848
|
+
],
|
|
849
|
+
[MODEL_USAGE_ATTRIBUTES.cacheReadInputTokens]: [
|
|
850
|
+
"gen_ai.usage.cache_read_tokens",
|
|
851
|
+
"gen_ai.usage.cache_read.input_tokens",
|
|
852
|
+
"ai.usage.cachedInputTokens",
|
|
853
|
+
"ai.usage.cached_tokens",
|
|
854
|
+
"ai.usage.cache_read_tokens",
|
|
855
|
+
"ai.usage.cache_read_input_tokens",
|
|
856
|
+
"ai.usage.cacheReadInputTokens"
|
|
857
|
+
],
|
|
858
|
+
[MODEL_USAGE_ATTRIBUTES.cacheWriteInputTokens]: [
|
|
859
|
+
"gen_ai.usage.cache_creation_input_tokens",
|
|
860
|
+
"gen_ai.usage.cache_creation.input_tokens",
|
|
861
|
+
"ai.usage.cacheWriteInputTokens",
|
|
862
|
+
"ai.usage.cache_creation_input_tokens",
|
|
863
|
+
"ai.usage.cacheCreationInputTokens"
|
|
864
|
+
]
|
|
865
|
+
};
|
|
866
|
+
function hasAttribute(attributes, key) {
|
|
867
|
+
return attributes.some((attribute) => attribute.key === key);
|
|
868
|
+
}
|
|
869
|
+
function findStringAttribute(attributes, keys) {
|
|
870
|
+
return attributes.find(
|
|
871
|
+
(attribute) => keys.includes(attribute.key) && typeof attribute.value.stringValue === "string" && attribute.value.stringValue.length > 0
|
|
872
|
+
);
|
|
873
|
+
}
|
|
874
|
+
function findNumberAttribute(attributes, keys) {
|
|
875
|
+
return attributes.find((attribute) => {
|
|
876
|
+
if (!keys.includes(attribute.key)) return false;
|
|
877
|
+
if (typeof attribute.value.doubleValue === "number" && Number.isSafeInteger(attribute.value.doubleValue) && attribute.value.doubleValue >= 0) {
|
|
878
|
+
return true;
|
|
879
|
+
}
|
|
880
|
+
const intValue = attribute.value.intValue;
|
|
881
|
+
return integerValue(intValue) !== void 0;
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
function integerValue(value) {
|
|
885
|
+
if (typeof value === "number") {
|
|
886
|
+
return Number.isSafeInteger(value) && value >= 0 ? value : void 0;
|
|
887
|
+
}
|
|
888
|
+
if (typeof value !== "string") return void 0;
|
|
889
|
+
const parsed = Number(value);
|
|
890
|
+
return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : void 0;
|
|
891
|
+
}
|
|
892
|
+
function appendAlias(attributes, target, source) {
|
|
893
|
+
if (!source || hasAttribute(attributes, target)) return attributes;
|
|
894
|
+
return [...attributes, { key: target, value: { ...source.value } }];
|
|
895
|
+
}
|
|
896
|
+
function appendProviderAlias(attributes) {
|
|
897
|
+
if (hasAttribute(attributes, MODEL_USAGE_ATTRIBUTES.providerName)) return attributes;
|
|
898
|
+
const source = findStringAttribute(attributes, ["gen_ai.system", "ai.model.provider"]);
|
|
899
|
+
if (!(source == null ? void 0 : source.value.stringValue)) return attributes;
|
|
900
|
+
const attribute = attrString(
|
|
901
|
+
MODEL_USAGE_ATTRIBUTES.providerName,
|
|
902
|
+
canonicalModelProvider(source.value.stringValue)
|
|
903
|
+
);
|
|
904
|
+
return attribute ? [...attributes, attribute] : attributes;
|
|
905
|
+
}
|
|
906
|
+
function normalizeModelUsageSpan(span) {
|
|
907
|
+
const original = span.attributes;
|
|
908
|
+
if (!original || original.length === 0) return span;
|
|
909
|
+
const responseModel = findStringAttribute(original, [
|
|
910
|
+
MODEL_USAGE_ATTRIBUTES.responseModel,
|
|
911
|
+
"ai.response.model"
|
|
912
|
+
]);
|
|
913
|
+
if (!responseModel) return span;
|
|
914
|
+
let attributes = appendAlias(original, MODEL_USAGE_ATTRIBUTES.responseModel, responseModel);
|
|
915
|
+
attributes = appendProviderAlias(attributes);
|
|
916
|
+
for (const [target, aliases] of Object.entries(STRING_ALIASES)) {
|
|
917
|
+
attributes = appendAlias(attributes, target, findStringAttribute(attributes, aliases));
|
|
918
|
+
}
|
|
919
|
+
for (const [target, aliases] of Object.entries(NUMBER_ALIASES)) {
|
|
920
|
+
attributes = appendAlias(attributes, target, findNumberAttribute(attributes, aliases));
|
|
921
|
+
}
|
|
922
|
+
return attributes === original ? span : { ...span, attributes };
|
|
923
|
+
}
|
|
720
924
|
var DEFAULT_SECRET_KEY_NAMES = [
|
|
721
925
|
"apikey",
|
|
722
926
|
"apisecret",
|
|
@@ -806,6 +1010,13 @@ function redactJsonAttributeValue(key, value) {
|
|
|
806
1010
|
if (scrubbedJson === json) return void 0;
|
|
807
1011
|
return { stringValue: scrubbedJson };
|
|
808
1012
|
}
|
|
1013
|
+
function identityAttrs(args) {
|
|
1014
|
+
return [
|
|
1015
|
+
attrString("ai.telemetry.metadata.raindrop.ai.userId", args.userId),
|
|
1016
|
+
attrString("ai.telemetry.metadata.raindrop.convoId", args.convoId),
|
|
1017
|
+
attrString("ai.telemetry.metadata.raindrop.eventName", args.eventName)
|
|
1018
|
+
];
|
|
1019
|
+
}
|
|
809
1020
|
function applyOtelSpanAttributeLimit(limit) {
|
|
810
1021
|
var _a, _b;
|
|
811
1022
|
try {
|
|
@@ -910,6 +1121,10 @@ var TraceShipper = class {
|
|
|
910
1121
|
return null;
|
|
911
1122
|
}
|
|
912
1123
|
}
|
|
1124
|
+
try {
|
|
1125
|
+
current = normalizeModelUsageSpan(current);
|
|
1126
|
+
} catch (e) {
|
|
1127
|
+
}
|
|
913
1128
|
if (!this.disableDefaultRedaction) {
|
|
914
1129
|
current = defaultTransformSpan(current);
|
|
915
1130
|
}
|
|
@@ -930,6 +1145,7 @@ var TraceShipper = class {
|
|
|
930
1145
|
const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
931
1146
|
const attrs = [
|
|
932
1147
|
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1148
|
+
...identityAttrs(args),
|
|
933
1149
|
attrString("ai.operationId", args.operationId)
|
|
934
1150
|
];
|
|
935
1151
|
if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
|
|
@@ -952,11 +1168,15 @@ var TraceShipper = class {
|
|
|
952
1168
|
const redacted = this.redactSpan(span);
|
|
953
1169
|
if (redacted === null) return;
|
|
954
1170
|
const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
|
|
955
|
-
mirrorTraceExportToLocalDebugger(body, {
|
|
1171
|
+
const p = mirrorTraceExportToLocalDebugger(body, {
|
|
956
1172
|
baseUrl: this.localDebuggerUrl,
|
|
957
1173
|
debug: false,
|
|
958
1174
|
sdkName: this.sdkName
|
|
959
1175
|
});
|
|
1176
|
+
this.inFlight.add(p);
|
|
1177
|
+
void p.finally(() => {
|
|
1178
|
+
this.inFlight.delete(p);
|
|
1179
|
+
});
|
|
960
1180
|
}
|
|
961
1181
|
endSpan(span, extra) {
|
|
962
1182
|
var _a, _b;
|
|
@@ -985,7 +1205,8 @@ var TraceShipper = class {
|
|
|
985
1205
|
var _a;
|
|
986
1206
|
const ids = createSpanIds(args.parent);
|
|
987
1207
|
const attrs = [
|
|
988
|
-
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId)
|
|
1208
|
+
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1209
|
+
...identityAttrs(args)
|
|
989
1210
|
];
|
|
990
1211
|
if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
|
|
991
1212
|
const otlp = buildOtlpSpan({
|
|
@@ -1029,7 +1250,11 @@ var TraceShipper = class {
|
|
|
1029
1250
|
}
|
|
1030
1251
|
}
|
|
1031
1252
|
async flush() {
|
|
1032
|
-
if (!this.enabled)
|
|
1253
|
+
if (!this.enabled) {
|
|
1254
|
+
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
1255
|
+
})));
|
|
1256
|
+
return;
|
|
1257
|
+
}
|
|
1033
1258
|
if (this.timer) {
|
|
1034
1259
|
clearTimeout(this.timer);
|
|
1035
1260
|
this.timer = void 0;
|
|
@@ -1150,9 +1375,81 @@ function installTracingSuppressionHook() {
|
|
|
1150
1375
|
}
|
|
1151
1376
|
installTracingSuppressionHook();
|
|
1152
1377
|
|
|
1378
|
+
// package.json
|
|
1379
|
+
var package_default = {
|
|
1380
|
+
name: "@raindrop-ai/claude-code",
|
|
1381
|
+
version: "0.0.19",
|
|
1382
|
+
description: "Raindrop observability for Claude Code CLI \u2014 automatic session, tool call, and prompt tracing via hooks",
|
|
1383
|
+
license: "MIT",
|
|
1384
|
+
homepage: "https://www.raindrop.ai/docs/integrations/claude-code/",
|
|
1385
|
+
bugs: {
|
|
1386
|
+
url: "https://www.raindrop.ai/docs/support/"
|
|
1387
|
+
},
|
|
1388
|
+
type: "module",
|
|
1389
|
+
main: "dist/index.cjs",
|
|
1390
|
+
module: "dist/index.js",
|
|
1391
|
+
types: "dist/index.d.ts",
|
|
1392
|
+
bin: {
|
|
1393
|
+
"raindrop-claude-code": "dist/cli.js"
|
|
1394
|
+
},
|
|
1395
|
+
exports: {
|
|
1396
|
+
".": {
|
|
1397
|
+
import: {
|
|
1398
|
+
types: "./dist/index.d.ts",
|
|
1399
|
+
default: "./dist/index.js"
|
|
1400
|
+
},
|
|
1401
|
+
require: {
|
|
1402
|
+
types: "./dist/index.d.cts",
|
|
1403
|
+
default: "./dist/index.cjs"
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
},
|
|
1407
|
+
sideEffects: false,
|
|
1408
|
+
files: [
|
|
1409
|
+
"dist/**",
|
|
1410
|
+
"README.md",
|
|
1411
|
+
".claude-plugin/**",
|
|
1412
|
+
"hooks/**",
|
|
1413
|
+
".mcp.json"
|
|
1414
|
+
],
|
|
1415
|
+
keywords: [
|
|
1416
|
+
"raindrop",
|
|
1417
|
+
"claude-code",
|
|
1418
|
+
"claude",
|
|
1419
|
+
"anthropic",
|
|
1420
|
+
"observability",
|
|
1421
|
+
"tracing",
|
|
1422
|
+
"hooks",
|
|
1423
|
+
"cli"
|
|
1424
|
+
],
|
|
1425
|
+
engines: {
|
|
1426
|
+
node: ">=18"
|
|
1427
|
+
},
|
|
1428
|
+
scripts: {
|
|
1429
|
+
build: "tsup",
|
|
1430
|
+
postbuild: "chmod +x ./dist/cli.js && node ./scripts/sync-plugin-version.mjs",
|
|
1431
|
+
prepack: "node ./scripts/sync-plugin-version.mjs",
|
|
1432
|
+
dev: "tsup --watch",
|
|
1433
|
+
clean: "rm -rf dist",
|
|
1434
|
+
test: "pnpm build && cd tests && pnpm test",
|
|
1435
|
+
"test:watch": "cd tests && pnpm test:watch"
|
|
1436
|
+
},
|
|
1437
|
+
devDependencies: {
|
|
1438
|
+
"@raindrop-ai/core": "workspace:*",
|
|
1439
|
+
"@types/node": "^20.11.17",
|
|
1440
|
+
msw: "^2.12.7",
|
|
1441
|
+
tsup: "^8.4.0",
|
|
1442
|
+
typescript: "^5.3.3",
|
|
1443
|
+
vitest: "^2.1.0"
|
|
1444
|
+
},
|
|
1445
|
+
publishConfig: {
|
|
1446
|
+
access: "public"
|
|
1447
|
+
}
|
|
1448
|
+
};
|
|
1449
|
+
|
|
1153
1450
|
// src/package-info.ts
|
|
1154
1451
|
var PACKAGE_NAME = "@raindrop-ai/claude-code";
|
|
1155
|
-
var PACKAGE_VERSION =
|
|
1452
|
+
var PACKAGE_VERSION = package_default.version;
|
|
1156
1453
|
|
|
1157
1454
|
// src/shipper.ts
|
|
1158
1455
|
var EventShipper2 = class extends EventShipper {
|
|
@@ -2202,7 +2499,6 @@ import { join as join3 } from "path";
|
|
|
2202
2499
|
var DEFAULT_PORT = 5899;
|
|
2203
2500
|
var DEFAULT_URL = `http://localhost:${DEFAULT_PORT}/v1/`;
|
|
2204
2501
|
var HEALTH_TIMEOUT_MS = 300;
|
|
2205
|
-
var MIRROR_TIMEOUT_MS = 2e3;
|
|
2206
2502
|
var CACHE_DIR = join3(tmpdir2(), "raindrop-claude-code");
|
|
2207
2503
|
var CACHE_FILE = join3(CACHE_DIR, "debugger_cache");
|
|
2208
2504
|
var CACHE_TTL_MS = 5e3;
|
|
@@ -2264,20 +2560,22 @@ async function detectLocalDebugger(debug) {
|
|
|
2264
2560
|
}
|
|
2265
2561
|
return { url: detected, autoDetected: detected !== null };
|
|
2266
2562
|
}
|
|
2267
|
-
function mirrorEventToLocalDebugger(baseUrl, payload, debug) {
|
|
2563
|
+
async function mirrorEventToLocalDebugger(baseUrl, payload, debug) {
|
|
2268
2564
|
const url = `${baseUrl}events/track_partial`;
|
|
2269
2565
|
if (debug) {
|
|
2270
2566
|
console.log(`[raindrop-ai/claude-code] Mirroring event to local debugger: ${url}`);
|
|
2271
2567
|
}
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2568
|
+
try {
|
|
2569
|
+
await runWithTracingSuppressed(
|
|
2570
|
+
() => fetch(url, {
|
|
2571
|
+
method: "POST",
|
|
2572
|
+
headers: { "Content-Type": "application/json" },
|
|
2573
|
+
body: JSON.stringify(payload),
|
|
2574
|
+
signal: AbortSignal.timeout(LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS)
|
|
2575
|
+
})
|
|
2576
|
+
);
|
|
2577
|
+
} catch (e) {
|
|
2578
|
+
}
|
|
2281
2579
|
}
|
|
2282
2580
|
|
|
2283
2581
|
// src/mcp-serve.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raindrop-ai/claude-code",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.19",
|
|
4
4
|
"description": "Raindrop observability for Claude Code CLI — automatic session, tool call, and prompt tracing via hooks",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://www.raindrop.ai/docs/integrations/claude-code/",
|
|
@@ -53,14 +53,14 @@
|
|
|
53
53
|
"tsup": "^8.4.0",
|
|
54
54
|
"typescript": "^5.3.3",
|
|
55
55
|
"vitest": "^2.1.0",
|
|
56
|
-
"@raindrop-ai/core": "0.
|
|
56
|
+
"@raindrop-ai/core": "0.2.1"
|
|
57
57
|
},
|
|
58
58
|
"publishConfig": {
|
|
59
59
|
"access": "public"
|
|
60
60
|
},
|
|
61
61
|
"scripts": {
|
|
62
62
|
"build": "tsup",
|
|
63
|
-
"postbuild": "chmod +x ./dist/cli.js",
|
|
63
|
+
"postbuild": "chmod +x ./dist/cli.js && node ./scripts/sync-plugin-version.mjs",
|
|
64
64
|
"dev": "tsup --watch",
|
|
65
65
|
"clean": "rm -rf dist",
|
|
66
66
|
"test": "pnpm build && cd tests && pnpm test",
|