@respan/cli 0.7.0 → 0.7.2
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/dist/commands/integrate/claude-code.d.ts +2 -0
- package/dist/commands/integrate/claude-code.js +35 -5
- package/dist/commands/integrate/codex-cli.d.ts +2 -0
- package/dist/commands/integrate/codex-cli.js +23 -2
- package/dist/commands/integrate/gemini-cli.d.ts +2 -0
- package/dist/commands/integrate/gemini-cli.js +36 -4
- package/dist/commands/integrate/opencode.d.ts +2 -0
- package/dist/commands/integrate/opencode.js +25 -2
- package/dist/hooks/claude-code.cjs +3 -1
- package/dist/hooks/claude-code.js +1 -0
- package/dist/hooks/codex-cli.cjs +73 -49
- package/dist/hooks/codex-cli.js +77 -57
- package/dist/hooks/gemini-cli.cjs +33 -55
- package/dist/hooks/gemini-cli.js +34 -61
- package/dist/hooks/shared.d.ts +1 -0
- package/dist/hooks/shared.js +3 -1
- package/dist/lib/integrate.d.ts +2 -0
- package/dist/lib/integrate.js +10 -0
- package/oclif.manifest.json +588 -512
- package/package.json +10 -2
|
@@ -258,6 +258,7 @@ function stringToSpanId(s) {
|
|
|
258
258
|
function toOtlpPayload(spans) {
|
|
259
259
|
const otlpSpans = spans.map((span) => {
|
|
260
260
|
const attrs = {};
|
|
261
|
+
if (span.session_identifier) attrs["respan.sessions.session_identifier"] = span.session_identifier;
|
|
261
262
|
if (span.thread_identifier) attrs["respan.threads.thread_identifier"] = span.thread_identifier;
|
|
262
263
|
if (span.customer_identifier) attrs["respan.customer_params.customer_identifier"] = span.customer_identifier;
|
|
263
264
|
if (span.span_workflow_name) attrs["traceloop.workflow.name"] = span.span_workflow_name;
|
|
@@ -318,7 +319,7 @@ function toOtlpPayload(spans) {
|
|
|
318
319
|
})
|
|
319
320
|
},
|
|
320
321
|
scopeSpans: [{
|
|
321
|
-
scope: { name: "respan-cli-hooks", version: "0.7.
|
|
322
|
+
scope: { name: "respan-cli-hooks", version: "0.7.1" },
|
|
322
323
|
spans: otlpSpans
|
|
323
324
|
}]
|
|
324
325
|
}]
|
|
@@ -438,6 +439,34 @@ function detectModel(hookData) {
|
|
|
438
439
|
const llmReq = hookData.llm_request ?? {};
|
|
439
440
|
return String(llmReq.model ?? "") || "gemini-cli";
|
|
440
441
|
}
|
|
442
|
+
function buildToolSpan(detail, idx, traceUniqueId, rootSpanId, safeId, turnTs, workflowName, beginTime, endTime) {
|
|
443
|
+
const toolName = detail?.name ?? "";
|
|
444
|
+
const toolArgs = detail?.args ?? detail?.input ?? {};
|
|
445
|
+
const toolOutput = detail?.output ?? "";
|
|
446
|
+
const displayName = toolName ? toolDisplayName(toolName) : `Call ${idx + 1}`;
|
|
447
|
+
const toolInputStr = toolName ? formatToolInput(toolName, toolArgs) : "";
|
|
448
|
+
const toolMeta = {};
|
|
449
|
+
if (toolName) toolMeta.tool_name = toolName;
|
|
450
|
+
if (detail?.error) toolMeta.error = detail.error;
|
|
451
|
+
const toolStart = detail?.start_time ?? beginTime;
|
|
452
|
+
const toolEnd = detail?.end_time ?? endTime;
|
|
453
|
+
const toolLat = latencySeconds(toolStart, toolEnd);
|
|
454
|
+
return {
|
|
455
|
+
trace_unique_id: traceUniqueId,
|
|
456
|
+
span_unique_id: `gcli_${safeId}_${turnTs}_tool_${idx + 1}`,
|
|
457
|
+
span_parent_id: rootSpanId,
|
|
458
|
+
span_name: `Tool: ${displayName}`,
|
|
459
|
+
span_workflow_name: workflowName,
|
|
460
|
+
span_path: toolName ? `tool_${toolName}` : "tool_call",
|
|
461
|
+
provider_id: "",
|
|
462
|
+
metadata: toolMeta,
|
|
463
|
+
input: toolInputStr,
|
|
464
|
+
output: truncate(toolOutput, MAX_CHARS),
|
|
465
|
+
timestamp: toolEnd,
|
|
466
|
+
start_time: toolStart,
|
|
467
|
+
...toolLat !== void 0 ? { latency: toolLat } : {}
|
|
468
|
+
};
|
|
469
|
+
}
|
|
441
470
|
function buildSpans(hookData, outputText, tokens, config, startTimeIso, toolTurns, toolDetails, thoughtsTokens, textRounds, roundStartTimes) {
|
|
442
471
|
const spans = [];
|
|
443
472
|
const sessionId = String(hookData.session_id ?? "");
|
|
@@ -464,6 +493,7 @@ function buildSpans(hookData, outputText, tokens, config, startTimeIso, toolTurn
|
|
|
464
493
|
const metadata = buildMetadata(config, baseMeta);
|
|
465
494
|
spans.push({
|
|
466
495
|
trace_unique_id: traceUniqueId,
|
|
496
|
+
session_identifier: threadId,
|
|
467
497
|
thread_identifier: threadId,
|
|
468
498
|
customer_identifier: customerId,
|
|
469
499
|
span_unique_id: rootSpanId,
|
|
@@ -519,33 +549,7 @@ function buildSpans(hookData, outputText, tokens, config, startTimeIso, toolTurn
|
|
|
519
549
|
}
|
|
520
550
|
if (r < rounds.length - 1) {
|
|
521
551
|
while (toolIdx < toolDetails.length) {
|
|
522
|
-
|
|
523
|
-
const toolName = detail?.name ?? "";
|
|
524
|
-
const toolArgs = detail?.args ?? detail?.input ?? {};
|
|
525
|
-
const toolOutput = detail?.output ?? "";
|
|
526
|
-
const displayName = toolName ? toolDisplayName(toolName) : `Call ${toolIdx + 1}`;
|
|
527
|
-
const toolInputStr = toolName ? formatToolInput(toolName, toolArgs) : "";
|
|
528
|
-
const toolMeta = {};
|
|
529
|
-
if (toolName) toolMeta.tool_name = toolName;
|
|
530
|
-
if (detail?.error) toolMeta.error = detail.error;
|
|
531
|
-
const toolStart = detail?.start_time ?? beginTime;
|
|
532
|
-
const toolEnd = detail?.end_time ?? endTime;
|
|
533
|
-
const toolLat = latencySeconds(toolStart, toolEnd);
|
|
534
|
-
spans.push({
|
|
535
|
-
trace_unique_id: traceUniqueId,
|
|
536
|
-
span_unique_id: `gcli_${safeId}_${turnTs}_tool_${toolIdx + 1}`,
|
|
537
|
-
span_parent_id: rootSpanId,
|
|
538
|
-
span_name: `Tool: ${displayName}`,
|
|
539
|
-
span_workflow_name: workflowName,
|
|
540
|
-
span_path: toolName ? `tool_${toolName}` : "tool_call",
|
|
541
|
-
provider_id: "",
|
|
542
|
-
metadata: toolMeta,
|
|
543
|
-
input: toolInputStr,
|
|
544
|
-
output: truncate(toolOutput, MAX_CHARS),
|
|
545
|
-
timestamp: toolEnd,
|
|
546
|
-
start_time: toolStart,
|
|
547
|
-
...toolLat !== void 0 ? { latency: toolLat } : {}
|
|
548
|
-
});
|
|
552
|
+
spans.push(buildToolSpan(toolDetails[toolIdx], toolIdx, traceUniqueId, rootSpanId, safeId, turnTs, workflowName, beginTime, endTime));
|
|
549
553
|
toolIdx++;
|
|
550
554
|
const nextDetail = toolDetails[toolIdx];
|
|
551
555
|
if (nextDetail && roundStarts[r + 1] && nextDetail.start_time && nextDetail.start_time > roundStarts[r + 1]) break;
|
|
@@ -553,33 +557,7 @@ function buildSpans(hookData, outputText, tokens, config, startTimeIso, toolTurn
|
|
|
553
557
|
}
|
|
554
558
|
}
|
|
555
559
|
while (toolIdx < toolDetails.length) {
|
|
556
|
-
|
|
557
|
-
const toolName = detail?.name ?? "";
|
|
558
|
-
const toolArgs = detail?.args ?? detail?.input ?? {};
|
|
559
|
-
const toolOutput = detail?.output ?? "";
|
|
560
|
-
const displayName = toolName ? toolDisplayName(toolName) : `Call ${toolIdx + 1}`;
|
|
561
|
-
const toolInputStr = toolName ? formatToolInput(toolName, toolArgs) : "";
|
|
562
|
-
const toolMeta = {};
|
|
563
|
-
if (toolName) toolMeta.tool_name = toolName;
|
|
564
|
-
if (detail?.error) toolMeta.error = detail.error;
|
|
565
|
-
const toolStart = detail?.start_time ?? beginTime;
|
|
566
|
-
const toolEnd = detail?.end_time ?? endTime;
|
|
567
|
-
const toolLat = latencySeconds(toolStart, toolEnd);
|
|
568
|
-
spans.push({
|
|
569
|
-
trace_unique_id: traceUniqueId,
|
|
570
|
-
span_unique_id: `gcli_${safeId}_${turnTs}_tool_${toolIdx + 1}`,
|
|
571
|
-
span_parent_id: rootSpanId,
|
|
572
|
-
span_name: `Tool: ${displayName}`,
|
|
573
|
-
span_workflow_name: workflowName,
|
|
574
|
-
span_path: toolName ? `tool_${toolName}` : "tool_call",
|
|
575
|
-
provider_id: "",
|
|
576
|
-
metadata: toolMeta,
|
|
577
|
-
input: toolInputStr,
|
|
578
|
-
output: truncate(toolOutput, MAX_CHARS),
|
|
579
|
-
timestamp: toolEnd,
|
|
580
|
-
start_time: toolStart,
|
|
581
|
-
...toolLat !== void 0 ? { latency: toolLat } : {}
|
|
582
|
-
});
|
|
560
|
+
spans.push(buildToolSpan(toolDetails[toolIdx], toolIdx, traceUniqueId, rootSpanId, safeId, turnTs, workflowName, beginTime, endTime));
|
|
583
561
|
toolIdx++;
|
|
584
562
|
}
|
|
585
563
|
if (thoughtsTokens > 0) {
|
package/dist/hooks/gemini-cli.js
CHANGED
|
@@ -142,6 +142,36 @@ function detectModel(hookData) {
|
|
|
142
142
|
return String(llmReq.model ?? '') || 'gemini-cli';
|
|
143
143
|
}
|
|
144
144
|
// ── Span construction ─────────────────────────────────────────────
|
|
145
|
+
function buildToolSpan(detail, idx, traceUniqueId, rootSpanId, safeId, turnTs, workflowName, beginTime, endTime) {
|
|
146
|
+
const toolName = detail?.name ?? '';
|
|
147
|
+
const toolArgs = detail?.args ?? detail?.input ?? {};
|
|
148
|
+
const toolOutput = detail?.output ?? '';
|
|
149
|
+
const displayName = toolName ? toolDisplayName(toolName) : `Call ${idx + 1}`;
|
|
150
|
+
const toolInputStr = toolName ? formatToolInput(toolName, toolArgs) : '';
|
|
151
|
+
const toolMeta = {};
|
|
152
|
+
if (toolName)
|
|
153
|
+
toolMeta.tool_name = toolName;
|
|
154
|
+
if (detail?.error)
|
|
155
|
+
toolMeta.error = detail.error;
|
|
156
|
+
const toolStart = detail?.start_time ?? beginTime;
|
|
157
|
+
const toolEnd = detail?.end_time ?? endTime;
|
|
158
|
+
const toolLat = latencySeconds(toolStart, toolEnd);
|
|
159
|
+
return {
|
|
160
|
+
trace_unique_id: traceUniqueId,
|
|
161
|
+
span_unique_id: `gcli_${safeId}_${turnTs}_tool_${idx + 1}`,
|
|
162
|
+
span_parent_id: rootSpanId,
|
|
163
|
+
span_name: `Tool: ${displayName}`,
|
|
164
|
+
span_workflow_name: workflowName,
|
|
165
|
+
span_path: toolName ? `tool_${toolName}` : 'tool_call',
|
|
166
|
+
provider_id: '',
|
|
167
|
+
metadata: toolMeta,
|
|
168
|
+
input: toolInputStr,
|
|
169
|
+
output: truncate(toolOutput, MAX_CHARS),
|
|
170
|
+
timestamp: toolEnd,
|
|
171
|
+
start_time: toolStart,
|
|
172
|
+
...(toolLat !== undefined ? { latency: toolLat } : {}),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
145
175
|
function buildSpans(hookData, outputText, tokens, config, startTimeIso, toolTurns, toolDetails, thoughtsTokens, textRounds, roundStartTimes) {
|
|
146
176
|
const spans = [];
|
|
147
177
|
const sessionId = String(hookData.session_id ?? '');
|
|
@@ -171,6 +201,7 @@ function buildSpans(hookData, outputText, tokens, config, startTimeIso, toolTurn
|
|
|
171
201
|
// Root span
|
|
172
202
|
spans.push({
|
|
173
203
|
trace_unique_id: traceUniqueId,
|
|
204
|
+
session_identifier: threadId,
|
|
174
205
|
thread_identifier: threadId,
|
|
175
206
|
customer_identifier: customerId,
|
|
176
207
|
span_unique_id: rootSpanId,
|
|
@@ -233,76 +264,18 @@ function buildSpans(hookData, outputText, tokens, config, startTimeIso, toolTurn
|
|
|
233
264
|
}
|
|
234
265
|
// Tool spans that come after this round (before next round)
|
|
235
266
|
if (r < rounds.length - 1) {
|
|
236
|
-
// Emit all tools between this round and the next
|
|
237
267
|
while (toolIdx < toolDetails.length) {
|
|
238
|
-
|
|
239
|
-
const toolName = detail?.name ?? '';
|
|
240
|
-
const toolArgs = detail?.args ?? detail?.input ?? {};
|
|
241
|
-
const toolOutput = detail?.output ?? '';
|
|
242
|
-
const displayName = toolName ? toolDisplayName(toolName) : `Call ${toolIdx + 1}`;
|
|
243
|
-
const toolInputStr = toolName ? formatToolInput(toolName, toolArgs) : '';
|
|
244
|
-
const toolMeta = {};
|
|
245
|
-
if (toolName)
|
|
246
|
-
toolMeta.tool_name = toolName;
|
|
247
|
-
if (detail?.error)
|
|
248
|
-
toolMeta.error = detail.error;
|
|
249
|
-
const toolStart = detail?.start_time ?? beginTime;
|
|
250
|
-
const toolEnd = detail?.end_time ?? endTime;
|
|
251
|
-
const toolLat = latencySeconds(toolStart, toolEnd);
|
|
252
|
-
spans.push({
|
|
253
|
-
trace_unique_id: traceUniqueId,
|
|
254
|
-
span_unique_id: `gcli_${safeId}_${turnTs}_tool_${toolIdx + 1}`,
|
|
255
|
-
span_parent_id: rootSpanId,
|
|
256
|
-
span_name: `Tool: ${displayName}`,
|
|
257
|
-
span_workflow_name: workflowName,
|
|
258
|
-
span_path: toolName ? `tool_${toolName}` : 'tool_call',
|
|
259
|
-
provider_id: '',
|
|
260
|
-
metadata: toolMeta,
|
|
261
|
-
input: toolInputStr,
|
|
262
|
-
output: truncate(toolOutput, MAX_CHARS),
|
|
263
|
-
timestamp: toolEnd,
|
|
264
|
-
start_time: toolStart,
|
|
265
|
-
...(toolLat !== undefined ? { latency: toolLat } : {}),
|
|
266
|
-
});
|
|
268
|
+
spans.push(buildToolSpan(toolDetails[toolIdx], toolIdx, traceUniqueId, rootSpanId, safeId, turnTs, workflowName, beginTime, endTime));
|
|
267
269
|
toolIdx++;
|
|
268
|
-
// If next tool starts after next round's start time, break — it belongs to a later gap
|
|
269
270
|
const nextDetail = toolDetails[toolIdx];
|
|
270
271
|
if (nextDetail && roundStarts[r + 1] && nextDetail.start_time && nextDetail.start_time > roundStarts[r + 1])
|
|
271
272
|
break;
|
|
272
273
|
}
|
|
273
274
|
}
|
|
274
275
|
}
|
|
275
|
-
// Any remaining tools not yet emitted
|
|
276
|
+
// Any remaining tools not yet emitted
|
|
276
277
|
while (toolIdx < toolDetails.length) {
|
|
277
|
-
|
|
278
|
-
const toolName = detail?.name ?? '';
|
|
279
|
-
const toolArgs = detail?.args ?? detail?.input ?? {};
|
|
280
|
-
const toolOutput = detail?.output ?? '';
|
|
281
|
-
const displayName = toolName ? toolDisplayName(toolName) : `Call ${toolIdx + 1}`;
|
|
282
|
-
const toolInputStr = toolName ? formatToolInput(toolName, toolArgs) : '';
|
|
283
|
-
const toolMeta = {};
|
|
284
|
-
if (toolName)
|
|
285
|
-
toolMeta.tool_name = toolName;
|
|
286
|
-
if (detail?.error)
|
|
287
|
-
toolMeta.error = detail.error;
|
|
288
|
-
const toolStart = detail?.start_time ?? beginTime;
|
|
289
|
-
const toolEnd = detail?.end_time ?? endTime;
|
|
290
|
-
const toolLat = latencySeconds(toolStart, toolEnd);
|
|
291
|
-
spans.push({
|
|
292
|
-
trace_unique_id: traceUniqueId,
|
|
293
|
-
span_unique_id: `gcli_${safeId}_${turnTs}_tool_${toolIdx + 1}`,
|
|
294
|
-
span_parent_id: rootSpanId,
|
|
295
|
-
span_name: `Tool: ${displayName}`,
|
|
296
|
-
span_workflow_name: workflowName,
|
|
297
|
-
span_path: toolName ? `tool_${toolName}` : 'tool_call',
|
|
298
|
-
provider_id: '',
|
|
299
|
-
metadata: toolMeta,
|
|
300
|
-
input: toolInputStr,
|
|
301
|
-
output: truncate(toolOutput, MAX_CHARS),
|
|
302
|
-
timestamp: toolEnd,
|
|
303
|
-
start_time: toolStart,
|
|
304
|
-
...(toolLat !== undefined ? { latency: toolLat } : {}),
|
|
305
|
-
});
|
|
278
|
+
spans.push(buildToolSpan(toolDetails[toolIdx], toolIdx, traceUniqueId, rootSpanId, safeId, turnTs, workflowName, beginTime, endTime));
|
|
306
279
|
toolIdx++;
|
|
307
280
|
}
|
|
308
281
|
// Reasoning span
|
package/dist/hooks/shared.d.ts
CHANGED
package/dist/hooks/shared.js
CHANGED
|
@@ -315,6 +315,8 @@ export function toOtlpPayload(spans) {
|
|
|
315
315
|
// Build OTEL-compatible attributes from SpanData fields
|
|
316
316
|
const attrs = {};
|
|
317
317
|
// Respan-specific attributes
|
|
318
|
+
if (span.session_identifier)
|
|
319
|
+
attrs['respan.sessions.session_identifier'] = span.session_identifier;
|
|
318
320
|
if (span.thread_identifier)
|
|
319
321
|
attrs['respan.threads.thread_identifier'] = span.thread_identifier;
|
|
320
322
|
if (span.customer_identifier)
|
|
@@ -395,7 +397,7 @@ export function toOtlpPayload(spans) {
|
|
|
395
397
|
}),
|
|
396
398
|
},
|
|
397
399
|
scopeSpans: [{
|
|
398
|
-
scope: { name: 'respan-cli-hooks', version: '0.7.
|
|
400
|
+
scope: { name: 'respan-cli-hooks', version: '0.7.1' },
|
|
399
401
|
spans: otlpSpans,
|
|
400
402
|
}],
|
|
401
403
|
}],
|
package/dist/lib/integrate.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export declare const DEFAULT_BASE_URL = "https://api.respan.ai/api";
|
|
|
3
3
|
export declare const integrateFlags: {
|
|
4
4
|
local: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
5
5
|
global: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
6
|
+
enable: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
disable: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
6
8
|
'project-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
9
|
'base-url': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
10
|
attrs: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
package/dist/lib/integrate.js
CHANGED
|
@@ -19,6 +19,16 @@ export const integrateFlags = {
|
|
|
19
19
|
default: false,
|
|
20
20
|
exclusive: ['local'],
|
|
21
21
|
}),
|
|
22
|
+
enable: Flags.boolean({
|
|
23
|
+
description: 'Enable tracing (default)',
|
|
24
|
+
default: false,
|
|
25
|
+
exclusive: ['disable'],
|
|
26
|
+
}),
|
|
27
|
+
disable: Flags.boolean({
|
|
28
|
+
description: 'Disable tracing',
|
|
29
|
+
default: false,
|
|
30
|
+
exclusive: ['enable'],
|
|
31
|
+
}),
|
|
22
32
|
'project-id': Flags.string({
|
|
23
33
|
description: 'Respan project ID (added to metadata / resource attributes)',
|
|
24
34
|
env: 'RESPAN_PROJECT_ID',
|