@raindrop-ai/claude-code 0.0.19 → 0.0.21
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 +26 -0
- package/dist/cli.js +1180 -120
- package/dist/index.cjs +1139 -97
- package/dist/index.d.cts +124 -1
- package/dist/index.d.ts +124 -1
- package/dist/index.js +1138 -97
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,521 @@ import { randomUUID as randomUUID2 } from "crypto";
|
|
|
7
7
|
import { tmpdir } from "os";
|
|
8
8
|
import { join } from "path";
|
|
9
9
|
|
|
10
|
-
// ../core/dist/chunk-
|
|
10
|
+
// ../core/dist/chunk-BYBMRLZM.js
|
|
11
|
+
var EVAL_CORRELATION_ID_ATTRIBUTE = "raindrop.eval_correlation_id";
|
|
12
|
+
var PROBE_SCOPE = { correlationId: "" };
|
|
13
|
+
var EvalScopeStorage = class {
|
|
14
|
+
constructor() {
|
|
15
|
+
this._als = null;
|
|
16
|
+
this._probed = false;
|
|
17
|
+
}
|
|
18
|
+
maybeAdoptAsyncLocalStorage() {
|
|
19
|
+
if (this._probed) return;
|
|
20
|
+
this._probed = true;
|
|
21
|
+
try {
|
|
22
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
23
|
+
if (!Ctor) return;
|
|
24
|
+
const als = new Ctor();
|
|
25
|
+
als.run(PROBE_SCOPE, () => {
|
|
26
|
+
});
|
|
27
|
+
this._als = als;
|
|
28
|
+
} catch (e) {
|
|
29
|
+
this._als = null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
run(scope, callback) {
|
|
33
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
34
|
+
if (this._als) return this._als.run(scope, callback);
|
|
35
|
+
const previous = this._syncScope;
|
|
36
|
+
this._syncScope = scope;
|
|
37
|
+
try {
|
|
38
|
+
return callback();
|
|
39
|
+
} finally {
|
|
40
|
+
this._syncScope = previous;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
current() {
|
|
44
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
45
|
+
if (this._als) return this._als.getStore();
|
|
46
|
+
return this._syncScope;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var EVAL_SCOPE_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.evalScopeStorage");
|
|
50
|
+
function evalScopeStorage() {
|
|
51
|
+
const holder = globalThis;
|
|
52
|
+
let storage = holder[EVAL_SCOPE_STORAGE_KEY];
|
|
53
|
+
if (!storage) {
|
|
54
|
+
storage = new EvalScopeStorage();
|
|
55
|
+
holder[EVAL_SCOPE_STORAGE_KEY] = storage;
|
|
56
|
+
}
|
|
57
|
+
return storage;
|
|
58
|
+
}
|
|
59
|
+
function currentEvalScope() {
|
|
60
|
+
try {
|
|
61
|
+
return evalScopeStorage().current();
|
|
62
|
+
} catch (e) {
|
|
63
|
+
return void 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function evalScopeAttributes() {
|
|
67
|
+
const scope = currentEvalScope();
|
|
68
|
+
if (!scope) return {};
|
|
69
|
+
return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ../core/dist/chunk-I6TVJQEC.js
|
|
73
|
+
var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
|
|
74
|
+
function state() {
|
|
75
|
+
const holder = globalThis;
|
|
76
|
+
let current = holder[STATE_KEY];
|
|
77
|
+
if (!current) {
|
|
78
|
+
let storage = null;
|
|
79
|
+
try {
|
|
80
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
81
|
+
if (Ctor) storage = new Ctor();
|
|
82
|
+
} catch (e) {
|
|
83
|
+
storage = null;
|
|
84
|
+
}
|
|
85
|
+
current = {
|
|
86
|
+
storage,
|
|
87
|
+
syncDestination: void 0,
|
|
88
|
+
spanDestinations: /* @__PURE__ */ new WeakMap()
|
|
89
|
+
};
|
|
90
|
+
holder[STATE_KEY] = current;
|
|
91
|
+
}
|
|
92
|
+
return current;
|
|
93
|
+
}
|
|
94
|
+
function currentReplayTraceDestination() {
|
|
95
|
+
var _a, _b;
|
|
96
|
+
const routing = state();
|
|
97
|
+
return (_b = (_a = routing.storage) == null ? void 0 : _a.getStore()) != null ? _b : routing.syncDestination;
|
|
98
|
+
}
|
|
99
|
+
function rememberReplayTraceDestination(span) {
|
|
100
|
+
const destination = currentReplayTraceDestination();
|
|
101
|
+
if (destination) state().spanDestinations.set(span, destination);
|
|
102
|
+
}
|
|
103
|
+
function copyReplayTraceDestination(source, target) {
|
|
104
|
+
const destination = state().spanDestinations.get(source);
|
|
105
|
+
if (destination) state().spanDestinations.set(target, destination);
|
|
106
|
+
}
|
|
107
|
+
function replayTraceDestinationFor(value) {
|
|
108
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
109
|
+
return void 0;
|
|
110
|
+
}
|
|
111
|
+
return state().spanDestinations.get(value);
|
|
112
|
+
}
|
|
113
|
+
function recordReplayExportedSpan(destination, spanId, traceId) {
|
|
114
|
+
var _a, _b;
|
|
115
|
+
if (!destination || !spanId || !traceId) return;
|
|
116
|
+
(_a = destination.exportedSpanIds) == null ? void 0 : _a.add(spanId);
|
|
117
|
+
(_b = destination.exportedTraceIds) == null ? void 0 : _b.add(traceId);
|
|
118
|
+
}
|
|
119
|
+
function replayTraceUrl(baseUrl) {
|
|
120
|
+
return `${baseUrl.replace(/\/+$/, "")}/v1/traces`;
|
|
121
|
+
}
|
|
122
|
+
function getAsyncLocalStorageCtor() {
|
|
123
|
+
return globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
124
|
+
}
|
|
125
|
+
var MAX_BINDING_STACK = 128;
|
|
126
|
+
var EMPTY_STACK = [];
|
|
127
|
+
var ContextStackStorage = class {
|
|
128
|
+
/** Emitted once when this runtime cannot support an ambient push. */
|
|
129
|
+
constructor(noAmbientBindWarning) {
|
|
130
|
+
this.noAmbientBindWarning = noAmbientBindWarning;
|
|
131
|
+
this._als = null;
|
|
132
|
+
this._enterWithUsable = false;
|
|
133
|
+
this._syncStack = EMPTY_STACK;
|
|
134
|
+
this._adoptionChecked = false;
|
|
135
|
+
this._warnedNoAmbientBind = false;
|
|
136
|
+
}
|
|
137
|
+
maybeAdoptAsyncLocalStorage() {
|
|
138
|
+
if (this._adoptionChecked) return;
|
|
139
|
+
this._adoptionChecked = true;
|
|
140
|
+
const Ctor = getAsyncLocalStorageCtor();
|
|
141
|
+
if (!Ctor) return;
|
|
142
|
+
const als = new Ctor();
|
|
143
|
+
try {
|
|
144
|
+
als.run(EMPTY_STACK, () => {
|
|
145
|
+
});
|
|
146
|
+
} catch (e) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
this._als = als;
|
|
150
|
+
if (typeof als.enterWith === "function") {
|
|
151
|
+
try {
|
|
152
|
+
als.enterWith(EMPTY_STACK);
|
|
153
|
+
this._enterWithUsable = true;
|
|
154
|
+
} catch (e) {
|
|
155
|
+
this._enterWithUsable = false;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
getStack() {
|
|
160
|
+
var _a;
|
|
161
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
162
|
+
if (this._als) return (_a = this._als.getStore()) != null ? _a : this._syncStack;
|
|
163
|
+
return this._syncStack;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Persist an ambient stack mutation. Returns false when an ALS is adopted but
|
|
167
|
+
* `enterWith` is unusable (workerd): callers must NOT fall back to the
|
|
168
|
+
* process-shared sync stack, since concurrent isolates would cross-stamp.
|
|
169
|
+
*/
|
|
170
|
+
setAmbientStack(stack) {
|
|
171
|
+
if (this._als) {
|
|
172
|
+
if (!this._enterWithUsable) return false;
|
|
173
|
+
this._als.enterWith(stack);
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
this._syncStack = stack;
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
push(binding) {
|
|
180
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
181
|
+
if (this._als && !this._enterWithUsable) {
|
|
182
|
+
this.warnNoAmbientBindOnce();
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
let stack = this.getStack();
|
|
186
|
+
if (stack.length >= MAX_BINDING_STACK) {
|
|
187
|
+
stack = stack.filter((b) => b.isLive());
|
|
188
|
+
if (stack.length >= MAX_BINDING_STACK) {
|
|
189
|
+
stack = stack.slice(stack.length - (MAX_BINDING_STACK - 1));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
this.setAmbientStack([...stack, binding]);
|
|
193
|
+
}
|
|
194
|
+
remove(binding) {
|
|
195
|
+
binding.markDead();
|
|
196
|
+
const stack = this.getStack();
|
|
197
|
+
const pruned = stack.filter((b) => b !== binding && b.isLive());
|
|
198
|
+
if (pruned.length !== stack.length) {
|
|
199
|
+
this.setAmbientStack(pruned);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
runWith(binding, callback) {
|
|
203
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
204
|
+
if (this._als) {
|
|
205
|
+
return this._als.run([...this.getStack(), binding], callback);
|
|
206
|
+
}
|
|
207
|
+
const previous = this._syncStack;
|
|
208
|
+
this._syncStack = [...previous, binding];
|
|
209
|
+
try {
|
|
210
|
+
return callback();
|
|
211
|
+
} finally {
|
|
212
|
+
this._syncStack = previous;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
current() {
|
|
216
|
+
const stack = this.getStack();
|
|
217
|
+
if (stack.length === 0) return void 0;
|
|
218
|
+
const top = stack[stack.length - 1];
|
|
219
|
+
if (top.isLive()) return top;
|
|
220
|
+
const pruned = stack.filter((b) => b.isLive());
|
|
221
|
+
this.setAmbientStack(pruned);
|
|
222
|
+
return pruned.length > 0 ? pruned[pruned.length - 1] : void 0;
|
|
223
|
+
}
|
|
224
|
+
warnNoAmbientBindOnce() {
|
|
225
|
+
if (this._warnedNoAmbientBind) return;
|
|
226
|
+
this._warnedNoAmbientBind = true;
|
|
227
|
+
console.warn(this.noAmbientBindWarning);
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
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.";
|
|
231
|
+
var ROUTING_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.routingContextStorage");
|
|
232
|
+
function routingStorage() {
|
|
233
|
+
const holder = globalThis;
|
|
234
|
+
let storage = holder[ROUTING_STORAGE_KEY];
|
|
235
|
+
if (!storage) {
|
|
236
|
+
storage = new ContextStackStorage(NO_AMBIENT_ROUTING_BIND_WARNING);
|
|
237
|
+
holder[ROUTING_STORAGE_KEY] = storage;
|
|
238
|
+
}
|
|
239
|
+
return storage;
|
|
240
|
+
}
|
|
241
|
+
function currentRoutingBinding() {
|
|
242
|
+
const bound = routingStorage().current();
|
|
243
|
+
if (!bound) return void 0;
|
|
244
|
+
return {
|
|
245
|
+
projectId: bound.projectId,
|
|
246
|
+
authHint: bound.authHint,
|
|
247
|
+
...bound.appGit ? { appGit: bound.appGit } : {},
|
|
248
|
+
...bound.appGitSource ? { appGitSource: bound.appGitSource } : {}
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
var APP_COMMIT_SHA = "raindrop.app.commit_sha";
|
|
252
|
+
var APP_COMMIT_DIRTY = "raindrop.app.commit_dirty";
|
|
253
|
+
var APP_BRANCH = "raindrop.app.branch";
|
|
254
|
+
var APP_GIT_KEYS = [APP_COMMIT_SHA, APP_COMMIT_DIRTY, APP_BRANCH];
|
|
255
|
+
var own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
256
|
+
function appGitExplicitKeys(properties) {
|
|
257
|
+
const keys = /* @__PURE__ */ new Set();
|
|
258
|
+
if (!properties) return keys;
|
|
259
|
+
for (const key of APP_GIT_KEYS) {
|
|
260
|
+
if (own(properties, key)) keys.add(key);
|
|
261
|
+
}
|
|
262
|
+
return keys;
|
|
263
|
+
}
|
|
264
|
+
function mergeAppGitSnapshot(base, properties, explicitKeys = /* @__PURE__ */ new Set()) {
|
|
265
|
+
try {
|
|
266
|
+
const result = { ...base };
|
|
267
|
+
if (properties && own(properties, APP_COMMIT_SHA) && properties[APP_COMMIT_SHA] !== result[APP_COMMIT_SHA]) {
|
|
268
|
+
if (!explicitKeys.has(APP_COMMIT_DIRTY) && !own(properties, APP_COMMIT_DIRTY)) {
|
|
269
|
+
delete result[APP_COMMIT_DIRTY];
|
|
270
|
+
}
|
|
271
|
+
if (!explicitKeys.has(APP_BRANCH) && !own(properties, APP_BRANCH)) {
|
|
272
|
+
delete result[APP_BRANCH];
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
for (const key of APP_GIT_KEYS) {
|
|
276
|
+
if (properties && own(properties, key)) result[key] = properties[key];
|
|
277
|
+
}
|
|
278
|
+
return Object.freeze(result);
|
|
279
|
+
} catch (e) {
|
|
280
|
+
return Object.freeze({});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function validAppCommitSha(value) {
|
|
284
|
+
if (typeof value !== "string" || value.length > 128) return void 0;
|
|
285
|
+
const cleaned = value.trim();
|
|
286
|
+
return /^(?:[a-fA-F0-9]{40}|[a-fA-F0-9]{64})$/.test(cleaned) ? cleaned.toLowerCase() : void 0;
|
|
287
|
+
}
|
|
288
|
+
function shortString(value) {
|
|
289
|
+
if (typeof value !== "string" || value.length > 1024) return void 0;
|
|
290
|
+
const cleaned = value.trim();
|
|
291
|
+
return cleaned.length > 0 ? cleaned : void 0;
|
|
292
|
+
}
|
|
293
|
+
function flag(value) {
|
|
294
|
+
if (value === true || value === "true" || value === "1") return true;
|
|
295
|
+
if (value === false || value === "false" || value === "0") return false;
|
|
296
|
+
return void 0;
|
|
297
|
+
}
|
|
298
|
+
function environment() {
|
|
299
|
+
try {
|
|
300
|
+
return typeof process === "undefined" ? {} : process.env;
|
|
301
|
+
} catch (e) {
|
|
302
|
+
return {};
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
var DEPLOYMENTS = [
|
|
306
|
+
["VERCEL", "VERCEL_GIT_COMMIT_SHA", "VERCEL_GIT_COMMIT_REF"],
|
|
307
|
+
["NETLIFY", "COMMIT_REF", "BRANCH"],
|
|
308
|
+
["RAILWAY_ENVIRONMENT_NAME", "RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH"],
|
|
309
|
+
["RAILWAY_ENVIRONMENT", "RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH"],
|
|
310
|
+
["RENDER", "RENDER_GIT_COMMIT", "RENDER_GIT_BRANCH"],
|
|
311
|
+
["DYNO", "HEROKU_BUILD_COMMIT", ""],
|
|
312
|
+
["DYNO", "HEROKU_SLUG_COMMIT", ""],
|
|
313
|
+
["AWS_APP_ID", "AWS_COMMIT_ID", "AWS_BRANCH"],
|
|
314
|
+
["WORKERS_CI", "WORKERS_CI_COMMIT_SHA", "WORKERS_CI_BRANCH"]
|
|
315
|
+
];
|
|
316
|
+
var CI_SOURCES = [
|
|
317
|
+
["GITHUB_ACTIONS", "GITHUB_SHA", "GITHUB_REF_NAME"],
|
|
318
|
+
["GITLAB_CI", "CI_COMMIT_SHA", "CI_COMMIT_REF_NAME"],
|
|
319
|
+
["CIRCLECI", "CIRCLE_SHA1", "CIRCLE_BRANCH"]
|
|
320
|
+
];
|
|
321
|
+
function detectedSource(env, table, detectBranch) {
|
|
322
|
+
for (const row of table) {
|
|
323
|
+
const [marker, shaKey, branchKey] = row;
|
|
324
|
+
if (!marker || !shaKey || !shortString(env[marker]) || flag(env[marker]) === false) continue;
|
|
325
|
+
const commitSha = validAppCommitSha(env[shaKey]);
|
|
326
|
+
if (commitSha)
|
|
327
|
+
return {
|
|
328
|
+
commitSha,
|
|
329
|
+
...detectBranch && branchKey ? { branch: shortString(env[branchKey]) } : {}
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
return {};
|
|
333
|
+
}
|
|
334
|
+
var AppGitContextImpl = class {
|
|
335
|
+
constructor(options, runtime = {}) {
|
|
336
|
+
this.defaults = {};
|
|
337
|
+
this.explicit = {};
|
|
338
|
+
this.explicitKeys = /* @__PURE__ */ new Set();
|
|
339
|
+
this.disposed = false;
|
|
340
|
+
this.operations = /* @__PURE__ */ new Map();
|
|
341
|
+
this.operationOverflow = false;
|
|
342
|
+
this.detectBranch = false;
|
|
343
|
+
this.disabled = false;
|
|
344
|
+
var _a, _b, _c, _d, _e, _f;
|
|
345
|
+
try {
|
|
346
|
+
if (options === false) {
|
|
347
|
+
this.disabled = true;
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
const opts = options != null ? options : {};
|
|
351
|
+
const env = (_a = runtime.env) != null ? _a : environment();
|
|
352
|
+
const detectBranch = (_c = (_b = flag(opts.detectBranch)) != null ? _b : flag(env.RAINDROP_GIT_DETECT_BRANCH)) != null ? _c : false;
|
|
353
|
+
this.detectBranch = detectBranch;
|
|
354
|
+
const collectBranch = detectBranch || runtime.captureLegacyReplayBranch === true;
|
|
355
|
+
const autoDetect = runtime.allowDiscovery === false ? false : (_e = (_d = flag(opts.autoDetect)) != null ? _d : flag(env.RAINDROP_GIT_AUTO_DETECT)) != null ? _e : true;
|
|
356
|
+
const configuredSha = opts.commitSha;
|
|
357
|
+
const explicitSha = configuredSha === void 0 ? env.RAINDROP_COMMIT_SHA : configuredSha;
|
|
358
|
+
if (explicitSha === null) this.explicit[APP_COMMIT_SHA] = null;
|
|
359
|
+
else if (typeof explicitSha === "string" && validAppCommitSha(explicitSha))
|
|
360
|
+
this.explicit[APP_COMMIT_SHA] = explicitSha;
|
|
361
|
+
const configuredDirty = opts.commitDirty;
|
|
362
|
+
const explicitDirty = configuredDirty === void 0 ? flag(env.RAINDROP_COMMIT_DIRTY) : configuredDirty;
|
|
363
|
+
if (explicitDirty === null || typeof explicitDirty === "boolean")
|
|
364
|
+
this.explicit[APP_COMMIT_DIRTY] = explicitDirty;
|
|
365
|
+
const configuredBranch = opts.branch;
|
|
366
|
+
const explicitBranch = configuredBranch === void 0 ? env.RAINDROP_BRANCH : configuredBranch;
|
|
367
|
+
if (explicitBranch === null) this.explicit[APP_BRANCH] = null;
|
|
368
|
+
else if (typeof explicitBranch === "string" && explicitBranch.length <= 1024)
|
|
369
|
+
this.explicit[APP_BRANCH] = explicitBranch;
|
|
370
|
+
this.explicitKeys = appGitExplicitKeys(this.explicit);
|
|
371
|
+
this.defaults = { ...this.explicit };
|
|
372
|
+
if (!autoDetect || explicitSha !== void 0) return;
|
|
373
|
+
const sourceDirectory = (_f = shortString(opts.sourceDirectory)) != null ? _f : shortString(env.RAINDROP_GIT_SOURCE_DIRECTORY);
|
|
374
|
+
if (runtime.allowLocalGit === false && !sourceDirectory) return;
|
|
375
|
+
const deploy = sourceDirectory ? {} : detectedSource(env, DEPLOYMENTS, collectBranch);
|
|
376
|
+
if (deploy.commitSha) {
|
|
377
|
+
this.accept(deploy);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
const fallback = sourceDirectory ? {} : detectedSource(env, CI_SOURCES, collectBranch);
|
|
381
|
+
if (runtime.resolveLocal && (runtime.allowLocalGit !== false || sourceDirectory)) {
|
|
382
|
+
this.cancel = runtime.resolveLocal(sourceDirectory, collectBranch, (result) => {
|
|
383
|
+
try {
|
|
384
|
+
if (!this.disposed) this.accept(result.commitSha ? result : fallback);
|
|
385
|
+
} catch (e) {
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
} else this.accept(fallback);
|
|
389
|
+
} catch (e) {
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
accept(result) {
|
|
393
|
+
const sha = validAppCommitSha(result.commitSha);
|
|
394
|
+
if (!sha) return;
|
|
395
|
+
this.replayBranch = shortString(result.branch);
|
|
396
|
+
this.defaults = {
|
|
397
|
+
[APP_COMMIT_SHA]: sha,
|
|
398
|
+
...typeof result.commitDirty === "boolean" ? { [APP_COMMIT_DIRTY]: result.commitDirty } : {},
|
|
399
|
+
...this.detectBranch && this.replayBranch ? { [APP_BRANCH]: this.replayBranch } : {},
|
|
400
|
+
...this.explicit
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
snapshot(properties) {
|
|
404
|
+
var _a;
|
|
405
|
+
try {
|
|
406
|
+
const binding = currentRoutingBinding();
|
|
407
|
+
const base = this.disabled && (binding == null ? void 0 : binding.appGitSource) !== "replay-override" ? {} : (_a = binding == null ? void 0 : binding.appGit) != null ? _a : this.defaults;
|
|
408
|
+
return this.mergeSnapshot(base, properties);
|
|
409
|
+
} catch (e) {
|
|
410
|
+
return Object.freeze({});
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
/** Safe defaults when no operation/span start was observed; never infer identity. */
|
|
414
|
+
snapshotExplicit(properties, eventId) {
|
|
415
|
+
try {
|
|
416
|
+
const base = { ...this.explicit };
|
|
417
|
+
const operation = eventId ? this.operations.get(eventId) : void 0;
|
|
418
|
+
if (operation) {
|
|
419
|
+
for (const key of operation.explicitKeys) base[key] = operation.snapshot[key];
|
|
420
|
+
}
|
|
421
|
+
return this.mergeSnapshot(base, properties, new Set(Object.keys(base)));
|
|
422
|
+
} catch (e) {
|
|
423
|
+
return mergeAppGitSnapshot({}, properties);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
/** Existing replay branch reporting stays separate from opt-in event properties. */
|
|
427
|
+
snapshotForReplay() {
|
|
428
|
+
const snapshot = this.snapshot();
|
|
429
|
+
if (this.replayBranch && !own(snapshot, APP_BRANCH) && snapshot[APP_COMMIT_SHA] === this.defaults[APP_COMMIT_SHA]) {
|
|
430
|
+
return Object.freeze({ ...snapshot, [APP_BRANCH]: this.replayBranch });
|
|
431
|
+
}
|
|
432
|
+
return snapshot;
|
|
433
|
+
}
|
|
434
|
+
/** Merge a frozen span snapshot without losing client-authored provenance. */
|
|
435
|
+
mergeSnapshot(base, properties, explicitKeys = this.explicitKeys) {
|
|
436
|
+
return mergeAppGitSnapshot(base, properties, /* @__PURE__ */ new Set([...this.explicitKeys, ...explicitKeys]));
|
|
437
|
+
}
|
|
438
|
+
/** Shippers belonging to one client share this bounded operation registry. */
|
|
439
|
+
forOperation(eventId, properties, owner) {
|
|
440
|
+
if (!eventId) return this.snapshot(properties);
|
|
441
|
+
let operation = this.operations.get(eventId);
|
|
442
|
+
if (!operation) {
|
|
443
|
+
if (this.operations.size >= 1e4) this.operationOverflow = true;
|
|
444
|
+
if (this.operationOverflow) return this.mergeSnapshot({}, properties);
|
|
445
|
+
operation = {
|
|
446
|
+
snapshot: this.snapshot(properties),
|
|
447
|
+
owners: /* @__PURE__ */ new Set(),
|
|
448
|
+
unowned: owner === void 0,
|
|
449
|
+
explicitKeys: appGitExplicitKeys(properties)
|
|
450
|
+
};
|
|
451
|
+
this.operations.set(eventId, operation);
|
|
452
|
+
} else if (properties && APP_GIT_KEYS.some((key) => own(properties, key))) {
|
|
453
|
+
const explicitKeys = /* @__PURE__ */ new Set([...this.explicitKeys, ...operation.explicitKeys]);
|
|
454
|
+
operation.snapshot = this.mergeSnapshot(operation.snapshot, properties, explicitKeys);
|
|
455
|
+
for (const key of appGitExplicitKeys(properties)) operation.explicitKeys.add(key);
|
|
456
|
+
}
|
|
457
|
+
if (!owner) operation.unowned = true;
|
|
458
|
+
if (owner) operation.owners.add(owner);
|
|
459
|
+
return operation.snapshot;
|
|
460
|
+
}
|
|
461
|
+
releaseOperation(eventId, owner) {
|
|
462
|
+
const operation = this.operations.get(eventId);
|
|
463
|
+
if (!operation) return;
|
|
464
|
+
operation.owners.delete(owner);
|
|
465
|
+
if (operation.owners.size === 0 && !operation.unowned) this.operations.delete(eventId);
|
|
466
|
+
}
|
|
467
|
+
finishOperation(eventId) {
|
|
468
|
+
this.operations.delete(eventId);
|
|
469
|
+
}
|
|
470
|
+
dispose() {
|
|
471
|
+
var _a;
|
|
472
|
+
this.disposed = true;
|
|
473
|
+
try {
|
|
474
|
+
(_a = this.cancel) == null ? void 0 : _a.call(this);
|
|
475
|
+
} catch (e) {
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
var AppGitContext = AppGitContextImpl;
|
|
480
|
+
function createAppGitContext(options, runtime = {}) {
|
|
481
|
+
return new AppGitContext(options, runtime);
|
|
482
|
+
}
|
|
483
|
+
function withAppGitProperties(properties, snapshot) {
|
|
484
|
+
try {
|
|
485
|
+
const merged = { ...properties };
|
|
486
|
+
for (const key of APP_GIT_KEYS)
|
|
487
|
+
if (!own(merged, key) && own(snapshot, key)) merged[key] = snapshot[key];
|
|
488
|
+
return merged;
|
|
489
|
+
} catch (e) {
|
|
490
|
+
return properties != null ? properties : {};
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
function withAppGitAttributes(attributes, snapshot) {
|
|
494
|
+
try {
|
|
495
|
+
const present = new Set(attributes.flatMap((attr) => attr ? [attr.key] : []));
|
|
496
|
+
const added = [];
|
|
497
|
+
for (const key of APP_GIT_KEYS) {
|
|
498
|
+
if (present.has(key) || present.has(`ai.telemetry.metadata.${key}`) || present.has(`traceloop.association.properties.${key}`))
|
|
499
|
+
continue;
|
|
500
|
+
const value = snapshot[key];
|
|
501
|
+
if (typeof value === "string") added.push({ key, value: { stringValue: value } });
|
|
502
|
+
else if (typeof value === "boolean") added.push({ key, value: { boolValue: value } });
|
|
503
|
+
}
|
|
504
|
+
return added.length ? [...attributes, ...added] : attributes;
|
|
505
|
+
} catch (e) {
|
|
506
|
+
return attributes;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
function appGitPropertiesFromAttributes(attributes) {
|
|
510
|
+
var _a, _b, _c;
|
|
511
|
+
const properties = {};
|
|
512
|
+
try {
|
|
513
|
+
for (const attr of attributes) {
|
|
514
|
+
if (!attr) continue;
|
|
515
|
+
for (const key of APP_GIT_KEYS) {
|
|
516
|
+
if (attr.key === key || attr.key === `ai.telemetry.metadata.${key}` || attr.key === `traceloop.association.properties.${key}`) {
|
|
517
|
+
properties[key] = (_c = (_b = (_a = attr.value.stringValue) != null ? _a : attr.value.boolValue) != null ? _b : attr.value.intValue) != null ? _c : null;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
} catch (e) {
|
|
522
|
+
}
|
|
523
|
+
return properties;
|
|
524
|
+
}
|
|
11
525
|
function getCrypto() {
|
|
12
526
|
const c = globalThis.crypto;
|
|
13
527
|
return c;
|
|
@@ -22,6 +536,17 @@ function randomBytes(length) {
|
|
|
22
536
|
for (let i = 0; i < out.length; i++) out[i] = Math.floor(Math.random() * 256);
|
|
23
537
|
return out;
|
|
24
538
|
}
|
|
539
|
+
function randomUUID() {
|
|
540
|
+
const cryptoObj = getCrypto();
|
|
541
|
+
if (cryptoObj && typeof cryptoObj.randomUUID === "function") {
|
|
542
|
+
return cryptoObj.randomUUID();
|
|
543
|
+
}
|
|
544
|
+
const b = randomBytes(16);
|
|
545
|
+
b[6] = b[6] & 15 | 64;
|
|
546
|
+
b[8] = b[8] & 63 | 128;
|
|
547
|
+
const hex = [...b].map((x) => x.toString(16).padStart(2, "0")).join("");
|
|
548
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
549
|
+
}
|
|
25
550
|
function base64Encode(bytes) {
|
|
26
551
|
const maybeBuffer = globalThis.Buffer;
|
|
27
552
|
if (maybeBuffer) {
|
|
@@ -51,6 +576,25 @@ function base64Encode(bytes) {
|
|
|
51
576
|
}
|
|
52
577
|
return out;
|
|
53
578
|
}
|
|
579
|
+
function base64ToHex(value) {
|
|
580
|
+
if (!value) return "";
|
|
581
|
+
const maybeBuffer = globalThis.Buffer;
|
|
582
|
+
if (maybeBuffer) {
|
|
583
|
+
return maybeBuffer.from(value, "base64").toString("hex");
|
|
584
|
+
}
|
|
585
|
+
const atobFn = globalThis.atob;
|
|
586
|
+
if (typeof atobFn !== "function") return "";
|
|
587
|
+
try {
|
|
588
|
+
const binary = atobFn(value);
|
|
589
|
+
let hex = "";
|
|
590
|
+
for (let i = 0; i < binary.length; i++) {
|
|
591
|
+
hex += (binary.charCodeAt(i) & 255).toString(16).padStart(2, "0");
|
|
592
|
+
}
|
|
593
|
+
return hex;
|
|
594
|
+
} catch (e) {
|
|
595
|
+
return "";
|
|
596
|
+
}
|
|
597
|
+
}
|
|
54
598
|
var HANDOFF_ATTRIBUTE_SUFFIXES = {
|
|
55
599
|
mode: "raindrop.handoff.mode",
|
|
56
600
|
childEventId: "raindrop.handoff.childEventId",
|
|
@@ -82,7 +626,7 @@ function runWithTracingSuppressed(fn) {
|
|
|
82
626
|
var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
83
627
|
var MAX_RETRY_DELAY_MS = 3e4;
|
|
84
628
|
function wait(ms) {
|
|
85
|
-
return new Promise((
|
|
629
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
86
630
|
}
|
|
87
631
|
function formatEndpoint(endpoint) {
|
|
88
632
|
if (!endpoint) return void 0;
|
|
@@ -119,9 +663,9 @@ async function raceWithTimeout(promise, timeoutMs) {
|
|
|
119
663
|
() => true,
|
|
120
664
|
() => true
|
|
121
665
|
),
|
|
122
|
-
new Promise((
|
|
666
|
+
new Promise((resolve3) => {
|
|
123
667
|
var _a;
|
|
124
|
-
timer = setTimeout(() =>
|
|
668
|
+
timer = setTimeout(() => resolve3(false), Math.max(0, timeoutMs));
|
|
125
669
|
(_a = timer.unref) == null ? void 0 : _a.call(timer);
|
|
126
670
|
})
|
|
127
671
|
]);
|
|
@@ -192,6 +736,7 @@ async function postJson(url, body, headers, opts) {
|
|
|
192
736
|
const resp = await runWithTracingSuppressed(
|
|
193
737
|
() => fetch(url, {
|
|
194
738
|
method: "POST",
|
|
739
|
+
redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
|
|
195
740
|
headers: {
|
|
196
741
|
"Content-Type": "application/json",
|
|
197
742
|
...headers
|
|
@@ -402,6 +947,13 @@ function projectIdHeaders(projectId) {
|
|
|
402
947
|
}
|
|
403
948
|
var SHUTDOWN_DEADLINE_MS = 1e4;
|
|
404
949
|
var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
950
|
+
function appGitOwnerId(prefix) {
|
|
951
|
+
try {
|
|
952
|
+
return `${prefix}:${randomUUID()}`;
|
|
953
|
+
} catch (e) {
|
|
954
|
+
return `${prefix}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
405
957
|
function mergePatches(target, source) {
|
|
406
958
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
407
959
|
const out = { ...target, ...source };
|
|
@@ -451,22 +1003,25 @@ function eventTelemetryProperties(patch) {
|
|
|
451
1003
|
}
|
|
452
1004
|
var EventShipper = class {
|
|
453
1005
|
constructor(opts) {
|
|
1006
|
+
this.appGitOwner = appGitOwnerId("event");
|
|
454
1007
|
this.buffers = /* @__PURE__ */ new Map();
|
|
455
1008
|
this.sticky = /* @__PURE__ */ new Map();
|
|
456
1009
|
this.timers = /* @__PURE__ */ new Map();
|
|
457
1010
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
458
1011
|
this.hasShutdown = false;
|
|
459
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
460
|
-
this.
|
|
461
|
-
this.
|
|
1012
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1013
|
+
this.appGitContext = (_a = opts.appGitContext) != null ? _a : createAppGitContext(opts.appGit);
|
|
1014
|
+
this.ownsAppGitContext = opts.appGitContext === void 0;
|
|
1015
|
+
this.writeKey = (_b = opts.writeKey) == null ? void 0 : _b.trim();
|
|
1016
|
+
this.baseUrl = (_c = formatEndpoint(opts.endpoint)) != null ? _c : "https://api.raindrop.ai/v1/";
|
|
462
1017
|
this.enabled = opts.enabled !== false;
|
|
463
1018
|
this.debug = opts.debug;
|
|
464
|
-
this.partialFlushMs = (
|
|
465
|
-
this.sdkName = (
|
|
1019
|
+
this.partialFlushMs = (_d = opts.partialFlushMs) != null ? _d : 1e3;
|
|
1020
|
+
this.sdkName = (_e = opts.sdkName) != null ? _e : "core";
|
|
466
1021
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
467
|
-
this.defaultEventName = (
|
|
1022
|
+
this.defaultEventName = (_f = opts.defaultEventName) != null ? _f : "ai_generation";
|
|
468
1023
|
this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
|
|
469
|
-
this.localDebuggerUrl = (
|
|
1024
|
+
this.localDebuggerUrl = (_g = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _g : void 0;
|
|
470
1025
|
if (this.debug && this.localDebuggerUrl) {
|
|
471
1026
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
472
1027
|
}
|
|
@@ -477,8 +1032,8 @@ var EventShipper = class {
|
|
|
477
1032
|
const isNode = typeof process !== "undefined" && typeof process.version === "string";
|
|
478
1033
|
this.context = {
|
|
479
1034
|
library: {
|
|
480
|
-
name: (
|
|
481
|
-
version: (
|
|
1035
|
+
name: (_h = opts.libraryName) != null ? _h : "@raindrop-ai/core",
|
|
1036
|
+
version: (_i = opts.libraryVersion) != null ? _i : "0.0.0"
|
|
482
1037
|
},
|
|
483
1038
|
metadata: {
|
|
484
1039
|
jsRuntime: isNode ? "node" : "web",
|
|
@@ -486,6 +1041,9 @@ var EventShipper = class {
|
|
|
486
1041
|
}
|
|
487
1042
|
};
|
|
488
1043
|
}
|
|
1044
|
+
ownAppGitContextForShutdown() {
|
|
1045
|
+
this.ownsAppGitContext = true;
|
|
1046
|
+
}
|
|
489
1047
|
isDebugEnabled() {
|
|
490
1048
|
return this.debug;
|
|
491
1049
|
}
|
|
@@ -534,6 +1092,15 @@ var EventShipper = class {
|
|
|
534
1092
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
535
1093
|
if (!this.enabled) return;
|
|
536
1094
|
if (!eventId || !eventId.trim()) return;
|
|
1095
|
+
const capturedSticky = this.sticky.get(eventId);
|
|
1096
|
+
const eventAlreadyKnown = capturedSticky !== void 0 || this.buffers.has(eventId);
|
|
1097
|
+
const destination = currentReplayTraceDestination();
|
|
1098
|
+
const cloudReplay = destination !== void 0 && destination.kind !== "workshop";
|
|
1099
|
+
if ((capturedSticky == null ? void 0 : capturedSticky.replayOnly) === true || !eventAlreadyKnown && cloudReplay) {
|
|
1100
|
+
if (patch.isPending === false) this.sticky.delete(eventId);
|
|
1101
|
+
else this.sticky.set(eventId, { ...capturedSticky, replayOnly: true });
|
|
1102
|
+
return;
|
|
1103
|
+
}
|
|
537
1104
|
const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
|
|
538
1105
|
if (typeof patch.input === "string" && patch.input.length > maxChars) {
|
|
539
1106
|
patch = { ...patch, input: capText(patch.input, maxChars) };
|
|
@@ -555,6 +1122,13 @@ var EventShipper = class {
|
|
|
555
1122
|
}
|
|
556
1123
|
const sticky = (_c = this.sticky.get(eventId)) != null ? _c : {};
|
|
557
1124
|
const existing = (_d = this.buffers.get(eventId)) != null ? _d : {};
|
|
1125
|
+
patch = {
|
|
1126
|
+
...patch,
|
|
1127
|
+
properties: withAppGitProperties(
|
|
1128
|
+
patch.properties,
|
|
1129
|
+
this.appGitContext.forOperation(eventId, patch.properties, this.appGitOwner)
|
|
1130
|
+
)
|
|
1131
|
+
};
|
|
558
1132
|
const merged = mergePatches(existing, patch);
|
|
559
1133
|
merged.isPending = (_g = (_f = (_e = patch.isPending) != null ? _e : existing.isPending) != null ? _f : sticky.isPending) != null ? _g : true;
|
|
560
1134
|
this.buffers.set(eventId, merged);
|
|
@@ -568,6 +1142,8 @@ var EventShipper = class {
|
|
|
568
1142
|
if (t) clearTimeout(t);
|
|
569
1143
|
if (merged.isPending === false) {
|
|
570
1144
|
await this.flushOne(eventId);
|
|
1145
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
|
|
1146
|
+
else this.appGitContext.finishOperation(eventId);
|
|
571
1147
|
return;
|
|
572
1148
|
}
|
|
573
1149
|
const timeout = setTimeout(() => {
|
|
@@ -592,15 +1168,21 @@ var EventShipper = class {
|
|
|
592
1168
|
try {
|
|
593
1169
|
for (const t of this.timers.values()) clearTimeout(t);
|
|
594
1170
|
this.timers.clear();
|
|
1171
|
+
for (const [eventId, sticky] of this.sticky) {
|
|
1172
|
+
if (sticky.replayOnly) this.sticky.delete(eventId);
|
|
1173
|
+
}
|
|
595
1174
|
const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
|
|
596
1175
|
if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
|
|
597
1176
|
} finally {
|
|
598
1177
|
this.shutdownDeadlineAt = void 0;
|
|
1178
|
+
if (this.ownsAppGitContext) this.appGitContext.dispose();
|
|
599
1179
|
}
|
|
600
1180
|
}
|
|
601
1181
|
async trackSignal(signal) {
|
|
602
1182
|
var _a, _b;
|
|
603
1183
|
if (!this.enabled) return;
|
|
1184
|
+
const destination = currentReplayTraceDestination();
|
|
1185
|
+
if (destination && destination.kind !== "workshop") return;
|
|
604
1186
|
const body = [
|
|
605
1187
|
{
|
|
606
1188
|
event_id: signal.eventId,
|
|
@@ -635,6 +1217,8 @@ var EventShipper = class {
|
|
|
635
1217
|
}
|
|
636
1218
|
async identify(users) {
|
|
637
1219
|
if (!this.enabled) return;
|
|
1220
|
+
const destination = currentReplayTraceDestination();
|
|
1221
|
+
if (destination && destination.kind !== "workshop") return;
|
|
638
1222
|
const list = Array.isArray(users) ? users : [users];
|
|
639
1223
|
const body = list.filter((user) => {
|
|
640
1224
|
if (!(user == null ? void 0 : user.userId) || !user.userId.trim()) {
|
|
@@ -687,8 +1271,9 @@ var EventShipper = class {
|
|
|
687
1271
|
this.buffers.delete(eventId);
|
|
688
1272
|
if (!accumulated) return;
|
|
689
1273
|
const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
|
|
690
|
-
const
|
|
691
|
-
const
|
|
1274
|
+
const isPending = (_c = (_b = accumulated.isPending) != null ? _b : sticky.isPending) != null ? _c : true;
|
|
1275
|
+
const eventName = (_e = (_d = accumulated.eventName) != null ? _d : sticky.eventName) != null ? _e : this.defaultEventName;
|
|
1276
|
+
const userId = (_f = accumulated.userId) != null ? _f : sticky.userId;
|
|
692
1277
|
if (!userId) {
|
|
693
1278
|
if (this.debug) {
|
|
694
1279
|
console.warn(`${this.prefix} skipping track_partial for ${eventId}: missing userId`);
|
|
@@ -696,14 +1281,13 @@ var EventShipper = class {
|
|
|
696
1281
|
this.sticky.delete(eventId);
|
|
697
1282
|
return;
|
|
698
1283
|
}
|
|
699
|
-
const { wizardSession, ...restProperties } = (
|
|
1284
|
+
const { wizardSession, ...restProperties } = (_g = accumulated.properties) != null ? _g : {};
|
|
700
1285
|
let telemetryProperties = {};
|
|
701
1286
|
try {
|
|
702
1287
|
telemetryProperties = eventTelemetryProperties(accumulated);
|
|
703
1288
|
} catch (e) {
|
|
704
1289
|
}
|
|
705
|
-
const convoId = (
|
|
706
|
-
const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
|
|
1290
|
+
const convoId = (_h = accumulated.convoId) != null ? _h : sticky.convoId;
|
|
707
1291
|
const payload = {
|
|
708
1292
|
event_id: eventId,
|
|
709
1293
|
user_id: userId,
|
|
@@ -1019,6 +1603,13 @@ function redactJsonAttributeValue(key, value) {
|
|
|
1019
1603
|
if (scrubbedJson === json) return void 0;
|
|
1020
1604
|
return { stringValue: scrubbedJson };
|
|
1021
1605
|
}
|
|
1606
|
+
function appGitOwnerId2(prefix) {
|
|
1607
|
+
try {
|
|
1608
|
+
return `${prefix}:${randomUUID()}`;
|
|
1609
|
+
} catch (e) {
|
|
1610
|
+
return `${prefix}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1022
1613
|
function identityAttrs(args2) {
|
|
1023
1614
|
return [
|
|
1024
1615
|
attrString("ai.telemetry.metadata.raindrop.ai.userId", args2.userId),
|
|
@@ -1041,23 +1632,30 @@ function applyOtelSpanAttributeLimit(limit) {
|
|
|
1041
1632
|
}
|
|
1042
1633
|
var TraceShipper = class {
|
|
1043
1634
|
constructor(opts) {
|
|
1635
|
+
this.appGitOwner = appGitOwnerId2("trace");
|
|
1636
|
+
this.appGitEventIds = /* @__PURE__ */ new WeakMap();
|
|
1637
|
+
this.appGitActiveSpans = /* @__PURE__ */ new Map();
|
|
1638
|
+
this.appGitCaptured = /* @__PURE__ */ new WeakSet();
|
|
1639
|
+
this.appGitAdded = /* @__PURE__ */ new WeakMap();
|
|
1044
1640
|
this.queue = [];
|
|
1045
1641
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
1046
1642
|
this.hasShutdown = false;
|
|
1047
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1048
|
-
this.
|
|
1049
|
-
this.
|
|
1643
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
1644
|
+
this.appGitContext = (_a = opts.appGitContext) != null ? _a : createAppGitContext(opts.appGit);
|
|
1645
|
+
this.ownsAppGitContext = opts.appGitContext === void 0;
|
|
1646
|
+
this.writeKey = (_b = opts.writeKey) == null ? void 0 : _b.trim();
|
|
1647
|
+
this.baseUrl = (_c = formatEndpoint(opts.endpoint)) != null ? _c : "https://api.raindrop.ai/v1/";
|
|
1050
1648
|
this.enabled = opts.enabled !== false;
|
|
1051
1649
|
this.debug = opts.debug;
|
|
1052
1650
|
this.debugSpans = opts.debugSpans === true;
|
|
1053
|
-
this.flushIntervalMs = (
|
|
1054
|
-
this.maxBatchSize = (
|
|
1055
|
-
this.maxQueueSize = (
|
|
1056
|
-
this.sdkName = (
|
|
1651
|
+
this.flushIntervalMs = (_d = opts.flushIntervalMs) != null ? _d : 1e3;
|
|
1652
|
+
this.maxBatchSize = (_e = opts.maxBatchSize) != null ? _e : 50;
|
|
1653
|
+
this.maxQueueSize = (_f = opts.maxQueueSize) != null ? _f : 5e3;
|
|
1654
|
+
this.sdkName = (_g = opts.sdkName) != null ? _g : "core";
|
|
1057
1655
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
1058
|
-
this.serviceName = (
|
|
1059
|
-
this.serviceVersion = (
|
|
1060
|
-
this.localDebuggerUrl = (
|
|
1656
|
+
this.serviceName = (_h = opts.serviceName) != null ? _h : "raindrop.core";
|
|
1657
|
+
this.serviceVersion = (_i = opts.serviceVersion) != null ? _i : "0.0.0";
|
|
1658
|
+
this.localDebuggerUrl = (_j = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _j : void 0;
|
|
1061
1659
|
if (this.debug && this.localDebuggerUrl) {
|
|
1062
1660
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
1063
1661
|
}
|
|
@@ -1121,7 +1719,10 @@ var TraceShipper = class {
|
|
|
1121
1719
|
try {
|
|
1122
1720
|
const result = this.transformSpanHook(current);
|
|
1123
1721
|
if (result === null) return null;
|
|
1124
|
-
if (result !== void 0)
|
|
1722
|
+
if (result !== void 0) {
|
|
1723
|
+
copyReplayTraceDestination(current, result);
|
|
1724
|
+
current = result;
|
|
1725
|
+
}
|
|
1125
1726
|
} catch (err) {
|
|
1126
1727
|
if (this.debug) {
|
|
1127
1728
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -1131,13 +1732,19 @@ var TraceShipper = class {
|
|
|
1131
1732
|
}
|
|
1132
1733
|
}
|
|
1133
1734
|
try {
|
|
1134
|
-
|
|
1735
|
+
const normalized = normalizeModelUsageSpan(current);
|
|
1736
|
+
copyReplayTraceDestination(current, normalized);
|
|
1737
|
+
current = normalized;
|
|
1135
1738
|
} catch (e) {
|
|
1136
1739
|
}
|
|
1137
1740
|
if (!this.disableDefaultRedaction) {
|
|
1138
|
-
|
|
1741
|
+
const redacted = defaultTransformSpan(current);
|
|
1742
|
+
copyReplayTraceDestination(current, redacted);
|
|
1743
|
+
current = redacted;
|
|
1139
1744
|
}
|
|
1140
|
-
|
|
1745
|
+
const capped = this.capSpanAttributes(current);
|
|
1746
|
+
copyReplayTraceDestination(current, capped);
|
|
1747
|
+
return capped;
|
|
1141
1748
|
}
|
|
1142
1749
|
isDebugEnabled() {
|
|
1143
1750
|
return this.debug;
|
|
@@ -1149,36 +1756,64 @@ var TraceShipper = class {
|
|
|
1149
1756
|
return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
|
|
1150
1757
|
}
|
|
1151
1758
|
startSpan(args2) {
|
|
1152
|
-
var _a, _b;
|
|
1759
|
+
var _a, _b, _c;
|
|
1153
1760
|
const ids = createSpanIds(args2.parent);
|
|
1154
1761
|
const started = (_a = args2.startTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
1155
1762
|
const attrs = [
|
|
1156
1763
|
attrString("ai.telemetry.metadata.raindrop.eventId", args2.eventId),
|
|
1157
1764
|
...identityAttrs(args2),
|
|
1158
|
-
attrString("ai.operationId", args2.operationId)
|
|
1765
|
+
attrString("ai.operationId", args2.operationId),
|
|
1766
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
1159
1767
|
];
|
|
1160
1768
|
if ((_b = args2.attributes) == null ? void 0 : _b.length) attrs.push(...args2.attributes);
|
|
1161
|
-
const
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
);
|
|
1769
|
+
const tracksAppGit = this.appGitActiveSpans.has(args2.eventId) || this.appGitActiveSpans.size < 1e4;
|
|
1770
|
+
const appGitOverrides = appGitPropertiesFromAttributes(attrs);
|
|
1771
|
+
const span = {
|
|
1772
|
+
ids,
|
|
1773
|
+
name: args2.name,
|
|
1774
|
+
startTimeUnixNano: started,
|
|
1775
|
+
attributes: withAppGitAttributes(
|
|
1776
|
+
attrs,
|
|
1777
|
+
this.appGitContext.forOperation(args2.eventId, appGitOverrides, this.appGitOwner)
|
|
1778
|
+
)
|
|
1779
|
+
};
|
|
1780
|
+
rememberReplayTraceDestination(span);
|
|
1781
|
+
this.appGitCaptured.add(span);
|
|
1782
|
+
this.appGitEventIds.set(span, args2.eventId);
|
|
1783
|
+
if (tracksAppGit) {
|
|
1784
|
+
this.appGitActiveSpans.set(args2.eventId, ((_c = this.appGitActiveSpans.get(args2.eventId)) != null ? _c : 0) + 1);
|
|
1785
|
+
}
|
|
1786
|
+
this.appGitAdded.set(span, new Set(span.attributes.filter((attr) => !attrs.includes(attr))));
|
|
1787
|
+
const openSpan = buildOtlpSpan({
|
|
1788
|
+
ids: span.ids,
|
|
1789
|
+
name: span.name,
|
|
1790
|
+
startTimeUnixNano: span.startTimeUnixNano,
|
|
1791
|
+
endTimeUnixNano: span.startTimeUnixNano,
|
|
1792
|
+
// placeholder — will be updated on endSpan
|
|
1793
|
+
attributes: span.attributes,
|
|
1794
|
+
status: { code: SpanStatusCode.UNSET }
|
|
1795
|
+
});
|
|
1796
|
+
copyReplayTraceDestination(span, openSpan);
|
|
1797
|
+
this.mirrorToLocalDebugger(openSpan);
|
|
1173
1798
|
return span;
|
|
1174
1799
|
}
|
|
1175
|
-
mirrorToLocalDebugger(span) {
|
|
1176
|
-
|
|
1800
|
+
mirrorToLocalDebugger(span, completed = false) {
|
|
1801
|
+
const destination = replayTraceDestinationFor(span);
|
|
1802
|
+
if (destination && destination.kind !== "workshop") return;
|
|
1803
|
+
const localDebuggerUrl = (destination == null ? void 0 : destination.kind) === "workshop" ? destination.url : this.localDebuggerUrl;
|
|
1804
|
+
if (!localDebuggerUrl) return;
|
|
1177
1805
|
const redacted = this.redactSpan(span);
|
|
1178
1806
|
if (redacted === null) return;
|
|
1807
|
+
if (completed && (destination == null ? void 0 : destination.kind) === "workshop") {
|
|
1808
|
+
recordReplayExportedSpan(
|
|
1809
|
+
destination,
|
|
1810
|
+
base64ToHex(redacted.spanId),
|
|
1811
|
+
base64ToHex(redacted.traceId)
|
|
1812
|
+
);
|
|
1813
|
+
}
|
|
1179
1814
|
const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
|
|
1180
1815
|
const p = mirrorTraceExportToLocalDebugger(body, {
|
|
1181
|
-
baseUrl:
|
|
1816
|
+
baseUrl: localDebuggerUrl,
|
|
1182
1817
|
debug: false,
|
|
1183
1818
|
sdkName: this.sdkName
|
|
1184
1819
|
});
|
|
@@ -1188,11 +1823,17 @@ var TraceShipper = class {
|
|
|
1188
1823
|
});
|
|
1189
1824
|
}
|
|
1190
1825
|
endSpan(span, extra) {
|
|
1191
|
-
var _a, _b;
|
|
1826
|
+
var _a, _b, _c;
|
|
1192
1827
|
if (span.endTimeUnixNano) return;
|
|
1193
1828
|
span.endTimeUnixNano = (_a = extra == null ? void 0 : extra.endTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
1194
1829
|
if ((_b = extra == null ? void 0 : extra.attributes) == null ? void 0 : _b.length) {
|
|
1830
|
+
const overrides = appGitPropertiesFromAttributes(extra.attributes);
|
|
1831
|
+
const eventId2 = this.appGitEventIds.get(span);
|
|
1832
|
+
const snapshot = eventId2 ? this.appGitContext.forOperation(eventId2, overrides, this.appGitOwner) : overrides;
|
|
1833
|
+
const added = this.appGitAdded.get(span);
|
|
1834
|
+
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));
|
|
1195
1835
|
span.attributes.push(...extra.attributes);
|
|
1836
|
+
span.attributes = withAppGitAttributes(span.attributes, snapshot);
|
|
1196
1837
|
}
|
|
1197
1838
|
let status = extra == null ? void 0 : extra.status;
|
|
1198
1839
|
if (!status && (extra == null ? void 0 : extra.error) !== void 0) {
|
|
@@ -1207,30 +1848,65 @@ var TraceShipper = class {
|
|
|
1207
1848
|
attributes: span.attributes,
|
|
1208
1849
|
status
|
|
1209
1850
|
});
|
|
1851
|
+
copyReplayTraceDestination(span, otlp);
|
|
1852
|
+
this.appGitCaptured.add(otlp);
|
|
1210
1853
|
this.enqueue(otlp);
|
|
1211
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1854
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1855
|
+
const eventId = this.appGitEventIds.get(span);
|
|
1856
|
+
if (eventId && this.appGitActiveSpans.has(eventId)) {
|
|
1857
|
+
const remaining = ((_c = this.appGitActiveSpans.get(eventId)) != null ? _c : 1) - 1;
|
|
1858
|
+
if (remaining > 0) this.appGitActiveSpans.set(eventId, remaining);
|
|
1859
|
+
else {
|
|
1860
|
+
this.appGitActiveSpans.delete(eventId);
|
|
1861
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
|
|
1862
|
+
else if (this.ownsAppGitContext) this.appGitContext.finishOperation(eventId);
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1212
1865
|
}
|
|
1213
1866
|
createSpan(args2) {
|
|
1214
1867
|
var _a;
|
|
1215
1868
|
const ids = createSpanIds(args2.parent);
|
|
1216
1869
|
const attrs = [
|
|
1217
1870
|
attrString("ai.telemetry.metadata.raindrop.eventId", args2.eventId),
|
|
1218
|
-
...identityAttrs(args2)
|
|
1871
|
+
...identityAttrs(args2),
|
|
1872
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
1219
1873
|
];
|
|
1220
1874
|
if ((_a = args2.attributes) == null ? void 0 : _a.length) attrs.push(...args2.attributes);
|
|
1875
|
+
const tracksAppGit = !this.appGitActiveSpans.has(args2.eventId);
|
|
1221
1876
|
const otlp = buildOtlpSpan({
|
|
1222
1877
|
ids,
|
|
1223
1878
|
name: args2.name,
|
|
1224
1879
|
startTimeUnixNano: args2.startTimeUnixNano,
|
|
1225
1880
|
endTimeUnixNano: args2.endTimeUnixNano,
|
|
1226
|
-
attributes:
|
|
1881
|
+
attributes: withAppGitAttributes(
|
|
1882
|
+
attrs,
|
|
1883
|
+
this.appGitContext.forOperation(
|
|
1884
|
+
args2.eventId,
|
|
1885
|
+
appGitPropertiesFromAttributes(attrs),
|
|
1886
|
+
this.appGitOwner
|
|
1887
|
+
)
|
|
1888
|
+
),
|
|
1227
1889
|
status: args2.status
|
|
1228
1890
|
});
|
|
1891
|
+
rememberReplayTraceDestination(otlp);
|
|
1892
|
+
this.appGitCaptured.add(otlp);
|
|
1893
|
+
if (tracksAppGit) {
|
|
1894
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(args2.eventId, this.appGitOwner);
|
|
1895
|
+
else if (this.ownsAppGitContext) this.appGitContext.finishOperation(args2.eventId);
|
|
1896
|
+
}
|
|
1229
1897
|
this.enqueue(otlp);
|
|
1230
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1898
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1231
1899
|
}
|
|
1232
1900
|
enqueue(span) {
|
|
1901
|
+
var _a;
|
|
1233
1902
|
if (!this.enabled) return;
|
|
1903
|
+
const attributes = (_a = span.attributes) != null ? _a : [];
|
|
1904
|
+
const enriched = this.appGitCaptured.has(span) ? attributes : withAppGitAttributes(attributes, this.appGitContext.snapshot(appGitPropertiesFromAttributes(attributes)));
|
|
1905
|
+
if (enriched !== attributes) {
|
|
1906
|
+
const original = span;
|
|
1907
|
+
span = { ...span, attributes: enriched.filter((attr) => attr !== void 0) };
|
|
1908
|
+
copyReplayTraceDestination(original, span);
|
|
1909
|
+
}
|
|
1234
1910
|
if (this.debugSpans) {
|
|
1235
1911
|
const short = (s) => s ? s.slice(-8) : "none";
|
|
1236
1912
|
console.log(
|
|
@@ -1241,6 +1917,13 @@ var TraceShipper = class {
|
|
|
1241
1917
|
}
|
|
1242
1918
|
const redacted = this.redactSpan(span);
|
|
1243
1919
|
if (redacted === null) return;
|
|
1920
|
+
const destination = replayTraceDestinationFor(redacted);
|
|
1921
|
+
recordReplayExportedSpan(
|
|
1922
|
+
destination,
|
|
1923
|
+
base64ToHex(redacted.spanId),
|
|
1924
|
+
base64ToHex(redacted.traceId)
|
|
1925
|
+
);
|
|
1926
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") return;
|
|
1244
1927
|
if (this.queue.length >= this.maxQueueSize) {
|
|
1245
1928
|
this.queue.shift();
|
|
1246
1929
|
}
|
|
@@ -1259,6 +1942,7 @@ var TraceShipper = class {
|
|
|
1259
1942
|
}
|
|
1260
1943
|
}
|
|
1261
1944
|
async flush() {
|
|
1945
|
+
var _a;
|
|
1262
1946
|
if (!this.enabled) {
|
|
1263
1947
|
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
1264
1948
|
})));
|
|
@@ -1270,40 +1954,55 @@ var TraceShipper = class {
|
|
|
1270
1954
|
}
|
|
1271
1955
|
while (this.queue.length > 0) {
|
|
1272
1956
|
const batch = this.queue.splice(0, this.maxBatchSize);
|
|
1273
|
-
|
|
1274
|
-
const
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
`${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
|
|
1280
|
-
)
|
|
1281
|
-
);
|
|
1282
|
-
continue;
|
|
1957
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1958
|
+
for (const span of batch) {
|
|
1959
|
+
const destination = replayTraceDestinationFor(span);
|
|
1960
|
+
const spans = groups.get(destination);
|
|
1961
|
+
if (spans) spans.push(span);
|
|
1962
|
+
else groups.set(destination, [span]);
|
|
1283
1963
|
}
|
|
1284
|
-
const
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
endpoint: url
|
|
1290
|
-
});
|
|
1291
|
-
}
|
|
1292
|
-
const p = postJson(url, body, this.requestHeaders(), opts);
|
|
1293
|
-
this.inFlight.add(p);
|
|
1294
|
-
try {
|
|
1295
|
-
try {
|
|
1296
|
-
await p;
|
|
1297
|
-
if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
|
|
1298
|
-
} catch (err) {
|
|
1299
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1964
|
+
for (const [destination, spans] of groups) {
|
|
1965
|
+
if (!destination && !this.writeKey) continue;
|
|
1966
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") continue;
|
|
1967
|
+
const opts = this.requestOpts();
|
|
1968
|
+
if (!opts) {
|
|
1300
1969
|
rateLimitedLog(
|
|
1301
|
-
`${this.prefix}.
|
|
1302
|
-
() => console.warn(
|
|
1970
|
+
`${this.prefix}.shutdown_deadline`,
|
|
1971
|
+
() => console.warn(
|
|
1972
|
+
`${this.prefix} shutdown flush deadline exceeded; dropping ${spans.length} spans`
|
|
1973
|
+
)
|
|
1303
1974
|
);
|
|
1975
|
+
continue;
|
|
1976
|
+
}
|
|
1977
|
+
const body = buildExportTraceServiceRequest(spans, this.serviceName, this.serviceVersion);
|
|
1978
|
+
const url = destination ? replayTraceUrl(destination.url) : `${this.baseUrl}traces`;
|
|
1979
|
+
const headers = destination ? {
|
|
1980
|
+
Authorization: `Bearer ${destination.apiKey}`,
|
|
1981
|
+
"X-Raindrop-Replay-Id": destination.replayId,
|
|
1982
|
+
"X-Raindrop-Project-Id": (_a = destination.projectId) != null ? _a : "default"
|
|
1983
|
+
} : this.requestHeaders();
|
|
1984
|
+
if (this.debug) {
|
|
1985
|
+
console.log(`${this.prefix} sending traces batch`, {
|
|
1986
|
+
spans: spans.length,
|
|
1987
|
+
endpoint: url
|
|
1988
|
+
});
|
|
1989
|
+
}
|
|
1990
|
+
const p = postJson(url, body, headers, opts);
|
|
1991
|
+
this.inFlight.add(p);
|
|
1992
|
+
try {
|
|
1993
|
+
try {
|
|
1994
|
+
await p;
|
|
1995
|
+
if (this.debug) console.log(`${this.prefix} sent ${spans.length} spans`);
|
|
1996
|
+
} catch (err) {
|
|
1997
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1998
|
+
rateLimitedLog(
|
|
1999
|
+
`${this.prefix}.send_spans_failed`,
|
|
2000
|
+
() => console.warn(`${this.prefix} failed to send ${spans.length} spans: ${msg}`)
|
|
2001
|
+
);
|
|
2002
|
+
}
|
|
2003
|
+
} finally {
|
|
2004
|
+
this.inFlight.delete(p);
|
|
1304
2005
|
}
|
|
1305
|
-
} finally {
|
|
1306
|
-
this.inFlight.delete(p);
|
|
1307
2006
|
}
|
|
1308
2007
|
}
|
|
1309
2008
|
}
|
|
@@ -1346,17 +2045,317 @@ var TraceShipper = class {
|
|
|
1346
2045
|
if (!settled) {
|
|
1347
2046
|
rateLimitedLog(
|
|
1348
2047
|
`${this.prefix}.shutdown_deadline`,
|
|
1349
|
-
() => console.warn(
|
|
2048
|
+
() => console.warn(
|
|
2049
|
+
`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`
|
|
2050
|
+
)
|
|
1350
2051
|
);
|
|
1351
2052
|
}
|
|
1352
2053
|
} finally {
|
|
1353
2054
|
this.shutdownDeadlineAt = void 0;
|
|
2055
|
+
if (this.ownsAppGitContext) this.appGitContext.dispose();
|
|
1354
2056
|
}
|
|
1355
2057
|
}
|
|
1356
2058
|
};
|
|
2059
|
+
var PROMPT_TOOLS_ATTRIBUTE = "ai.prompt.tools";
|
|
2060
|
+
function isRecord(value) {
|
|
2061
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2062
|
+
}
|
|
2063
|
+
var JSON_SCHEMA_KEYS = [
|
|
2064
|
+
"type",
|
|
2065
|
+
"properties",
|
|
2066
|
+
"$schema",
|
|
2067
|
+
"$ref",
|
|
2068
|
+
"anyOf",
|
|
2069
|
+
"oneOf",
|
|
2070
|
+
"allOf",
|
|
2071
|
+
"enum",
|
|
2072
|
+
"const",
|
|
2073
|
+
"items",
|
|
2074
|
+
"additionalProperties",
|
|
2075
|
+
"required"
|
|
2076
|
+
];
|
|
2077
|
+
function isJsonSchema(value) {
|
|
2078
|
+
if (!isRecord(value)) return false;
|
|
2079
|
+
if (typeof value["~standard"] === "object") return false;
|
|
2080
|
+
if (isRecord(value._def) || isRecord(value._zod)) return false;
|
|
2081
|
+
if (Object.keys(value).length === 0) return true;
|
|
2082
|
+
return JSON_SCHEMA_KEYS.some((key) => key in value);
|
|
2083
|
+
}
|
|
2084
|
+
function toJsonSchema(value, options) {
|
|
2085
|
+
if (value === void 0 || value === null) return void 0;
|
|
2086
|
+
if (isJsonSchema(value)) return value;
|
|
2087
|
+
if (isRecord(value) && isJsonSchema(value.jsonSchema)) return value.jsonSchema;
|
|
2088
|
+
if (isRecord(value) && isJsonSchema(value.json)) return value.json;
|
|
2089
|
+
if (options == null ? void 0 : options.schema) {
|
|
2090
|
+
try {
|
|
2091
|
+
return options.schema(value);
|
|
2092
|
+
} catch (e) {
|
|
2093
|
+
return void 0;
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
return void 0;
|
|
2097
|
+
}
|
|
2098
|
+
function pickString(value) {
|
|
2099
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2100
|
+
}
|
|
2101
|
+
function functionTool(name, description, schema, options) {
|
|
2102
|
+
const tool = { type: "function", name };
|
|
2103
|
+
const desc = pickString(description);
|
|
2104
|
+
if (desc !== void 0) tool.description = desc;
|
|
2105
|
+
const inputSchema = toJsonSchema(schema, options);
|
|
2106
|
+
if (inputSchema !== void 0) tool.inputSchema = inputSchema;
|
|
2107
|
+
return tool;
|
|
2108
|
+
}
|
|
2109
|
+
function normalizeToolDeclaration(tool, options, fallbackName) {
|
|
2110
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
2111
|
+
if (!isRecord(tool)) return void 0;
|
|
2112
|
+
if (tool.type === "provider-defined" || tool.type === "provider") {
|
|
2113
|
+
const name2 = (_b = (_a = pickString(tool.name)) != null ? _a : pickString(tool.id)) != null ? _b : fallbackName;
|
|
2114
|
+
if (name2 === void 0) return void 0;
|
|
2115
|
+
const declaration = { type: "provider-defined", name: name2 };
|
|
2116
|
+
const id = pickString(tool.id);
|
|
2117
|
+
if (id !== void 0) declaration.id = id;
|
|
2118
|
+
if (isRecord(tool.args)) declaration.args = tool.args;
|
|
2119
|
+
return declaration;
|
|
2120
|
+
}
|
|
2121
|
+
if (isRecord(tool.toolSpec)) {
|
|
2122
|
+
const spec = tool.toolSpec;
|
|
2123
|
+
const name2 = (_c = pickString(spec.name)) != null ? _c : fallbackName;
|
|
2124
|
+
if (name2 === void 0) return void 0;
|
|
2125
|
+
return functionTool(name2, spec.description, spec.inputSchema, options);
|
|
2126
|
+
}
|
|
2127
|
+
if (isRecord(tool.function)) {
|
|
2128
|
+
const fn = tool.function;
|
|
2129
|
+
const name2 = (_d = pickString(fn.name)) != null ? _d : fallbackName;
|
|
2130
|
+
if (name2 === void 0) return void 0;
|
|
2131
|
+
return functionTool(name2, fn.description, (_e = fn.parameters) != null ? _e : fn.input_schema, options);
|
|
2132
|
+
}
|
|
2133
|
+
const name = (_g = (_f = pickString(tool.name)) != null ? _f : pickString(tool.id)) != null ? _g : fallbackName;
|
|
2134
|
+
if (name === void 0) return void 0;
|
|
2135
|
+
const type = pickString(tool.type);
|
|
2136
|
+
if (type !== void 0 && type !== "function" && type !== "dynamic" && type !== "custom") {
|
|
2137
|
+
if (!("input_schema" in tool) && !("inputSchema" in tool) && !("parameters" in tool)) {
|
|
2138
|
+
return { type: "provider-defined", id: type, name };
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
return functionTool(
|
|
2142
|
+
name,
|
|
2143
|
+
tool.description,
|
|
2144
|
+
(_j = (_i = (_h = tool.inputSchema) != null ? _h : tool.input_schema) != null ? _i : tool.parameters) != null ? _j : tool.schema,
|
|
2145
|
+
options
|
|
2146
|
+
);
|
|
2147
|
+
}
|
|
2148
|
+
var NOT_A_GEMINI_GROUP_KEYS = ["name", "id", "type", "function", "toolSpec", "cachePoint"];
|
|
2149
|
+
function isGeminiToolGroup(tool) {
|
|
2150
|
+
if (Array.isArray(tool.functionDeclarations)) return true;
|
|
2151
|
+
const keys = Object.keys(tool);
|
|
2152
|
+
if (keys.length === 0 || NOT_A_GEMINI_GROUP_KEYS.some((key) => key in tool)) return false;
|
|
2153
|
+
return keys.every((key) => isRecord(tool[key]));
|
|
2154
|
+
}
|
|
2155
|
+
function expandGeminiTool(tool, options) {
|
|
2156
|
+
const declarations = [];
|
|
2157
|
+
for (const [key, value] of Object.entries(tool)) {
|
|
2158
|
+
if (key === "functionDeclarations" && Array.isArray(value)) {
|
|
2159
|
+
for (const declaration of value) {
|
|
2160
|
+
const normalized = normalizeToolDeclaration(declaration, options);
|
|
2161
|
+
if (normalized) declarations.push(normalized);
|
|
2162
|
+
}
|
|
2163
|
+
} else if (isRecord(value)) {
|
|
2164
|
+
declarations.push({ type: "provider-defined", id: key, name: key, args: value });
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
return declarations;
|
|
2168
|
+
}
|
|
2169
|
+
function normalizeToolDeclarations(tools, options) {
|
|
2170
|
+
if (tools === void 0 || tools === null) return void 0;
|
|
2171
|
+
if (Array.isArray(tools)) {
|
|
2172
|
+
return tools.flatMap((tool) => {
|
|
2173
|
+
if (isRecord(tool) && isGeminiToolGroup(tool)) {
|
|
2174
|
+
return expandGeminiTool(tool, options);
|
|
2175
|
+
}
|
|
2176
|
+
const declaration = normalizeToolDeclaration(tool, options);
|
|
2177
|
+
return declaration ? [declaration] : [];
|
|
2178
|
+
});
|
|
2179
|
+
}
|
|
2180
|
+
if (!isRecord(tools)) return void 0;
|
|
2181
|
+
return Object.entries(tools).flatMap(([key, tool]) => {
|
|
2182
|
+
const declaration = normalizeToolDeclaration(tool, options, key);
|
|
2183
|
+
return declaration ? [declaration] : [];
|
|
2184
|
+
});
|
|
2185
|
+
}
|
|
2186
|
+
function resolvePromptTools(args2) {
|
|
2187
|
+
var _a;
|
|
2188
|
+
if (args2.override !== void 0) {
|
|
2189
|
+
return (_a = normalizeToolDeclarations(args2.override, args2.options)) != null ? _a : [];
|
|
2190
|
+
}
|
|
2191
|
+
return normalizeToolDeclarations(args2.inferred, args2.options);
|
|
2192
|
+
}
|
|
2193
|
+
function promptToolsAttribute(tools) {
|
|
2194
|
+
const values = promptToolsAttributeValue(tools);
|
|
2195
|
+
if (values === void 0) return void 0;
|
|
2196
|
+
return {
|
|
2197
|
+
key: PROMPT_TOOLS_ATTRIBUTE,
|
|
2198
|
+
value: { arrayValue: { values: values.map((stringValue) => ({ stringValue })) } }
|
|
2199
|
+
};
|
|
2200
|
+
}
|
|
2201
|
+
function promptToolsAttributeValue(tools) {
|
|
2202
|
+
if (tools === void 0) return void 0;
|
|
2203
|
+
return tools.map((tool) => {
|
|
2204
|
+
try {
|
|
2205
|
+
return JSON.stringify(tool);
|
|
2206
|
+
} catch (e) {
|
|
2207
|
+
return JSON.stringify({ type: tool.type, name: tool.name });
|
|
2208
|
+
}
|
|
2209
|
+
});
|
|
2210
|
+
}
|
|
1357
2211
|
|
|
1358
2212
|
// ../core/dist/index.node.js
|
|
1359
2213
|
import { AsyncLocalStorage } from "async_hooks";
|
|
2214
|
+
import { execFile } from "child_process";
|
|
2215
|
+
import { resolve } from "path";
|
|
2216
|
+
var resolveLocal = (sourceDirectory, detectBranch, completed) => {
|
|
2217
|
+
const cwd = sourceDirectory ? resolve(sourceDirectory) : process.cwd();
|
|
2218
|
+
let cancelled = false;
|
|
2219
|
+
let active;
|
|
2220
|
+
let deadlineTimer;
|
|
2221
|
+
const deadline = Date.now() + 1e3;
|
|
2222
|
+
const run = (args2, done) => {
|
|
2223
|
+
if (cancelled) return;
|
|
2224
|
+
const remaining = deadline - Date.now();
|
|
2225
|
+
if (remaining <= 0) {
|
|
2226
|
+
done(void 0);
|
|
2227
|
+
return;
|
|
2228
|
+
}
|
|
2229
|
+
try {
|
|
2230
|
+
active = execFile(
|
|
2231
|
+
"git",
|
|
2232
|
+
args2,
|
|
2233
|
+
{
|
|
2234
|
+
cwd,
|
|
2235
|
+
encoding: "utf8",
|
|
2236
|
+
maxBuffer: 4096,
|
|
2237
|
+
windowsHide: true,
|
|
2238
|
+
env: {
|
|
2239
|
+
...process.env,
|
|
2240
|
+
// The selected application cwd, not the invoking shell's Git plumbing, owns identity.
|
|
2241
|
+
GIT_DIR: void 0,
|
|
2242
|
+
GIT_WORK_TREE: void 0,
|
|
2243
|
+
GIT_COMMON_DIR: void 0,
|
|
2244
|
+
GIT_NAMESPACE: void 0,
|
|
2245
|
+
GIT_INDEX_FILE: void 0,
|
|
2246
|
+
GIT_OBJECT_DIRECTORY: void 0,
|
|
2247
|
+
GIT_ALTERNATE_OBJECT_DIRECTORIES: void 0,
|
|
2248
|
+
GIT_CONFIG_PARAMETERS: void 0,
|
|
2249
|
+
GIT_CONFIG_COUNT: "0",
|
|
2250
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
2251
|
+
GIT_OPTIONAL_LOCKS: "0"
|
|
2252
|
+
}
|
|
2253
|
+
},
|
|
2254
|
+
(error, stdout) => {
|
|
2255
|
+
clearTimeout(deadlineTimer);
|
|
2256
|
+
deadlineTimer = void 0;
|
|
2257
|
+
active = void 0;
|
|
2258
|
+
if (!cancelled) {
|
|
2259
|
+
try {
|
|
2260
|
+
done(error ? void 0 : stdout.trim());
|
|
2261
|
+
} catch (e) {
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
);
|
|
2266
|
+
active.unref();
|
|
2267
|
+
if (active.stdout && "unref" in active.stdout && typeof active.stdout.unref === "function")
|
|
2268
|
+
active.stdout.unref();
|
|
2269
|
+
if (active.stderr && "unref" in active.stderr && typeof active.stderr.unref === "function")
|
|
2270
|
+
active.stderr.unref();
|
|
2271
|
+
deadlineTimer = setTimeout(() => {
|
|
2272
|
+
try {
|
|
2273
|
+
active == null ? void 0 : active.kill("SIGKILL");
|
|
2274
|
+
} catch (e) {
|
|
2275
|
+
}
|
|
2276
|
+
}, remaining);
|
|
2277
|
+
deadlineTimer.unref();
|
|
2278
|
+
} catch (e) {
|
|
2279
|
+
try {
|
|
2280
|
+
done(void 0);
|
|
2281
|
+
} catch (e2) {
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
};
|
|
2285
|
+
const scheduled = setTimeout(() => {
|
|
2286
|
+
try {
|
|
2287
|
+
run(["rev-parse", "HEAD"], (rawSha) => {
|
|
2288
|
+
const commitSha = validAppCommitSha(rawSha);
|
|
2289
|
+
if (!commitSha) {
|
|
2290
|
+
completed({});
|
|
2291
|
+
return;
|
|
2292
|
+
}
|
|
2293
|
+
run(["-c", "core.fsmonitor=false", "status", "--porcelain"], (status) => {
|
|
2294
|
+
const finish = (branch) => {
|
|
2295
|
+
run(["rev-parse", "HEAD"], (finalSha) => {
|
|
2296
|
+
const coherent = validAppCommitSha(finalSha) === commitSha;
|
|
2297
|
+
completed({
|
|
2298
|
+
commitSha,
|
|
2299
|
+
...coherent && status !== void 0 ? { commitDirty: status !== "" } : {},
|
|
2300
|
+
...coherent && branch && branch !== "HEAD" ? { branch } : {}
|
|
2301
|
+
});
|
|
2302
|
+
});
|
|
2303
|
+
};
|
|
2304
|
+
if (detectBranch) run(["symbolic-ref", "--quiet", "--short", "HEAD"], finish);
|
|
2305
|
+
else finish();
|
|
2306
|
+
});
|
|
2307
|
+
});
|
|
2308
|
+
} catch (e) {
|
|
2309
|
+
completed({});
|
|
2310
|
+
}
|
|
2311
|
+
}, 0);
|
|
2312
|
+
scheduled.unref();
|
|
2313
|
+
return () => {
|
|
2314
|
+
cancelled = true;
|
|
2315
|
+
clearTimeout(scheduled);
|
|
2316
|
+
clearTimeout(deadlineTimer);
|
|
2317
|
+
try {
|
|
2318
|
+
active == null ? void 0 : active.kill("SIGKILL");
|
|
2319
|
+
} catch (e) {
|
|
2320
|
+
}
|
|
2321
|
+
};
|
|
2322
|
+
};
|
|
2323
|
+
function createAppGitContext2(options, runtime = {}) {
|
|
2324
|
+
return new AppGitContext(options, { ...runtime, resolveLocal });
|
|
2325
|
+
}
|
|
2326
|
+
function hasDestination(options) {
|
|
2327
|
+
var _a;
|
|
2328
|
+
if (options.enabled === false) return false;
|
|
2329
|
+
return Boolean(((_a = options.writeKey) == null ? void 0 : _a.trim()) || resolveLocalDebuggerBaseUrl(options.localDebuggerUrl));
|
|
2330
|
+
}
|
|
2331
|
+
var EventShipper2 = class extends EventShipper {
|
|
2332
|
+
constructor(options) {
|
|
2333
|
+
var _a;
|
|
2334
|
+
const ownsAppGitContext = options.appGitContext === void 0;
|
|
2335
|
+
const appGitContext = (_a = options.appGitContext) != null ? _a : createAppGitContext2(options.appGit, { allowDiscovery: hasDestination(options) });
|
|
2336
|
+
try {
|
|
2337
|
+
super({ ...options, appGitContext });
|
|
2338
|
+
} catch (error) {
|
|
2339
|
+
if (ownsAppGitContext) appGitContext.dispose();
|
|
2340
|
+
throw error;
|
|
2341
|
+
}
|
|
2342
|
+
if (ownsAppGitContext) this.ownAppGitContextForShutdown();
|
|
2343
|
+
}
|
|
2344
|
+
};
|
|
2345
|
+
var TraceShipper2 = class extends TraceShipper {
|
|
2346
|
+
constructor(options) {
|
|
2347
|
+
var _a;
|
|
2348
|
+
const ownsAppGitContext = options.appGitContext === void 0;
|
|
2349
|
+
const appGitContext = (_a = options.appGitContext) != null ? _a : createAppGitContext2(options.appGit, { allowDiscovery: hasDestination(options) });
|
|
2350
|
+
try {
|
|
2351
|
+
super({ ...options, appGitContext });
|
|
2352
|
+
} catch (error) {
|
|
2353
|
+
if (ownsAppGitContext) appGitContext.dispose();
|
|
2354
|
+
throw error;
|
|
2355
|
+
}
|
|
2356
|
+
this.ownsAppGitContext = ownsAppGitContext;
|
|
2357
|
+
}
|
|
2358
|
+
};
|
|
1360
2359
|
globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = AsyncLocalStorage;
|
|
1361
2360
|
var SUPPRESS_TRACING_KEY = /* @__PURE__ */ Symbol.for(
|
|
1362
2361
|
"OpenTelemetry SDK Context Key SUPPRESS_TRACING"
|
|
@@ -1387,7 +2386,7 @@ installTracingSuppressionHook();
|
|
|
1387
2386
|
// package.json
|
|
1388
2387
|
var package_default = {
|
|
1389
2388
|
name: "@raindrop-ai/claude-code",
|
|
1390
|
-
version: "0.0.
|
|
2389
|
+
version: "0.0.21",
|
|
1391
2390
|
description: "Raindrop observability for Claude Code CLI \u2014 automatic session, tool call, and prompt tracing via hooks",
|
|
1392
2391
|
license: "MIT",
|
|
1393
2392
|
homepage: "https://www.raindrop.ai/docs/integrations/claude-code/",
|
|
@@ -1461,7 +2460,7 @@ var PACKAGE_NAME = "@raindrop-ai/claude-code";
|
|
|
1461
2460
|
var PACKAGE_VERSION = package_default.version;
|
|
1462
2461
|
|
|
1463
2462
|
// src/shipper.ts
|
|
1464
|
-
var
|
|
2463
|
+
var EventShipper3 = class extends EventShipper2 {
|
|
1465
2464
|
constructor(opts) {
|
|
1466
2465
|
var _a, _b, _c, _d;
|
|
1467
2466
|
super({
|
|
@@ -1473,7 +2472,7 @@ var EventShipper2 = class extends EventShipper {
|
|
|
1473
2472
|
});
|
|
1474
2473
|
}
|
|
1475
2474
|
};
|
|
1476
|
-
var
|
|
2475
|
+
var TraceShipper3 = class extends TraceShipper2 {
|
|
1477
2476
|
constructor(opts) {
|
|
1478
2477
|
var _a, _b, _c;
|
|
1479
2478
|
super({
|
|
@@ -2296,7 +3295,7 @@ function isoToNanoString(iso, fallback) {
|
|
|
2296
3295
|
return fallback;
|
|
2297
3296
|
}
|
|
2298
3297
|
}
|
|
2299
|
-
function enrichFromTranscript(payload, eventId, traceShipper) {
|
|
3298
|
+
function enrichFromTranscript(payload, eventId, traceShipper, promptTools) {
|
|
2300
3299
|
var _a, _b, _c, _d;
|
|
2301
3300
|
if (!payload.transcript_path) {
|
|
2302
3301
|
return { summary: void 0, props: {} };
|
|
@@ -2335,7 +3334,8 @@ function enrichFromTranscript(payload, eventId, traceShipper) {
|
|
|
2335
3334
|
attrString("ai.response.text", truncate(outputText)),
|
|
2336
3335
|
...toolCallNames ? [attrString("ai.toolCall.names", toolCallNames)] : [],
|
|
2337
3336
|
...phase.hasThinking ? [attrString("ai.has_thinking", "true")] : [],
|
|
2338
|
-
attrInt("ai.llm_call.index", emittedPhaseIndex)
|
|
3337
|
+
attrInt("ai.llm_call.index", emittedPhaseIndex),
|
|
3338
|
+
promptTools
|
|
2339
3339
|
]
|
|
2340
3340
|
});
|
|
2341
3341
|
emittedPhaseIndex++;
|
|
@@ -2357,7 +3357,8 @@ function enrichFromTranscript(payload, eventId, traceShipper) {
|
|
|
2357
3357
|
attrString("gen_ai.system", "anthropic"),
|
|
2358
3358
|
attrInt("gen_ai.usage.prompt_tokens", spanInputTokens),
|
|
2359
3359
|
attrInt("gen_ai.usage.completion_tokens", spanOutputTokens),
|
|
2360
|
-
...summary.lastTurnCacheReadTokens != null && summary.lastTurnCacheReadTokens > 0 ? [attrInt("gen_ai.usage.cache_read_tokens", summary.lastTurnCacheReadTokens)] : []
|
|
3360
|
+
...summary.lastTurnCacheReadTokens != null && summary.lastTurnCacheReadTokens > 0 ? [attrInt("gen_ai.usage.cache_read_tokens", summary.lastTurnCacheReadTokens)] : [],
|
|
3361
|
+
promptTools
|
|
2361
3362
|
]
|
|
2362
3363
|
});
|
|
2363
3364
|
}
|
|
@@ -2383,7 +3384,12 @@ function buildStopOutput(summary, lastAssistantMessage) {
|
|
|
2383
3384
|
return finalMessage;
|
|
2384
3385
|
}
|
|
2385
3386
|
async function handleStopOrFailure(payload, eventId, convoId, config, properties, eventShipper, traceShipper, extraProperties) {
|
|
2386
|
-
const { summary, props: transcriptProps } = enrichFromTranscript(
|
|
3387
|
+
const { summary, props: transcriptProps } = enrichFromTranscript(
|
|
3388
|
+
payload,
|
|
3389
|
+
eventId,
|
|
3390
|
+
traceShipper,
|
|
3391
|
+
promptToolsAttribute(resolvePromptTools({ override: config.tools }))
|
|
3392
|
+
);
|
|
2387
3393
|
const instructions = gatherInstructions(payload.session_id);
|
|
2388
3394
|
const appendSysPrompt = readAppendSystemPrompt(payload.session_id);
|
|
2389
3395
|
const output = buildStopOutput(summary, payload.last_assistant_message);
|
|
@@ -2448,6 +3454,15 @@ function loadConfig() {
|
|
|
2448
3454
|
} catch (e) {
|
|
2449
3455
|
}
|
|
2450
3456
|
}
|
|
3457
|
+
let tools = Array.isArray(file.tools) ? file.tools : void 0;
|
|
3458
|
+
const envTools = process.env["RAINDROP_TOOLS"];
|
|
3459
|
+
if (envTools) {
|
|
3460
|
+
try {
|
|
3461
|
+
const parsed = JSON.parse(envTools);
|
|
3462
|
+
if (Array.isArray(parsed)) tools = parsed;
|
|
3463
|
+
} catch (e) {
|
|
3464
|
+
}
|
|
3465
|
+
}
|
|
2451
3466
|
let selfDiagnostics = file.self_diagnostics;
|
|
2452
3467
|
const envDiag = process.env["RAINDROP_SELF_DIAGNOSTICS"];
|
|
2453
3468
|
if (envDiag) {
|
|
@@ -2475,7 +3490,21 @@ function loadConfig() {
|
|
|
2475
3490
|
})(),
|
|
2476
3491
|
eventName: (_l = (_k = process.env["RAINDROP_EVENT_NAME"]) != null ? _k : file.event_name) != null ? _l : "claude_code_session",
|
|
2477
3492
|
customProperties,
|
|
2478
|
-
selfDiagnostics
|
|
3493
|
+
selfDiagnostics,
|
|
3494
|
+
appGit: mapAppGit(file.app_git),
|
|
3495
|
+
tools
|
|
3496
|
+
};
|
|
3497
|
+
}
|
|
3498
|
+
function mapAppGit(value) {
|
|
3499
|
+
if (value === false) return false;
|
|
3500
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
3501
|
+
return {
|
|
3502
|
+
commitSha: "commit_sha" in value && (typeof value.commit_sha === "string" || value.commit_sha === null) ? value.commit_sha : void 0,
|
|
3503
|
+
commitDirty: "commit_dirty" in value && (typeof value.commit_dirty === "boolean" || value.commit_dirty === null) ? value.commit_dirty : void 0,
|
|
3504
|
+
branch: "branch" in value && (typeof value.branch === "string" || value.branch === null) ? value.branch : void 0,
|
|
3505
|
+
detectBranch: "detect_branch" in value && typeof value.detect_branch === "boolean" ? value.detect_branch : void 0,
|
|
3506
|
+
sourceDirectory: "source_directory" in value && typeof value.source_directory === "string" ? value.source_directory : void 0,
|
|
3507
|
+
autoDetect: "auto_detect" in value && typeof value.auto_detect === "boolean" ? value.auto_detect : void 0
|
|
2479
3508
|
};
|
|
2480
3509
|
}
|
|
2481
3510
|
function getConfigPath() {
|
|
@@ -2597,16 +3626,16 @@ function hookFlushDeadlineMs() {
|
|
|
2597
3626
|
return DEFAULT_HOOK_FLUSH_DEADLINE_MS;
|
|
2598
3627
|
}
|
|
2599
3628
|
function withDeadline(promise, ms) {
|
|
2600
|
-
return new Promise((
|
|
3629
|
+
return new Promise((resolve3, reject) => {
|
|
2601
3630
|
const timer = setTimeout(() => {
|
|
2602
3631
|
promise.catch(() => {
|
|
2603
3632
|
});
|
|
2604
|
-
|
|
3633
|
+
resolve3("deadline");
|
|
2605
3634
|
}, ms);
|
|
2606
3635
|
promise.then(
|
|
2607
3636
|
(value) => {
|
|
2608
3637
|
clearTimeout(timer);
|
|
2609
|
-
|
|
3638
|
+
resolve3(value);
|
|
2610
3639
|
},
|
|
2611
3640
|
(err) => {
|
|
2612
3641
|
clearTimeout(timer);
|
|
@@ -2628,9 +3657,9 @@ function getOtlpTraceId(sessionId) {
|
|
|
2628
3657
|
}
|
|
2629
3658
|
}
|
|
2630
3659
|
function readStdin() {
|
|
2631
|
-
return new Promise((
|
|
3660
|
+
return new Promise((resolve3) => {
|
|
2632
3661
|
if (process.stdin.isTTY) {
|
|
2633
|
-
|
|
3662
|
+
resolve3("");
|
|
2634
3663
|
return;
|
|
2635
3664
|
}
|
|
2636
3665
|
const chunks = [];
|
|
@@ -2641,7 +3670,7 @@ function readStdin() {
|
|
|
2641
3670
|
clearTimeout(timeout);
|
|
2642
3671
|
process.stdin.removeAllListeners();
|
|
2643
3672
|
process.stdin.destroy();
|
|
2644
|
-
|
|
3673
|
+
resolve3(value);
|
|
2645
3674
|
}
|
|
2646
3675
|
const timeout = setTimeout(() => {
|
|
2647
3676
|
done(chunks.length > 0 ? Buffer.concat(chunks).toString("utf-8") : "");
|
|
@@ -2652,6 +3681,7 @@ function readStdin() {
|
|
|
2652
3681
|
});
|
|
2653
3682
|
}
|
|
2654
3683
|
async function handleHook() {
|
|
3684
|
+
var _a;
|
|
2655
3685
|
const startedAtMs = Date.now();
|
|
2656
3686
|
const raw = await readStdin();
|
|
2657
3687
|
if (!raw.trim()) {
|
|
@@ -2684,9 +3714,14 @@ async function handleHook() {
|
|
|
2684
3714
|
convoId: config.convoId,
|
|
2685
3715
|
debug: config.debug,
|
|
2686
3716
|
eventName: config.eventName,
|
|
2687
|
-
customProperties: config.customProperties
|
|
3717
|
+
customProperties: config.customProperties,
|
|
3718
|
+
tools: config.tools
|
|
2688
3719
|
};
|
|
2689
|
-
const
|
|
3720
|
+
const appGitContext = createAppGitContext2(
|
|
3721
|
+
((_a = config.writeKey) == null ? void 0 : _a.trim()) || hasDebugger ? config.appGit : false,
|
|
3722
|
+
{ allowLocalGit: false }
|
|
3723
|
+
);
|
|
3724
|
+
const eventShipper = new EventShipper3({
|
|
2690
3725
|
writeKey: config.writeKey,
|
|
2691
3726
|
endpoint: config.endpoint,
|
|
2692
3727
|
debug: config.debug,
|
|
@@ -2694,21 +3729,23 @@ async function handleHook() {
|
|
|
2694
3729
|
// Only ship to the cloud when we have an API key. When only the local
|
|
2695
3730
|
// debugger is present the shipper still needs to be instantiated so the
|
|
2696
3731
|
// event mapper can call patch/finish, but cloud POSTs are skipped.
|
|
2697
|
-
enabled: hasCloudKey
|
|
3732
|
+
enabled: hasCloudKey,
|
|
3733
|
+
appGitContext
|
|
2698
3734
|
});
|
|
2699
|
-
const traceShipper = new
|
|
3735
|
+
const traceShipper = new TraceShipper3({
|
|
2700
3736
|
writeKey: config.writeKey,
|
|
2701
3737
|
endpoint: config.endpoint,
|
|
2702
3738
|
debug: config.debug,
|
|
2703
3739
|
projectId: config.projectId,
|
|
2704
|
-
enabled: hasCloudKey
|
|
3740
|
+
enabled: hasCloudKey,
|
|
3741
|
+
appGitContext
|
|
2705
3742
|
});
|
|
2706
3743
|
if (debugger_.url) {
|
|
2707
3744
|
const debuggerUrl = debugger_.url;
|
|
2708
3745
|
const origPatch = eventShipper.patch.bind(eventShipper);
|
|
2709
3746
|
eventShipper.patch = async (eventId, patch) => {
|
|
2710
|
-
var
|
|
2711
|
-
const traceId = (
|
|
3747
|
+
var _a2, _b, _c, _d;
|
|
3748
|
+
const traceId = (_a2 = getOtlpTraceId(payload.session_id)) != null ? _a2 : payload.session_id;
|
|
2712
3749
|
await Promise.all([
|
|
2713
3750
|
mirrorEventToLocalDebugger(debuggerUrl, {
|
|
2714
3751
|
event_id: eventId,
|
|
@@ -2722,7 +3759,10 @@ async function handleHook() {
|
|
|
2722
3759
|
convo_id: patch.convoId
|
|
2723
3760
|
},
|
|
2724
3761
|
properties: {
|
|
2725
|
-
...
|
|
3762
|
+
...withAppGitProperties(
|
|
3763
|
+
patch.properties,
|
|
3764
|
+
appGitContext.forOperation(eventId, patch.properties)
|
|
3765
|
+
),
|
|
2726
3766
|
...payload.session_id ? { trace_id: traceId } : {}
|
|
2727
3767
|
},
|
|
2728
3768
|
is_pending: (_d = patch.isPending) != null ? _d : true
|
|
@@ -2736,14 +3776,23 @@ async function handleHook() {
|
|
|
2736
3776
|
MIN_FLUSH_WINDOW_MS,
|
|
2737
3777
|
hookFlushDeadlineMs() - (Date.now() - startedAtMs)
|
|
2738
3778
|
);
|
|
2739
|
-
const
|
|
2740
|
-
|
|
3779
|
+
const hookWork = (async () => {
|
|
3780
|
+
try {
|
|
2741
3781
|
await mapHookToRaindrop(payload, mapperConfig, eventShipper, traceShipper);
|
|
2742
3782
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
2743
3783
|
await Promise.all([eventShipper.shutdown(), traceShipper.shutdown()]);
|
|
2744
|
-
}
|
|
2745
|
-
|
|
2746
|
-
|
|
3784
|
+
} finally {
|
|
3785
|
+
try {
|
|
3786
|
+
appGitContext.dispose();
|
|
3787
|
+
} catch (e) {
|
|
3788
|
+
}
|
|
3789
|
+
}
|
|
3790
|
+
})();
|
|
3791
|
+
const outcome = await withDeadline(hookWork, remainingMs);
|
|
3792
|
+
try {
|
|
3793
|
+
appGitContext.dispose();
|
|
3794
|
+
} catch (e) {
|
|
3795
|
+
}
|
|
2747
3796
|
if (outcome === "deadline" && config.debug) {
|
|
2748
3797
|
console.error(
|
|
2749
3798
|
`[raindrop-ai/claude-code] hook work exceeded the ${hookFlushDeadlineMs()}ms deadline; exiting without waiting on the network (pending telemetry dropped)`
|
|
@@ -2761,12 +3810,12 @@ async function handleHook() {
|
|
|
2761
3810
|
// src/setup.ts
|
|
2762
3811
|
import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
|
|
2763
3812
|
import { homedir as homedir2, userInfo as userInfo2 } from "os";
|
|
2764
|
-
import { dirname as dirname2, join as join5, resolve } from "path";
|
|
3813
|
+
import { dirname as dirname2, join as join5, resolve as resolve2 } from "path";
|
|
2765
3814
|
import { createInterface } from "readline";
|
|
2766
3815
|
import { execSync as execSync2 } from "child_process";
|
|
2767
3816
|
function getClaudeSettingsPath(scope, cwd) {
|
|
2768
3817
|
if (scope === "project") {
|
|
2769
|
-
return
|
|
3818
|
+
return resolve2(cwd, ".claude", "settings.json");
|
|
2770
3819
|
}
|
|
2771
3820
|
return join5(homedir2(), ".claude", "settings.json");
|
|
2772
3821
|
}
|
|
@@ -2849,10 +3898,10 @@ function makeHookConfig(hookEvents, useAsync) {
|
|
|
2849
3898
|
}
|
|
2850
3899
|
function prompt(question) {
|
|
2851
3900
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
2852
|
-
return new Promise((
|
|
3901
|
+
return new Promise((resolve3) => {
|
|
2853
3902
|
rl.question(question, (answer) => {
|
|
2854
3903
|
rl.close();
|
|
2855
|
-
|
|
3904
|
+
resolve3(answer.trim());
|
|
2856
3905
|
});
|
|
2857
3906
|
});
|
|
2858
3907
|
}
|
|
@@ -3192,6 +4241,7 @@ function resolveCurrentEventId() {
|
|
|
3192
4241
|
}
|
|
3193
4242
|
}
|
|
3194
4243
|
async function executeTool(args2) {
|
|
4244
|
+
var _a;
|
|
3195
4245
|
const category = typeof args2["category"] === "string" ? args2["category"] : "";
|
|
3196
4246
|
const detail = typeof args2["detail"] === "string" ? args2["detail"] : "";
|
|
3197
4247
|
if (!category || !activeSignals[category]) {
|
|
@@ -3217,12 +4267,17 @@ async function executeTool(args2) {
|
|
|
3217
4267
|
if (!eventId) {
|
|
3218
4268
|
return { content: [{ type: "text", text: "Signal noted (no active event found)." }] };
|
|
3219
4269
|
}
|
|
3220
|
-
const
|
|
4270
|
+
const appGitContext = createAppGitContext2(
|
|
4271
|
+
((_a = config.writeKey) == null ? void 0 : _a.trim()) ? config.appGit : false,
|
|
4272
|
+
{ allowLocalGit: false }
|
|
4273
|
+
);
|
|
4274
|
+
const shipper = new EventShipper3({
|
|
3221
4275
|
writeKey: config.writeKey,
|
|
3222
4276
|
endpoint: config.endpoint,
|
|
3223
4277
|
debug: false,
|
|
3224
4278
|
projectId: config.projectId,
|
|
3225
|
-
enabled: true
|
|
4279
|
+
enabled: true,
|
|
4280
|
+
appGitContext
|
|
3226
4281
|
});
|
|
3227
4282
|
try {
|
|
3228
4283
|
const signalDef = activeSignals[category];
|
|
@@ -3249,6 +4304,11 @@ async function executeTool(args2) {
|
|
|
3249
4304
|
});
|
|
3250
4305
|
await shipper.shutdown();
|
|
3251
4306
|
} catch (e) {
|
|
4307
|
+
} finally {
|
|
4308
|
+
try {
|
|
4309
|
+
appGitContext.dispose();
|
|
4310
|
+
} catch (e) {
|
|
4311
|
+
}
|
|
3252
4312
|
}
|
|
3253
4313
|
return { content: [{ type: "text", text: "Signal recorded." }] };
|
|
3254
4314
|
}
|
|
@@ -3374,8 +4434,8 @@ var args = process.argv.slice(2);
|
|
|
3374
4434
|
var command = args[0];
|
|
3375
4435
|
function parseFlag(name) {
|
|
3376
4436
|
const prefix = `--${name}=`;
|
|
3377
|
-
const
|
|
3378
|
-
return
|
|
4437
|
+
const flag2 = args.find((a) => a.startsWith(prefix));
|
|
4438
|
+
return flag2 ? flag2.slice(prefix.length) : void 0;
|
|
3379
4439
|
}
|
|
3380
4440
|
async function main() {
|
|
3381
4441
|
switch (command) {
|