@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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "raindrop",
3
- "version": "0.0.13",
3
+ "version": "0.0.19",
4
4
  "description": "Observability for Claude Code \u2014 automatic session, tool call, and prompt tracing",
5
5
  "author": {
6
6
  "name": "Raindrop AI",
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@ import { randomUUID as randomUUID2 } from "crypto";
7
7
  import { tmpdir } from "os";
8
8
  import { join } from "path";
9
9
 
10
- // ../core/dist/chunk-WKRW55KX.js
10
+ // ../core/dist/chunk-5PSWD267.js
11
11
  function getCrypto() {
12
12
  const c = globalThis.crypto;
13
13
  return c;
@@ -51,6 +51,20 @@ function base64Encode(bytes) {
51
51
  }
52
52
  return out;
53
53
  }
54
+ var HANDOFF_ATTRIBUTE_SUFFIXES = {
55
+ mode: "raindrop.handoff.mode",
56
+ childEventId: "raindrop.handoff.childEventId",
57
+ parentEventId: "raindrop.handoff.parentEventId",
58
+ parentSpanId: "raindrop.handoff.parentSpanId",
59
+ name: "raindrop.handoff.name",
60
+ terminal: "raindrop.handoff.terminal",
61
+ agentRole: "raindrop.agent.role"
62
+ };
63
+ var HANDOFF_TERMINAL_PROPERTY_KEY = HANDOFF_ATTRIBUTE_SUFFIXES.terminal;
64
+ var TRACEPARENT_HEADER = "traceparent";
65
+ var BAGGAGE_HEADER = "baggage";
66
+ var HANDOFF_HEADER = "x-raindrop-handoff";
67
+ 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.`;
54
68
  function runWithTracingSuppressed(fn) {
55
69
  const hook = globalThis.RAINDROP_SUPPRESS_TRACING;
56
70
  if (typeof hook !== "function") return fn();
@@ -341,26 +355,29 @@ function resolveLocalDebuggerBaseUrl(baseUrl) {
341
355
  if (shouldAutoEnableLocalWorkshop()) return DEFAULT_LOCAL_WORKSHOP_URL;
342
356
  return null;
343
357
  }
358
+ var LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS = 2e3;
344
359
  function mirrorTraceExportToLocalDebugger(body, options = {}) {
345
360
  var _a;
346
361
  const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
347
- if (!baseUrl) return;
348
- void postJson(`${baseUrl}traces`, body, {}, {
362
+ if (!baseUrl) return Promise.resolve();
363
+ return postJson(`${baseUrl}traces`, body, {}, {
349
364
  maxAttempts: 1,
350
365
  debug: (_a = options.debug) != null ? _a : false,
351
- sdkName: options.sdkName
366
+ sdkName: options.sdkName,
367
+ timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
352
368
  }).catch(() => {
353
369
  });
354
370
  }
355
371
  function mirrorPartialEventToLocalDebugger(event, options = {}) {
356
372
  var _a;
357
373
  const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
358
- if (!baseUrl) return;
374
+ if (!baseUrl) return Promise.resolve();
359
375
  const headers = options.writeKey ? { Authorization: `Bearer ${options.writeKey}` } : {};
360
- void postJson(`${baseUrl}events/track_partial`, event, headers, {
376
+ return postJson(`${baseUrl}events/track_partial`, event, headers, {
361
377
  maxAttempts: 1,
362
378
  debug: (_a = options.debug) != null ? _a : false,
363
- sdkName: options.sdkName
379
+ sdkName: options.sdkName,
380
+ timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
364
381
  }).catch(() => {
365
382
  });
366
383
  }
@@ -386,16 +403,52 @@ function projectIdHeaders(projectId) {
386
403
  var SHUTDOWN_DEADLINE_MS = 1e4;
387
404
  var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
388
405
  function mergePatches(target, source) {
389
- var _a, _b, _c, _d;
406
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
390
407
  const out = { ...target, ...source };
391
408
  if (target.properties || source.properties) {
392
409
  out.properties = { ...(_a = target.properties) != null ? _a : {}, ...(_b = source.properties) != null ? _b : {} };
393
410
  }
411
+ if (target.usage || source.usage) {
412
+ out.usage = { ...(_c = target.usage) != null ? _c : {} };
413
+ if (((_d = source.usage) == null ? void 0 : _d.promptTokens) !== void 0) {
414
+ out.usage.promptTokens = source.usage.promptTokens;
415
+ }
416
+ if (((_e = source.usage) == null ? void 0 : _e.completionTokens) !== void 0) {
417
+ out.usage.completionTokens = source.usage.completionTokens;
418
+ }
419
+ }
420
+ if (source.error === void 0) {
421
+ out.error = target.error;
422
+ }
423
+ if (target.featureFlags || source.featureFlags) {
424
+ out.featureFlags = { ...(_f = target.featureFlags) != null ? _f : {}, ...(_g = source.featureFlags) != null ? _g : {} };
425
+ }
394
426
  if (target.attachments || source.attachments) {
395
- out.attachments = [...(_c = target.attachments) != null ? _c : [], ...(_d = source.attachments) != null ? _d : []];
427
+ out.attachments = [...(_h = target.attachments) != null ? _h : [], ...(_i = source.attachments) != null ? _i : []];
396
428
  }
397
429
  return out;
398
430
  }
431
+ function isErrorLike(value) {
432
+ return value !== null && typeof value === "object";
433
+ }
434
+ function eventTelemetryProperties(patch) {
435
+ var _a, _b;
436
+ const properties = {};
437
+ if (((_a = patch.usage) == null ? void 0 : _a.promptTokens) !== void 0 && Number.isFinite(patch.usage.promptTokens)) {
438
+ properties["ai.usage.prompt_tokens"] = patch.usage.promptTokens;
439
+ }
440
+ if (((_b = patch.usage) == null ? void 0 : _b.completionTokens) !== void 0 && Number.isFinite(patch.usage.completionTokens)) {
441
+ properties["ai.usage.completion_tokens"] = patch.usage.completionTokens;
442
+ }
443
+ if (patch.error !== void 0 && patch.error !== null) {
444
+ const constructorName = patch.error instanceof Error && patch.error.constructor !== Error ? patch.error.constructor.name : void 0;
445
+ 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";
446
+ const errorMessage = patch.error instanceof Error ? patch.error.message : isErrorLike(patch.error) && typeof patch.error.message === "string" ? patch.error.message : String(patch.error);
447
+ properties["error.type"] = errorType;
448
+ properties["error.message"] = errorMessage;
449
+ }
450
+ return properties;
451
+ }
399
452
  var EventShipper = class {
400
453
  constructor(opts) {
401
454
  this.buffers = /* @__PURE__ */ new Map();
@@ -644,6 +697,11 @@ var EventShipper = class {
644
697
  return;
645
698
  }
646
699
  const { wizardSession, ...restProperties } = (_e = accumulated.properties) != null ? _e : {};
700
+ let telemetryProperties = {};
701
+ try {
702
+ telemetryProperties = eventTelemetryProperties(accumulated);
703
+ } catch (e) {
704
+ }
647
705
  const convoId = (_f = accumulated.convoId) != null ? _f : sticky.convoId;
648
706
  const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
649
707
  const payload = {
@@ -653,15 +711,17 @@ var EventShipper = class {
653
711
  timestamp: (_i = accumulated.timestamp) != null ? _i : (/* @__PURE__ */ new Date()).toISOString(),
654
712
  ai_data: {
655
713
  input: accumulated.input,
656
- output: accumulated.output,
714
+ output: accumulated.error !== void 0 && accumulated.error !== null ? void 0 : accumulated.output,
657
715
  model: accumulated.model,
658
716
  convo_id: convoId
659
717
  },
660
718
  properties: {
661
719
  ...restProperties,
720
+ ...telemetryProperties,
662
721
  ...wizardSession ? { "raindrop.wizardSession": wizardSession } : {},
663
722
  $context: this.context
664
723
  },
724
+ ...accumulated.featureFlags && Object.keys(accumulated.featureFlags).length > 0 ? { feature_flags: accumulated.featureFlags } : {},
665
725
  attachments: accumulated.attachments,
666
726
  is_pending: isPending
667
727
  };
@@ -685,29 +745,30 @@ var EventShipper = class {
685
745
  endpoint: url
686
746
  });
687
747
  }
688
- if (this.localDebuggerUrl) {
689
- mirrorPartialEventToLocalDebugger(payload, {
690
- baseUrl: this.localDebuggerUrl,
691
- writeKey: this.writeKey,
692
- debug: this.debug,
693
- sdkName: this.sdkName
694
- });
695
- }
748
+ const mirror = this.localDebuggerUrl ? mirrorPartialEventToLocalDebugger(payload, {
749
+ baseUrl: this.localDebuggerUrl,
750
+ writeKey: this.writeKey,
751
+ debug: this.debug,
752
+ sdkName: this.sdkName
753
+ }) : void 0;
696
754
  if (!this.writeKey) {
697
755
  if (!isPending) this.sticky.delete(eventId);
756
+ if (mirror) await mirror;
698
757
  return;
699
758
  }
700
759
  const opts = this.requestOpts();
701
760
  if (!opts) {
702
761
  this.warnShutdownDrop(`track_partial ${eventId}`);
703
762
  if (!isPending) this.sticky.delete(eventId);
763
+ if (mirror) await mirror;
704
764
  return;
705
765
  }
706
766
  const p = postJson(url, payload, this.requestHeaders(), opts);
707
- this.inFlight.add(p);
767
+ const combined = mirror ? Promise.all([mirror, p]).then(() => void 0) : p;
768
+ this.inFlight.add(combined);
708
769
  try {
709
770
  try {
710
- await p;
771
+ await combined;
711
772
  if (this.debug) {
712
773
  console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
713
774
  }
@@ -719,13 +780,156 @@ var EventShipper = class {
719
780
  );
720
781
  }
721
782
  } finally {
722
- this.inFlight.delete(p);
783
+ this.inFlight.delete(combined);
723
784
  }
724
785
  if (!isPending) {
725
786
  this.sticky.delete(eventId);
726
787
  }
727
788
  }
728
789
  };
790
+ var MODEL_USAGE_ATTRIBUTES = {
791
+ usageSource: "raindrop.usage.source",
792
+ providerName: "gen_ai.provider.name",
793
+ requestModel: "gen_ai.request.model",
794
+ responseModel: "gen_ai.response.model",
795
+ inputTokens: "gen_ai.usage.input_tokens",
796
+ outputTokens: "gen_ai.usage.output_tokens",
797
+ reasoningTokens: "gen_ai.usage.reasoning_tokens",
798
+ cacheReadInputTokens: "gen_ai.usage.cache_read_input_tokens",
799
+ cacheWriteInputTokens: "gen_ai.usage.cache_write_input_tokens",
800
+ providerReportedCost: "gen_ai.usage.provider_reported_cost",
801
+ nonCachedInputTokens: "raindrop.usage.input_tokens.non_cached",
802
+ nonReasoningOutputTokens: "raindrop.usage.output_tokens.non_reasoning",
803
+ totalOutputTokens: "raindrop.usage.output_tokens.total",
804
+ reasoningOutputTokens: "raindrop.usage.output_tokens.reasoning",
805
+ cacheReadTokens: "raindrop.usage.input_tokens.cache_read",
806
+ cacheWriteTokens: "raindrop.usage.input_tokens.cache_write"
807
+ };
808
+ var MODEL_PROVIDER_NAMES = [
809
+ ["google.vertex.anthropic", "google-vertex"],
810
+ ["google.vertex_ai", "google-vertex"],
811
+ ["google.vertex", "google-vertex"],
812
+ ["gcp.vertex_ai", "google-vertex"],
813
+ ["gcp.gemini", "google"],
814
+ ["google_vertexai", "google-vertex"],
815
+ ["vertex.anthropic", "google-vertex"],
816
+ ["amazon-bedrock", "amazon-bedrock"],
817
+ ["aws.bedrock", "amazon-bedrock"],
818
+ ["bedrock", "amazon-bedrock"],
819
+ ["anthropic", "anthropic"],
820
+ ["openai", "openai"],
821
+ ["google", "google"],
822
+ ["az.ai.openai", "azure"],
823
+ ["azure", "azure"],
824
+ ["openrouter", "openrouter"]
825
+ ];
826
+ function canonicalModelProvider(provider) {
827
+ var _a;
828
+ const normalizedProvider = provider.trim().toLowerCase();
829
+ if (normalizedProvider === "gateway") return "vercel";
830
+ const match = MODEL_PROVIDER_NAMES.find(
831
+ ([family]) => normalizedProvider === family || normalizedProvider.startsWith(`${family}.`)
832
+ );
833
+ return (_a = match == null ? void 0 : match[1]) != null ? _a : normalizedProvider;
834
+ }
835
+ var STRING_ALIASES = {
836
+ [MODEL_USAGE_ATTRIBUTES.requestModel]: ["ai.model.id", "ai.model"]
837
+ };
838
+ var NUMBER_ALIASES = {
839
+ [MODEL_USAGE_ATTRIBUTES.inputTokens]: [
840
+ "gen_ai.usage.prompt_tokens",
841
+ "ai.usage.prompt_tokens",
842
+ "ai.usage.promptTokens",
843
+ "ai.usage.input_tokens",
844
+ "ai.usage.inputTokens"
845
+ ],
846
+ [MODEL_USAGE_ATTRIBUTES.outputTokens]: [
847
+ "gen_ai.usage.completion_tokens",
848
+ "ai.usage.completion_tokens",
849
+ "ai.usage.completionTokens",
850
+ "ai.usage.output_tokens",
851
+ "ai.usage.outputTokens"
852
+ ],
853
+ [MODEL_USAGE_ATTRIBUTES.reasoningTokens]: [
854
+ "gen_ai.usage.reasoning.output_tokens",
855
+ "ai.usage.reasoningTokens",
856
+ "ai.usage.thoughts_tokens"
857
+ ],
858
+ [MODEL_USAGE_ATTRIBUTES.cacheReadInputTokens]: [
859
+ "gen_ai.usage.cache_read_tokens",
860
+ "gen_ai.usage.cache_read.input_tokens",
861
+ "ai.usage.cachedInputTokens",
862
+ "ai.usage.cached_tokens",
863
+ "ai.usage.cache_read_tokens",
864
+ "ai.usage.cache_read_input_tokens",
865
+ "ai.usage.cacheReadInputTokens"
866
+ ],
867
+ [MODEL_USAGE_ATTRIBUTES.cacheWriteInputTokens]: [
868
+ "gen_ai.usage.cache_creation_input_tokens",
869
+ "gen_ai.usage.cache_creation.input_tokens",
870
+ "ai.usage.cacheWriteInputTokens",
871
+ "ai.usage.cache_creation_input_tokens",
872
+ "ai.usage.cacheCreationInputTokens"
873
+ ]
874
+ };
875
+ function hasAttribute(attributes, key) {
876
+ return attributes.some((attribute) => attribute.key === key);
877
+ }
878
+ function findStringAttribute(attributes, keys) {
879
+ return attributes.find(
880
+ (attribute) => keys.includes(attribute.key) && typeof attribute.value.stringValue === "string" && attribute.value.stringValue.length > 0
881
+ );
882
+ }
883
+ function findNumberAttribute(attributes, keys) {
884
+ return attributes.find((attribute) => {
885
+ if (!keys.includes(attribute.key)) return false;
886
+ if (typeof attribute.value.doubleValue === "number" && Number.isSafeInteger(attribute.value.doubleValue) && attribute.value.doubleValue >= 0) {
887
+ return true;
888
+ }
889
+ const intValue = attribute.value.intValue;
890
+ return integerValue(intValue) !== void 0;
891
+ });
892
+ }
893
+ function integerValue(value) {
894
+ if (typeof value === "number") {
895
+ return Number.isSafeInteger(value) && value >= 0 ? value : void 0;
896
+ }
897
+ if (typeof value !== "string") return void 0;
898
+ const parsed = Number(value);
899
+ return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : void 0;
900
+ }
901
+ function appendAlias(attributes, target, source) {
902
+ if (!source || hasAttribute(attributes, target)) return attributes;
903
+ return [...attributes, { key: target, value: { ...source.value } }];
904
+ }
905
+ function appendProviderAlias(attributes) {
906
+ if (hasAttribute(attributes, MODEL_USAGE_ATTRIBUTES.providerName)) return attributes;
907
+ const source = findStringAttribute(attributes, ["gen_ai.system", "ai.model.provider"]);
908
+ if (!(source == null ? void 0 : source.value.stringValue)) return attributes;
909
+ const attribute = attrString(
910
+ MODEL_USAGE_ATTRIBUTES.providerName,
911
+ canonicalModelProvider(source.value.stringValue)
912
+ );
913
+ return attribute ? [...attributes, attribute] : attributes;
914
+ }
915
+ function normalizeModelUsageSpan(span) {
916
+ const original = span.attributes;
917
+ if (!original || original.length === 0) return span;
918
+ const responseModel = findStringAttribute(original, [
919
+ MODEL_USAGE_ATTRIBUTES.responseModel,
920
+ "ai.response.model"
921
+ ]);
922
+ if (!responseModel) return span;
923
+ let attributes = appendAlias(original, MODEL_USAGE_ATTRIBUTES.responseModel, responseModel);
924
+ attributes = appendProviderAlias(attributes);
925
+ for (const [target, aliases] of Object.entries(STRING_ALIASES)) {
926
+ attributes = appendAlias(attributes, target, findStringAttribute(attributes, aliases));
927
+ }
928
+ for (const [target, aliases] of Object.entries(NUMBER_ALIASES)) {
929
+ attributes = appendAlias(attributes, target, findNumberAttribute(attributes, aliases));
930
+ }
931
+ return attributes === original ? span : { ...span, attributes };
932
+ }
729
933
  var DEFAULT_SECRET_KEY_NAMES = [
730
934
  "apikey",
731
935
  "apisecret",
@@ -815,6 +1019,13 @@ function redactJsonAttributeValue(key, value) {
815
1019
  if (scrubbedJson === json) return void 0;
816
1020
  return { stringValue: scrubbedJson };
817
1021
  }
1022
+ function identityAttrs(args2) {
1023
+ return [
1024
+ attrString("ai.telemetry.metadata.raindrop.ai.userId", args2.userId),
1025
+ attrString("ai.telemetry.metadata.raindrop.convoId", args2.convoId),
1026
+ attrString("ai.telemetry.metadata.raindrop.eventName", args2.eventName)
1027
+ ];
1028
+ }
818
1029
  function applyOtelSpanAttributeLimit(limit) {
819
1030
  var _a, _b;
820
1031
  try {
@@ -919,6 +1130,10 @@ var TraceShipper = class {
919
1130
  return null;
920
1131
  }
921
1132
  }
1133
+ try {
1134
+ current = normalizeModelUsageSpan(current);
1135
+ } catch (e) {
1136
+ }
922
1137
  if (!this.disableDefaultRedaction) {
923
1138
  current = defaultTransformSpan(current);
924
1139
  }
@@ -939,6 +1154,7 @@ var TraceShipper = class {
939
1154
  const started = (_a = args2.startTimeUnixNano) != null ? _a : nowUnixNanoString();
940
1155
  const attrs = [
941
1156
  attrString("ai.telemetry.metadata.raindrop.eventId", args2.eventId),
1157
+ ...identityAttrs(args2),
942
1158
  attrString("ai.operationId", args2.operationId)
943
1159
  ];
944
1160
  if ((_b = args2.attributes) == null ? void 0 : _b.length) attrs.push(...args2.attributes);
@@ -961,11 +1177,15 @@ var TraceShipper = class {
961
1177
  const redacted = this.redactSpan(span);
962
1178
  if (redacted === null) return;
963
1179
  const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
964
- mirrorTraceExportToLocalDebugger(body, {
1180
+ const p = mirrorTraceExportToLocalDebugger(body, {
965
1181
  baseUrl: this.localDebuggerUrl,
966
1182
  debug: false,
967
1183
  sdkName: this.sdkName
968
1184
  });
1185
+ this.inFlight.add(p);
1186
+ void p.finally(() => {
1187
+ this.inFlight.delete(p);
1188
+ });
969
1189
  }
970
1190
  endSpan(span, extra) {
971
1191
  var _a, _b;
@@ -994,7 +1214,8 @@ var TraceShipper = class {
994
1214
  var _a;
995
1215
  const ids = createSpanIds(args2.parent);
996
1216
  const attrs = [
997
- attrString("ai.telemetry.metadata.raindrop.eventId", args2.eventId)
1217
+ attrString("ai.telemetry.metadata.raindrop.eventId", args2.eventId),
1218
+ ...identityAttrs(args2)
998
1219
  ];
999
1220
  if ((_a = args2.attributes) == null ? void 0 : _a.length) attrs.push(...args2.attributes);
1000
1221
  const otlp = buildOtlpSpan({
@@ -1038,7 +1259,11 @@ var TraceShipper = class {
1038
1259
  }
1039
1260
  }
1040
1261
  async flush() {
1041
- if (!this.enabled) return;
1262
+ if (!this.enabled) {
1263
+ await Promise.all([...this.inFlight].map((p) => p.catch(() => {
1264
+ })));
1265
+ return;
1266
+ }
1042
1267
  if (this.timer) {
1043
1268
  clearTimeout(this.timer);
1044
1269
  this.timer = void 0;
@@ -1159,9 +1384,81 @@ function installTracingSuppressionHook() {
1159
1384
  }
1160
1385
  installTracingSuppressionHook();
1161
1386
 
1387
+ // package.json
1388
+ var package_default = {
1389
+ name: "@raindrop-ai/claude-code",
1390
+ version: "0.0.19",
1391
+ description: "Raindrop observability for Claude Code CLI \u2014 automatic session, tool call, and prompt tracing via hooks",
1392
+ license: "MIT",
1393
+ homepage: "https://www.raindrop.ai/docs/integrations/claude-code/",
1394
+ bugs: {
1395
+ url: "https://www.raindrop.ai/docs/support/"
1396
+ },
1397
+ type: "module",
1398
+ main: "dist/index.cjs",
1399
+ module: "dist/index.js",
1400
+ types: "dist/index.d.ts",
1401
+ bin: {
1402
+ "raindrop-claude-code": "dist/cli.js"
1403
+ },
1404
+ exports: {
1405
+ ".": {
1406
+ import: {
1407
+ types: "./dist/index.d.ts",
1408
+ default: "./dist/index.js"
1409
+ },
1410
+ require: {
1411
+ types: "./dist/index.d.cts",
1412
+ default: "./dist/index.cjs"
1413
+ }
1414
+ }
1415
+ },
1416
+ sideEffects: false,
1417
+ files: [
1418
+ "dist/**",
1419
+ "README.md",
1420
+ ".claude-plugin/**",
1421
+ "hooks/**",
1422
+ ".mcp.json"
1423
+ ],
1424
+ keywords: [
1425
+ "raindrop",
1426
+ "claude-code",
1427
+ "claude",
1428
+ "anthropic",
1429
+ "observability",
1430
+ "tracing",
1431
+ "hooks",
1432
+ "cli"
1433
+ ],
1434
+ engines: {
1435
+ node: ">=18"
1436
+ },
1437
+ scripts: {
1438
+ build: "tsup",
1439
+ postbuild: "chmod +x ./dist/cli.js && node ./scripts/sync-plugin-version.mjs",
1440
+ prepack: "node ./scripts/sync-plugin-version.mjs",
1441
+ dev: "tsup --watch",
1442
+ clean: "rm -rf dist",
1443
+ test: "pnpm build && cd tests && pnpm test",
1444
+ "test:watch": "cd tests && pnpm test:watch"
1445
+ },
1446
+ devDependencies: {
1447
+ "@raindrop-ai/core": "workspace:*",
1448
+ "@types/node": "^20.11.17",
1449
+ msw: "^2.12.7",
1450
+ tsup: "^8.4.0",
1451
+ typescript: "^5.3.3",
1452
+ vitest: "^2.1.0"
1453
+ },
1454
+ publishConfig: {
1455
+ access: "public"
1456
+ }
1457
+ };
1458
+
1162
1459
  // src/package-info.ts
1163
1460
  var PACKAGE_NAME = "@raindrop-ai/claude-code";
1164
- var PACKAGE_VERSION = "0.0.13";
1461
+ var PACKAGE_VERSION = package_default.version;
1165
1462
 
1166
1463
  // src/shipper.ts
1167
1464
  var EventShipper2 = class extends EventShipper {
@@ -2204,7 +2501,6 @@ import { join as join3 } from "path";
2204
2501
  var DEFAULT_PORT = 5899;
2205
2502
  var DEFAULT_URL = `http://localhost:${DEFAULT_PORT}/v1/`;
2206
2503
  var HEALTH_TIMEOUT_MS = 300;
2207
- var MIRROR_TIMEOUT_MS = 2e3;
2208
2504
  var CACHE_DIR = join3(tmpdir2(), "raindrop-claude-code");
2209
2505
  var CACHE_FILE = join3(CACHE_DIR, "debugger_cache");
2210
2506
  var CACHE_TTL_MS = 5e3;
@@ -2266,20 +2562,22 @@ async function detectLocalDebugger(debug) {
2266
2562
  }
2267
2563
  return { url: detected, autoDetected: detected !== null };
2268
2564
  }
2269
- function mirrorEventToLocalDebugger(baseUrl, payload, debug) {
2565
+ async function mirrorEventToLocalDebugger(baseUrl, payload, debug) {
2270
2566
  const url = `${baseUrl}events/track_partial`;
2271
2567
  if (debug) {
2272
2568
  console.log(`[raindrop-ai/claude-code] Mirroring event to local debugger: ${url}`);
2273
2569
  }
2274
- void runWithTracingSuppressed(
2275
- () => fetch(url, {
2276
- method: "POST",
2277
- headers: { "Content-Type": "application/json" },
2278
- body: JSON.stringify(payload),
2279
- signal: AbortSignal.timeout(MIRROR_TIMEOUT_MS)
2280
- })
2281
- ).catch(() => {
2282
- });
2570
+ try {
2571
+ await runWithTracingSuppressed(
2572
+ () => fetch(url, {
2573
+ method: "POST",
2574
+ headers: { "Content-Type": "application/json" },
2575
+ body: JSON.stringify(payload),
2576
+ signal: AbortSignal.timeout(LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS)
2577
+ })
2578
+ );
2579
+ } catch (e) {
2580
+ }
2283
2581
  }
2284
2582
 
2285
2583
  // src/hook-handler.ts
@@ -2411,24 +2709,26 @@ async function handleHook() {
2411
2709
  eventShipper.patch = async (eventId, patch) => {
2412
2710
  var _a, _b, _c, _d;
2413
2711
  const traceId = (_a = getOtlpTraceId(payload.session_id)) != null ? _a : payload.session_id;
2414
- mirrorEventToLocalDebugger(debuggerUrl, {
2415
- event_id: eventId,
2416
- user_id: (_b = patch.userId) != null ? _b : config.userId,
2417
- event: (_c = patch.eventName) != null ? _c : "claude_code_session",
2418
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2419
- ai_data: {
2420
- input: patch.input,
2421
- output: patch.output,
2422
- model: patch.model,
2423
- convo_id: patch.convoId
2424
- },
2425
- properties: {
2426
- ...patch.properties,
2427
- ...payload.session_id ? { trace_id: traceId } : {}
2428
- },
2429
- is_pending: (_d = patch.isPending) != null ? _d : true
2430
- }, config.debug);
2431
- await origPatch(eventId, patch);
2712
+ await Promise.all([
2713
+ mirrorEventToLocalDebugger(debuggerUrl, {
2714
+ event_id: eventId,
2715
+ user_id: (_b = patch.userId) != null ? _b : config.userId,
2716
+ event: (_c = patch.eventName) != null ? _c : "claude_code_session",
2717
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2718
+ ai_data: {
2719
+ input: patch.input,
2720
+ output: patch.output,
2721
+ model: patch.model,
2722
+ convo_id: patch.convoId
2723
+ },
2724
+ properties: {
2725
+ ...patch.properties,
2726
+ ...payload.session_id ? { trace_id: traceId } : {}
2727
+ },
2728
+ is_pending: (_d = patch.isPending) != null ? _d : true
2729
+ }, config.debug),
2730
+ origPatch(eventId, patch)
2731
+ ]);
2432
2732
  };
2433
2733
  }
2434
2734
  try {