@raindrop-ai/claude-code 0.0.19 → 0.0.20
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/README.md +4 -0
- package/dist/cli.js +1005 -115
- package/dist/index.cjs +966 -93
- package/dist/index.d.cts +91 -1
- package/dist/index.d.ts +91 -1
- package/dist/index.js +965 -93
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,4 +1,518 @@
|
|
|
1
|
-
// ../core/dist/chunk-
|
|
1
|
+
// ../core/dist/chunk-BYBMRLZM.js
|
|
2
|
+
var EVAL_CORRELATION_ID_ATTRIBUTE = "raindrop.eval_correlation_id";
|
|
3
|
+
var PROBE_SCOPE = { correlationId: "" };
|
|
4
|
+
var EvalScopeStorage = class {
|
|
5
|
+
constructor() {
|
|
6
|
+
this._als = null;
|
|
7
|
+
this._probed = false;
|
|
8
|
+
}
|
|
9
|
+
maybeAdoptAsyncLocalStorage() {
|
|
10
|
+
if (this._probed) return;
|
|
11
|
+
this._probed = true;
|
|
12
|
+
try {
|
|
13
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
14
|
+
if (!Ctor) return;
|
|
15
|
+
const als = new Ctor();
|
|
16
|
+
als.run(PROBE_SCOPE, () => {
|
|
17
|
+
});
|
|
18
|
+
this._als = als;
|
|
19
|
+
} catch (e) {
|
|
20
|
+
this._als = null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
run(scope, callback) {
|
|
24
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
25
|
+
if (this._als) return this._als.run(scope, callback);
|
|
26
|
+
const previous = this._syncScope;
|
|
27
|
+
this._syncScope = scope;
|
|
28
|
+
try {
|
|
29
|
+
return callback();
|
|
30
|
+
} finally {
|
|
31
|
+
this._syncScope = previous;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
current() {
|
|
35
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
36
|
+
if (this._als) return this._als.getStore();
|
|
37
|
+
return this._syncScope;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var EVAL_SCOPE_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.evalScopeStorage");
|
|
41
|
+
function evalScopeStorage() {
|
|
42
|
+
const holder = globalThis;
|
|
43
|
+
let storage = holder[EVAL_SCOPE_STORAGE_KEY];
|
|
44
|
+
if (!storage) {
|
|
45
|
+
storage = new EvalScopeStorage();
|
|
46
|
+
holder[EVAL_SCOPE_STORAGE_KEY] = storage;
|
|
47
|
+
}
|
|
48
|
+
return storage;
|
|
49
|
+
}
|
|
50
|
+
function currentEvalScope() {
|
|
51
|
+
try {
|
|
52
|
+
return evalScopeStorage().current();
|
|
53
|
+
} catch (e) {
|
|
54
|
+
return void 0;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function evalScopeAttributes() {
|
|
58
|
+
const scope = currentEvalScope();
|
|
59
|
+
if (!scope) return {};
|
|
60
|
+
return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ../core/dist/chunk-WJOR6M7H.js
|
|
64
|
+
var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
|
|
65
|
+
function state() {
|
|
66
|
+
const holder = globalThis;
|
|
67
|
+
let current = holder[STATE_KEY];
|
|
68
|
+
if (!current) {
|
|
69
|
+
let storage = null;
|
|
70
|
+
try {
|
|
71
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
72
|
+
if (Ctor) storage = new Ctor();
|
|
73
|
+
} catch (e) {
|
|
74
|
+
storage = null;
|
|
75
|
+
}
|
|
76
|
+
current = {
|
|
77
|
+
storage,
|
|
78
|
+
syncDestination: void 0,
|
|
79
|
+
spanDestinations: /* @__PURE__ */ new WeakMap()
|
|
80
|
+
};
|
|
81
|
+
holder[STATE_KEY] = current;
|
|
82
|
+
}
|
|
83
|
+
return current;
|
|
84
|
+
}
|
|
85
|
+
function currentReplayTraceDestination() {
|
|
86
|
+
var _a, _b;
|
|
87
|
+
const routing = state();
|
|
88
|
+
return (_b = (_a = routing.storage) == null ? void 0 : _a.getStore()) != null ? _b : routing.syncDestination;
|
|
89
|
+
}
|
|
90
|
+
function rememberReplayTraceDestination(span) {
|
|
91
|
+
const destination = currentReplayTraceDestination();
|
|
92
|
+
if (destination) state().spanDestinations.set(span, destination);
|
|
93
|
+
}
|
|
94
|
+
function copyReplayTraceDestination(source, target) {
|
|
95
|
+
const destination = state().spanDestinations.get(source);
|
|
96
|
+
if (destination) state().spanDestinations.set(target, destination);
|
|
97
|
+
}
|
|
98
|
+
function replayTraceDestinationFor(value) {
|
|
99
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
100
|
+
return void 0;
|
|
101
|
+
}
|
|
102
|
+
return state().spanDestinations.get(value);
|
|
103
|
+
}
|
|
104
|
+
function recordReplayExportedSpan(destination, spanId, traceId) {
|
|
105
|
+
var _a, _b;
|
|
106
|
+
if (!destination || !spanId || !traceId) return;
|
|
107
|
+
(_a = destination.exportedSpanIds) == null ? void 0 : _a.add(spanId);
|
|
108
|
+
(_b = destination.exportedTraceIds) == null ? void 0 : _b.add(traceId);
|
|
109
|
+
}
|
|
110
|
+
function replayTraceUrl(baseUrl) {
|
|
111
|
+
return `${baseUrl.replace(/\/+$/, "")}/v1/traces`;
|
|
112
|
+
}
|
|
113
|
+
function getAsyncLocalStorageCtor() {
|
|
114
|
+
return globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
115
|
+
}
|
|
116
|
+
var MAX_BINDING_STACK = 128;
|
|
117
|
+
var EMPTY_STACK = [];
|
|
118
|
+
var ContextStackStorage = class {
|
|
119
|
+
/** Emitted once when this runtime cannot support an ambient push. */
|
|
120
|
+
constructor(noAmbientBindWarning) {
|
|
121
|
+
this.noAmbientBindWarning = noAmbientBindWarning;
|
|
122
|
+
this._als = null;
|
|
123
|
+
this._enterWithUsable = false;
|
|
124
|
+
this._syncStack = EMPTY_STACK;
|
|
125
|
+
this._adoptionChecked = false;
|
|
126
|
+
this._warnedNoAmbientBind = false;
|
|
127
|
+
}
|
|
128
|
+
maybeAdoptAsyncLocalStorage() {
|
|
129
|
+
if (this._adoptionChecked) return;
|
|
130
|
+
this._adoptionChecked = true;
|
|
131
|
+
const Ctor = getAsyncLocalStorageCtor();
|
|
132
|
+
if (!Ctor) return;
|
|
133
|
+
const als = new Ctor();
|
|
134
|
+
try {
|
|
135
|
+
als.run(EMPTY_STACK, () => {
|
|
136
|
+
});
|
|
137
|
+
} catch (e) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
this._als = als;
|
|
141
|
+
if (typeof als.enterWith === "function") {
|
|
142
|
+
try {
|
|
143
|
+
als.enterWith(EMPTY_STACK);
|
|
144
|
+
this._enterWithUsable = true;
|
|
145
|
+
} catch (e) {
|
|
146
|
+
this._enterWithUsable = false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
getStack() {
|
|
151
|
+
var _a;
|
|
152
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
153
|
+
if (this._als) return (_a = this._als.getStore()) != null ? _a : this._syncStack;
|
|
154
|
+
return this._syncStack;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Persist an ambient stack mutation. Returns false when an ALS is adopted but
|
|
158
|
+
* `enterWith` is unusable (workerd): callers must NOT fall back to the
|
|
159
|
+
* process-shared sync stack, since concurrent isolates would cross-stamp.
|
|
160
|
+
*/
|
|
161
|
+
setAmbientStack(stack) {
|
|
162
|
+
if (this._als) {
|
|
163
|
+
if (!this._enterWithUsable) return false;
|
|
164
|
+
this._als.enterWith(stack);
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
this._syncStack = stack;
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
push(binding) {
|
|
171
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
172
|
+
if (this._als && !this._enterWithUsable) {
|
|
173
|
+
this.warnNoAmbientBindOnce();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
let stack = this.getStack();
|
|
177
|
+
if (stack.length >= MAX_BINDING_STACK) {
|
|
178
|
+
stack = stack.filter((b) => b.isLive());
|
|
179
|
+
if (stack.length >= MAX_BINDING_STACK) {
|
|
180
|
+
stack = stack.slice(stack.length - (MAX_BINDING_STACK - 1));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
this.setAmbientStack([...stack, binding]);
|
|
184
|
+
}
|
|
185
|
+
remove(binding) {
|
|
186
|
+
binding.markDead();
|
|
187
|
+
const stack = this.getStack();
|
|
188
|
+
const pruned = stack.filter((b) => b !== binding && b.isLive());
|
|
189
|
+
if (pruned.length !== stack.length) {
|
|
190
|
+
this.setAmbientStack(pruned);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
runWith(binding, callback) {
|
|
194
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
195
|
+
if (this._als) {
|
|
196
|
+
return this._als.run([...this.getStack(), binding], callback);
|
|
197
|
+
}
|
|
198
|
+
const previous = this._syncStack;
|
|
199
|
+
this._syncStack = [...previous, binding];
|
|
200
|
+
try {
|
|
201
|
+
return callback();
|
|
202
|
+
} finally {
|
|
203
|
+
this._syncStack = previous;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
current() {
|
|
207
|
+
const stack = this.getStack();
|
|
208
|
+
if (stack.length === 0) return void 0;
|
|
209
|
+
const top = stack[stack.length - 1];
|
|
210
|
+
if (top.isLive()) return top;
|
|
211
|
+
const pruned = stack.filter((b) => b.isLive());
|
|
212
|
+
this.setAmbientStack(pruned);
|
|
213
|
+
return pruned.length > 0 ? pruned[pruned.length - 1] : void 0;
|
|
214
|
+
}
|
|
215
|
+
warnNoAmbientBindOnce() {
|
|
216
|
+
if (this._warnedNoAmbientBind) return;
|
|
217
|
+
this._warnedNoAmbientBind = true;
|
|
218
|
+
console.warn(this.noAmbientBindWarning);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
var NO_AMBIENT_ROUTING_BIND_WARNING = "[raindrop] This runtime's AsyncLocalStorage does not implement enterWith (e.g. Cloudflare Workers), so begin()/finish() cannot scope auto-instrumented spans to a project without cross-contaminating concurrent requests. Manual events and explicit span routing are unaffected; use asCurrent()/withSpan (run-based) to route auto-instrumented spans on this runtime.";
|
|
222
|
+
var ROUTING_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.routingContextStorage");
|
|
223
|
+
function routingStorage() {
|
|
224
|
+
const holder = globalThis;
|
|
225
|
+
let storage = holder[ROUTING_STORAGE_KEY];
|
|
226
|
+
if (!storage) {
|
|
227
|
+
storage = new ContextStackStorage(NO_AMBIENT_ROUTING_BIND_WARNING);
|
|
228
|
+
holder[ROUTING_STORAGE_KEY] = storage;
|
|
229
|
+
}
|
|
230
|
+
return storage;
|
|
231
|
+
}
|
|
232
|
+
function currentRoutingBinding() {
|
|
233
|
+
const bound = routingStorage().current();
|
|
234
|
+
if (!bound) return void 0;
|
|
235
|
+
return {
|
|
236
|
+
projectId: bound.projectId,
|
|
237
|
+
authHint: bound.authHint,
|
|
238
|
+
...bound.appGit ? { appGit: bound.appGit } : {},
|
|
239
|
+
...bound.appGitSource ? { appGitSource: bound.appGitSource } : {}
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
var APP_COMMIT_SHA = "raindrop.app.commit_sha";
|
|
243
|
+
var APP_COMMIT_DIRTY = "raindrop.app.commit_dirty";
|
|
244
|
+
var APP_BRANCH = "raindrop.app.branch";
|
|
245
|
+
var APP_GIT_KEYS = [APP_COMMIT_SHA, APP_COMMIT_DIRTY, APP_BRANCH];
|
|
246
|
+
var own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
247
|
+
function appGitExplicitKeys(properties) {
|
|
248
|
+
const keys = /* @__PURE__ */ new Set();
|
|
249
|
+
if (!properties) return keys;
|
|
250
|
+
for (const key of APP_GIT_KEYS) {
|
|
251
|
+
if (own(properties, key)) keys.add(key);
|
|
252
|
+
}
|
|
253
|
+
return keys;
|
|
254
|
+
}
|
|
255
|
+
function mergeAppGitSnapshot(base, properties, explicitKeys = /* @__PURE__ */ new Set()) {
|
|
256
|
+
try {
|
|
257
|
+
const result = { ...base };
|
|
258
|
+
if (properties && own(properties, APP_COMMIT_SHA) && properties[APP_COMMIT_SHA] !== result[APP_COMMIT_SHA]) {
|
|
259
|
+
if (!explicitKeys.has(APP_COMMIT_DIRTY) && !own(properties, APP_COMMIT_DIRTY)) {
|
|
260
|
+
delete result[APP_COMMIT_DIRTY];
|
|
261
|
+
}
|
|
262
|
+
if (!explicitKeys.has(APP_BRANCH) && !own(properties, APP_BRANCH)) {
|
|
263
|
+
delete result[APP_BRANCH];
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
for (const key of APP_GIT_KEYS) {
|
|
267
|
+
if (properties && own(properties, key)) result[key] = properties[key];
|
|
268
|
+
}
|
|
269
|
+
return Object.freeze(result);
|
|
270
|
+
} catch (e) {
|
|
271
|
+
return Object.freeze({});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function validAppCommitSha(value) {
|
|
275
|
+
if (typeof value !== "string" || value.length > 128) return void 0;
|
|
276
|
+
const cleaned = value.trim();
|
|
277
|
+
return /^(?:[a-fA-F0-9]{40}|[a-fA-F0-9]{64})$/.test(cleaned) ? cleaned.toLowerCase() : void 0;
|
|
278
|
+
}
|
|
279
|
+
function shortString(value) {
|
|
280
|
+
if (typeof value !== "string" || value.length > 1024) return void 0;
|
|
281
|
+
const cleaned = value.trim();
|
|
282
|
+
return cleaned.length > 0 ? cleaned : void 0;
|
|
283
|
+
}
|
|
284
|
+
function flag(value) {
|
|
285
|
+
if (value === true || value === "true" || value === "1") return true;
|
|
286
|
+
if (value === false || value === "false" || value === "0") return false;
|
|
287
|
+
return void 0;
|
|
288
|
+
}
|
|
289
|
+
function environment() {
|
|
290
|
+
try {
|
|
291
|
+
return typeof process === "undefined" ? {} : process.env;
|
|
292
|
+
} catch (e) {
|
|
293
|
+
return {};
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
var DEPLOYMENTS = [
|
|
297
|
+
["VERCEL", "VERCEL_GIT_COMMIT_SHA", "VERCEL_GIT_COMMIT_REF"],
|
|
298
|
+
["NETLIFY", "COMMIT_REF", "BRANCH"],
|
|
299
|
+
["RAILWAY_ENVIRONMENT_NAME", "RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH"],
|
|
300
|
+
["RAILWAY_ENVIRONMENT", "RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH"],
|
|
301
|
+
["RENDER", "RENDER_GIT_COMMIT", "RENDER_GIT_BRANCH"],
|
|
302
|
+
["DYNO", "HEROKU_BUILD_COMMIT", ""],
|
|
303
|
+
["DYNO", "HEROKU_SLUG_COMMIT", ""],
|
|
304
|
+
["AWS_APP_ID", "AWS_COMMIT_ID", "AWS_BRANCH"],
|
|
305
|
+
["WORKERS_CI", "WORKERS_CI_COMMIT_SHA", "WORKERS_CI_BRANCH"]
|
|
306
|
+
];
|
|
307
|
+
var CI_SOURCES = [
|
|
308
|
+
["GITHUB_ACTIONS", "GITHUB_SHA", "GITHUB_REF_NAME"],
|
|
309
|
+
["GITLAB_CI", "CI_COMMIT_SHA", "CI_COMMIT_REF_NAME"],
|
|
310
|
+
["CIRCLECI", "CIRCLE_SHA1", "CIRCLE_BRANCH"]
|
|
311
|
+
];
|
|
312
|
+
function detectedSource(env, table, detectBranch) {
|
|
313
|
+
for (const row of table) {
|
|
314
|
+
const [marker, shaKey, branchKey] = row;
|
|
315
|
+
if (!marker || !shaKey || !shortString(env[marker]) || flag(env[marker]) === false) continue;
|
|
316
|
+
const commitSha = validAppCommitSha(env[shaKey]);
|
|
317
|
+
if (commitSha)
|
|
318
|
+
return {
|
|
319
|
+
commitSha,
|
|
320
|
+
...detectBranch && branchKey ? { branch: shortString(env[branchKey]) } : {}
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
return {};
|
|
324
|
+
}
|
|
325
|
+
var AppGitContextImpl = class {
|
|
326
|
+
constructor(options, runtime = {}) {
|
|
327
|
+
this.defaults = {};
|
|
328
|
+
this.explicit = {};
|
|
329
|
+
this.explicitKeys = /* @__PURE__ */ new Set();
|
|
330
|
+
this.disposed = false;
|
|
331
|
+
this.operations = /* @__PURE__ */ new Map();
|
|
332
|
+
this.operationOverflow = false;
|
|
333
|
+
this.detectBranch = false;
|
|
334
|
+
this.disabled = false;
|
|
335
|
+
var _a, _b, _c, _d, _e, _f;
|
|
336
|
+
try {
|
|
337
|
+
if (options === false) {
|
|
338
|
+
this.disabled = true;
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
const opts = options != null ? options : {};
|
|
342
|
+
const env = (_a = runtime.env) != null ? _a : environment();
|
|
343
|
+
const detectBranch = (_c = (_b = flag(opts.detectBranch)) != null ? _b : flag(env.RAINDROP_GIT_DETECT_BRANCH)) != null ? _c : false;
|
|
344
|
+
this.detectBranch = detectBranch;
|
|
345
|
+
const collectBranch = detectBranch || runtime.captureLegacyReplayBranch === true;
|
|
346
|
+
const autoDetect = runtime.allowDiscovery === false ? false : (_e = (_d = flag(opts.autoDetect)) != null ? _d : flag(env.RAINDROP_GIT_AUTO_DETECT)) != null ? _e : true;
|
|
347
|
+
const configuredSha = opts.commitSha;
|
|
348
|
+
const explicitSha = configuredSha === void 0 ? env.RAINDROP_COMMIT_SHA : configuredSha;
|
|
349
|
+
if (explicitSha === null) this.explicit[APP_COMMIT_SHA] = null;
|
|
350
|
+
else if (typeof explicitSha === "string" && validAppCommitSha(explicitSha))
|
|
351
|
+
this.explicit[APP_COMMIT_SHA] = explicitSha;
|
|
352
|
+
const configuredDirty = opts.commitDirty;
|
|
353
|
+
const explicitDirty = configuredDirty === void 0 ? flag(env.RAINDROP_COMMIT_DIRTY) : configuredDirty;
|
|
354
|
+
if (explicitDirty === null || typeof explicitDirty === "boolean")
|
|
355
|
+
this.explicit[APP_COMMIT_DIRTY] = explicitDirty;
|
|
356
|
+
const configuredBranch = opts.branch;
|
|
357
|
+
const explicitBranch = configuredBranch === void 0 ? env.RAINDROP_BRANCH : configuredBranch;
|
|
358
|
+
if (explicitBranch === null) this.explicit[APP_BRANCH] = null;
|
|
359
|
+
else if (typeof explicitBranch === "string" && explicitBranch.length <= 1024)
|
|
360
|
+
this.explicit[APP_BRANCH] = explicitBranch;
|
|
361
|
+
this.explicitKeys = appGitExplicitKeys(this.explicit);
|
|
362
|
+
this.defaults = { ...this.explicit };
|
|
363
|
+
if (!autoDetect || explicitSha !== void 0) return;
|
|
364
|
+
const sourceDirectory = (_f = shortString(opts.sourceDirectory)) != null ? _f : shortString(env.RAINDROP_GIT_SOURCE_DIRECTORY);
|
|
365
|
+
if (runtime.allowLocalGit === false && !sourceDirectory) return;
|
|
366
|
+
const deploy = sourceDirectory ? {} : detectedSource(env, DEPLOYMENTS, collectBranch);
|
|
367
|
+
if (deploy.commitSha) {
|
|
368
|
+
this.accept(deploy);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
const fallback = sourceDirectory ? {} : detectedSource(env, CI_SOURCES, collectBranch);
|
|
372
|
+
if (runtime.resolveLocal && (runtime.allowLocalGit !== false || sourceDirectory)) {
|
|
373
|
+
this.cancel = runtime.resolveLocal(sourceDirectory, collectBranch, (result) => {
|
|
374
|
+
try {
|
|
375
|
+
if (!this.disposed) this.accept(result.commitSha ? result : fallback);
|
|
376
|
+
} catch (e) {
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
} else this.accept(fallback);
|
|
380
|
+
} catch (e) {
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
accept(result) {
|
|
384
|
+
const sha = validAppCommitSha(result.commitSha);
|
|
385
|
+
if (!sha) return;
|
|
386
|
+
this.replayBranch = shortString(result.branch);
|
|
387
|
+
this.defaults = {
|
|
388
|
+
[APP_COMMIT_SHA]: sha,
|
|
389
|
+
...typeof result.commitDirty === "boolean" ? { [APP_COMMIT_DIRTY]: result.commitDirty } : {},
|
|
390
|
+
...this.detectBranch && this.replayBranch ? { [APP_BRANCH]: this.replayBranch } : {},
|
|
391
|
+
...this.explicit
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
snapshot(properties) {
|
|
395
|
+
var _a;
|
|
396
|
+
try {
|
|
397
|
+
const binding = currentRoutingBinding();
|
|
398
|
+
const base = this.disabled && (binding == null ? void 0 : binding.appGitSource) !== "replay-override" ? {} : (_a = binding == null ? void 0 : binding.appGit) != null ? _a : this.defaults;
|
|
399
|
+
return this.mergeSnapshot(base, properties);
|
|
400
|
+
} catch (e) {
|
|
401
|
+
return Object.freeze({});
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/** Safe defaults when no operation/span start was observed; never infer identity. */
|
|
405
|
+
snapshotExplicit(properties, eventId) {
|
|
406
|
+
try {
|
|
407
|
+
const base = { ...this.explicit };
|
|
408
|
+
const operation = eventId ? this.operations.get(eventId) : void 0;
|
|
409
|
+
if (operation) {
|
|
410
|
+
for (const key of operation.explicitKeys) base[key] = operation.snapshot[key];
|
|
411
|
+
}
|
|
412
|
+
return this.mergeSnapshot(base, properties, new Set(Object.keys(base)));
|
|
413
|
+
} catch (e) {
|
|
414
|
+
return mergeAppGitSnapshot({}, properties);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
/** Existing replay branch reporting stays separate from opt-in event properties. */
|
|
418
|
+
snapshotForReplay() {
|
|
419
|
+
const snapshot = this.snapshot();
|
|
420
|
+
if (this.replayBranch && !own(snapshot, APP_BRANCH) && snapshot[APP_COMMIT_SHA] === this.defaults[APP_COMMIT_SHA]) {
|
|
421
|
+
return Object.freeze({ ...snapshot, [APP_BRANCH]: this.replayBranch });
|
|
422
|
+
}
|
|
423
|
+
return snapshot;
|
|
424
|
+
}
|
|
425
|
+
/** Merge a frozen span snapshot without losing client-authored provenance. */
|
|
426
|
+
mergeSnapshot(base, properties, explicitKeys = this.explicitKeys) {
|
|
427
|
+
return mergeAppGitSnapshot(base, properties, /* @__PURE__ */ new Set([...this.explicitKeys, ...explicitKeys]));
|
|
428
|
+
}
|
|
429
|
+
/** Shippers belonging to one client share this bounded operation registry. */
|
|
430
|
+
forOperation(eventId, properties, owner) {
|
|
431
|
+
if (!eventId) return this.snapshot(properties);
|
|
432
|
+
let operation = this.operations.get(eventId);
|
|
433
|
+
if (!operation) {
|
|
434
|
+
if (this.operations.size >= 1e4) this.operationOverflow = true;
|
|
435
|
+
if (this.operationOverflow) return this.mergeSnapshot({}, properties);
|
|
436
|
+
operation = {
|
|
437
|
+
snapshot: this.snapshot(properties),
|
|
438
|
+
owners: /* @__PURE__ */ new Set(),
|
|
439
|
+
unowned: owner === void 0,
|
|
440
|
+
explicitKeys: appGitExplicitKeys(properties)
|
|
441
|
+
};
|
|
442
|
+
this.operations.set(eventId, operation);
|
|
443
|
+
} else if (properties && APP_GIT_KEYS.some((key) => own(properties, key))) {
|
|
444
|
+
const explicitKeys = /* @__PURE__ */ new Set([...this.explicitKeys, ...operation.explicitKeys]);
|
|
445
|
+
operation.snapshot = this.mergeSnapshot(operation.snapshot, properties, explicitKeys);
|
|
446
|
+
for (const key of appGitExplicitKeys(properties)) operation.explicitKeys.add(key);
|
|
447
|
+
}
|
|
448
|
+
if (!owner) operation.unowned = true;
|
|
449
|
+
if (owner) operation.owners.add(owner);
|
|
450
|
+
return operation.snapshot;
|
|
451
|
+
}
|
|
452
|
+
releaseOperation(eventId, owner) {
|
|
453
|
+
const operation = this.operations.get(eventId);
|
|
454
|
+
if (!operation) return;
|
|
455
|
+
operation.owners.delete(owner);
|
|
456
|
+
if (operation.owners.size === 0 && !operation.unowned) this.operations.delete(eventId);
|
|
457
|
+
}
|
|
458
|
+
finishOperation(eventId) {
|
|
459
|
+
this.operations.delete(eventId);
|
|
460
|
+
}
|
|
461
|
+
dispose() {
|
|
462
|
+
var _a;
|
|
463
|
+
this.disposed = true;
|
|
464
|
+
try {
|
|
465
|
+
(_a = this.cancel) == null ? void 0 : _a.call(this);
|
|
466
|
+
} catch (e) {
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
var AppGitContext = AppGitContextImpl;
|
|
471
|
+
function createAppGitContext(options, runtime = {}) {
|
|
472
|
+
return new AppGitContext(options, runtime);
|
|
473
|
+
}
|
|
474
|
+
function withAppGitProperties(properties, snapshot) {
|
|
475
|
+
try {
|
|
476
|
+
const merged = { ...properties };
|
|
477
|
+
for (const key of APP_GIT_KEYS)
|
|
478
|
+
if (!own(merged, key) && own(snapshot, key)) merged[key] = snapshot[key];
|
|
479
|
+
return merged;
|
|
480
|
+
} catch (e) {
|
|
481
|
+
return properties != null ? properties : {};
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
function withAppGitAttributes(attributes, snapshot) {
|
|
485
|
+
try {
|
|
486
|
+
const present = new Set(attributes.flatMap((attr) => attr ? [attr.key] : []));
|
|
487
|
+
const added = [];
|
|
488
|
+
for (const key of APP_GIT_KEYS) {
|
|
489
|
+
if (present.has(key) || present.has(`ai.telemetry.metadata.${key}`) || present.has(`traceloop.association.properties.${key}`))
|
|
490
|
+
continue;
|
|
491
|
+
const value = snapshot[key];
|
|
492
|
+
if (typeof value === "string") added.push({ key, value: { stringValue: value } });
|
|
493
|
+
else if (typeof value === "boolean") added.push({ key, value: { boolValue: value } });
|
|
494
|
+
}
|
|
495
|
+
return added.length ? [...attributes, ...added] : attributes;
|
|
496
|
+
} catch (e) {
|
|
497
|
+
return attributes;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
function appGitPropertiesFromAttributes(attributes) {
|
|
501
|
+
var _a, _b, _c;
|
|
502
|
+
const properties = {};
|
|
503
|
+
try {
|
|
504
|
+
for (const attr of attributes) {
|
|
505
|
+
if (!attr) continue;
|
|
506
|
+
for (const key of APP_GIT_KEYS) {
|
|
507
|
+
if (attr.key === key || attr.key === `ai.telemetry.metadata.${key}` || attr.key === `traceloop.association.properties.${key}`) {
|
|
508
|
+
properties[key] = (_c = (_b = (_a = attr.value.stringValue) != null ? _a : attr.value.boolValue) != null ? _b : attr.value.intValue) != null ? _c : null;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
} catch (e) {
|
|
513
|
+
}
|
|
514
|
+
return properties;
|
|
515
|
+
}
|
|
2
516
|
function getCrypto() {
|
|
3
517
|
const c = globalThis.crypto;
|
|
4
518
|
return c;
|
|
@@ -13,6 +527,17 @@ function randomBytes(length) {
|
|
|
13
527
|
for (let i = 0; i < out.length; i++) out[i] = Math.floor(Math.random() * 256);
|
|
14
528
|
return out;
|
|
15
529
|
}
|
|
530
|
+
function randomUUID() {
|
|
531
|
+
const cryptoObj = getCrypto();
|
|
532
|
+
if (cryptoObj && typeof cryptoObj.randomUUID === "function") {
|
|
533
|
+
return cryptoObj.randomUUID();
|
|
534
|
+
}
|
|
535
|
+
const b = randomBytes(16);
|
|
536
|
+
b[6] = b[6] & 15 | 64;
|
|
537
|
+
b[8] = b[8] & 63 | 128;
|
|
538
|
+
const hex = [...b].map((x) => x.toString(16).padStart(2, "0")).join("");
|
|
539
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
540
|
+
}
|
|
16
541
|
function base64Encode(bytes) {
|
|
17
542
|
const maybeBuffer = globalThis.Buffer;
|
|
18
543
|
if (maybeBuffer) {
|
|
@@ -42,6 +567,25 @@ function base64Encode(bytes) {
|
|
|
42
567
|
}
|
|
43
568
|
return out;
|
|
44
569
|
}
|
|
570
|
+
function base64ToHex(value) {
|
|
571
|
+
if (!value) return "";
|
|
572
|
+
const maybeBuffer = globalThis.Buffer;
|
|
573
|
+
if (maybeBuffer) {
|
|
574
|
+
return maybeBuffer.from(value, "base64").toString("hex");
|
|
575
|
+
}
|
|
576
|
+
const atobFn = globalThis.atob;
|
|
577
|
+
if (typeof atobFn !== "function") return "";
|
|
578
|
+
try {
|
|
579
|
+
const binary = atobFn(value);
|
|
580
|
+
let hex = "";
|
|
581
|
+
for (let i = 0; i < binary.length; i++) {
|
|
582
|
+
hex += (binary.charCodeAt(i) & 255).toString(16).padStart(2, "0");
|
|
583
|
+
}
|
|
584
|
+
return hex;
|
|
585
|
+
} catch (e) {
|
|
586
|
+
return "";
|
|
587
|
+
}
|
|
588
|
+
}
|
|
45
589
|
var HANDOFF_ATTRIBUTE_SUFFIXES = {
|
|
46
590
|
mode: "raindrop.handoff.mode",
|
|
47
591
|
childEventId: "raindrop.handoff.childEventId",
|
|
@@ -73,7 +617,7 @@ function runWithTracingSuppressed(fn) {
|
|
|
73
617
|
var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
74
618
|
var MAX_RETRY_DELAY_MS = 3e4;
|
|
75
619
|
function wait(ms) {
|
|
76
|
-
return new Promise((
|
|
620
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
77
621
|
}
|
|
78
622
|
function formatEndpoint(endpoint) {
|
|
79
623
|
if (!endpoint) return void 0;
|
|
@@ -110,9 +654,9 @@ async function raceWithTimeout(promise, timeoutMs) {
|
|
|
110
654
|
() => true,
|
|
111
655
|
() => true
|
|
112
656
|
),
|
|
113
|
-
new Promise((
|
|
657
|
+
new Promise((resolve2) => {
|
|
114
658
|
var _a;
|
|
115
|
-
timer = setTimeout(() =>
|
|
659
|
+
timer = setTimeout(() => resolve2(false), Math.max(0, timeoutMs));
|
|
116
660
|
(_a = timer.unref) == null ? void 0 : _a.call(timer);
|
|
117
661
|
})
|
|
118
662
|
]);
|
|
@@ -183,6 +727,7 @@ async function postJson(url, body, headers, opts) {
|
|
|
183
727
|
const resp = await runWithTracingSuppressed(
|
|
184
728
|
() => fetch(url, {
|
|
185
729
|
method: "POST",
|
|
730
|
+
redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
|
|
186
731
|
headers: {
|
|
187
732
|
"Content-Type": "application/json",
|
|
188
733
|
...headers
|
|
@@ -393,6 +938,13 @@ function projectIdHeaders(projectId) {
|
|
|
393
938
|
}
|
|
394
939
|
var SHUTDOWN_DEADLINE_MS = 1e4;
|
|
395
940
|
var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
941
|
+
function appGitOwnerId(prefix) {
|
|
942
|
+
try {
|
|
943
|
+
return `${prefix}:${randomUUID()}`;
|
|
944
|
+
} catch (e) {
|
|
945
|
+
return `${prefix}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
946
|
+
}
|
|
947
|
+
}
|
|
396
948
|
function mergePatches(target, source) {
|
|
397
949
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
398
950
|
const out = { ...target, ...source };
|
|
@@ -442,22 +994,25 @@ function eventTelemetryProperties(patch) {
|
|
|
442
994
|
}
|
|
443
995
|
var EventShipper = class {
|
|
444
996
|
constructor(opts) {
|
|
997
|
+
this.appGitOwner = appGitOwnerId("event");
|
|
445
998
|
this.buffers = /* @__PURE__ */ new Map();
|
|
446
999
|
this.sticky = /* @__PURE__ */ new Map();
|
|
447
1000
|
this.timers = /* @__PURE__ */ new Map();
|
|
448
1001
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
449
1002
|
this.hasShutdown = false;
|
|
450
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
451
|
-
this.
|
|
452
|
-
this.
|
|
1003
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1004
|
+
this.appGitContext = (_a = opts.appGitContext) != null ? _a : createAppGitContext(opts.appGit);
|
|
1005
|
+
this.ownsAppGitContext = opts.appGitContext === void 0;
|
|
1006
|
+
this.writeKey = (_b = opts.writeKey) == null ? void 0 : _b.trim();
|
|
1007
|
+
this.baseUrl = (_c = formatEndpoint(opts.endpoint)) != null ? _c : "https://api.raindrop.ai/v1/";
|
|
453
1008
|
this.enabled = opts.enabled !== false;
|
|
454
1009
|
this.debug = opts.debug;
|
|
455
|
-
this.partialFlushMs = (
|
|
456
|
-
this.sdkName = (
|
|
1010
|
+
this.partialFlushMs = (_d = opts.partialFlushMs) != null ? _d : 1e3;
|
|
1011
|
+
this.sdkName = (_e = opts.sdkName) != null ? _e : "core";
|
|
457
1012
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
458
|
-
this.defaultEventName = (
|
|
1013
|
+
this.defaultEventName = (_f = opts.defaultEventName) != null ? _f : "ai_generation";
|
|
459
1014
|
this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
|
|
460
|
-
this.localDebuggerUrl = (
|
|
1015
|
+
this.localDebuggerUrl = (_g = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _g : void 0;
|
|
461
1016
|
if (this.debug && this.localDebuggerUrl) {
|
|
462
1017
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
463
1018
|
}
|
|
@@ -468,8 +1023,8 @@ var EventShipper = class {
|
|
|
468
1023
|
const isNode = typeof process !== "undefined" && typeof process.version === "string";
|
|
469
1024
|
this.context = {
|
|
470
1025
|
library: {
|
|
471
|
-
name: (
|
|
472
|
-
version: (
|
|
1026
|
+
name: (_h = opts.libraryName) != null ? _h : "@raindrop-ai/core",
|
|
1027
|
+
version: (_i = opts.libraryVersion) != null ? _i : "0.0.0"
|
|
473
1028
|
},
|
|
474
1029
|
metadata: {
|
|
475
1030
|
jsRuntime: isNode ? "node" : "web",
|
|
@@ -477,6 +1032,9 @@ var EventShipper = class {
|
|
|
477
1032
|
}
|
|
478
1033
|
};
|
|
479
1034
|
}
|
|
1035
|
+
ownAppGitContextForShutdown() {
|
|
1036
|
+
this.ownsAppGitContext = true;
|
|
1037
|
+
}
|
|
480
1038
|
isDebugEnabled() {
|
|
481
1039
|
return this.debug;
|
|
482
1040
|
}
|
|
@@ -525,6 +1083,15 @@ var EventShipper = class {
|
|
|
525
1083
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
526
1084
|
if (!this.enabled) return;
|
|
527
1085
|
if (!eventId || !eventId.trim()) return;
|
|
1086
|
+
const capturedSticky = this.sticky.get(eventId);
|
|
1087
|
+
const eventAlreadyKnown = capturedSticky !== void 0 || this.buffers.has(eventId);
|
|
1088
|
+
const destination = currentReplayTraceDestination();
|
|
1089
|
+
const cloudReplay = destination !== void 0 && destination.kind !== "workshop";
|
|
1090
|
+
if ((capturedSticky == null ? void 0 : capturedSticky.replayOnly) === true || !eventAlreadyKnown && cloudReplay) {
|
|
1091
|
+
if (patch.isPending === false) this.sticky.delete(eventId);
|
|
1092
|
+
else this.sticky.set(eventId, { ...capturedSticky, replayOnly: true });
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
528
1095
|
const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
|
|
529
1096
|
if (typeof patch.input === "string" && patch.input.length > maxChars) {
|
|
530
1097
|
patch = { ...patch, input: capText(patch.input, maxChars) };
|
|
@@ -546,6 +1113,13 @@ var EventShipper = class {
|
|
|
546
1113
|
}
|
|
547
1114
|
const sticky = (_c = this.sticky.get(eventId)) != null ? _c : {};
|
|
548
1115
|
const existing = (_d = this.buffers.get(eventId)) != null ? _d : {};
|
|
1116
|
+
patch = {
|
|
1117
|
+
...patch,
|
|
1118
|
+
properties: withAppGitProperties(
|
|
1119
|
+
patch.properties,
|
|
1120
|
+
this.appGitContext.forOperation(eventId, patch.properties, this.appGitOwner)
|
|
1121
|
+
)
|
|
1122
|
+
};
|
|
549
1123
|
const merged = mergePatches(existing, patch);
|
|
550
1124
|
merged.isPending = (_g = (_f = (_e = patch.isPending) != null ? _e : existing.isPending) != null ? _f : sticky.isPending) != null ? _g : true;
|
|
551
1125
|
this.buffers.set(eventId, merged);
|
|
@@ -559,6 +1133,8 @@ var EventShipper = class {
|
|
|
559
1133
|
if (t) clearTimeout(t);
|
|
560
1134
|
if (merged.isPending === false) {
|
|
561
1135
|
await this.flushOne(eventId);
|
|
1136
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
|
|
1137
|
+
else this.appGitContext.finishOperation(eventId);
|
|
562
1138
|
return;
|
|
563
1139
|
}
|
|
564
1140
|
const timeout = setTimeout(() => {
|
|
@@ -583,15 +1159,21 @@ var EventShipper = class {
|
|
|
583
1159
|
try {
|
|
584
1160
|
for (const t of this.timers.values()) clearTimeout(t);
|
|
585
1161
|
this.timers.clear();
|
|
1162
|
+
for (const [eventId, sticky] of this.sticky) {
|
|
1163
|
+
if (sticky.replayOnly) this.sticky.delete(eventId);
|
|
1164
|
+
}
|
|
586
1165
|
const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
|
|
587
1166
|
if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
|
|
588
1167
|
} finally {
|
|
589
1168
|
this.shutdownDeadlineAt = void 0;
|
|
1169
|
+
if (this.ownsAppGitContext) this.appGitContext.dispose();
|
|
590
1170
|
}
|
|
591
1171
|
}
|
|
592
1172
|
async trackSignal(signal) {
|
|
593
1173
|
var _a, _b;
|
|
594
1174
|
if (!this.enabled) return;
|
|
1175
|
+
const destination = currentReplayTraceDestination();
|
|
1176
|
+
if (destination && destination.kind !== "workshop") return;
|
|
595
1177
|
const body = [
|
|
596
1178
|
{
|
|
597
1179
|
event_id: signal.eventId,
|
|
@@ -626,6 +1208,8 @@ var EventShipper = class {
|
|
|
626
1208
|
}
|
|
627
1209
|
async identify(users) {
|
|
628
1210
|
if (!this.enabled) return;
|
|
1211
|
+
const destination = currentReplayTraceDestination();
|
|
1212
|
+
if (destination && destination.kind !== "workshop") return;
|
|
629
1213
|
const list = Array.isArray(users) ? users : [users];
|
|
630
1214
|
const body = list.filter((user) => {
|
|
631
1215
|
if (!(user == null ? void 0 : user.userId) || !user.userId.trim()) {
|
|
@@ -678,8 +1262,9 @@ var EventShipper = class {
|
|
|
678
1262
|
this.buffers.delete(eventId);
|
|
679
1263
|
if (!accumulated) return;
|
|
680
1264
|
const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
|
|
681
|
-
const
|
|
682
|
-
const
|
|
1265
|
+
const isPending = (_c = (_b = accumulated.isPending) != null ? _b : sticky.isPending) != null ? _c : true;
|
|
1266
|
+
const eventName = (_e = (_d = accumulated.eventName) != null ? _d : sticky.eventName) != null ? _e : this.defaultEventName;
|
|
1267
|
+
const userId = (_f = accumulated.userId) != null ? _f : sticky.userId;
|
|
683
1268
|
if (!userId) {
|
|
684
1269
|
if (this.debug) {
|
|
685
1270
|
console.warn(`${this.prefix} skipping track_partial for ${eventId}: missing userId`);
|
|
@@ -687,14 +1272,13 @@ var EventShipper = class {
|
|
|
687
1272
|
this.sticky.delete(eventId);
|
|
688
1273
|
return;
|
|
689
1274
|
}
|
|
690
|
-
const { wizardSession, ...restProperties } = (
|
|
1275
|
+
const { wizardSession, ...restProperties } = (_g = accumulated.properties) != null ? _g : {};
|
|
691
1276
|
let telemetryProperties = {};
|
|
692
1277
|
try {
|
|
693
1278
|
telemetryProperties = eventTelemetryProperties(accumulated);
|
|
694
1279
|
} catch (e) {
|
|
695
1280
|
}
|
|
696
|
-
const convoId = (
|
|
697
|
-
const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
|
|
1281
|
+
const convoId = (_h = accumulated.convoId) != null ? _h : sticky.convoId;
|
|
698
1282
|
const payload = {
|
|
699
1283
|
event_id: eventId,
|
|
700
1284
|
user_id: userId,
|
|
@@ -1010,6 +1594,13 @@ function redactJsonAttributeValue(key, value) {
|
|
|
1010
1594
|
if (scrubbedJson === json) return void 0;
|
|
1011
1595
|
return { stringValue: scrubbedJson };
|
|
1012
1596
|
}
|
|
1597
|
+
function appGitOwnerId2(prefix) {
|
|
1598
|
+
try {
|
|
1599
|
+
return `${prefix}:${randomUUID()}`;
|
|
1600
|
+
} catch (e) {
|
|
1601
|
+
return `${prefix}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1013
1604
|
function identityAttrs(args) {
|
|
1014
1605
|
return [
|
|
1015
1606
|
attrString("ai.telemetry.metadata.raindrop.ai.userId", args.userId),
|
|
@@ -1032,23 +1623,30 @@ function applyOtelSpanAttributeLimit(limit) {
|
|
|
1032
1623
|
}
|
|
1033
1624
|
var TraceShipper = class {
|
|
1034
1625
|
constructor(opts) {
|
|
1626
|
+
this.appGitOwner = appGitOwnerId2("trace");
|
|
1627
|
+
this.appGitEventIds = /* @__PURE__ */ new WeakMap();
|
|
1628
|
+
this.appGitActiveSpans = /* @__PURE__ */ new Map();
|
|
1629
|
+
this.appGitCaptured = /* @__PURE__ */ new WeakSet();
|
|
1630
|
+
this.appGitAdded = /* @__PURE__ */ new WeakMap();
|
|
1035
1631
|
this.queue = [];
|
|
1036
1632
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
1037
1633
|
this.hasShutdown = false;
|
|
1038
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1039
|
-
this.
|
|
1040
|
-
this.
|
|
1634
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
1635
|
+
this.appGitContext = (_a = opts.appGitContext) != null ? _a : createAppGitContext(opts.appGit);
|
|
1636
|
+
this.ownsAppGitContext = opts.appGitContext === void 0;
|
|
1637
|
+
this.writeKey = (_b = opts.writeKey) == null ? void 0 : _b.trim();
|
|
1638
|
+
this.baseUrl = (_c = formatEndpoint(opts.endpoint)) != null ? _c : "https://api.raindrop.ai/v1/";
|
|
1041
1639
|
this.enabled = opts.enabled !== false;
|
|
1042
1640
|
this.debug = opts.debug;
|
|
1043
1641
|
this.debugSpans = opts.debugSpans === true;
|
|
1044
|
-
this.flushIntervalMs = (
|
|
1045
|
-
this.maxBatchSize = (
|
|
1046
|
-
this.maxQueueSize = (
|
|
1047
|
-
this.sdkName = (
|
|
1642
|
+
this.flushIntervalMs = (_d = opts.flushIntervalMs) != null ? _d : 1e3;
|
|
1643
|
+
this.maxBatchSize = (_e = opts.maxBatchSize) != null ? _e : 50;
|
|
1644
|
+
this.maxQueueSize = (_f = opts.maxQueueSize) != null ? _f : 5e3;
|
|
1645
|
+
this.sdkName = (_g = opts.sdkName) != null ? _g : "core";
|
|
1048
1646
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
1049
|
-
this.serviceName = (
|
|
1050
|
-
this.serviceVersion = (
|
|
1051
|
-
this.localDebuggerUrl = (
|
|
1647
|
+
this.serviceName = (_h = opts.serviceName) != null ? _h : "raindrop.core";
|
|
1648
|
+
this.serviceVersion = (_i = opts.serviceVersion) != null ? _i : "0.0.0";
|
|
1649
|
+
this.localDebuggerUrl = (_j = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _j : void 0;
|
|
1052
1650
|
if (this.debug && this.localDebuggerUrl) {
|
|
1053
1651
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
1054
1652
|
}
|
|
@@ -1112,7 +1710,10 @@ var TraceShipper = class {
|
|
|
1112
1710
|
try {
|
|
1113
1711
|
const result = this.transformSpanHook(current);
|
|
1114
1712
|
if (result === null) return null;
|
|
1115
|
-
if (result !== void 0)
|
|
1713
|
+
if (result !== void 0) {
|
|
1714
|
+
copyReplayTraceDestination(current, result);
|
|
1715
|
+
current = result;
|
|
1716
|
+
}
|
|
1116
1717
|
} catch (err) {
|
|
1117
1718
|
if (this.debug) {
|
|
1118
1719
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -1122,13 +1723,19 @@ var TraceShipper = class {
|
|
|
1122
1723
|
}
|
|
1123
1724
|
}
|
|
1124
1725
|
try {
|
|
1125
|
-
|
|
1726
|
+
const normalized = normalizeModelUsageSpan(current);
|
|
1727
|
+
copyReplayTraceDestination(current, normalized);
|
|
1728
|
+
current = normalized;
|
|
1126
1729
|
} catch (e) {
|
|
1127
1730
|
}
|
|
1128
1731
|
if (!this.disableDefaultRedaction) {
|
|
1129
|
-
|
|
1732
|
+
const redacted = defaultTransformSpan(current);
|
|
1733
|
+
copyReplayTraceDestination(current, redacted);
|
|
1734
|
+
current = redacted;
|
|
1130
1735
|
}
|
|
1131
|
-
|
|
1736
|
+
const capped = this.capSpanAttributes(current);
|
|
1737
|
+
copyReplayTraceDestination(current, capped);
|
|
1738
|
+
return capped;
|
|
1132
1739
|
}
|
|
1133
1740
|
isDebugEnabled() {
|
|
1134
1741
|
return this.debug;
|
|
@@ -1140,36 +1747,64 @@ var TraceShipper = class {
|
|
|
1140
1747
|
return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
|
|
1141
1748
|
}
|
|
1142
1749
|
startSpan(args) {
|
|
1143
|
-
var _a, _b;
|
|
1750
|
+
var _a, _b, _c;
|
|
1144
1751
|
const ids = createSpanIds(args.parent);
|
|
1145
1752
|
const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
1146
1753
|
const attrs = [
|
|
1147
1754
|
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1148
1755
|
...identityAttrs(args),
|
|
1149
|
-
attrString("ai.operationId", args.operationId)
|
|
1756
|
+
attrString("ai.operationId", args.operationId),
|
|
1757
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
1150
1758
|
];
|
|
1151
1759
|
if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
|
|
1152
|
-
const
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
);
|
|
1760
|
+
const tracksAppGit = this.appGitActiveSpans.has(args.eventId) || this.appGitActiveSpans.size < 1e4;
|
|
1761
|
+
const appGitOverrides = appGitPropertiesFromAttributes(attrs);
|
|
1762
|
+
const span = {
|
|
1763
|
+
ids,
|
|
1764
|
+
name: args.name,
|
|
1765
|
+
startTimeUnixNano: started,
|
|
1766
|
+
attributes: withAppGitAttributes(
|
|
1767
|
+
attrs,
|
|
1768
|
+
this.appGitContext.forOperation(args.eventId, appGitOverrides, this.appGitOwner)
|
|
1769
|
+
)
|
|
1770
|
+
};
|
|
1771
|
+
rememberReplayTraceDestination(span);
|
|
1772
|
+
this.appGitCaptured.add(span);
|
|
1773
|
+
this.appGitEventIds.set(span, args.eventId);
|
|
1774
|
+
if (tracksAppGit) {
|
|
1775
|
+
this.appGitActiveSpans.set(args.eventId, ((_c = this.appGitActiveSpans.get(args.eventId)) != null ? _c : 0) + 1);
|
|
1776
|
+
}
|
|
1777
|
+
this.appGitAdded.set(span, new Set(span.attributes.filter((attr) => !attrs.includes(attr))));
|
|
1778
|
+
const openSpan = buildOtlpSpan({
|
|
1779
|
+
ids: span.ids,
|
|
1780
|
+
name: span.name,
|
|
1781
|
+
startTimeUnixNano: span.startTimeUnixNano,
|
|
1782
|
+
endTimeUnixNano: span.startTimeUnixNano,
|
|
1783
|
+
// placeholder — will be updated on endSpan
|
|
1784
|
+
attributes: span.attributes,
|
|
1785
|
+
status: { code: SpanStatusCode.UNSET }
|
|
1786
|
+
});
|
|
1787
|
+
copyReplayTraceDestination(span, openSpan);
|
|
1788
|
+
this.mirrorToLocalDebugger(openSpan);
|
|
1164
1789
|
return span;
|
|
1165
1790
|
}
|
|
1166
|
-
mirrorToLocalDebugger(span) {
|
|
1167
|
-
|
|
1791
|
+
mirrorToLocalDebugger(span, completed = false) {
|
|
1792
|
+
const destination = replayTraceDestinationFor(span);
|
|
1793
|
+
if (destination && destination.kind !== "workshop") return;
|
|
1794
|
+
const localDebuggerUrl = (destination == null ? void 0 : destination.kind) === "workshop" ? destination.url : this.localDebuggerUrl;
|
|
1795
|
+
if (!localDebuggerUrl) return;
|
|
1168
1796
|
const redacted = this.redactSpan(span);
|
|
1169
1797
|
if (redacted === null) return;
|
|
1798
|
+
if (completed && (destination == null ? void 0 : destination.kind) === "workshop") {
|
|
1799
|
+
recordReplayExportedSpan(
|
|
1800
|
+
destination,
|
|
1801
|
+
base64ToHex(redacted.spanId),
|
|
1802
|
+
base64ToHex(redacted.traceId)
|
|
1803
|
+
);
|
|
1804
|
+
}
|
|
1170
1805
|
const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
|
|
1171
1806
|
const p = mirrorTraceExportToLocalDebugger(body, {
|
|
1172
|
-
baseUrl:
|
|
1807
|
+
baseUrl: localDebuggerUrl,
|
|
1173
1808
|
debug: false,
|
|
1174
1809
|
sdkName: this.sdkName
|
|
1175
1810
|
});
|
|
@@ -1179,11 +1814,17 @@ var TraceShipper = class {
|
|
|
1179
1814
|
});
|
|
1180
1815
|
}
|
|
1181
1816
|
endSpan(span, extra) {
|
|
1182
|
-
var _a, _b;
|
|
1817
|
+
var _a, _b, _c;
|
|
1183
1818
|
if (span.endTimeUnixNano) return;
|
|
1184
1819
|
span.endTimeUnixNano = (_a = extra == null ? void 0 : extra.endTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
1185
1820
|
if ((_b = extra == null ? void 0 : extra.attributes) == null ? void 0 : _b.length) {
|
|
1821
|
+
const overrides = appGitPropertiesFromAttributes(extra.attributes);
|
|
1822
|
+
const eventId2 = this.appGitEventIds.get(span);
|
|
1823
|
+
const snapshot = eventId2 ? this.appGitContext.forOperation(eventId2, overrides, this.appGitOwner) : overrides;
|
|
1824
|
+
const added = this.appGitAdded.get(span);
|
|
1825
|
+
span.attributes = span.attributes.filter((attr) => !(added == null ? void 0 : added.has(attr)) || !attr || !Object.prototype.hasOwnProperty.call(overrides, APP_COMMIT_SHA) && !Object.prototype.hasOwnProperty.call(overrides, attr.key));
|
|
1186
1826
|
span.attributes.push(...extra.attributes);
|
|
1827
|
+
span.attributes = withAppGitAttributes(span.attributes, snapshot);
|
|
1187
1828
|
}
|
|
1188
1829
|
let status = extra == null ? void 0 : extra.status;
|
|
1189
1830
|
if (!status && (extra == null ? void 0 : extra.error) !== void 0) {
|
|
@@ -1198,30 +1839,65 @@ var TraceShipper = class {
|
|
|
1198
1839
|
attributes: span.attributes,
|
|
1199
1840
|
status
|
|
1200
1841
|
});
|
|
1842
|
+
copyReplayTraceDestination(span, otlp);
|
|
1843
|
+
this.appGitCaptured.add(otlp);
|
|
1201
1844
|
this.enqueue(otlp);
|
|
1202
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1845
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1846
|
+
const eventId = this.appGitEventIds.get(span);
|
|
1847
|
+
if (eventId && this.appGitActiveSpans.has(eventId)) {
|
|
1848
|
+
const remaining = ((_c = this.appGitActiveSpans.get(eventId)) != null ? _c : 1) - 1;
|
|
1849
|
+
if (remaining > 0) this.appGitActiveSpans.set(eventId, remaining);
|
|
1850
|
+
else {
|
|
1851
|
+
this.appGitActiveSpans.delete(eventId);
|
|
1852
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
|
|
1853
|
+
else if (this.ownsAppGitContext) this.appGitContext.finishOperation(eventId);
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1203
1856
|
}
|
|
1204
1857
|
createSpan(args) {
|
|
1205
1858
|
var _a;
|
|
1206
1859
|
const ids = createSpanIds(args.parent);
|
|
1207
1860
|
const attrs = [
|
|
1208
1861
|
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1209
|
-
...identityAttrs(args)
|
|
1862
|
+
...identityAttrs(args),
|
|
1863
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
1210
1864
|
];
|
|
1211
1865
|
if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
|
|
1866
|
+
const tracksAppGit = !this.appGitActiveSpans.has(args.eventId);
|
|
1212
1867
|
const otlp = buildOtlpSpan({
|
|
1213
1868
|
ids,
|
|
1214
1869
|
name: args.name,
|
|
1215
1870
|
startTimeUnixNano: args.startTimeUnixNano,
|
|
1216
1871
|
endTimeUnixNano: args.endTimeUnixNano,
|
|
1217
|
-
attributes:
|
|
1872
|
+
attributes: withAppGitAttributes(
|
|
1873
|
+
attrs,
|
|
1874
|
+
this.appGitContext.forOperation(
|
|
1875
|
+
args.eventId,
|
|
1876
|
+
appGitPropertiesFromAttributes(attrs),
|
|
1877
|
+
this.appGitOwner
|
|
1878
|
+
)
|
|
1879
|
+
),
|
|
1218
1880
|
status: args.status
|
|
1219
1881
|
});
|
|
1882
|
+
rememberReplayTraceDestination(otlp);
|
|
1883
|
+
this.appGitCaptured.add(otlp);
|
|
1884
|
+
if (tracksAppGit) {
|
|
1885
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(args.eventId, this.appGitOwner);
|
|
1886
|
+
else if (this.ownsAppGitContext) this.appGitContext.finishOperation(args.eventId);
|
|
1887
|
+
}
|
|
1220
1888
|
this.enqueue(otlp);
|
|
1221
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1889
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1222
1890
|
}
|
|
1223
1891
|
enqueue(span) {
|
|
1892
|
+
var _a;
|
|
1224
1893
|
if (!this.enabled) return;
|
|
1894
|
+
const attributes = (_a = span.attributes) != null ? _a : [];
|
|
1895
|
+
const enriched = this.appGitCaptured.has(span) ? attributes : withAppGitAttributes(attributes, this.appGitContext.snapshot(appGitPropertiesFromAttributes(attributes)));
|
|
1896
|
+
if (enriched !== attributes) {
|
|
1897
|
+
const original = span;
|
|
1898
|
+
span = { ...span, attributes: enriched.filter((attr) => attr !== void 0) };
|
|
1899
|
+
copyReplayTraceDestination(original, span);
|
|
1900
|
+
}
|
|
1225
1901
|
if (this.debugSpans) {
|
|
1226
1902
|
const short = (s) => s ? s.slice(-8) : "none";
|
|
1227
1903
|
console.log(
|
|
@@ -1232,6 +1908,13 @@ var TraceShipper = class {
|
|
|
1232
1908
|
}
|
|
1233
1909
|
const redacted = this.redactSpan(span);
|
|
1234
1910
|
if (redacted === null) return;
|
|
1911
|
+
const destination = replayTraceDestinationFor(redacted);
|
|
1912
|
+
recordReplayExportedSpan(
|
|
1913
|
+
destination,
|
|
1914
|
+
base64ToHex(redacted.spanId),
|
|
1915
|
+
base64ToHex(redacted.traceId)
|
|
1916
|
+
);
|
|
1917
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") return;
|
|
1235
1918
|
if (this.queue.length >= this.maxQueueSize) {
|
|
1236
1919
|
this.queue.shift();
|
|
1237
1920
|
}
|
|
@@ -1250,6 +1933,7 @@ var TraceShipper = class {
|
|
|
1250
1933
|
}
|
|
1251
1934
|
}
|
|
1252
1935
|
async flush() {
|
|
1936
|
+
var _a;
|
|
1253
1937
|
if (!this.enabled) {
|
|
1254
1938
|
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
1255
1939
|
})));
|
|
@@ -1261,40 +1945,55 @@ var TraceShipper = class {
|
|
|
1261
1945
|
}
|
|
1262
1946
|
while (this.queue.length > 0) {
|
|
1263
1947
|
const batch = this.queue.splice(0, this.maxBatchSize);
|
|
1264
|
-
|
|
1265
|
-
const
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
`${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
|
|
1271
|
-
)
|
|
1272
|
-
);
|
|
1273
|
-
continue;
|
|
1274
|
-
}
|
|
1275
|
-
const body = buildExportTraceServiceRequest(batch, this.serviceName, this.serviceVersion);
|
|
1276
|
-
const url = `${this.baseUrl}traces`;
|
|
1277
|
-
if (this.debug) {
|
|
1278
|
-
console.log(`${this.prefix} sending traces batch`, {
|
|
1279
|
-
spans: batch.length,
|
|
1280
|
-
endpoint: url
|
|
1281
|
-
});
|
|
1948
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1949
|
+
for (const span of batch) {
|
|
1950
|
+
const destination = replayTraceDestinationFor(span);
|
|
1951
|
+
const spans = groups.get(destination);
|
|
1952
|
+
if (spans) spans.push(span);
|
|
1953
|
+
else groups.set(destination, [span]);
|
|
1282
1954
|
}
|
|
1283
|
-
const
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
|
|
1289
|
-
} catch (err) {
|
|
1290
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1955
|
+
for (const [destination, spans] of groups) {
|
|
1956
|
+
if (!destination && !this.writeKey) continue;
|
|
1957
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") continue;
|
|
1958
|
+
const opts = this.requestOpts();
|
|
1959
|
+
if (!opts) {
|
|
1291
1960
|
rateLimitedLog(
|
|
1292
|
-
`${this.prefix}.
|
|
1293
|
-
() => console.warn(
|
|
1961
|
+
`${this.prefix}.shutdown_deadline`,
|
|
1962
|
+
() => console.warn(
|
|
1963
|
+
`${this.prefix} shutdown flush deadline exceeded; dropping ${spans.length} spans`
|
|
1964
|
+
)
|
|
1294
1965
|
);
|
|
1966
|
+
continue;
|
|
1967
|
+
}
|
|
1968
|
+
const body = buildExportTraceServiceRequest(spans, this.serviceName, this.serviceVersion);
|
|
1969
|
+
const url = destination ? replayTraceUrl(destination.url) : `${this.baseUrl}traces`;
|
|
1970
|
+
const headers = destination ? {
|
|
1971
|
+
Authorization: `Bearer ${destination.apiKey}`,
|
|
1972
|
+
"X-Raindrop-Replay-Id": destination.replayId,
|
|
1973
|
+
"X-Raindrop-Project-Id": (_a = destination.projectId) != null ? _a : "default"
|
|
1974
|
+
} : this.requestHeaders();
|
|
1975
|
+
if (this.debug) {
|
|
1976
|
+
console.log(`${this.prefix} sending traces batch`, {
|
|
1977
|
+
spans: spans.length,
|
|
1978
|
+
endpoint: url
|
|
1979
|
+
});
|
|
1980
|
+
}
|
|
1981
|
+
const p = postJson(url, body, headers, opts);
|
|
1982
|
+
this.inFlight.add(p);
|
|
1983
|
+
try {
|
|
1984
|
+
try {
|
|
1985
|
+
await p;
|
|
1986
|
+
if (this.debug) console.log(`${this.prefix} sent ${spans.length} spans`);
|
|
1987
|
+
} catch (err) {
|
|
1988
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1989
|
+
rateLimitedLog(
|
|
1990
|
+
`${this.prefix}.send_spans_failed`,
|
|
1991
|
+
() => console.warn(`${this.prefix} failed to send ${spans.length} spans: ${msg}`)
|
|
1992
|
+
);
|
|
1993
|
+
}
|
|
1994
|
+
} finally {
|
|
1995
|
+
this.inFlight.delete(p);
|
|
1295
1996
|
}
|
|
1296
|
-
} finally {
|
|
1297
|
-
this.inFlight.delete(p);
|
|
1298
1997
|
}
|
|
1299
1998
|
}
|
|
1300
1999
|
}
|
|
@@ -1337,17 +2036,165 @@ var TraceShipper = class {
|
|
|
1337
2036
|
if (!settled) {
|
|
1338
2037
|
rateLimitedLog(
|
|
1339
2038
|
`${this.prefix}.shutdown_deadline`,
|
|
1340
|
-
() => console.warn(
|
|
2039
|
+
() => console.warn(
|
|
2040
|
+
`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`
|
|
2041
|
+
)
|
|
1341
2042
|
);
|
|
1342
2043
|
}
|
|
1343
2044
|
} finally {
|
|
1344
2045
|
this.shutdownDeadlineAt = void 0;
|
|
2046
|
+
if (this.ownsAppGitContext) this.appGitContext.dispose();
|
|
1345
2047
|
}
|
|
1346
2048
|
}
|
|
1347
2049
|
};
|
|
1348
2050
|
|
|
1349
2051
|
// ../core/dist/index.node.js
|
|
1350
2052
|
import { AsyncLocalStorage } from "async_hooks";
|
|
2053
|
+
import { execFile } from "child_process";
|
|
2054
|
+
import { resolve } from "path";
|
|
2055
|
+
var resolveLocal = (sourceDirectory, detectBranch, completed) => {
|
|
2056
|
+
const cwd = sourceDirectory ? resolve(sourceDirectory) : process.cwd();
|
|
2057
|
+
let cancelled = false;
|
|
2058
|
+
let active;
|
|
2059
|
+
let deadlineTimer;
|
|
2060
|
+
const deadline = Date.now() + 1e3;
|
|
2061
|
+
const run = (args, done) => {
|
|
2062
|
+
if (cancelled) return;
|
|
2063
|
+
const remaining = deadline - Date.now();
|
|
2064
|
+
if (remaining <= 0) {
|
|
2065
|
+
done(void 0);
|
|
2066
|
+
return;
|
|
2067
|
+
}
|
|
2068
|
+
try {
|
|
2069
|
+
active = execFile(
|
|
2070
|
+
"git",
|
|
2071
|
+
args,
|
|
2072
|
+
{
|
|
2073
|
+
cwd,
|
|
2074
|
+
encoding: "utf8",
|
|
2075
|
+
maxBuffer: 4096,
|
|
2076
|
+
windowsHide: true,
|
|
2077
|
+
env: {
|
|
2078
|
+
...process.env,
|
|
2079
|
+
// The selected application cwd, not the invoking shell's Git plumbing, owns identity.
|
|
2080
|
+
GIT_DIR: void 0,
|
|
2081
|
+
GIT_WORK_TREE: void 0,
|
|
2082
|
+
GIT_COMMON_DIR: void 0,
|
|
2083
|
+
GIT_NAMESPACE: void 0,
|
|
2084
|
+
GIT_INDEX_FILE: void 0,
|
|
2085
|
+
GIT_OBJECT_DIRECTORY: void 0,
|
|
2086
|
+
GIT_ALTERNATE_OBJECT_DIRECTORIES: void 0,
|
|
2087
|
+
GIT_CONFIG_PARAMETERS: void 0,
|
|
2088
|
+
GIT_CONFIG_COUNT: "0",
|
|
2089
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
2090
|
+
GIT_OPTIONAL_LOCKS: "0"
|
|
2091
|
+
}
|
|
2092
|
+
},
|
|
2093
|
+
(error, stdout) => {
|
|
2094
|
+
clearTimeout(deadlineTimer);
|
|
2095
|
+
deadlineTimer = void 0;
|
|
2096
|
+
active = void 0;
|
|
2097
|
+
if (!cancelled) {
|
|
2098
|
+
try {
|
|
2099
|
+
done(error ? void 0 : stdout.trim());
|
|
2100
|
+
} catch (e) {
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
);
|
|
2105
|
+
active.unref();
|
|
2106
|
+
if (active.stdout && "unref" in active.stdout && typeof active.stdout.unref === "function")
|
|
2107
|
+
active.stdout.unref();
|
|
2108
|
+
if (active.stderr && "unref" in active.stderr && typeof active.stderr.unref === "function")
|
|
2109
|
+
active.stderr.unref();
|
|
2110
|
+
deadlineTimer = setTimeout(() => {
|
|
2111
|
+
try {
|
|
2112
|
+
active == null ? void 0 : active.kill("SIGKILL");
|
|
2113
|
+
} catch (e) {
|
|
2114
|
+
}
|
|
2115
|
+
}, remaining);
|
|
2116
|
+
deadlineTimer.unref();
|
|
2117
|
+
} catch (e) {
|
|
2118
|
+
try {
|
|
2119
|
+
done(void 0);
|
|
2120
|
+
} catch (e2) {
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
};
|
|
2124
|
+
const scheduled = setTimeout(() => {
|
|
2125
|
+
try {
|
|
2126
|
+
run(["rev-parse", "HEAD"], (rawSha) => {
|
|
2127
|
+
const commitSha = validAppCommitSha(rawSha);
|
|
2128
|
+
if (!commitSha) {
|
|
2129
|
+
completed({});
|
|
2130
|
+
return;
|
|
2131
|
+
}
|
|
2132
|
+
run(["-c", "core.fsmonitor=false", "status", "--porcelain"], (status) => {
|
|
2133
|
+
const finish = (branch) => {
|
|
2134
|
+
run(["rev-parse", "HEAD"], (finalSha) => {
|
|
2135
|
+
const coherent = validAppCommitSha(finalSha) === commitSha;
|
|
2136
|
+
completed({
|
|
2137
|
+
commitSha,
|
|
2138
|
+
...coherent && status !== void 0 ? { commitDirty: status !== "" } : {},
|
|
2139
|
+
...coherent && branch && branch !== "HEAD" ? { branch } : {}
|
|
2140
|
+
});
|
|
2141
|
+
});
|
|
2142
|
+
};
|
|
2143
|
+
if (detectBranch) run(["symbolic-ref", "--quiet", "--short", "HEAD"], finish);
|
|
2144
|
+
else finish();
|
|
2145
|
+
});
|
|
2146
|
+
});
|
|
2147
|
+
} catch (e) {
|
|
2148
|
+
completed({});
|
|
2149
|
+
}
|
|
2150
|
+
}, 0);
|
|
2151
|
+
scheduled.unref();
|
|
2152
|
+
return () => {
|
|
2153
|
+
cancelled = true;
|
|
2154
|
+
clearTimeout(scheduled);
|
|
2155
|
+
clearTimeout(deadlineTimer);
|
|
2156
|
+
try {
|
|
2157
|
+
active == null ? void 0 : active.kill("SIGKILL");
|
|
2158
|
+
} catch (e) {
|
|
2159
|
+
}
|
|
2160
|
+
};
|
|
2161
|
+
};
|
|
2162
|
+
function createAppGitContext2(options, runtime = {}) {
|
|
2163
|
+
return new AppGitContext(options, { ...runtime, resolveLocal });
|
|
2164
|
+
}
|
|
2165
|
+
function hasDestination(options) {
|
|
2166
|
+
var _a;
|
|
2167
|
+
if (options.enabled === false) return false;
|
|
2168
|
+
return Boolean(((_a = options.writeKey) == null ? void 0 : _a.trim()) || resolveLocalDebuggerBaseUrl(options.localDebuggerUrl));
|
|
2169
|
+
}
|
|
2170
|
+
var EventShipper2 = class extends EventShipper {
|
|
2171
|
+
constructor(options) {
|
|
2172
|
+
var _a;
|
|
2173
|
+
const ownsAppGitContext = options.appGitContext === void 0;
|
|
2174
|
+
const appGitContext = (_a = options.appGitContext) != null ? _a : createAppGitContext2(options.appGit, { allowDiscovery: hasDestination(options) });
|
|
2175
|
+
try {
|
|
2176
|
+
super({ ...options, appGitContext });
|
|
2177
|
+
} catch (error) {
|
|
2178
|
+
if (ownsAppGitContext) appGitContext.dispose();
|
|
2179
|
+
throw error;
|
|
2180
|
+
}
|
|
2181
|
+
if (ownsAppGitContext) this.ownAppGitContextForShutdown();
|
|
2182
|
+
}
|
|
2183
|
+
};
|
|
2184
|
+
var TraceShipper2 = class extends TraceShipper {
|
|
2185
|
+
constructor(options) {
|
|
2186
|
+
var _a;
|
|
2187
|
+
const ownsAppGitContext = options.appGitContext === void 0;
|
|
2188
|
+
const appGitContext = (_a = options.appGitContext) != null ? _a : createAppGitContext2(options.appGit, { allowDiscovery: hasDestination(options) });
|
|
2189
|
+
try {
|
|
2190
|
+
super({ ...options, appGitContext });
|
|
2191
|
+
} catch (error) {
|
|
2192
|
+
if (ownsAppGitContext) appGitContext.dispose();
|
|
2193
|
+
throw error;
|
|
2194
|
+
}
|
|
2195
|
+
this.ownsAppGitContext = ownsAppGitContext;
|
|
2196
|
+
}
|
|
2197
|
+
};
|
|
1351
2198
|
globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = AsyncLocalStorage;
|
|
1352
2199
|
var SUPPRESS_TRACING_KEY = /* @__PURE__ */ Symbol.for(
|
|
1353
2200
|
"OpenTelemetry SDK Context Key SUPPRESS_TRACING"
|
|
@@ -1378,7 +2225,7 @@ installTracingSuppressionHook();
|
|
|
1378
2225
|
// package.json
|
|
1379
2226
|
var package_default = {
|
|
1380
2227
|
name: "@raindrop-ai/claude-code",
|
|
1381
|
-
version: "0.0.
|
|
2228
|
+
version: "0.0.20",
|
|
1382
2229
|
description: "Raindrop observability for Claude Code CLI \u2014 automatic session, tool call, and prompt tracing via hooks",
|
|
1383
2230
|
license: "MIT",
|
|
1384
2231
|
homepage: "https://www.raindrop.ai/docs/integrations/claude-code/",
|
|
@@ -1452,7 +2299,7 @@ var PACKAGE_NAME = "@raindrop-ai/claude-code";
|
|
|
1452
2299
|
var PACKAGE_VERSION = package_default.version;
|
|
1453
2300
|
|
|
1454
2301
|
// src/shipper.ts
|
|
1455
|
-
var
|
|
2302
|
+
var EventShipper3 = class extends EventShipper2 {
|
|
1456
2303
|
constructor(opts) {
|
|
1457
2304
|
var _a, _b, _c, _d;
|
|
1458
2305
|
super({
|
|
@@ -1464,7 +2311,7 @@ var EventShipper2 = class extends EventShipper {
|
|
|
1464
2311
|
});
|
|
1465
2312
|
}
|
|
1466
2313
|
};
|
|
1467
|
-
var
|
|
2314
|
+
var TraceShipper3 = class extends TraceShipper2 {
|
|
1468
2315
|
constructor(opts) {
|
|
1469
2316
|
var _a, _b, _c;
|
|
1470
2317
|
super({
|
|
@@ -1545,7 +2392,20 @@ function loadConfig() {
|
|
|
1545
2392
|
})(),
|
|
1546
2393
|
eventName: (_l = (_k = process.env["RAINDROP_EVENT_NAME"]) != null ? _k : file.event_name) != null ? _l : "claude_code_session",
|
|
1547
2394
|
customProperties,
|
|
1548
|
-
selfDiagnostics
|
|
2395
|
+
selfDiagnostics,
|
|
2396
|
+
appGit: mapAppGit(file.app_git)
|
|
2397
|
+
};
|
|
2398
|
+
}
|
|
2399
|
+
function mapAppGit(value) {
|
|
2400
|
+
if (value === false) return false;
|
|
2401
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
2402
|
+
return {
|
|
2403
|
+
commitSha: "commit_sha" in value && (typeof value.commit_sha === "string" || value.commit_sha === null) ? value.commit_sha : void 0,
|
|
2404
|
+
commitDirty: "commit_dirty" in value && (typeof value.commit_dirty === "boolean" || value.commit_dirty === null) ? value.commit_dirty : void 0,
|
|
2405
|
+
branch: "branch" in value && (typeof value.branch === "string" || value.branch === null) ? value.branch : void 0,
|
|
2406
|
+
detectBranch: "detect_branch" in value && typeof value.detect_branch === "boolean" ? value.detect_branch : void 0,
|
|
2407
|
+
sourceDirectory: "source_directory" in value && typeof value.source_directory === "string" ? value.source_directory : void 0,
|
|
2408
|
+
autoDetect: "auto_detect" in value && typeof value.auto_detect === "boolean" ? value.auto_detect : void 0
|
|
1549
2409
|
};
|
|
1550
2410
|
}
|
|
1551
2411
|
function getConfigPath() {
|
|
@@ -2685,6 +3545,7 @@ function resolveCurrentEventId() {
|
|
|
2685
3545
|
}
|
|
2686
3546
|
}
|
|
2687
3547
|
async function executeTool(args) {
|
|
3548
|
+
var _a;
|
|
2688
3549
|
const category = typeof args["category"] === "string" ? args["category"] : "";
|
|
2689
3550
|
const detail = typeof args["detail"] === "string" ? args["detail"] : "";
|
|
2690
3551
|
if (!category || !activeSignals[category]) {
|
|
@@ -2710,12 +3571,17 @@ async function executeTool(args) {
|
|
|
2710
3571
|
if (!eventId) {
|
|
2711
3572
|
return { content: [{ type: "text", text: "Signal noted (no active event found)." }] };
|
|
2712
3573
|
}
|
|
2713
|
-
const
|
|
3574
|
+
const appGitContext = createAppGitContext2(
|
|
3575
|
+
((_a = config.writeKey) == null ? void 0 : _a.trim()) ? config.appGit : false,
|
|
3576
|
+
{ allowLocalGit: false }
|
|
3577
|
+
);
|
|
3578
|
+
const shipper = new EventShipper3({
|
|
2714
3579
|
writeKey: config.writeKey,
|
|
2715
3580
|
endpoint: config.endpoint,
|
|
2716
3581
|
debug: false,
|
|
2717
3582
|
projectId: config.projectId,
|
|
2718
|
-
enabled: true
|
|
3583
|
+
enabled: true,
|
|
3584
|
+
appGitContext
|
|
2719
3585
|
});
|
|
2720
3586
|
try {
|
|
2721
3587
|
const signalDef = activeSignals[category];
|
|
@@ -2742,6 +3608,11 @@ async function executeTool(args) {
|
|
|
2742
3608
|
});
|
|
2743
3609
|
await shipper.shutdown();
|
|
2744
3610
|
} catch (e) {
|
|
3611
|
+
} finally {
|
|
3612
|
+
try {
|
|
3613
|
+
appGitContext.dispose();
|
|
3614
|
+
} catch (e) {
|
|
3615
|
+
}
|
|
2745
3616
|
}
|
|
2746
3617
|
return { content: [{ type: "text", text: "Signal recorded." }] };
|
|
2747
3618
|
}
|
|
@@ -2863,11 +3734,12 @@ async function handleLine(line, toolSchema) {
|
|
|
2863
3734
|
}
|
|
2864
3735
|
export {
|
|
2865
3736
|
DEFAULT_CATEGORY_KEYS,
|
|
2866
|
-
|
|
3737
|
+
EventShipper3 as EventShipper,
|
|
2867
3738
|
PACKAGE_NAME,
|
|
2868
3739
|
PACKAGE_VERSION,
|
|
2869
3740
|
TOOL_SCHEMA,
|
|
2870
|
-
|
|
3741
|
+
TraceShipper3 as TraceShipper,
|
|
3742
|
+
createAppGitContext2 as createAppGitContext,
|
|
2871
3743
|
detectLocalDebugger,
|
|
2872
3744
|
executeTool,
|
|
2873
3745
|
extractAppendSystemPrompt,
|