@raindrop-ai/claude-code 0.0.17 → 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 +407 -62
- package/dist/index.cjs +387 -44
- package/dist/index.d.cts +55 -9
- package/dist/index.d.ts +55 -9
- package/dist/index.js +387 -44
- package/package.json +3 -3
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,34 @@ 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.`;
|
|
59
|
+
function runWithTracingSuppressed(fn) {
|
|
60
|
+
const hook = globalThis.RAINDROP_SUPPRESS_TRACING;
|
|
61
|
+
if (typeof hook !== "function") return fn();
|
|
62
|
+
let started = false;
|
|
63
|
+
try {
|
|
64
|
+
return hook(() => {
|
|
65
|
+
started = true;
|
|
66
|
+
return fn();
|
|
67
|
+
});
|
|
68
|
+
} catch (err) {
|
|
69
|
+
if (started) throw err;
|
|
70
|
+
return fn();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
45
73
|
var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
46
74
|
var MAX_RETRY_DELAY_MS = 3e4;
|
|
47
75
|
function wait(ms) {
|
|
@@ -152,15 +180,17 @@ async function postJson(url, body, headers, opts) {
|
|
|
152
180
|
const timeoutMs = (_a = opts.timeoutMs) != null ? _a : DEFAULT_REQUEST_TIMEOUT_MS;
|
|
153
181
|
await withRetry(
|
|
154
182
|
async () => {
|
|
155
|
-
const resp = await
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
183
|
+
const resp = await runWithTracingSuppressed(
|
|
184
|
+
() => fetch(url, {
|
|
185
|
+
method: "POST",
|
|
186
|
+
headers: {
|
|
187
|
+
"Content-Type": "application/json",
|
|
188
|
+
...headers
|
|
189
|
+
},
|
|
190
|
+
body: JSON.stringify(body),
|
|
191
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
192
|
+
})
|
|
193
|
+
);
|
|
164
194
|
if (!resp.ok) {
|
|
165
195
|
const text = await resp.text().catch(() => "");
|
|
166
196
|
const err = new Error(
|
|
@@ -316,26 +346,29 @@ function resolveLocalDebuggerBaseUrl(baseUrl) {
|
|
|
316
346
|
if (shouldAutoEnableLocalWorkshop()) return DEFAULT_LOCAL_WORKSHOP_URL;
|
|
317
347
|
return null;
|
|
318
348
|
}
|
|
349
|
+
var LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS = 2e3;
|
|
319
350
|
function mirrorTraceExportToLocalDebugger(body, options = {}) {
|
|
320
351
|
var _a;
|
|
321
352
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
322
|
-
if (!baseUrl) return;
|
|
323
|
-
|
|
353
|
+
if (!baseUrl) return Promise.resolve();
|
|
354
|
+
return postJson(`${baseUrl}traces`, body, {}, {
|
|
324
355
|
maxAttempts: 1,
|
|
325
356
|
debug: (_a = options.debug) != null ? _a : false,
|
|
326
|
-
sdkName: options.sdkName
|
|
357
|
+
sdkName: options.sdkName,
|
|
358
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
327
359
|
}).catch(() => {
|
|
328
360
|
});
|
|
329
361
|
}
|
|
330
362
|
function mirrorPartialEventToLocalDebugger(event, options = {}) {
|
|
331
363
|
var _a;
|
|
332
364
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
333
|
-
if (!baseUrl) return;
|
|
365
|
+
if (!baseUrl) return Promise.resolve();
|
|
334
366
|
const headers = options.writeKey ? { Authorization: `Bearer ${options.writeKey}` } : {};
|
|
335
|
-
|
|
367
|
+
return postJson(`${baseUrl}events/track_partial`, event, headers, {
|
|
336
368
|
maxAttempts: 1,
|
|
337
369
|
debug: (_a = options.debug) != null ? _a : false,
|
|
338
|
-
sdkName: options.sdkName
|
|
370
|
+
sdkName: options.sdkName,
|
|
371
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
339
372
|
}).catch(() => {
|
|
340
373
|
});
|
|
341
374
|
}
|
|
@@ -361,16 +394,52 @@ function projectIdHeaders(projectId) {
|
|
|
361
394
|
var SHUTDOWN_DEADLINE_MS = 1e4;
|
|
362
395
|
var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
363
396
|
function mergePatches(target, source) {
|
|
364
|
-
var _a, _b, _c, _d;
|
|
397
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
365
398
|
const out = { ...target, ...source };
|
|
366
399
|
if (target.properties || source.properties) {
|
|
367
400
|
out.properties = { ...(_a = target.properties) != null ? _a : {}, ...(_b = source.properties) != null ? _b : {} };
|
|
368
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
|
+
}
|
|
369
417
|
if (target.attachments || source.attachments) {
|
|
370
|
-
out.attachments = [...(
|
|
418
|
+
out.attachments = [...(_h = target.attachments) != null ? _h : [], ...(_i = source.attachments) != null ? _i : []];
|
|
371
419
|
}
|
|
372
420
|
return out;
|
|
373
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
|
+
}
|
|
374
443
|
var EventShipper = class {
|
|
375
444
|
constructor(opts) {
|
|
376
445
|
this.buffers = /* @__PURE__ */ new Map();
|
|
@@ -619,6 +688,11 @@ var EventShipper = class {
|
|
|
619
688
|
return;
|
|
620
689
|
}
|
|
621
690
|
const { wizardSession, ...restProperties } = (_e = accumulated.properties) != null ? _e : {};
|
|
691
|
+
let telemetryProperties = {};
|
|
692
|
+
try {
|
|
693
|
+
telemetryProperties = eventTelemetryProperties(accumulated);
|
|
694
|
+
} catch (e) {
|
|
695
|
+
}
|
|
622
696
|
const convoId = (_f = accumulated.convoId) != null ? _f : sticky.convoId;
|
|
623
697
|
const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
|
|
624
698
|
const payload = {
|
|
@@ -628,15 +702,17 @@ var EventShipper = class {
|
|
|
628
702
|
timestamp: (_i = accumulated.timestamp) != null ? _i : (/* @__PURE__ */ new Date()).toISOString(),
|
|
629
703
|
ai_data: {
|
|
630
704
|
input: accumulated.input,
|
|
631
|
-
output: accumulated.output,
|
|
705
|
+
output: accumulated.error !== void 0 && accumulated.error !== null ? void 0 : accumulated.output,
|
|
632
706
|
model: accumulated.model,
|
|
633
707
|
convo_id: convoId
|
|
634
708
|
},
|
|
635
709
|
properties: {
|
|
636
710
|
...restProperties,
|
|
711
|
+
...telemetryProperties,
|
|
637
712
|
...wizardSession ? { "raindrop.wizardSession": wizardSession } : {},
|
|
638
713
|
$context: this.context
|
|
639
714
|
},
|
|
715
|
+
...accumulated.featureFlags && Object.keys(accumulated.featureFlags).length > 0 ? { feature_flags: accumulated.featureFlags } : {},
|
|
640
716
|
attachments: accumulated.attachments,
|
|
641
717
|
is_pending: isPending
|
|
642
718
|
};
|
|
@@ -660,29 +736,30 @@ var EventShipper = class {
|
|
|
660
736
|
endpoint: url
|
|
661
737
|
});
|
|
662
738
|
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
});
|
|
670
|
-
}
|
|
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;
|
|
671
745
|
if (!this.writeKey) {
|
|
672
746
|
if (!isPending) this.sticky.delete(eventId);
|
|
747
|
+
if (mirror) await mirror;
|
|
673
748
|
return;
|
|
674
749
|
}
|
|
675
750
|
const opts = this.requestOpts();
|
|
676
751
|
if (!opts) {
|
|
677
752
|
this.warnShutdownDrop(`track_partial ${eventId}`);
|
|
678
753
|
if (!isPending) this.sticky.delete(eventId);
|
|
754
|
+
if (mirror) await mirror;
|
|
679
755
|
return;
|
|
680
756
|
}
|
|
681
757
|
const p = postJson(url, payload, this.requestHeaders(), opts);
|
|
682
|
-
|
|
758
|
+
const combined = mirror ? Promise.all([mirror, p]).then(() => void 0) : p;
|
|
759
|
+
this.inFlight.add(combined);
|
|
683
760
|
try {
|
|
684
761
|
try {
|
|
685
|
-
await
|
|
762
|
+
await combined;
|
|
686
763
|
if (this.debug) {
|
|
687
764
|
console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
|
|
688
765
|
}
|
|
@@ -694,13 +771,156 @@ var EventShipper = class {
|
|
|
694
771
|
);
|
|
695
772
|
}
|
|
696
773
|
} finally {
|
|
697
|
-
this.inFlight.delete(
|
|
774
|
+
this.inFlight.delete(combined);
|
|
698
775
|
}
|
|
699
776
|
if (!isPending) {
|
|
700
777
|
this.sticky.delete(eventId);
|
|
701
778
|
}
|
|
702
779
|
}
|
|
703
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
|
+
}
|
|
704
924
|
var DEFAULT_SECRET_KEY_NAMES = [
|
|
705
925
|
"apikey",
|
|
706
926
|
"apisecret",
|
|
@@ -790,6 +1010,13 @@ function redactJsonAttributeValue(key, value) {
|
|
|
790
1010
|
if (scrubbedJson === json) return void 0;
|
|
791
1011
|
return { stringValue: scrubbedJson };
|
|
792
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
|
+
}
|
|
793
1020
|
function applyOtelSpanAttributeLimit(limit) {
|
|
794
1021
|
var _a, _b;
|
|
795
1022
|
try {
|
|
@@ -894,6 +1121,10 @@ var TraceShipper = class {
|
|
|
894
1121
|
return null;
|
|
895
1122
|
}
|
|
896
1123
|
}
|
|
1124
|
+
try {
|
|
1125
|
+
current = normalizeModelUsageSpan(current);
|
|
1126
|
+
} catch (e) {
|
|
1127
|
+
}
|
|
897
1128
|
if (!this.disableDefaultRedaction) {
|
|
898
1129
|
current = defaultTransformSpan(current);
|
|
899
1130
|
}
|
|
@@ -914,6 +1145,7 @@ var TraceShipper = class {
|
|
|
914
1145
|
const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
915
1146
|
const attrs = [
|
|
916
1147
|
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1148
|
+
...identityAttrs(args),
|
|
917
1149
|
attrString("ai.operationId", args.operationId)
|
|
918
1150
|
];
|
|
919
1151
|
if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
|
|
@@ -936,11 +1168,15 @@ var TraceShipper = class {
|
|
|
936
1168
|
const redacted = this.redactSpan(span);
|
|
937
1169
|
if (redacted === null) return;
|
|
938
1170
|
const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
|
|
939
|
-
mirrorTraceExportToLocalDebugger(body, {
|
|
1171
|
+
const p = mirrorTraceExportToLocalDebugger(body, {
|
|
940
1172
|
baseUrl: this.localDebuggerUrl,
|
|
941
1173
|
debug: false,
|
|
942
1174
|
sdkName: this.sdkName
|
|
943
1175
|
});
|
|
1176
|
+
this.inFlight.add(p);
|
|
1177
|
+
void p.finally(() => {
|
|
1178
|
+
this.inFlight.delete(p);
|
|
1179
|
+
});
|
|
944
1180
|
}
|
|
945
1181
|
endSpan(span, extra) {
|
|
946
1182
|
var _a, _b;
|
|
@@ -969,7 +1205,8 @@ var TraceShipper = class {
|
|
|
969
1205
|
var _a;
|
|
970
1206
|
const ids = createSpanIds(args.parent);
|
|
971
1207
|
const attrs = [
|
|
972
|
-
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId)
|
|
1208
|
+
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1209
|
+
...identityAttrs(args)
|
|
973
1210
|
];
|
|
974
1211
|
if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
|
|
975
1212
|
const otlp = buildOtlpSpan({
|
|
@@ -1013,7 +1250,11 @@ var TraceShipper = class {
|
|
|
1013
1250
|
}
|
|
1014
1251
|
}
|
|
1015
1252
|
async flush() {
|
|
1016
|
-
if (!this.enabled)
|
|
1253
|
+
if (!this.enabled) {
|
|
1254
|
+
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
1255
|
+
})));
|
|
1256
|
+
return;
|
|
1257
|
+
}
|
|
1017
1258
|
if (this.timer) {
|
|
1018
1259
|
clearTimeout(this.timer);
|
|
1019
1260
|
this.timer = void 0;
|
|
@@ -1108,10 +1349,107 @@ var TraceShipper = class {
|
|
|
1108
1349
|
// ../core/dist/index.node.js
|
|
1109
1350
|
import { AsyncLocalStorage } from "async_hooks";
|
|
1110
1351
|
globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = AsyncLocalStorage;
|
|
1352
|
+
var SUPPRESS_TRACING_KEY = /* @__PURE__ */ Symbol.for(
|
|
1353
|
+
"OpenTelemetry SDK Context Key SUPPRESS_TRACING"
|
|
1354
|
+
);
|
|
1355
|
+
function findOtelContextManager() {
|
|
1356
|
+
var _a;
|
|
1357
|
+
for (const sym of Object.getOwnPropertySymbols(globalThis)) {
|
|
1358
|
+
if (!((_a = sym.description) == null ? void 0 : _a.startsWith("opentelemetry.js.api."))) continue;
|
|
1359
|
+
const api = globalThis[sym];
|
|
1360
|
+
const cm = api == null ? void 0 : api.context;
|
|
1361
|
+
if (cm && typeof cm.with === "function" && typeof cm.active === "function") {
|
|
1362
|
+
return cm;
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
return void 0;
|
|
1366
|
+
}
|
|
1367
|
+
function installTracingSuppressionHook() {
|
|
1368
|
+
if (typeof globalThis.RAINDROP_SUPPRESS_TRACING === "function") return;
|
|
1369
|
+
const hook = (fn) => {
|
|
1370
|
+
const cm = findOtelContextManager();
|
|
1371
|
+
if (!cm) return fn();
|
|
1372
|
+
return cm.with(cm.active().setValue(SUPPRESS_TRACING_KEY, true), fn);
|
|
1373
|
+
};
|
|
1374
|
+
globalThis.RAINDROP_SUPPRESS_TRACING = hook;
|
|
1375
|
+
}
|
|
1376
|
+
installTracingSuppressionHook();
|
|
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
|
+
};
|
|
1111
1449
|
|
|
1112
1450
|
// src/package-info.ts
|
|
1113
1451
|
var PACKAGE_NAME = "@raindrop-ai/claude-code";
|
|
1114
|
-
var PACKAGE_VERSION =
|
|
1452
|
+
var PACKAGE_VERSION = package_default.version;
|
|
1115
1453
|
|
|
1116
1454
|
// src/shipper.ts
|
|
1117
1455
|
var EventShipper2 = class extends EventShipper {
|
|
@@ -2161,7 +2499,6 @@ import { join as join3 } from "path";
|
|
|
2161
2499
|
var DEFAULT_PORT = 5899;
|
|
2162
2500
|
var DEFAULT_URL = `http://localhost:${DEFAULT_PORT}/v1/`;
|
|
2163
2501
|
var HEALTH_TIMEOUT_MS = 300;
|
|
2164
|
-
var MIRROR_TIMEOUT_MS = 2e3;
|
|
2165
2502
|
var CACHE_DIR = join3(tmpdir2(), "raindrop-claude-code");
|
|
2166
2503
|
var CACHE_FILE = join3(CACHE_DIR, "debugger_cache");
|
|
2167
2504
|
var CACHE_TTL_MS = 5e3;
|
|
@@ -2186,7 +2523,9 @@ async function healthPing(baseUrl) {
|
|
|
2186
2523
|
const healthUrl = baseUrl.replace(/\/v1\/$/, "/health");
|
|
2187
2524
|
try {
|
|
2188
2525
|
const signal = AbortSignal.timeout(HEALTH_TIMEOUT_MS);
|
|
2189
|
-
const resp = await
|
|
2526
|
+
const resp = await runWithTracingSuppressed(
|
|
2527
|
+
() => fetch(healthUrl, { signal })
|
|
2528
|
+
);
|
|
2190
2529
|
if (resp.ok) {
|
|
2191
2530
|
const body = await resp.json();
|
|
2192
2531
|
if (body.ok) return baseUrl;
|
|
@@ -2221,18 +2560,22 @@ async function detectLocalDebugger(debug) {
|
|
|
2221
2560
|
}
|
|
2222
2561
|
return { url: detected, autoDetected: detected !== null };
|
|
2223
2562
|
}
|
|
2224
|
-
function mirrorEventToLocalDebugger(baseUrl, payload, debug) {
|
|
2563
|
+
async function mirrorEventToLocalDebugger(baseUrl, payload, debug) {
|
|
2225
2564
|
const url = `${baseUrl}events/track_partial`;
|
|
2226
2565
|
if (debug) {
|
|
2227
2566
|
console.log(`[raindrop-ai/claude-code] Mirroring event to local debugger: ${url}`);
|
|
2228
2567
|
}
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
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
|
+
}
|
|
2236
2579
|
}
|
|
2237
2580
|
|
|
2238
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",
|