@tracebird/cli 0.1.0 → 0.1.1
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/LICENSE +21 -0
- package/dist/cli.js +251 -162
- package/dist/cli.js.map +1 -1
- package/package.json +2 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 utsabpanta
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/cli.js
CHANGED
|
@@ -15,178 +15,267 @@ import {
|
|
|
15
15
|
import { parseOtlp } from "@tracebird/core";
|
|
16
16
|
|
|
17
17
|
// src/otlp/protobuf.ts
|
|
18
|
-
|
|
19
|
-
var
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"doubleValue",
|
|
28
|
-
"arrayValue",
|
|
29
|
-
"kvlistValue",
|
|
30
|
-
"bytesValue"
|
|
31
|
-
]
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
fields: {
|
|
35
|
-
stringValue: { type: "string", id: 1 },
|
|
36
|
-
boolValue: { type: "bool", id: 2 },
|
|
37
|
-
intValue: { type: "int64", id: 3 },
|
|
38
|
-
doubleValue: { type: "double", id: 4 },
|
|
39
|
-
arrayValue: { type: "ArrayValue", id: 5 },
|
|
40
|
-
kvlistValue: { type: "KeyValueList", id: 6 },
|
|
41
|
-
bytesValue: { type: "bytes", id: 7 }
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
ArrayValue: { fields: { values: { rule: "repeated", type: "AnyValue", id: 1 } } },
|
|
45
|
-
KeyValueList: { fields: { values: { rule: "repeated", type: "KeyValue", id: 1 } } },
|
|
46
|
-
KeyValue: {
|
|
47
|
-
fields: { key: { type: "string", id: 1 }, value: { type: "AnyValue", id: 2 } }
|
|
48
|
-
},
|
|
49
|
-
InstrumentationScope: {
|
|
50
|
-
fields: {
|
|
51
|
-
name: { type: "string", id: 1 },
|
|
52
|
-
version: { type: "string", id: 2 },
|
|
53
|
-
attributes: { rule: "repeated", type: "KeyValue", id: 3 }
|
|
54
|
-
}
|
|
18
|
+
var textDecoder = new TextDecoder();
|
|
19
|
+
var textEncoder = new TextEncoder();
|
|
20
|
+
var VARINT = 0;
|
|
21
|
+
var I64 = 1;
|
|
22
|
+
var LEN = 2;
|
|
23
|
+
var I32 = 5;
|
|
24
|
+
var Reader = class {
|
|
25
|
+
constructor(buf) {
|
|
26
|
+
this.buf = buf;
|
|
55
27
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
Resource: {
|
|
70
|
-
fields: { attributes: { rule: "repeated", type: KV, id: 1 } }
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
trace: {
|
|
77
|
-
nested: {
|
|
78
|
-
v1: {
|
|
79
|
-
nested: {
|
|
80
|
-
ResourceSpans: {
|
|
81
|
-
fields: {
|
|
82
|
-
resource: { type: "opentelemetry.proto.resource.v1.Resource", id: 1 },
|
|
83
|
-
scopeSpans: { rule: "repeated", type: "ScopeSpans", id: 2 },
|
|
84
|
-
schemaUrl: { type: "string", id: 3 }
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
ScopeSpans: {
|
|
88
|
-
fields: {
|
|
89
|
-
scope: {
|
|
90
|
-
type: "opentelemetry.proto.common.v1.InstrumentationScope",
|
|
91
|
-
id: 1
|
|
92
|
-
},
|
|
93
|
-
spans: { rule: "repeated", type: "Span", id: 2 },
|
|
94
|
-
schemaUrl: { type: "string", id: 3 }
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
Span: {
|
|
98
|
-
fields: {
|
|
99
|
-
traceId: { type: "bytes", id: 1 },
|
|
100
|
-
spanId: { type: "bytes", id: 2 },
|
|
101
|
-
traceState: { type: "string", id: 3 },
|
|
102
|
-
parentSpanId: { type: "bytes", id: 4 },
|
|
103
|
-
name: { type: "string", id: 5 },
|
|
104
|
-
kind: { type: "int32", id: 6 },
|
|
105
|
-
startTimeUnixNano: { type: "fixed64", id: 7 },
|
|
106
|
-
endTimeUnixNano: { type: "fixed64", id: 8 },
|
|
107
|
-
attributes: { rule: "repeated", type: KV, id: 9 },
|
|
108
|
-
events: { rule: "repeated", type: "Event", id: 11 },
|
|
109
|
-
status: { type: "Status", id: 15 }
|
|
110
|
-
},
|
|
111
|
-
nested: {
|
|
112
|
-
Event: {
|
|
113
|
-
fields: {
|
|
114
|
-
timeUnixNano: { type: "fixed64", id: 1 },
|
|
115
|
-
name: { type: "string", id: 2 },
|
|
116
|
-
attributes: { rule: "repeated", type: KV, id: 3 }
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
},
|
|
121
|
-
Status: {
|
|
122
|
-
fields: {
|
|
123
|
-
message: { type: "string", id: 2 },
|
|
124
|
-
code: { type: "int32", id: 3 }
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
collector: {
|
|
132
|
-
nested: {
|
|
133
|
-
trace: {
|
|
134
|
-
nested: {
|
|
135
|
-
v1: {
|
|
136
|
-
nested: {
|
|
137
|
-
ExportTraceServiceRequest: {
|
|
138
|
-
fields: {
|
|
139
|
-
resourceSpans: {
|
|
140
|
-
rule: "repeated",
|
|
141
|
-
type: "opentelemetry.proto.trace.v1.ResourceSpans",
|
|
142
|
-
id: 1
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
28
|
+
buf;
|
|
29
|
+
pos = 0;
|
|
30
|
+
get eof() {
|
|
31
|
+
return this.pos >= this.buf.length;
|
|
32
|
+
}
|
|
33
|
+
varint() {
|
|
34
|
+
let result = 0n;
|
|
35
|
+
let shift = 0n;
|
|
36
|
+
for (; ; ) {
|
|
37
|
+
const byte = this.buf[this.pos++];
|
|
38
|
+
result |= BigInt(byte & 127) << shift;
|
|
39
|
+
if ((byte & 128) === 0) break;
|
|
40
|
+
shift += 7n;
|
|
155
41
|
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
tag() {
|
|
45
|
+
const v = Number(this.varint());
|
|
46
|
+
return { field: v >>> 3, wire: v & 7 };
|
|
47
|
+
}
|
|
48
|
+
fixed64() {
|
|
49
|
+
let v = 0n;
|
|
50
|
+
for (let i = 0; i < 8; i++) v |= BigInt(this.buf[this.pos++]) << BigInt(8 * i);
|
|
51
|
+
return v;
|
|
52
|
+
}
|
|
53
|
+
double() {
|
|
54
|
+
const view = new DataView(this.buf.buffer, this.buf.byteOffset + this.pos, 8);
|
|
55
|
+
this.pos += 8;
|
|
56
|
+
return view.getFloat64(0, true);
|
|
57
|
+
}
|
|
58
|
+
bytes() {
|
|
59
|
+
const len = Number(this.varint());
|
|
60
|
+
const out = this.buf.subarray(this.pos, this.pos + len);
|
|
61
|
+
this.pos += len;
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
string() {
|
|
65
|
+
return textDecoder.decode(this.bytes());
|
|
66
|
+
}
|
|
67
|
+
/** Skip an unknown field by its wire type, preserving forward-compatibility. */
|
|
68
|
+
skip(wire) {
|
|
69
|
+
if (wire === VARINT) this.varint();
|
|
70
|
+
else if (wire === I64) this.pos += 8;
|
|
71
|
+
else if (wire === LEN) this.bytes();
|
|
72
|
+
else if (wire === I32) this.pos += 4;
|
|
73
|
+
else throw new Error(`unsupported wire type ${wire}`);
|
|
156
74
|
}
|
|
157
75
|
};
|
|
158
|
-
var root = protobuf.Root.fromJSON(descriptor);
|
|
159
|
-
var RequestType = root.lookupType(
|
|
160
|
-
"opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest"
|
|
161
|
-
);
|
|
162
76
|
function bytesToHex(bytes) {
|
|
163
|
-
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
return arr.map((b) => (b & 255).toString(16).padStart(2, "0")).join("");
|
|
77
|
+
let hex = "";
|
|
78
|
+
for (const b of bytes) hex += (b & 255).toString(16).padStart(2, "0");
|
|
79
|
+
return hex;
|
|
167
80
|
}
|
|
168
|
-
function
|
|
169
|
-
const
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
81
|
+
function parseAnyValue(buf) {
|
|
82
|
+
const r = new Reader(buf);
|
|
83
|
+
const out = {};
|
|
84
|
+
while (!r.eof) {
|
|
85
|
+
const { field, wire } = r.tag();
|
|
86
|
+
switch (field) {
|
|
87
|
+
case 1:
|
|
88
|
+
out.stringValue = r.string();
|
|
89
|
+
break;
|
|
90
|
+
case 2:
|
|
91
|
+
out.boolValue = r.varint() !== 0n;
|
|
92
|
+
break;
|
|
93
|
+
case 3:
|
|
94
|
+
out.intValue = r.varint().toString();
|
|
95
|
+
break;
|
|
96
|
+
case 4:
|
|
97
|
+
out.doubleValue = r.double();
|
|
98
|
+
break;
|
|
99
|
+
case 5:
|
|
100
|
+
out.arrayValue = { values: parseRepeated(r.bytes(), parseAnyValue) };
|
|
101
|
+
break;
|
|
102
|
+
case 6:
|
|
103
|
+
out.kvlistValue = { values: parseRepeated(r.bytes(), parseKeyValue) };
|
|
104
|
+
break;
|
|
105
|
+
case 7:
|
|
106
|
+
out.bytesValue = bytesToHex(r.bytes());
|
|
107
|
+
break;
|
|
108
|
+
default:
|
|
109
|
+
r.skip(wire);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
function parseRepeated(buf, parse) {
|
|
115
|
+
const r = new Reader(buf);
|
|
116
|
+
const out = [];
|
|
117
|
+
while (!r.eof) {
|
|
118
|
+
const { field, wire } = r.tag();
|
|
119
|
+
if (field === 1 && wire === LEN) out.push(parse(r.bytes()));
|
|
120
|
+
else r.skip(wire);
|
|
121
|
+
}
|
|
122
|
+
return out;
|
|
123
|
+
}
|
|
124
|
+
function parseKeyValue(buf) {
|
|
125
|
+
const r = new Reader(buf);
|
|
126
|
+
const kv = {};
|
|
127
|
+
while (!r.eof) {
|
|
128
|
+
const { field, wire } = r.tag();
|
|
129
|
+
if (field === 1) kv.key = r.string();
|
|
130
|
+
else if (field === 2) kv.value = parseAnyValue(r.bytes());
|
|
131
|
+
else r.skip(wire);
|
|
132
|
+
}
|
|
133
|
+
return kv;
|
|
134
|
+
}
|
|
135
|
+
function parseKeyValues(buf, into) {
|
|
136
|
+
into.push(parseKeyValue(buf));
|
|
137
|
+
}
|
|
138
|
+
function parseEvent(buf) {
|
|
139
|
+
const r = new Reader(buf);
|
|
140
|
+
const ev = {};
|
|
141
|
+
const attributes = [];
|
|
142
|
+
while (!r.eof) {
|
|
143
|
+
const { field, wire } = r.tag();
|
|
144
|
+
switch (field) {
|
|
145
|
+
case 1:
|
|
146
|
+
ev.timeUnixNano = r.fixed64().toString();
|
|
147
|
+
break;
|
|
148
|
+
case 2:
|
|
149
|
+
ev.name = r.string();
|
|
150
|
+
break;
|
|
151
|
+
case 3:
|
|
152
|
+
parseKeyValues(r.bytes(), attributes);
|
|
153
|
+
break;
|
|
154
|
+
default:
|
|
155
|
+
r.skip(wire);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (attributes.length) ev.attributes = attributes;
|
|
159
|
+
return ev;
|
|
160
|
+
}
|
|
161
|
+
function parseStatus(buf) {
|
|
162
|
+
const r = new Reader(buf);
|
|
163
|
+
const status = {};
|
|
164
|
+
while (!r.eof) {
|
|
165
|
+
const { field, wire } = r.tag();
|
|
166
|
+
if (field === 2) status.message = r.string();
|
|
167
|
+
else if (field === 3) status.code = Number(r.varint());
|
|
168
|
+
else r.skip(wire);
|
|
169
|
+
}
|
|
170
|
+
return status;
|
|
171
|
+
}
|
|
172
|
+
function parseSpan(buf) {
|
|
173
|
+
const r = new Reader(buf);
|
|
174
|
+
const span2 = {};
|
|
175
|
+
const attributes = [];
|
|
176
|
+
const events = [];
|
|
177
|
+
while (!r.eof) {
|
|
178
|
+
const { field, wire } = r.tag();
|
|
179
|
+
switch (field) {
|
|
180
|
+
case 1:
|
|
181
|
+
span2.traceId = bytesToHex(r.bytes());
|
|
182
|
+
break;
|
|
183
|
+
case 2:
|
|
184
|
+
span2.spanId = bytesToHex(r.bytes());
|
|
185
|
+
break;
|
|
186
|
+
case 4: {
|
|
187
|
+
const parent = bytesToHex(r.bytes());
|
|
184
188
|
if (parent) span2.parentSpanId = parent;
|
|
185
|
-
|
|
189
|
+
break;
|
|
186
190
|
}
|
|
191
|
+
case 5:
|
|
192
|
+
span2.name = r.string();
|
|
193
|
+
break;
|
|
194
|
+
case 6:
|
|
195
|
+
span2.kind = Number(r.varint());
|
|
196
|
+
break;
|
|
197
|
+
case 7:
|
|
198
|
+
span2.startTimeUnixNano = r.fixed64().toString();
|
|
199
|
+
break;
|
|
200
|
+
case 8:
|
|
201
|
+
span2.endTimeUnixNano = r.fixed64().toString();
|
|
202
|
+
break;
|
|
203
|
+
case 9:
|
|
204
|
+
parseKeyValues(r.bytes(), attributes);
|
|
205
|
+
break;
|
|
206
|
+
case 11:
|
|
207
|
+
events.push(parseEvent(r.bytes()));
|
|
208
|
+
break;
|
|
209
|
+
case 15:
|
|
210
|
+
span2.status = parseStatus(r.bytes());
|
|
211
|
+
break;
|
|
212
|
+
default:
|
|
213
|
+
r.skip(wire);
|
|
187
214
|
}
|
|
188
215
|
}
|
|
189
|
-
|
|
216
|
+
if (attributes.length) span2.attributes = attributes;
|
|
217
|
+
if (events.length) span2.events = events;
|
|
218
|
+
return span2;
|
|
219
|
+
}
|
|
220
|
+
function parseScope(buf) {
|
|
221
|
+
const r = new Reader(buf);
|
|
222
|
+
const scope = {};
|
|
223
|
+
const attributes = [];
|
|
224
|
+
while (!r.eof) {
|
|
225
|
+
const { field, wire } = r.tag();
|
|
226
|
+
if (field === 1) scope.name = r.string();
|
|
227
|
+
else if (field === 2) scope.version = r.string();
|
|
228
|
+
else if (field === 3) parseKeyValues(r.bytes(), attributes);
|
|
229
|
+
else r.skip(wire);
|
|
230
|
+
}
|
|
231
|
+
if (attributes.length) scope.attributes = attributes;
|
|
232
|
+
return scope;
|
|
233
|
+
}
|
|
234
|
+
function parseScopeSpans(buf) {
|
|
235
|
+
const r = new Reader(buf);
|
|
236
|
+
const out = {};
|
|
237
|
+
const spans = [];
|
|
238
|
+
while (!r.eof) {
|
|
239
|
+
const { field, wire } = r.tag();
|
|
240
|
+
if (field === 1) out.scope = parseScope(r.bytes());
|
|
241
|
+
else if (field === 2) spans.push(parseSpan(r.bytes()));
|
|
242
|
+
else r.skip(wire);
|
|
243
|
+
}
|
|
244
|
+
out.spans = spans;
|
|
245
|
+
return out;
|
|
246
|
+
}
|
|
247
|
+
function parseResource(buf) {
|
|
248
|
+
const attributes = [];
|
|
249
|
+
const r = new Reader(buf);
|
|
250
|
+
while (!r.eof) {
|
|
251
|
+
const { field, wire } = r.tag();
|
|
252
|
+
if (field === 1) parseKeyValues(r.bytes(), attributes);
|
|
253
|
+
else r.skip(wire);
|
|
254
|
+
}
|
|
255
|
+
return { attributes };
|
|
256
|
+
}
|
|
257
|
+
function parseResourceSpans(buf) {
|
|
258
|
+
const r = new Reader(buf);
|
|
259
|
+
const out = {};
|
|
260
|
+
const scopeSpans = [];
|
|
261
|
+
while (!r.eof) {
|
|
262
|
+
const { field, wire } = r.tag();
|
|
263
|
+
if (field === 1) out.resource = parseResource(r.bytes());
|
|
264
|
+
else if (field === 2) scopeSpans.push(parseScopeSpans(r.bytes()));
|
|
265
|
+
else r.skip(wire);
|
|
266
|
+
}
|
|
267
|
+
out.scopeSpans = scopeSpans;
|
|
268
|
+
return out;
|
|
269
|
+
}
|
|
270
|
+
function decodeProtobufTraces(body) {
|
|
271
|
+
const r = new Reader(body);
|
|
272
|
+
const resourceSpans = [];
|
|
273
|
+
while (!r.eof) {
|
|
274
|
+
const { field, wire } = r.tag();
|
|
275
|
+
if (field === 1) resourceSpans.push(parseResourceSpans(r.bytes()));
|
|
276
|
+
else r.skip(wire);
|
|
277
|
+
}
|
|
278
|
+
return { resourceSpans };
|
|
190
279
|
}
|
|
191
280
|
|
|
192
281
|
// src/server.ts
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/live.ts","../src/server.ts","../src/otlp/protobuf.ts","../src/storage/session-store.ts","../src/trace-buffer.ts","../src/render/tree.ts","../src/render/format.ts","../src/api.ts","../src/export.ts","../src/static-files.ts","../src/app.ts","../src/ui-dir.ts","../src/open-browser.ts","../src/sse.ts","../src/commands/open.ts","../src/commands/demo.ts","../../../libs/fixtures/src/otlp/builders.ts","../../../libs/fixtures/src/otlp/weather-happy-path.ts","../../../libs/fixtures/src/otlp/tool-error.ts","../../../libs/fixtures/src/otlp/diff-pair.ts","../../../libs/fixtures/src/otlp/openinference.ts","../../../libs/fixtures/src/otlp/vercel-ai-sdk.ts","../../../libs/fixtures/src/otlp/claude-code.ts","../../../libs/fixtures/src/index.ts"],"sourcesContent":["import { parseArgs } from 'node:util';\nimport { resolve } from 'node:path';\nimport { runLive } from './commands/live.js';\nimport { runOpen } from './commands/open.js';\nimport { runDemo } from './commands/demo.js';\n\nconst HELP = `tracebird — a local-first, time-travel debugger for AI agent runs.\n\nUsage:\n tracebird [live] Start the OTLP receiver + UI (default).\n tracebird demo Serve the UI with bundled sample runs (no agent needed).\n tracebird open <file.jsonl> Load a saved session and serve the UI.\n tracebird --help Show this help.\n\nOptions:\n --port <n> Port for the OTLP receiver / UI server (default 4318).\n --host <addr> Address to bind (default 127.0.0.1).\n --out <dir> Directory for captured sessions (default ./.tracebird).\n --no-open Do not open the browser on start.\n\nPoint your agent's OpenTelemetry exporter at the receiver:\n export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318\n`;\n\nasync function main(argv: string[]): Promise<void> {\n // Node's parseArgs has no built-in negation; handle --no-open ourselves.\n const noOpen = argv.includes('--no-open');\n const cleaned = argv.filter((a) => a !== '--no-open');\n\n const { values, positionals } = parseArgs({\n args: cleaned,\n allowPositionals: true,\n options: {\n port: { type: 'string' },\n host: { type: 'string' },\n out: { type: 'string' },\n help: { type: 'boolean', short: 'h' },\n },\n });\n\n if (values.help) {\n process.stdout.write(HELP);\n return;\n }\n\n const command = positionals[0] ?? 'live';\n const port = values.port ? Number(values.port) : 4318;\n const host = values.host ?? '127.0.0.1';\n const outDir = resolve(values.out ?? '.tracebird');\n const open = !noOpen;\n\n switch (command) {\n case 'live':\n await runLive({ port, host, outDir, open });\n break;\n case 'demo':\n await runDemo({ port, host, open });\n break;\n case 'open': {\n const file = positionals[1];\n if (!file) {\n process.stderr.write('Usage: tracebird open <file.jsonl>\\n');\n process.exitCode = 1;\n break;\n }\n await runOpen({ file, port, host, open });\n break;\n }\n case 'help':\n process.stdout.write(HELP);\n break;\n default:\n process.stderr.write(`Unknown command: ${command}\\n\\n${HELP}`);\n process.exitCode = 1;\n }\n}\n\nmain(process.argv.slice(2)).catch((err) => {\n process.stderr.write(`tracebird: ${(err as Error).message}\\n`);\n process.exitCode = 1;\n});\n","import { join } from 'node:path';\nimport { buildRun } from '@tracebird/core';\nimport { createServer, listen } from '../server.js';\nimport { SessionStore } from '../storage/session-store.js';\nimport { TraceBuffer } from '../trace-buffer.js';\nimport { renderRunTree } from '../render/tree.js';\nimport { createAppHandler } from '../app.js';\nimport { resolveUiDir } from '../ui-dir.js';\nimport { openBrowser } from '../open-browser.js';\nimport { SseHub } from '../sse.js';\n\nexport interface LiveOptions {\n port: number;\n host: string;\n outDir: string;\n open: boolean;\n}\n\n/**\n * `tracebird live` — start the OTLP receiver, reconstruct each completed trace,\n * print its tree, persist it, and serve the UI (which polls the JSON API).\n */\nexport async function runLive(options: LiveOptions): Promise<void> {\n const store = new SessionStore(join(options.outDir, `session-${Date.now()}.jsonl`));\n const sse = new SseHub();\n\n const buffer = new TraceBuffer({\n onComplete: (_traceId, spans) => {\n const run = buildRun(spans);\n store.addRun(run);\n process.stdout.write('\\n' + renderRunTree(run) + '\\n');\n sse.broadcast('run', { id: run.id });\n },\n });\n\n const server = createServer({\n onExport: (spans) => {\n buffer.add(spans);\n sse.broadcast('activity', { spans: spans.length });\n },\n extraHandler: createAppHandler({ store, live: true }, resolveUiDir(), sse),\n });\n\n const boundPort = await listen(server, options.port, options.host);\n const endpoint = `http://${options.host}:${boundPort}`;\n\n process.stdout.write(\n [\n '',\n ' tracebird — listening for OpenTelemetry traces',\n '',\n ` UI ${endpoint}`,\n ` OTLP endpoint ${endpoint}/v1/traces`,\n ` Session file ${store.filePath}`,\n '',\n ' Point your agent at this receiver:',\n ` export OTEL_EXPORTER_OTLP_ENDPOINT=${endpoint}`,\n '',\n ' Waiting for your first agent run… (Ctrl-C to stop)',\n '',\n ].join('\\n') + '\\n',\n );\n\n if (options.open) openBrowser(endpoint);\n\n await new Promise<void>((resolveShutdown) => {\n const shutdown = () => {\n process.stdout.write('\\n Stopping…\\n');\n buffer.flushAll();\n sse.close();\n server.close(() => {\n void store.close().then(() => resolveShutdown());\n });\n };\n process.once('SIGINT', shutdown);\n process.once('SIGTERM', shutdown);\n });\n}\n","import {\n createServer as createHttpServer,\n type IncomingMessage,\n type Server,\n type ServerResponse,\n} from 'node:http';\nimport { parseOtlp, type ExportTraceServiceRequest, type Span } from '@tracebird/core';\nimport { decodeProtobufTraces } from './otlp/protobuf.js';\n\n/** Called whenever a batch of spans is received and parsed. */\nexport type ExportHandler = (spans: Span[], raw: ExportTraceServiceRequest) => void | Promise<void>;\n\nexport interface ServerOptions {\n /** Invoked with the parsed spans for every accepted OTLP export. */\n onExport?: ExportHandler;\n /**\n * Optional extra request handler tried before the 404 fallback — used by the\n * UI/API layer in later stages. Return `true` if it handled the request.\n */\n extraHandler?: (req: IncomingMessage, res: ServerResponse) => boolean | Promise<boolean>;\n}\n\nconst MAX_BODY_BYTES = 50 * 1024 * 1024; // 50 MB — generous for batched exports.\n\nfunction readBody(req: IncomingMessage): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let size = 0;\n req.on('data', (chunk: Buffer) => {\n size += chunk.length;\n if (size > MAX_BODY_BYTES) {\n reject(new Error('payload too large'));\n req.destroy();\n return;\n }\n chunks.push(chunk);\n });\n req.on('end', () => resolve(Buffer.concat(chunks)));\n req.on('error', reject);\n });\n}\n\nfunction decodeExport(contentType: string, body: Buffer): ExportTraceServiceRequest {\n if (\n contentType.includes('application/x-protobuf') ||\n contentType.includes('application/protobuf')\n ) {\n return decodeProtobufTraces(body);\n }\n // Default to JSON (the OTLP/HTTP JSON content type, or anything unspecified).\n const text = body.toString('utf8').trim();\n return text ? (JSON.parse(text) as ExportTraceServiceRequest) : {};\n}\n\nfunction sendProtobuf(res: ServerResponse, status: number): void {\n // An empty ExportTraceServiceResponse encodes to zero bytes (full success).\n res.writeHead(status, { 'content-type': 'application/x-protobuf' });\n res.end();\n}\n\nfunction sendJson(res: ServerResponse, status: number, payload: unknown): void {\n res.writeHead(status, { 'content-type': 'application/json' });\n res.end(JSON.stringify(payload));\n}\n\nasync function handleTraces(\n req: IncomingMessage,\n res: ServerResponse,\n onExport?: ExportHandler,\n): Promise<void> {\n const contentType = req.headers['content-type'] ?? 'application/json';\n let body: Buffer;\n try {\n body = await readBody(req);\n } catch {\n sendJson(res, 413, { error: 'payload too large' });\n return;\n }\n\n let request: ExportTraceServiceRequest;\n try {\n request = decodeExport(contentType, body);\n } catch (err) {\n sendJson(res, 400, { error: `failed to decode OTLP payload: ${(err as Error).message}` });\n return;\n }\n\n const spans = parseOtlp(request);\n try {\n await onExport?.(spans, request);\n } catch (err) {\n sendJson(res, 500, { error: `export handler failed: ${(err as Error).message}` });\n return;\n }\n\n const isProtobuf =\n contentType.includes('application/x-protobuf') || contentType.includes('application/protobuf');\n if (isProtobuf) sendProtobuf(res, 200);\n else sendJson(res, 200, {});\n}\n\n/** Create the tracebird HTTP server (OTLP receiver + optional extra routes). */\nexport function createServer(options: ServerOptions = {}): Server {\n return createHttpServer((req, res) => {\n void (async () => {\n const url = (req.url ?? '/').split('?')[0];\n\n if (req.method === 'POST' && url === '/v1/traces') {\n await handleTraces(req, res, options.onExport);\n return;\n }\n\n if (req.method === 'GET' && (url === '/health' || url === '/healthz')) {\n sendJson(res, 200, { status: 'ok' });\n return;\n }\n\n if (options.extraHandler) {\n const handled = await options.extraHandler(req, res);\n if (handled) return;\n }\n\n sendJson(res, 404, { error: 'not found' });\n })().catch((err) => {\n if (!res.headersSent) sendJson(res, 500, { error: (err as Error).message });\n });\n });\n}\n\n/** Start a server and resolve once it is listening, with the bound port. */\nexport function listen(server: Server, port: number, host: string): Promise<number> {\n return new Promise((resolve, reject) => {\n server.once('error', reject);\n server.listen(port, host, () => {\n const addr = server.address();\n const boundPort = typeof addr === 'object' && addr ? addr.port : port;\n resolve(boundPort);\n });\n });\n}\n","import protobuf from 'protobufjs';\nimport type { ExportTraceServiceRequest } from '@tracebird/core';\n\n/**\n * Decode OTLP/HTTP protobuf trace payloads without a build-time codegen step.\n *\n * Most OpenTelemetry SDKs default to `http/protobuf`, so this is the path that\n * makes tracebird genuinely drop-in. We describe just the subset of the OTLP\n * trace schema we need as a protobufjs JSON descriptor, decode, then convert to\n * the exact same camelCase shape that `parseOtlp` consumes from OTLP/JSON\n * (hex trace/span ids, stringified nanos).\n */\n\nconst common = {\n AnyValue: {\n oneofs: {\n value: {\n oneof: [\n 'stringValue',\n 'boolValue',\n 'intValue',\n 'doubleValue',\n 'arrayValue',\n 'kvlistValue',\n 'bytesValue',\n ],\n },\n },\n fields: {\n stringValue: { type: 'string', id: 1 },\n boolValue: { type: 'bool', id: 2 },\n intValue: { type: 'int64', id: 3 },\n doubleValue: { type: 'double', id: 4 },\n arrayValue: { type: 'ArrayValue', id: 5 },\n kvlistValue: { type: 'KeyValueList', id: 6 },\n bytesValue: { type: 'bytes', id: 7 },\n },\n },\n ArrayValue: { fields: { values: { rule: 'repeated', type: 'AnyValue', id: 1 } } },\n KeyValueList: { fields: { values: { rule: 'repeated', type: 'KeyValue', id: 1 } } },\n KeyValue: {\n fields: { key: { type: 'string', id: 1 }, value: { type: 'AnyValue', id: 2 } },\n },\n InstrumentationScope: {\n fields: {\n name: { type: 'string', id: 1 },\n version: { type: 'string', id: 2 },\n attributes: { rule: 'repeated', type: 'KeyValue', id: 3 },\n },\n },\n};\n\nconst KV = 'opentelemetry.proto.common.v1.KeyValue';\n\nconst descriptor = {\n nested: {\n opentelemetry: {\n nested: {\n proto: {\n nested: {\n common: { nested: { v1: { nested: common } } },\n resource: {\n nested: {\n v1: {\n nested: {\n Resource: {\n fields: { attributes: { rule: 'repeated', type: KV, id: 1 } },\n },\n },\n },\n },\n },\n trace: {\n nested: {\n v1: {\n nested: {\n ResourceSpans: {\n fields: {\n resource: { type: 'opentelemetry.proto.resource.v1.Resource', id: 1 },\n scopeSpans: { rule: 'repeated', type: 'ScopeSpans', id: 2 },\n schemaUrl: { type: 'string', id: 3 },\n },\n },\n ScopeSpans: {\n fields: {\n scope: {\n type: 'opentelemetry.proto.common.v1.InstrumentationScope',\n id: 1,\n },\n spans: { rule: 'repeated', type: 'Span', id: 2 },\n schemaUrl: { type: 'string', id: 3 },\n },\n },\n Span: {\n fields: {\n traceId: { type: 'bytes', id: 1 },\n spanId: { type: 'bytes', id: 2 },\n traceState: { type: 'string', id: 3 },\n parentSpanId: { type: 'bytes', id: 4 },\n name: { type: 'string', id: 5 },\n kind: { type: 'int32', id: 6 },\n startTimeUnixNano: { type: 'fixed64', id: 7 },\n endTimeUnixNano: { type: 'fixed64', id: 8 },\n attributes: { rule: 'repeated', type: KV, id: 9 },\n events: { rule: 'repeated', type: 'Event', id: 11 },\n status: { type: 'Status', id: 15 },\n },\n nested: {\n Event: {\n fields: {\n timeUnixNano: { type: 'fixed64', id: 1 },\n name: { type: 'string', id: 2 },\n attributes: { rule: 'repeated', type: KV, id: 3 },\n },\n },\n },\n },\n Status: {\n fields: {\n message: { type: 'string', id: 2 },\n code: { type: 'int32', id: 3 },\n },\n },\n },\n },\n },\n },\n collector: {\n nested: {\n trace: {\n nested: {\n v1: {\n nested: {\n ExportTraceServiceRequest: {\n fields: {\n resourceSpans: {\n rule: 'repeated',\n type: 'opentelemetry.proto.trace.v1.ResourceSpans',\n id: 1,\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n};\n\nconst root = protobuf.Root.fromJSON(descriptor);\nconst RequestType = root.lookupType(\n 'opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest',\n);\n\nfunction hexToBytes(hex: string | undefined): Uint8Array {\n if (!hex) return new Uint8Array(0);\n const clean = hex.length % 2 === 0 ? hex : '0' + hex;\n const out = new Uint8Array(clean.length / 2);\n for (let i = 0; i < out.length; i++) {\n out[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);\n }\n return out;\n}\n\nfunction bytesToHex(bytes: unknown): string | undefined {\n if (!bytes) return undefined;\n const arr: number[] = Array.isArray(bytes)\n ? bytes\n : bytes instanceof Uint8Array\n ? Array.from(bytes)\n : [];\n if (arr.length === 0) return undefined;\n return arr.map((b) => (b & 0xff).toString(16).padStart(2, '0')).join('');\n}\n\ninterface RawSpan {\n traceId?: unknown;\n spanId?: unknown;\n parentSpanId?: unknown;\n [key: string]: unknown;\n}\n\n/** Decode an OTLP/protobuf body into the JSON `ExportTraceServiceRequest` shape. */\nexport function decodeProtobufTraces(body: Uint8Array): ExportTraceServiceRequest {\n const message = RequestType.decode(body);\n const obj = RequestType.toObject(message, {\n longs: String,\n enums: Number,\n bytes: Array,\n defaults: false,\n arrays: true,\n objects: true,\n }) as ExportTraceServiceRequest;\n\n // protobuf carries trace/span ids as bytes; OTLP/JSON (and parseOtlp) want hex.\n for (const rs of obj.resourceSpans ?? []) {\n for (const ss of rs.scopeSpans ?? []) {\n for (const span of (ss.spans ?? []) as RawSpan[]) {\n span.traceId = bytesToHex(span.traceId) ?? '';\n span.spanId = bytesToHex(span.spanId) ?? '';\n const parent = bytesToHex(span.parentSpanId);\n if (parent) span.parentSpanId = parent;\n else delete span.parentSpanId;\n }\n }\n }\n return obj;\n}\n\ninterface MutableSpan {\n traceId?: unknown;\n spanId?: unknown;\n parentSpanId?: unknown;\n}\n\n/**\n * Encode a JSON `ExportTraceServiceRequest` (hex ids, string nanos) back into\n * OTLP/protobuf bytes. The inverse of {@link decodeProtobufTraces}; used by\n * tests and the e2e harness to exercise the protobuf ingest path.\n */\nexport function encodeProtobufTraces(request: ExportTraceServiceRequest): Uint8Array {\n const clone = structuredClone(request) as ExportTraceServiceRequest;\n for (const rs of clone.resourceSpans ?? []) {\n for (const ss of rs.scopeSpans ?? []) {\n for (const span of (ss.spans ?? []) as MutableSpan[]) {\n span.traceId = hexToBytes(span.traceId as string | undefined);\n span.spanId = hexToBytes(span.spanId as string | undefined);\n if (span.parentSpanId) span.parentSpanId = hexToBytes(span.parentSpanId as string);\n else delete span.parentSpanId;\n }\n }\n }\n const message = RequestType.fromObject(clone as Record<string, unknown>);\n return RequestType.encode(message).finish();\n}\n","import { createWriteStream, mkdirSync, readFileSync, type WriteStream } from 'node:fs';\nimport { dirname } from 'node:path';\nimport {\n parseSession,\n runMatches,\n serializeRun,\n StatusCode,\n type Run,\n type TraceNode,\n} from '@tracebird/core';\n\nexport interface RunFilter {\n /** Deep text search across summary, prompts, completions, tool I/O. */\n query?: string;\n /** Restrict by status; `'all'` (default) keeps everything. */\n status?: 'all' | 'ok' | 'error' | 'unset';\n}\n\n/** Lightweight run summary for list views (no heavy prompt/completion payloads). */\nexport interface RunSummary {\n id: string;\n traceId: string;\n summary: string;\n startTimeUnixNano: string;\n durationMs: number;\n status: 'ok' | 'error' | 'unset';\n tokens: Run['tokens'];\n costUsd: number | null;\n service?: string;\n nodeCount: number;\n}\n\nfunction statusLabel(code: StatusCode): RunSummary['status'] {\n if (code === StatusCode.Error) return 'error';\n if (code === StatusCode.Ok) return 'ok';\n return 'unset';\n}\n\nfunction countNodes(node: TraceNode): number {\n return 1 + node.children.reduce((sum, child) => sum + countNodes(child), 0);\n}\n\n/**\n * Holds the runs for one session in memory and (optionally) appends them to a\n * `.jsonl` file. Backs both `live` capture (append mode) and `open` (read-only).\n */\nexport class SessionStore {\n private readonly runs: Run[] = [];\n private readonly byId = new Map<string, Run>();\n private stream?: WriteStream;\n readonly filePath?: string;\n\n constructor(filePath?: string) {\n if (filePath) {\n mkdirSync(dirname(filePath), { recursive: true });\n this.filePath = filePath;\n this.stream = createWriteStream(filePath, { flags: 'a' });\n }\n }\n\n /** Load an existing session file read-only (for `tracebird open`). */\n static load(filePath: string): SessionStore {\n const store = new SessionStore();\n const text = readFileSync(filePath, 'utf8');\n for (const run of parseSession(text)) store.addRun(run, { persist: false });\n return store;\n }\n\n addRun(run: Run, options: { persist?: boolean } = {}): void {\n this.runs.push(run);\n this.byId.set(run.id, run);\n if (options.persist !== false) this.stream?.write(serializeRun(run) + '\\n');\n }\n\n get(id: string): Run | undefined {\n return this.byId.get(id);\n }\n\n all(): Run[] {\n return this.runs;\n }\n\n /** Run summaries, newest first, optionally filtered by text and status. */\n list(filter: RunFilter = {}): RunSummary[] {\n const status = filter.status ?? 'all';\n const query = filter.query ?? '';\n return this.runs\n .filter((run) => status === 'all' || statusLabel(run.status.code) === status)\n .filter((run) => runMatches(run, query))\n .map((run) => ({\n id: run.id,\n traceId: run.traceId,\n summary: run.summary,\n startTimeUnixNano: run.startTimeUnixNano,\n durationMs: run.durationMs,\n status: statusLabel(run.status.code),\n tokens: run.tokens,\n costUsd: run.costUsd,\n ...(run.service ? { service: run.service } : {}),\n nodeCount: countNodes(run.root),\n }))\n .sort((a, b) => (a.startTimeUnixNano < b.startTimeUnixNano ? 1 : -1));\n }\n\n get size(): number {\n return this.runs.length;\n }\n\n async close(): Promise<void> {\n const stream = this.stream;\n if (!stream) return;\n await new Promise<void>((resolve, reject) => {\n stream.end((err?: Error | null) => (err ? reject(err) : resolve()));\n });\n }\n}\n","import type { Span } from '@tracebird/core';\n\nexport interface TraceBufferOptions {\n /** Flush a trace after this many ms with no new spans. Default 1500. */\n idleMs?: number;\n /** Called with all buffered spans for a trace once it goes idle. */\n onComplete: (traceId: string, spans: Span[]) => void;\n}\n\n/**\n * Buffers incoming spans per trace id and flushes a trace once it has been idle\n * for `idleMs`. OTLP gives us no explicit \"trace complete\" signal, so idle\n * detection is the pragmatic trigger; `flushAll` forces completion on shutdown.\n */\nexport class TraceBuffer {\n private readonly idleMs: number;\n private readonly onComplete: TraceBufferOptions['onComplete'];\n private readonly traces = new Map<string, { spans: Span[]; timer: NodeJS.Timeout }>();\n\n constructor(options: TraceBufferOptions) {\n this.idleMs = options.idleMs ?? 1500;\n this.onComplete = options.onComplete;\n }\n\n add(spans: Span[]): void {\n const grouped = new Map<string, Span[]>();\n for (const span of spans) {\n const list = grouped.get(span.traceId) ?? [];\n list.push(span);\n grouped.set(span.traceId, list);\n }\n for (const [traceId, group] of grouped) {\n const entry = this.traces.get(traceId);\n if (entry) {\n entry.spans.push(...group);\n clearTimeout(entry.timer);\n entry.timer = this.schedule(traceId);\n } else {\n this.traces.set(traceId, { spans: group, timer: this.schedule(traceId) });\n }\n }\n }\n\n private schedule(traceId: string): NodeJS.Timeout {\n const timer = setTimeout(() => this.flush(traceId), this.idleMs);\n // Don't keep the event loop alive solely for a pending flush.\n timer.unref?.();\n return timer;\n }\n\n /** Flush a single trace now, if buffered. */\n flush(traceId: string): void {\n const entry = this.traces.get(traceId);\n if (!entry) return;\n clearTimeout(entry.timer);\n this.traces.delete(traceId);\n this.onComplete(traceId, entry.spans);\n }\n\n /** Flush every buffered trace (e.g. on shutdown). */\n flushAll(): void {\n for (const traceId of [...this.traces.keys()]) this.flush(traceId);\n }\n\n get pending(): number {\n return this.traces.size;\n }\n}\n","import { StatusCode, type LlmCall, type Run, type ToolCall, type TraceNode } from '@tracebird/core';\nimport { formatCost, formatDuration, formatTokens } from './format.js';\n\n/** Render a reconstructed {@link Run} as an indented tree for the terminal. */\n\nconst ICON: Record<TraceNode['kind'], string> = {\n run: '⏺',\n agent: '◆',\n llm: '✦',\n tool: '⚙',\n step: '▫',\n};\n\nfunction metrics(node: TraceNode): string {\n const parts: string[] = [formatDuration(node.durationMs)];\n if (node.kind === 'llm') {\n const llm = node as LlmCall;\n const tok = formatTokens(llm.usage.total ?? llm.usage.input);\n if (tok) parts.push(tok);\n const cost = formatCost(llm.costUsd);\n if (cost) parts.push(cost);\n if (llm.model) parts.push(llm.model);\n }\n if (node.kind === 'tool' && (node as ToolCall).isError) parts.push('ERROR');\n return parts.join(' ');\n}\n\nfunction label(node: TraceNode): string {\n return `${ICON[node.kind]} ${node.name} ${metrics(node)}`;\n}\n\nfunction renderChildren(nodes: TraceNode[], prefix: string, lines: string[]): void {\n nodes.forEach((node, i) => {\n const last = i === nodes.length - 1;\n lines.push(`${prefix}${last ? '└─ ' : '├─ '}${label(node)}`);\n renderChildren(node.children, prefix + (last ? ' ' : '│ '), lines);\n });\n}\n\nexport function renderRunTree(run: Run): string {\n const header: string[] = [run.summary, formatDuration(run.durationMs)];\n const tok = formatTokens(run.tokens.total);\n if (tok) header.push(tok);\n const cost = formatCost(run.costUsd);\n if (cost) header.push(cost);\n if (run.status.code === StatusCode.Error) header.push('ERROR');\n\n const lines: string[] = [header.join(' · ')];\n renderChildren(run.root.children, '', lines);\n return lines.join('\\n');\n}\n","/** Compact formatters for terminal output. */\n\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms) || ms < 0) return '—';\n if (ms < 1000) return `${Math.round(ms)}ms`;\n const seconds = ms / 1000;\n if (seconds < 60) return `${seconds.toFixed(2).replace(/\\.?0+$/, '')}s`;\n const mins = Math.floor(seconds / 60);\n const rem = Math.round(seconds % 60);\n return `${mins}m ${rem}s`;\n}\n\nexport function formatTokens(tokens: number | undefined): string | undefined {\n return tokens == null ? undefined : `${tokens.toLocaleString('en-US')} tok`;\n}\n\nexport function formatCost(usd: number | null | undefined): string | undefined {\n if (usd == null) return undefined;\n if (usd === 0) return '$0';\n if (usd < 0.01) return `$${usd.toFixed(4)}`;\n return `$${usd.toFixed(2)}`;\n}\n","import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport { diffRuns, type Run } from '@tracebird/core';\nimport type { SessionStore } from './storage/session-store.js';\nimport { buildHtmlSnapshot, exportJsonl } from './export.js';\n\n/**\n * The JSON API the UI reads. Pure delegation to the {@link SessionStore} (which\n * delegates reconstruction/diff to `@tracebird/core`); no business logic here.\n *\n * GET /api/session → { live, filePath, count }\n * GET /api/runs → RunSummary[]\n * GET /api/runs/:id → Run\n */\n\nexport interface ApiContext {\n store: SessionStore;\n live: boolean;\n /** Directory of the built UI assets (needed for HTML snapshot export). */\n uiDir?: string;\n}\n\nfunction json(res: ServerResponse, status: number, payload: unknown): void {\n res.writeHead(status, { 'content-type': 'application/json', 'cache-control': 'no-store' });\n res.end(JSON.stringify(payload));\n}\n\n/** Handle an `/api/*` request. Returns false if the path isn't an API route. */\nexport function handleApi(ctx: ApiContext, req: IncomingMessage, res: ServerResponse): boolean {\n const url = (req.url ?? '/').split('?')[0];\n if (!url.startsWith('/api/')) return false;\n\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' });\n return true;\n }\n\n if (url === '/api/session') {\n json(res, 200, {\n live: ctx.live,\n filePath: ctx.store.filePath ?? null,\n count: ctx.store.size,\n });\n return true;\n }\n\n if (url === '/api/runs') {\n const params = new URL(req.url ?? '', 'http://localhost').searchParams;\n const query = params.get('q') ?? undefined;\n const statusParam = params.get('status');\n const status =\n statusParam === 'ok' || statusParam === 'error' || statusParam === 'unset'\n ? statusParam\n : 'all';\n json(res, 200, ctx.store.list({ query, status }));\n return true;\n }\n\n if (url === '/api/diff') {\n const params = new URL(req.url ?? '', 'http://localhost').searchParams;\n const aId = params.get('a');\n const bId = params.get('b');\n if (!aId || !bId) {\n json(res, 400, { error: 'diff requires ?a=<runId>&b=<runId>' });\n return true;\n }\n const a = ctx.store.get(aId);\n const b = ctx.store.get(bId);\n if (!a || !b) {\n json(res, 404, { error: `run not found: ${!a ? aId : bId}` });\n return true;\n }\n json(res, 200, diffRuns(a, b));\n return true;\n }\n\n if (url === '/api/export') {\n const params = new URL(req.url ?? '', 'http://localhost').searchParams;\n const id = params.get('id');\n const format = params.get('format') === 'jsonl' ? 'jsonl' : 'html';\n\n let runs: Run[];\n let name: string;\n if (id) {\n const run = ctx.store.get(id);\n if (!run) {\n json(res, 404, { error: `run not found: ${id}` });\n return true;\n }\n runs = [run];\n name = `tracebird-run-${run.traceId.slice(0, 8) || 'export'}`;\n } else {\n runs = ctx.store.all();\n name = 'tracebird-session';\n }\n\n if (format === 'jsonl') {\n res.writeHead(200, {\n 'content-type': 'application/x-ndjson; charset=utf-8',\n 'content-disposition': `attachment; filename=\"${name}.jsonl\"`,\n });\n res.end(exportJsonl(runs));\n return true;\n }\n\n if (!ctx.uiDir || !existsSync(join(ctx.uiDir, 'index.html'))) {\n json(res, 503, { error: 'UI assets not available for HTML export' });\n return true;\n }\n res.writeHead(200, {\n 'content-type': 'text/html; charset=utf-8',\n 'content-disposition': `attachment; filename=\"${name}.html\"`,\n });\n res.end(buildHtmlSnapshot(ctx.uiDir, runs));\n return true;\n }\n\n const match = /^\\/api\\/runs\\/([^/]+)$/.exec(url);\n if (match) {\n const id = decodeURIComponent(match[1]);\n const run = ctx.store.get(id);\n if (!run) json(res, 404, { error: `run not found: ${id}` });\n else json(res, 200, run);\n return true;\n }\n\n json(res, 404, { error: 'unknown api route' });\n return true;\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { serializeSession, type Run } from '@tracebird/core';\nimport { SessionStore } from './storage/session-store.js';\n\n/**\n * Shareable-run export. Two formats:\n * - `jsonl` — the run(s) as a session file (re-openable with `tracebird open`).\n * - `html` — a single self-contained page that inlines the UI bundle + the run\n * data, so a coworker can open it offline with no install.\n */\n\nexport function exportJsonl(runs: Run[]): string {\n return serializeSession(runs);\n}\n\nfunction inlineAssets(uiDir: string, html: string): string {\n const withJs = html.replace(\n /<script\\b[^>]*\\bsrc=\"(\\.?\\/?assets\\/[^\"]+\\.js)\"[^>]*><\\/script>/g,\n (_match, src: string) => {\n const code = readFileSync(join(uiDir, src.replace(/^\\.?\\//, '')), 'utf8').replace(\n /<\\/(script)/gi,\n '<\\\\/$1',\n );\n return `<script type=\"module\">${code}</script>`;\n },\n );\n return withJs.replace(\n /<link\\b[^>]*\\bhref=\"(\\.?\\/?assets\\/[^\"]+\\.css)\"[^>]*>/g,\n (_match, href: string) => {\n const css = readFileSync(join(uiDir, href.replace(/^\\.?\\//, '')), 'utf8');\n return `<style>${css}</style>`;\n },\n );\n}\n\n/** Produce a self-contained HTML snapshot of the given runs. */\nexport function buildHtmlSnapshot(uiDir: string, runs: Run[]): string {\n const store = new SessionStore();\n for (const run of runs) store.addRun(run, { persist: false });\n\n const snapshot = {\n session: { live: false, filePath: null, count: runs.length },\n runs: store.list(),\n runsById: Object.fromEntries(runs.map((r) => [r.id, r])),\n };\n // Escape `</` so the JSON can't break out of the <script> element.\n const json = JSON.stringify(snapshot).replace(/<\\//g, '<\\\\/');\n const inject = `<script>window.__TRACEBIRD_SNAPSHOT__=${json}</script>`;\n\n const html = inlineAssets(uiDir, readFileSync(join(uiDir, 'index.html'), 'utf8'));\n if (html.includes('<script type=\"module\">')) {\n return html.replace('<script type=\"module\">', `${inject}<script type=\"module\">`);\n }\n return html.replace('</head>', `${inject}</head>`);\n}\n","import { createReadStream, existsSync, statSync } from 'node:fs';\nimport { join, normalize, extname } from 'node:path';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'text/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.ico': 'image/x-icon',\n '.woff2': 'font/woff2',\n '.map': 'application/json; charset=utf-8',\n};\n\n/**\n * Serve the pre-built UI static assets from `rootDir`, with SPA fallback to\n * `index.html`. Returns false if `rootDir` doesn't exist (UI not bundled).\n */\nexport function serveStatic(rootDir: string, req: IncomingMessage, res: ServerResponse): boolean {\n if (!existsSync(rootDir)) return false;\n if (req.method !== 'GET' && req.method !== 'HEAD') return false;\n\n const urlPath = decodeURIComponent((req.url ?? '/').split('?')[0]);\n // Resolve within rootDir; reject path traversal.\n const rel = normalize(urlPath).replace(/^(\\.\\.[/\\\\])+/, '');\n let filePath = join(rootDir, rel);\n if (!filePath.startsWith(rootDir)) filePath = join(rootDir, 'index.html');\n\n if (!existsSync(filePath) || statSync(filePath).isDirectory()) {\n filePath = join(rootDir, 'index.html'); // SPA fallback\n }\n if (!existsSync(filePath)) return false;\n\n const type = MIME[extname(filePath)] ?? 'application/octet-stream';\n res.writeHead(200, { 'content-type': type });\n if (req.method === 'HEAD') {\n res.end();\n return true;\n }\n createReadStream(filePath).pipe(res);\n return true;\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport { handleApi, type ApiContext } from './api.js';\nimport { serveStatic } from './static-files.js';\nimport type { SseHub } from './sse.js';\n\n/**\n * Build the combined UI/API request handler passed to the server as its\n * `extraHandler`: the SSE stream and API routes first, then the static UI\n * (with SPA fallback).\n */\nexport function createAppHandler(ctx: ApiContext, uiDir: string, sse?: SseHub) {\n const apiCtx: ApiContext = { ...ctx, uiDir };\n return (req: IncomingMessage, res: ServerResponse): boolean => {\n const url = (req.url ?? '/').split('?')[0];\n if (sse && req.method === 'GET' && url === '/api/stream') {\n sse.handle(req, res);\n return true;\n }\n if (handleApi(apiCtx, req, res)) return true;\n if (serveStatic(uiDir, req, res)) return true;\n return false;\n };\n}\n","import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Locate the pre-built UI assets. In the published package they sit next to the\n * bundled `cli.js` at `dist/ui`; in the dev tree they're at `packages/ui/dist`.\n */\nexport function resolveUiDir(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(here, 'ui'), // dist/ui (published / built)\n join(here, '..', '..', 'ui', 'dist'), // packages/cli/dist → packages/ui/dist\n ];\n return candidates.find((dir) => existsSync(join(dir, 'index.html'))) ?? candidates[0];\n}\n","import { spawn } from 'node:child_process';\n\n/** Best-effort: open a URL in the user's default browser. Never throws. */\nexport function openBrowser(url: string): void {\n const platform = process.platform;\n const command = platform === 'darwin' ? 'open' : platform === 'win32' ? 'cmd' : 'xdg-open';\n const args = platform === 'win32' ? ['/c', 'start', '\"\"', url] : [url];\n try {\n const child = spawn(command, args, { stdio: 'ignore', detached: true });\n child.on('error', () => undefined);\n child.unref();\n } catch {\n // Headless environment, etc. — the URL is printed for the user anyway.\n }\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http';\n\n/**\n * A tiny Server-Sent-Events hub. The UI subscribes once to `GET /api/stream`\n * and is pushed `activity` (spans arriving) and `run` (a run completed) events,\n * so it updates instantly instead of polling.\n */\nexport class SseHub {\n private readonly clients = new Set<ServerResponse>();\n private heartbeat?: ReturnType<typeof setInterval>;\n\n /** Register a long-lived SSE connection. */\n handle(req: IncomingMessage, res: ServerResponse): void {\n res.writeHead(200, {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-cache, no-transform',\n connection: 'keep-alive',\n 'x-accel-buffering': 'no',\n });\n res.write('retry: 2000\\n\\n');\n this.clients.add(res);\n req.on('close', () => this.clients.delete(res));\n\n if (!this.heartbeat) {\n this.heartbeat = setInterval(() => this.write(':ping\\n\\n'), 15000);\n this.heartbeat.unref?.();\n }\n }\n\n /** Push a named event with a JSON payload to every connected client. */\n broadcast(event: string, data: unknown = {}): void {\n this.write(`event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`);\n }\n\n private write(text: string): void {\n for (const res of this.clients) {\n try {\n res.write(text);\n } catch {\n this.clients.delete(res);\n }\n }\n }\n\n get size(): number {\n return this.clients.size;\n }\n\n close(): void {\n if (this.heartbeat) clearInterval(this.heartbeat);\n for (const res of this.clients) {\n try {\n res.end();\n } catch {\n /* client already gone */\n }\n }\n this.clients.clear();\n }\n}\n","import { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { createServer, listen } from '../server.js';\nimport { SessionStore } from '../storage/session-store.js';\nimport { createAppHandler } from '../app.js';\nimport { resolveUiDir } from '../ui-dir.js';\nimport { openBrowser } from '../open-browser.js';\n\nexport interface OpenOptions {\n file: string;\n port: number;\n host: string;\n open: boolean;\n}\n\n/**\n * `tracebird open <file.jsonl>` — load a saved session and serve the UI with no\n * receiver. The \"drag a run to a coworker\" loop.\n */\nexport async function runOpen(options: OpenOptions): Promise<void> {\n const file = resolve(options.file);\n if (!existsSync(file)) {\n process.stderr.write(`tracebird: session file not found: ${file}\\n`);\n process.exitCode = 1;\n return;\n }\n\n let store: SessionStore;\n try {\n store = SessionStore.load(file);\n } catch (err) {\n process.stderr.write(`tracebird: failed to load session: ${(err as Error).message}\\n`);\n process.exitCode = 1;\n return;\n }\n\n const server = createServer({\n extraHandler: createAppHandler({ store, live: false }, resolveUiDir()),\n });\n\n const boundPort = await listen(server, options.port, options.host);\n const endpoint = `http://${options.host}:${boundPort}`;\n\n process.stdout.write(\n [\n '',\n ` tracebird — serving ${store.size} run(s) from`,\n ` ${file}`,\n '',\n ` UI ${endpoint}`,\n '',\n ' (Ctrl-C to stop)',\n '',\n ].join('\\n') + '\\n',\n );\n\n if (options.open) openBrowser(endpoint);\n\n await new Promise<void>((resolveShutdown) => {\n const shutdown = () => {\n process.stdout.write('\\n Stopping…\\n');\n server.close(() => resolveShutdown());\n };\n process.once('SIGINT', shutdown);\n process.once('SIGTERM', shutdown);\n });\n}\n","import { buildRuns, parseOtlp } from '@tracebird/core';\nimport { otlpFixtures } from '@tracebird/fixtures';\nimport { createServer, listen } from '../server.js';\nimport { SessionStore } from '../storage/session-store.js';\nimport { createAppHandler } from '../app.js';\nimport { resolveUiDir } from '../ui-dir.js';\nimport { openBrowser } from '../open-browser.js';\n\nexport interface DemoOptions {\n port: number;\n host: string;\n open: boolean;\n}\n\n/**\n * `tracebird demo` — serve the UI pre-loaded with the bundled sample runs\n * (a multi-tool run, a tool error, and a diff pair) so you can explore the\n * inspector, scrubber, and diff without wiring up a real agent.\n */\nexport async function runDemo(options: DemoOptions): Promise<void> {\n const store = new SessionStore();\n for (const payload of Object.values(otlpFixtures)) {\n for (const run of buildRuns(parseOtlp(payload))) store.addRun(run, { persist: false });\n }\n\n const server = createServer({\n extraHandler: createAppHandler({ store, live: false }, resolveUiDir()),\n });\n const boundPort = await listen(server, options.port, options.host);\n const endpoint = `http://${options.host}:${boundPort}`;\n\n process.stdout.write(\n [\n '',\n ` tracebird — demo mode, ${store.size} sample run(s) loaded`,\n '',\n ` UI ${endpoint}`,\n '',\n ' Try the Diff tab (the two support-triage runs differ on one decision),',\n ' and drag the scrubber to time-travel through a run.',\n '',\n ' (Ctrl-C to stop)',\n '',\n ].join('\\n') + '\\n',\n );\n\n if (options.open) openBrowser(endpoint);\n\n await new Promise<void>((resolveShutdown) => {\n const shutdown = () => {\n process.stdout.write('\\n Stopping…\\n');\n server.close(() => resolveShutdown());\n };\n process.once('SIGINT', shutdown);\n process.once('SIGTERM', shutdown);\n });\n}\n","/**\n * Tiny builders for assembling OTLP/HTTP JSON trace payloads by hand.\n *\n * Intentionally self-contained — fixtures import nothing internal so the\n * project graph stays acyclic (core's tests depend on fixtures, not vice-versa).\n * The emitted shape matches the OTLP/JSON protobuf mapping that\n * `@tracebird/core`'s `parseOtlp` consumes.\n */\n\nexport interface AnyValue {\n stringValue?: string;\n boolValue?: boolean;\n intValue?: string;\n doubleValue?: number;\n arrayValue?: { values: AnyValue[] };\n}\n\nexport interface KeyValue {\n key: string;\n value: AnyValue;\n}\n\nexport type AttrInput = string | number | boolean;\n\nfunction toAnyValue(v: AttrInput): AnyValue {\n if (typeof v === 'string') return { stringValue: v };\n if (typeof v === 'boolean') return { boolValue: v };\n return Number.isInteger(v) ? { intValue: String(v) } : { doubleValue: v };\n}\n\n/** Convert a flat record into an OTLP `KeyValue[]`. */\nexport function attrs(record: Record<string, AttrInput>): KeyValue[] {\n return Object.entries(record).map(([key, v]) => ({ key, value: toAnyValue(v) }));\n}\n\nexport interface SpanInput {\n traceId: string;\n spanId: string;\n parentSpanId?: string;\n name: string;\n kind?: number;\n startTimeUnixNano: string;\n endTimeUnixNano: string;\n attributes?: Record<string, AttrInput>;\n /** OTLP status code: 0 unset, 1 ok, 2 error. */\n statusCode?: number;\n statusMessage?: string;\n}\n\nexport interface OtlpSpanJson {\n traceId: string;\n spanId: string;\n parentSpanId?: string;\n name: string;\n kind: number;\n startTimeUnixNano: string;\n endTimeUnixNano: string;\n attributes: KeyValue[];\n status: { code: number; message?: string };\n}\n\nexport function span(input: SpanInput): OtlpSpanJson {\n return {\n traceId: input.traceId,\n spanId: input.spanId,\n ...(input.parentSpanId ? { parentSpanId: input.parentSpanId } : {}),\n name: input.name,\n kind: input.kind ?? 1,\n startTimeUnixNano: input.startTimeUnixNano,\n endTimeUnixNano: input.endTimeUnixNano,\n attributes: attrs(input.attributes ?? {}),\n status: {\n code: input.statusCode ?? 0,\n ...(input.statusMessage ? { message: input.statusMessage } : {}),\n },\n };\n}\n\nexport interface TraceRequestInput {\n serviceName: string;\n scopeName: string;\n scopeVersion?: string;\n spans: OtlpSpanJson[];\n}\n\n/** Wrap spans into a complete `ExportTraceServiceRequest` JSON payload. */\nexport function traceRequest(input: TraceRequestInput) {\n return {\n resourceSpans: [\n {\n resource: {\n attributes: attrs({ 'service.name': input.serviceName }),\n },\n scopeSpans: [\n {\n scope: {\n name: input.scopeName,\n ...(input.scopeVersion ? { version: input.scopeVersion } : {}),\n },\n spans: input.spans,\n },\n ],\n },\n ],\n };\n}\n\n/** Nanosecond timestamp helper: base epoch-nanos + a millisecond offset. */\nexport function at(baseNano: bigint, offsetMs: number): string {\n return (baseNano + BigInt(offsetMs) * 1_000_000n).toString();\n}\n","import { at, span, traceRequest } from './builders.js';\n\n/**\n * Happy-path, multi-tool agent run: a weather assistant that makes one planning\n * LLM call, fans out to two tools (get_weather, get_forecast), then makes a\n * final LLM call to compose the answer. Uses the OpenLLMetry-style buffered\n * prompt/completion attributes (`gen_ai.prompt.N.*` / `gen_ai.completion.N.*`).\n */\n\nconst BASE = 1733000000000000000n;\nconst TRACE = '0af7651916cd43dd8448eb211c80319c';\n\nconst ROOT = '1111111111111111';\nconst LLM1 = '2222222222222222';\nconst TOOL1 = '3333333333333333';\nconst TOOL2 = '4444444444444444';\nconst LLM2 = '5555555555555555';\n\nexport const weatherHappyPath = traceRequest({\n serviceName: 'weather-assistant',\n scopeName: 'opentelemetry.instrumentation.openai',\n scopeVersion: '0.30.0',\n spans: [\n span({\n traceId: TRACE,\n spanId: ROOT,\n name: 'invoke_agent weather-assistant',\n startTimeUnixNano: at(BASE, 0),\n endTimeUnixNano: at(BASE, 1300),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'invoke_agent',\n 'gen_ai.agent.name': 'weather-assistant',\n 'gen_ai.system': 'openai',\n },\n }),\n span({\n traceId: TRACE,\n spanId: LLM1,\n parentSpanId: ROOT,\n name: 'chat gpt-4o',\n startTimeUnixNano: at(BASE, 10),\n endTimeUnixNano: at(BASE, 520),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'chat',\n 'gen_ai.system': 'openai',\n 'gen_ai.request.model': 'gpt-4o',\n 'gen_ai.response.model': 'gpt-4o-2024-08-06',\n 'gen_ai.request.temperature': 0.7,\n 'gen_ai.usage.input_tokens': 58,\n 'gen_ai.usage.output_tokens': 34,\n 'gen_ai.prompt.0.role': 'system',\n 'gen_ai.prompt.0.content':\n 'You are a helpful weather assistant. Use tools to look up live data before answering.',\n 'gen_ai.prompt.1.role': 'user',\n 'gen_ai.prompt.1.content': 'What should I wear in Paris today?',\n 'gen_ai.completion.0.role': 'assistant',\n 'gen_ai.completion.0.content': '',\n 'gen_ai.completion.0.tool_calls.0.id': 'call_weather',\n 'gen_ai.completion.0.tool_calls.0.name': 'get_weather',\n 'gen_ai.completion.0.tool_calls.0.arguments': '{\"location\":\"Paris\"}',\n 'gen_ai.completion.0.tool_calls.1.id': 'call_forecast',\n 'gen_ai.completion.0.tool_calls.1.name': 'get_forecast',\n 'gen_ai.completion.0.tool_calls.1.arguments': '{\"location\":\"Paris\",\"hours\":12}',\n },\n }),\n span({\n traceId: TRACE,\n spanId: TOOL1,\n parentSpanId: ROOT,\n name: 'execute_tool get_weather',\n startTimeUnixNano: at(BASE, 530),\n endTimeUnixNano: at(BASE, 548),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'execute_tool',\n 'gen_ai.tool.name': 'get_weather',\n 'gen_ai.tool.call.id': 'call_weather',\n 'gen_ai.tool.call.arguments': '{\"location\":\"Paris\"}',\n 'gen_ai.tool.call.result': '{\"tempC\":18,\"condition\":\"sunny\",\"humidity\":0.41}',\n },\n }),\n span({\n traceId: TRACE,\n spanId: TOOL2,\n parentSpanId: ROOT,\n name: 'execute_tool get_forecast',\n startTimeUnixNano: at(BASE, 532),\n endTimeUnixNano: at(BASE, 560),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'execute_tool',\n 'gen_ai.tool.name': 'get_forecast',\n 'gen_ai.tool.call.id': 'call_forecast',\n 'gen_ai.tool.call.arguments': '{\"location\":\"Paris\",\"hours\":12}',\n 'gen_ai.tool.call.result': '{\"highC\":21,\"lowC\":12,\"rain\":false}',\n },\n }),\n span({\n traceId: TRACE,\n spanId: LLM2,\n parentSpanId: ROOT,\n name: 'chat gpt-4o',\n startTimeUnixNano: at(BASE, 580),\n endTimeUnixNano: at(BASE, 1290),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'chat',\n 'gen_ai.system': 'openai',\n 'gen_ai.request.model': 'gpt-4o',\n 'gen_ai.response.model': 'gpt-4o-2024-08-06',\n 'gen_ai.request.temperature': 0.7,\n 'gen_ai.usage.input_tokens': 140,\n 'gen_ai.usage.output_tokens': 42,\n 'gen_ai.prompt.0.role': 'system',\n 'gen_ai.prompt.0.content':\n 'You are a helpful weather assistant. Use tools to look up live data before answering.',\n 'gen_ai.prompt.1.role': 'user',\n 'gen_ai.prompt.1.content': 'What should I wear in Paris today?',\n 'gen_ai.prompt.2.role': 'tool',\n 'gen_ai.prompt.2.content': '{\"tempC\":18,\"condition\":\"sunny\",\"humidity\":0.41}',\n 'gen_ai.prompt.3.role': 'tool',\n 'gen_ai.prompt.3.content': '{\"highC\":21,\"lowC\":12,\"rain\":false}',\n 'gen_ai.completion.0.role': 'assistant',\n 'gen_ai.completion.0.content':\n \"It's 18°C and sunny in Paris, with a high of 21°C and no rain expected. \" +\n \"A light jacket or long sleeves will be perfect — you won't need an umbrella.\",\n },\n }),\n ],\n});\n","import { at, span, traceRequest } from './builders.js';\n\n/**\n * A run where a tool call fails: the model asks for weather in a place the tool\n * can't resolve, the `execute_tool` span carries an ERROR status, and the agent\n * recovers with an apology. Exercises error propagation in the tree.\n */\n\nconst BASE = 1733000100000000000n;\nconst TRACE = 'b2c3d4e5f60718293a4b5c6d7e8f9012';\n\nconst ROOT = 'aa00000000000001';\nconst LLM1 = 'aa00000000000002';\nconst TOOL1 = 'aa00000000000003';\nconst LLM2 = 'aa00000000000004';\n\nexport const toolError = traceRequest({\n serviceName: 'weather-assistant',\n scopeName: 'opentelemetry.instrumentation.openai',\n scopeVersion: '0.30.0',\n spans: [\n span({\n traceId: TRACE,\n spanId: ROOT,\n name: 'invoke_agent weather-assistant',\n startTimeUnixNano: at(BASE, 0),\n endTimeUnixNano: at(BASE, 900),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'invoke_agent',\n 'gen_ai.agent.name': 'weather-assistant',\n 'gen_ai.system': 'openai',\n },\n }),\n span({\n traceId: TRACE,\n spanId: LLM1,\n parentSpanId: ROOT,\n name: 'chat gpt-4o',\n startTimeUnixNano: at(BASE, 8),\n endTimeUnixNano: at(BASE, 410),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'chat',\n 'gen_ai.system': 'openai',\n 'gen_ai.request.model': 'gpt-4o',\n 'gen_ai.response.model': 'gpt-4o-2024-08-06',\n 'gen_ai.usage.input_tokens': 52,\n 'gen_ai.usage.output_tokens': 16,\n 'gen_ai.prompt.0.role': 'user',\n 'gen_ai.prompt.0.content': \"What's the weather in Atlantis?\",\n 'gen_ai.completion.0.role': 'assistant',\n 'gen_ai.completion.0.content': '',\n 'gen_ai.completion.0.tool_calls.0.id': 'call_weather',\n 'gen_ai.completion.0.tool_calls.0.name': 'get_weather',\n 'gen_ai.completion.0.tool_calls.0.arguments': '{\"location\":\"Atlantis\"}',\n },\n }),\n span({\n traceId: TRACE,\n spanId: TOOL1,\n parentSpanId: ROOT,\n name: 'execute_tool get_weather',\n startTimeUnixNano: at(BASE, 420),\n endTimeUnixNano: at(BASE, 438),\n statusCode: 2,\n statusMessage: 'UnknownLocationError: no such location \"Atlantis\"',\n attributes: {\n 'gen_ai.operation.name': 'execute_tool',\n 'gen_ai.tool.name': 'get_weather',\n 'gen_ai.tool.call.id': 'call_weather',\n 'gen_ai.tool.call.arguments': '{\"location\":\"Atlantis\"}',\n 'error.type': 'UnknownLocationError',\n 'gen_ai.tool.call.result': '{\"error\":\"no such location \\\\\"Atlantis\\\\\"\"}',\n },\n }),\n span({\n traceId: TRACE,\n spanId: LLM2,\n parentSpanId: ROOT,\n name: 'chat gpt-4o',\n startTimeUnixNano: at(BASE, 450),\n endTimeUnixNano: at(BASE, 890),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'chat',\n 'gen_ai.system': 'openai',\n 'gen_ai.request.model': 'gpt-4o',\n 'gen_ai.response.model': 'gpt-4o-2024-08-06',\n 'gen_ai.usage.input_tokens': 88,\n 'gen_ai.usage.output_tokens': 28,\n 'gen_ai.prompt.0.role': 'user',\n 'gen_ai.prompt.0.content': \"What's the weather in Atlantis?\",\n 'gen_ai.prompt.1.role': 'tool',\n 'gen_ai.prompt.1.content': '{\"error\":\"no such location \\\\\"Atlantis\\\\\"\"}',\n 'gen_ai.completion.0.role': 'assistant',\n 'gen_ai.completion.0.content':\n 'I couldn\\'t find a place called \"Atlantis\" to look up the weather. Could you double-check the spelling or give me a nearby city?',\n },\n }),\n ],\n});\n","import { at, span, traceRequest } from './builders.js';\n\n/**\n * Two near-identical triage runs over the same support ticket that diverge on a\n * single decision: run A (gpt-4o) assigns priority P1; run B (gpt-4o-mini)\n * assigns P2. Same prompt, same shape — ideal for the diff demo.\n */\n\nconst TICKET =\n 'Customer reports the checkout page returns a 500 error intermittently on mobile Safari. ' +\n 'They have tried twice. No charge was made.';\n\nconst SYSTEM =\n 'You are a support triage agent. Read the ticket and assign a priority from P1 (urgent) to P4 (low).';\n\nfunction triageRun(opts: {\n base: bigint;\n trace: string;\n rootId: string;\n llmId: string;\n model: string;\n responseModel: string;\n outputTokens: number;\n endMs: number;\n completion: string;\n}) {\n return traceRequest({\n serviceName: 'support-triage',\n scopeName: 'opentelemetry.instrumentation.openai',\n scopeVersion: '0.30.0',\n spans: [\n span({\n traceId: opts.trace,\n spanId: opts.rootId,\n name: 'invoke_agent support-triage',\n startTimeUnixNano: at(opts.base, 0),\n endTimeUnixNano: at(opts.base, opts.endMs),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'invoke_agent',\n 'gen_ai.agent.name': 'support-triage',\n 'gen_ai.system': 'openai',\n },\n }),\n span({\n traceId: opts.trace,\n spanId: opts.llmId,\n parentSpanId: opts.rootId,\n name: `chat ${opts.model}`,\n startTimeUnixNano: at(opts.base, 6),\n endTimeUnixNano: at(opts.base, opts.endMs - 4),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'chat',\n 'gen_ai.system': 'openai',\n 'gen_ai.request.model': opts.model,\n 'gen_ai.response.model': opts.responseModel,\n 'gen_ai.request.temperature': 0.2,\n 'gen_ai.usage.input_tokens': 96,\n 'gen_ai.usage.output_tokens': opts.outputTokens,\n 'gen_ai.prompt.0.role': 'system',\n 'gen_ai.prompt.0.content': SYSTEM,\n 'gen_ai.prompt.1.role': 'user',\n 'gen_ai.prompt.1.content': TICKET,\n 'gen_ai.completion.0.role': 'assistant',\n 'gen_ai.completion.0.content': opts.completion,\n },\n }),\n ],\n });\n}\n\nexport const diffPairA = triageRun({\n base: 1733000200000000000n,\n trace: 'c1000000000000000000000000000a01',\n rootId: 'c100000000000a01',\n llmId: 'c100000000000a02',\n model: 'gpt-4o',\n responseModel: 'gpt-4o-2024-08-06',\n outputTokens: 54,\n endMs: 640,\n completion:\n 'Priority: P1. A 500 error at checkout blocks revenue and affects all mobile Safari ' +\n 'users intermittently. Escalate to the payments team immediately.',\n});\n\nexport const diffPairB = triageRun({\n base: 1733000300000000000n,\n trace: 'c2000000000000000000000000000b01',\n rootId: 'c200000000000b01',\n llmId: 'c200000000000b02',\n model: 'gpt-4o-mini',\n responseModel: 'gpt-4o-mini-2024-07-18',\n outputTokens: 48,\n endMs: 410,\n completion:\n 'Priority: P2. Checkout returns a 500 on mobile Safari intermittently, but no charge ' +\n 'was made and a retry path exists. Route to the web team for investigation.',\n});\n","import { at, span, traceRequest } from './builders.js';\n\n/**\n * OpenInference (Arize Phoenix) dialect: `openinference.span.kind` + `llm.*` /\n * `tool.*` / `input.value` attributes. A small agent that calls one tool.\n */\n\nconst BASE = 1733000400000000000n;\nconst TRACE = 'd1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1';\nconst ROOT = 'd1000000000000a1';\nconst LLM = 'd1000000000000a2';\nconst TOOL = 'd1000000000000a3';\n\nexport const openinferenceAgent = traceRequest({\n serviceName: 'docs-assistant',\n scopeName: 'openinference.instrumentation.openai',\n scopeVersion: '0.1.0',\n spans: [\n span({\n traceId: TRACE,\n spanId: ROOT,\n name: 'agent',\n startTimeUnixNano: at(BASE, 0),\n endTimeUnixNano: at(BASE, 900),\n statusCode: 1,\n attributes: { 'openinference.span.kind': 'AGENT' },\n }),\n span({\n traceId: TRACE,\n spanId: LLM,\n parentSpanId: ROOT,\n name: 'ChatCompletion',\n startTimeUnixNano: at(BASE, 10),\n endTimeUnixNano: at(BASE, 460),\n statusCode: 1,\n attributes: {\n 'openinference.span.kind': 'LLM',\n 'llm.model_name': 'gpt-4o',\n 'llm.provider': 'openai',\n 'llm.token_count.prompt': 42,\n 'llm.token_count.completion': 18,\n 'llm.input_messages.0.message.role': 'system',\n 'llm.input_messages.0.message.content': 'You answer questions about the docs.',\n 'llm.input_messages.1.message.role': 'user',\n 'llm.input_messages.1.message.content': 'How do I enable telemetry?',\n 'llm.output_messages.0.message.role': 'assistant',\n 'llm.output_messages.0.message.content': '',\n 'llm.output_messages.0.message.tool_calls.0.tool_call.function.name': 'search_docs',\n 'llm.output_messages.0.message.tool_calls.0.tool_call.function.arguments':\n '{\"query\":\"enable telemetry\"}',\n },\n }),\n span({\n traceId: TRACE,\n spanId: TOOL,\n parentSpanId: ROOT,\n name: 'search_docs',\n startTimeUnixNano: at(BASE, 470),\n endTimeUnixNano: at(BASE, 500),\n statusCode: 1,\n attributes: {\n 'openinference.span.kind': 'TOOL',\n 'tool.name': 'search_docs',\n 'input.value': '{\"query\":\"enable telemetry\"}',\n 'output.value': '{\"hits\":[\"Set OTEL_EXPORTER_OTLP_ENDPOINT=…\"]}',\n },\n }),\n ],\n});\n","import { at, span, traceRequest } from './builders.js';\n\n/**\n * Vercel AI SDK dialect: `ai.generateText` wrapper, an inner `.doGenerate`\n * model call, and an `ai.toolCall` span — the shape emitted by\n * `experimental_telemetry`.\n */\n\nconst BASE = 1733000500000000000n;\nconst TRACE = 'e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1';\nconst ROOT = 'e1000000000000b1';\nconst GEN = 'e1000000000000b2';\nconst TOOL = 'e1000000000000b3';\n\nexport const vercelAiSdk = traceRequest({\n serviceName: 'ai-sdk-app',\n scopeName: 'ai',\n scopeVersion: '4.0.0',\n spans: [\n span({\n traceId: TRACE,\n spanId: ROOT,\n name: 'ai.generateText',\n startTimeUnixNano: at(BASE, 0),\n endTimeUnixNano: at(BASE, 1100),\n statusCode: 1,\n attributes: {\n 'ai.model.id': 'gpt-4o',\n 'ai.model.provider': 'openai.chat',\n 'ai.usage.promptTokens': 64,\n 'ai.usage.completionTokens': 30,\n },\n }),\n span({\n traceId: TRACE,\n spanId: GEN,\n parentSpanId: ROOT,\n name: 'ai.generateText.doGenerate',\n startTimeUnixNano: at(BASE, 20),\n endTimeUnixNano: at(BASE, 540),\n statusCode: 1,\n attributes: {\n 'ai.model.id': 'gpt-4o',\n 'ai.model.provider': 'openai.chat',\n 'ai.usage.promptTokens': 64,\n 'ai.usage.completionTokens': 30,\n 'ai.prompt.messages':\n '[{\"role\":\"user\",\"content\":\"What is the weather in San Francisco?\"}]',\n 'ai.response.text': 'Let me check the current conditions in San Francisco.',\n },\n }),\n span({\n traceId: TRACE,\n spanId: TOOL,\n parentSpanId: ROOT,\n name: 'ai.toolCall',\n startTimeUnixNano: at(BASE, 560),\n endTimeUnixNano: at(BASE, 600),\n statusCode: 1,\n attributes: {\n 'ai.toolCall.name': 'getWeather',\n 'ai.toolCall.args': '{\"city\":\"San Francisco\"}',\n 'ai.toolCall.result': '{\"tempC\":17,\"condition\":\"foggy\"}',\n },\n }),\n ],\n});\n","import { at, span, traceRequest } from './builders.js';\n\n/**\n * Claude Code (CLI) enhanced-telemetry dialect: `claude_code.interaction`,\n * `claude_code.llm_request`, `claude_code.tool` spans with bare token counts\n * and `tool_name` / `user_prompt` attributes.\n */\n\nconst BASE = 1733000600000000000n;\nconst TRACE = 'f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1';\nconst ROOT = 'f1000000000000c1';\nconst LLM = 'f1000000000000c2';\nconst TOOL = 'f1000000000000c3';\n\nexport const claudeCodeSession = traceRequest({\n serviceName: 'claude-code',\n scopeName: 'com.anthropic.claude_code',\n scopeVersion: '2.0.0',\n spans: [\n span({\n traceId: TRACE,\n spanId: ROOT,\n name: 'claude_code.interaction',\n startTimeUnixNano: at(BASE, 0),\n endTimeUnixNano: at(BASE, 4200),\n statusCode: 1,\n attributes: {\n 'user_prompt': 'Add a --json flag to the parser CLI',\n 'interaction.sequence': 1,\n },\n }),\n span({\n traceId: TRACE,\n spanId: LLM,\n parentSpanId: ROOT,\n name: 'claude_code.llm_request',\n startTimeUnixNano: at(BASE, 30),\n endTimeUnixNano: at(BASE, 2600),\n statusCode: 1,\n attributes: {\n 'gen_ai.system': 'anthropic',\n 'gen_ai.request.model': 'claude-sonnet-4',\n 'input_tokens': 1840,\n 'output_tokens': 420,\n 'cache_read_tokens': 12000,\n 'gen_ai.response.finish_reasons': 'tool_use',\n 'user_prompt': 'Add a --json flag to the parser CLI',\n },\n }),\n span({\n traceId: TRACE,\n spanId: TOOL,\n parentSpanId: ROOT,\n name: 'claude_code.tool',\n startTimeUnixNano: at(BASE, 2650),\n endTimeUnixNano: at(BASE, 2710),\n statusCode: 1,\n attributes: {\n 'tool_name': 'Edit',\n 'file_path': 'packages/cli/src/parser.ts',\n 'tool_output': 'Applied 1 edit to packages/cli/src/parser.ts',\n },\n }),\n ],\n});\n","/**\n * @tracebird/fixtures — sample OTLP payloads and recorded sessions used by\n * core/cli tests and as demo data for `tracebird open`.\n */\n\nexport * from './otlp/builders.js';\nexport { weatherHappyPath } from './otlp/weather-happy-path.js';\nexport { toolError } from './otlp/tool-error.js';\nexport { diffPairA, diffPairB } from './otlp/diff-pair.js';\nexport { openinferenceAgent } from './otlp/openinference.js';\nexport { vercelAiSdk } from './otlp/vercel-ai-sdk.js';\nexport { claudeCodeSession } from './otlp/claude-code.js';\n\nimport { weatherHappyPath } from './otlp/weather-happy-path.js';\nimport { toolError } from './otlp/tool-error.js';\nimport { diffPairA, diffPairB } from './otlp/diff-pair.js';\nimport { openinferenceAgent } from './otlp/openinference.js';\nimport { vercelAiSdk } from './otlp/vercel-ai-sdk.js';\nimport { claudeCodeSession } from './otlp/claude-code.js';\n\n/** All OTLP request fixtures, keyed by a short name. */\nexport const otlpFixtures = {\n weatherHappyPath,\n toolError,\n diffPairA,\n diffPairB,\n openinferenceAgent,\n vercelAiSdk,\n claudeCodeSession,\n} as const;\n\nexport type OtlpFixtureName = keyof typeof otlpFixtures;\n"],"mappings":"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","names":["resolve","join","span","resolve","resolve","span","StatusCode","StatusCode","join","readFileSync","readFileSync","json","join","existsSync","join","existsSync","dirname","join","join","existsSync","existsSync","parseOtlp","BASE","TRACE","ROOT","LLM1","TOOL1","LLM2","BASE","TRACE","ROOT","BASE","TRACE","ROOT","TOOL","BASE","TRACE","ROOT","LLM","TOOL","parseOtlp","resolve"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/live.ts","../src/server.ts","../src/otlp/protobuf.ts","../src/storage/session-store.ts","../src/trace-buffer.ts","../src/render/tree.ts","../src/render/format.ts","../src/api.ts","../src/export.ts","../src/static-files.ts","../src/app.ts","../src/ui-dir.ts","../src/open-browser.ts","../src/sse.ts","../src/commands/open.ts","../src/commands/demo.ts","../../../libs/fixtures/src/otlp/builders.ts","../../../libs/fixtures/src/otlp/weather-happy-path.ts","../../../libs/fixtures/src/otlp/tool-error.ts","../../../libs/fixtures/src/otlp/diff-pair.ts","../../../libs/fixtures/src/otlp/openinference.ts","../../../libs/fixtures/src/otlp/vercel-ai-sdk.ts","../../../libs/fixtures/src/otlp/claude-code.ts","../../../libs/fixtures/src/index.ts"],"sourcesContent":["import { parseArgs } from 'node:util';\nimport { resolve } from 'node:path';\nimport { runLive } from './commands/live.js';\nimport { runOpen } from './commands/open.js';\nimport { runDemo } from './commands/demo.js';\n\nconst HELP = `tracebird — a local-first, time-travel debugger for AI agent runs.\n\nUsage:\n tracebird [live] Start the OTLP receiver + UI (default).\n tracebird demo Serve the UI with bundled sample runs (no agent needed).\n tracebird open <file.jsonl> Load a saved session and serve the UI.\n tracebird --help Show this help.\n\nOptions:\n --port <n> Port for the OTLP receiver / UI server (default 4318).\n --host <addr> Address to bind (default 127.0.0.1).\n --out <dir> Directory for captured sessions (default ./.tracebird).\n --no-open Do not open the browser on start.\n\nPoint your agent's OpenTelemetry exporter at the receiver:\n export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318\n`;\n\nasync function main(argv: string[]): Promise<void> {\n // Node's parseArgs has no built-in negation; handle --no-open ourselves.\n const noOpen = argv.includes('--no-open');\n const cleaned = argv.filter((a) => a !== '--no-open');\n\n const { values, positionals } = parseArgs({\n args: cleaned,\n allowPositionals: true,\n options: {\n port: { type: 'string' },\n host: { type: 'string' },\n out: { type: 'string' },\n help: { type: 'boolean', short: 'h' },\n },\n });\n\n if (values.help) {\n process.stdout.write(HELP);\n return;\n }\n\n const command = positionals[0] ?? 'live';\n const port = values.port ? Number(values.port) : 4318;\n const host = values.host ?? '127.0.0.1';\n const outDir = resolve(values.out ?? '.tracebird');\n const open = !noOpen;\n\n switch (command) {\n case 'live':\n await runLive({ port, host, outDir, open });\n break;\n case 'demo':\n await runDemo({ port, host, open });\n break;\n case 'open': {\n const file = positionals[1];\n if (!file) {\n process.stderr.write('Usage: tracebird open <file.jsonl>\\n');\n process.exitCode = 1;\n break;\n }\n await runOpen({ file, port, host, open });\n break;\n }\n case 'help':\n process.stdout.write(HELP);\n break;\n default:\n process.stderr.write(`Unknown command: ${command}\\n\\n${HELP}`);\n process.exitCode = 1;\n }\n}\n\nmain(process.argv.slice(2)).catch((err) => {\n process.stderr.write(`tracebird: ${(err as Error).message}\\n`);\n process.exitCode = 1;\n});\n","import { join } from 'node:path';\nimport { buildRun } from '@tracebird/core';\nimport { createServer, listen } from '../server.js';\nimport { SessionStore } from '../storage/session-store.js';\nimport { TraceBuffer } from '../trace-buffer.js';\nimport { renderRunTree } from '../render/tree.js';\nimport { createAppHandler } from '../app.js';\nimport { resolveUiDir } from '../ui-dir.js';\nimport { openBrowser } from '../open-browser.js';\nimport { SseHub } from '../sse.js';\n\nexport interface LiveOptions {\n port: number;\n host: string;\n outDir: string;\n open: boolean;\n}\n\n/**\n * `tracebird live` — start the OTLP receiver, reconstruct each completed trace,\n * print its tree, persist it, and serve the UI (which polls the JSON API).\n */\nexport async function runLive(options: LiveOptions): Promise<void> {\n const store = new SessionStore(join(options.outDir, `session-${Date.now()}.jsonl`));\n const sse = new SseHub();\n\n const buffer = new TraceBuffer({\n onComplete: (_traceId, spans) => {\n const run = buildRun(spans);\n store.addRun(run);\n process.stdout.write('\\n' + renderRunTree(run) + '\\n');\n sse.broadcast('run', { id: run.id });\n },\n });\n\n const server = createServer({\n onExport: (spans) => {\n buffer.add(spans);\n sse.broadcast('activity', { spans: spans.length });\n },\n extraHandler: createAppHandler({ store, live: true }, resolveUiDir(), sse),\n });\n\n const boundPort = await listen(server, options.port, options.host);\n const endpoint = `http://${options.host}:${boundPort}`;\n\n process.stdout.write(\n [\n '',\n ' tracebird — listening for OpenTelemetry traces',\n '',\n ` UI ${endpoint}`,\n ` OTLP endpoint ${endpoint}/v1/traces`,\n ` Session file ${store.filePath}`,\n '',\n ' Point your agent at this receiver:',\n ` export OTEL_EXPORTER_OTLP_ENDPOINT=${endpoint}`,\n '',\n ' Waiting for your first agent run… (Ctrl-C to stop)',\n '',\n ].join('\\n') + '\\n',\n );\n\n if (options.open) openBrowser(endpoint);\n\n await new Promise<void>((resolveShutdown) => {\n const shutdown = () => {\n process.stdout.write('\\n Stopping…\\n');\n buffer.flushAll();\n sse.close();\n server.close(() => {\n void store.close().then(() => resolveShutdown());\n });\n };\n process.once('SIGINT', shutdown);\n process.once('SIGTERM', shutdown);\n });\n}\n","import {\n createServer as createHttpServer,\n type IncomingMessage,\n type Server,\n type ServerResponse,\n} from 'node:http';\nimport { parseOtlp, type ExportTraceServiceRequest, type Span } from '@tracebird/core';\nimport { decodeProtobufTraces } from './otlp/protobuf.js';\n\n/** Called whenever a batch of spans is received and parsed. */\nexport type ExportHandler = (spans: Span[], raw: ExportTraceServiceRequest) => void | Promise<void>;\n\nexport interface ServerOptions {\n /** Invoked with the parsed spans for every accepted OTLP export. */\n onExport?: ExportHandler;\n /**\n * Optional extra request handler tried before the 404 fallback — used by the\n * UI/API layer in later stages. Return `true` if it handled the request.\n */\n extraHandler?: (req: IncomingMessage, res: ServerResponse) => boolean | Promise<boolean>;\n}\n\nconst MAX_BODY_BYTES = 50 * 1024 * 1024; // 50 MB — generous for batched exports.\n\nfunction readBody(req: IncomingMessage): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let size = 0;\n req.on('data', (chunk: Buffer) => {\n size += chunk.length;\n if (size > MAX_BODY_BYTES) {\n reject(new Error('payload too large'));\n req.destroy();\n return;\n }\n chunks.push(chunk);\n });\n req.on('end', () => resolve(Buffer.concat(chunks)));\n req.on('error', reject);\n });\n}\n\nfunction decodeExport(contentType: string, body: Buffer): ExportTraceServiceRequest {\n if (\n contentType.includes('application/x-protobuf') ||\n contentType.includes('application/protobuf')\n ) {\n return decodeProtobufTraces(body);\n }\n // Default to JSON (the OTLP/HTTP JSON content type, or anything unspecified).\n const text = body.toString('utf8').trim();\n return text ? (JSON.parse(text) as ExportTraceServiceRequest) : {};\n}\n\nfunction sendProtobuf(res: ServerResponse, status: number): void {\n // An empty ExportTraceServiceResponse encodes to zero bytes (full success).\n res.writeHead(status, { 'content-type': 'application/x-protobuf' });\n res.end();\n}\n\nfunction sendJson(res: ServerResponse, status: number, payload: unknown): void {\n res.writeHead(status, { 'content-type': 'application/json' });\n res.end(JSON.stringify(payload));\n}\n\nasync function handleTraces(\n req: IncomingMessage,\n res: ServerResponse,\n onExport?: ExportHandler,\n): Promise<void> {\n const contentType = req.headers['content-type'] ?? 'application/json';\n let body: Buffer;\n try {\n body = await readBody(req);\n } catch {\n sendJson(res, 413, { error: 'payload too large' });\n return;\n }\n\n let request: ExportTraceServiceRequest;\n try {\n request = decodeExport(contentType, body);\n } catch (err) {\n sendJson(res, 400, { error: `failed to decode OTLP payload: ${(err as Error).message}` });\n return;\n }\n\n const spans = parseOtlp(request);\n try {\n await onExport?.(spans, request);\n } catch (err) {\n sendJson(res, 500, { error: `export handler failed: ${(err as Error).message}` });\n return;\n }\n\n const isProtobuf =\n contentType.includes('application/x-protobuf') || contentType.includes('application/protobuf');\n if (isProtobuf) sendProtobuf(res, 200);\n else sendJson(res, 200, {});\n}\n\n/** Create the tracebird HTTP server (OTLP receiver + optional extra routes). */\nexport function createServer(options: ServerOptions = {}): Server {\n return createHttpServer((req, res) => {\n void (async () => {\n const url = (req.url ?? '/').split('?')[0];\n\n if (req.method === 'POST' && url === '/v1/traces') {\n await handleTraces(req, res, options.onExport);\n return;\n }\n\n if (req.method === 'GET' && (url === '/health' || url === '/healthz')) {\n sendJson(res, 200, { status: 'ok' });\n return;\n }\n\n if (options.extraHandler) {\n const handled = await options.extraHandler(req, res);\n if (handled) return;\n }\n\n sendJson(res, 404, { error: 'not found' });\n })().catch((err) => {\n if (!res.headersSent) sendJson(res, 500, { error: (err as Error).message });\n });\n });\n}\n\n/** Start a server and resolve once it is listening, with the bound port. */\nexport function listen(server: Server, port: number, host: string): Promise<number> {\n return new Promise((resolve, reject) => {\n server.once('error', reject);\n server.listen(port, host, () => {\n const addr = server.address();\n const boundPort = typeof addr === 'object' && addr ? addr.port : port;\n resolve(boundPort);\n });\n });\n}\n","import type { ExportTraceServiceRequest } from '@tracebird/core';\n\n/**\n * Decode OTLP/HTTP **protobuf** trace payloads with zero dependencies.\n *\n * Most OpenTelemetry SDKs default to `http/protobuf`, so this is the path that\n * makes tracebird genuinely drop-in. Rather than pull in a protobuf runtime, we\n * hand-roll a minimal reader/writer for exactly the subset of the OTLP trace\n * schema we need, and emit the same camelCase shape `parseOtlp` consumes from\n * OTLP/JSON (hex trace/span ids, stringified nanos).\n *\n * Wire format: https://protobuf.dev/programming-guides/encoding/\n * OTLP trace schema (field numbers below):\n * https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/trace/v1/trace.proto\n */\n\nconst textDecoder = new TextDecoder();\nconst textEncoder = new TextEncoder();\n\n// Wire types\nconst VARINT = 0;\nconst I64 = 1;\nconst LEN = 2;\nconst I32 = 5;\n\n// ---------------------------------------------------------------------------\n// Reader\n// ---------------------------------------------------------------------------\n\nclass Reader {\n pos = 0;\n constructor(private readonly buf: Uint8Array) {}\n\n get eof(): boolean {\n return this.pos >= this.buf.length;\n }\n\n varint(): bigint {\n let result = 0n;\n let shift = 0n;\n for (;;) {\n const byte = this.buf[this.pos++];\n result |= BigInt(byte & 0x7f) << shift;\n if ((byte & 0x80) === 0) break;\n shift += 7n;\n }\n return result;\n }\n\n tag(): { field: number; wire: number } {\n const v = Number(this.varint());\n return { field: v >>> 3, wire: v & 7 };\n }\n\n fixed64(): bigint {\n let v = 0n;\n for (let i = 0; i < 8; i++) v |= BigInt(this.buf[this.pos++]) << BigInt(8 * i);\n return v;\n }\n\n double(): number {\n const view = new DataView(this.buf.buffer, this.buf.byteOffset + this.pos, 8);\n this.pos += 8;\n return view.getFloat64(0, true);\n }\n\n bytes(): Uint8Array {\n const len = Number(this.varint());\n const out = this.buf.subarray(this.pos, this.pos + len);\n this.pos += len;\n return out;\n }\n\n string(): string {\n return textDecoder.decode(this.bytes());\n }\n\n /** Skip an unknown field by its wire type, preserving forward-compatibility. */\n skip(wire: number): void {\n if (wire === VARINT) this.varint();\n else if (wire === I64) this.pos += 8;\n else if (wire === LEN) this.bytes();\n else if (wire === I32) this.pos += 4;\n else throw new Error(`unsupported wire type ${wire}`);\n }\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n let hex = '';\n for (const b of bytes) hex += (b & 0xff).toString(16).padStart(2, '0');\n return hex;\n}\n\n// Each parser takes the message's bytes and returns the JSON-shaped object.\n\nfunction parseAnyValue(buf: Uint8Array): Record<string, unknown> {\n const r = new Reader(buf);\n const out: Record<string, unknown> = {};\n while (!r.eof) {\n const { field, wire } = r.tag();\n switch (field) {\n case 1:\n out.stringValue = r.string();\n break;\n case 2:\n out.boolValue = r.varint() !== 0n;\n break;\n case 3:\n out.intValue = r.varint().toString();\n break;\n case 4:\n out.doubleValue = r.double();\n break;\n case 5:\n out.arrayValue = { values: parseRepeated(r.bytes(), parseAnyValue) };\n break;\n case 6:\n out.kvlistValue = { values: parseRepeated(r.bytes(), parseKeyValue) };\n break;\n case 7:\n out.bytesValue = bytesToHex(r.bytes());\n break;\n default:\n r.skip(wire);\n }\n }\n return out;\n}\n\nfunction parseRepeated<T>(buf: Uint8Array, parse: (b: Uint8Array) => T): T[] {\n // A KeyValueList / ArrayList message: repeated field #1 of sub-messages.\n const r = new Reader(buf);\n const out: T[] = [];\n while (!r.eof) {\n const { field, wire } = r.tag();\n if (field === 1 && wire === LEN) out.push(parse(r.bytes()));\n else r.skip(wire);\n }\n return out;\n}\n\nfunction parseKeyValue(buf: Uint8Array): Record<string, unknown> {\n const r = new Reader(buf);\n const kv: Record<string, unknown> = {};\n while (!r.eof) {\n const { field, wire } = r.tag();\n if (field === 1) kv.key = r.string();\n else if (field === 2) kv.value = parseAnyValue(r.bytes());\n else r.skip(wire);\n }\n return kv;\n}\n\nfunction parseKeyValues(buf: Uint8Array, into: Record<string, unknown>[]): void {\n into.push(parseKeyValue(buf));\n}\n\nfunction parseEvent(buf: Uint8Array): Record<string, unknown> {\n const r = new Reader(buf);\n const ev: Record<string, unknown> = {};\n const attributes: Record<string, unknown>[] = [];\n while (!r.eof) {\n const { field, wire } = r.tag();\n switch (field) {\n case 1:\n ev.timeUnixNano = r.fixed64().toString();\n break;\n case 2:\n ev.name = r.string();\n break;\n case 3:\n parseKeyValues(r.bytes(), attributes);\n break;\n default:\n r.skip(wire);\n }\n }\n if (attributes.length) ev.attributes = attributes;\n return ev;\n}\n\nfunction parseStatus(buf: Uint8Array): Record<string, unknown> {\n const r = new Reader(buf);\n const status: Record<string, unknown> = {};\n while (!r.eof) {\n const { field, wire } = r.tag();\n if (field === 2) status.message = r.string();\n else if (field === 3) status.code = Number(r.varint());\n else r.skip(wire);\n }\n return status;\n}\n\nfunction parseSpan(buf: Uint8Array): Record<string, unknown> {\n const r = new Reader(buf);\n const span: Record<string, unknown> = {};\n const attributes: Record<string, unknown>[] = [];\n const events: Record<string, unknown>[] = [];\n while (!r.eof) {\n const { field, wire } = r.tag();\n switch (field) {\n case 1:\n span.traceId = bytesToHex(r.bytes());\n break;\n case 2:\n span.spanId = bytesToHex(r.bytes());\n break;\n case 4: {\n const parent = bytesToHex(r.bytes());\n if (parent) span.parentSpanId = parent;\n break;\n }\n case 5:\n span.name = r.string();\n break;\n case 6:\n span.kind = Number(r.varint());\n break;\n case 7:\n span.startTimeUnixNano = r.fixed64().toString();\n break;\n case 8:\n span.endTimeUnixNano = r.fixed64().toString();\n break;\n case 9:\n parseKeyValues(r.bytes(), attributes);\n break;\n case 11:\n events.push(parseEvent(r.bytes()));\n break;\n case 15:\n span.status = parseStatus(r.bytes());\n break;\n default:\n r.skip(wire);\n }\n }\n if (attributes.length) span.attributes = attributes;\n if (events.length) span.events = events;\n return span;\n}\n\nfunction parseScope(buf: Uint8Array): Record<string, unknown> {\n const r = new Reader(buf);\n const scope: Record<string, unknown> = {};\n const attributes: Record<string, unknown>[] = [];\n while (!r.eof) {\n const { field, wire } = r.tag();\n if (field === 1) scope.name = r.string();\n else if (field === 2) scope.version = r.string();\n else if (field === 3) parseKeyValues(r.bytes(), attributes);\n else r.skip(wire);\n }\n if (attributes.length) scope.attributes = attributes;\n return scope;\n}\n\nfunction parseScopeSpans(buf: Uint8Array): Record<string, unknown> {\n const r = new Reader(buf);\n const out: Record<string, unknown> = {};\n const spans: Record<string, unknown>[] = [];\n while (!r.eof) {\n const { field, wire } = r.tag();\n if (field === 1) out.scope = parseScope(r.bytes());\n else if (field === 2) spans.push(parseSpan(r.bytes()));\n else r.skip(wire);\n }\n out.spans = spans;\n return out;\n}\n\nfunction parseResource(buf: Uint8Array): Record<string, unknown> {\n const attributes: Record<string, unknown>[] = [];\n const r = new Reader(buf);\n while (!r.eof) {\n const { field, wire } = r.tag();\n if (field === 1) parseKeyValues(r.bytes(), attributes);\n else r.skip(wire);\n }\n return { attributes };\n}\n\nfunction parseResourceSpans(buf: Uint8Array): Record<string, unknown> {\n const r = new Reader(buf);\n const out: Record<string, unknown> = {};\n const scopeSpans: Record<string, unknown>[] = [];\n while (!r.eof) {\n const { field, wire } = r.tag();\n if (field === 1) out.resource = parseResource(r.bytes());\n else if (field === 2) scopeSpans.push(parseScopeSpans(r.bytes()));\n else r.skip(wire);\n }\n out.scopeSpans = scopeSpans;\n return out;\n}\n\n/** Decode an OTLP/protobuf body into the JSON `ExportTraceServiceRequest` shape. */\nexport function decodeProtobufTraces(body: Uint8Array): ExportTraceServiceRequest {\n const r = new Reader(body);\n const resourceSpans: Record<string, unknown>[] = [];\n while (!r.eof) {\n const { field, wire } = r.tag();\n if (field === 1) resourceSpans.push(parseResourceSpans(r.bytes()));\n else r.skip(wire);\n }\n return { resourceSpans } as ExportTraceServiceRequest;\n}\n\n// ---------------------------------------------------------------------------\n// Writer (inverse — used by tests and the protobuf-ingest e2e path)\n// ---------------------------------------------------------------------------\n\nclass Writer {\n private readonly out: number[] = [];\n\n private push(byte: number): void {\n this.out.push(byte & 0xff);\n }\n\n varint(value: bigint): void {\n let v = value;\n while (v > 0x7fn) {\n this.push(Number(v & 0x7fn) | 0x80);\n v >>= 7n;\n }\n this.push(Number(v));\n }\n\n tag(field: number, wire: number): void {\n this.varint(BigInt((field << 3) | wire));\n }\n\n fixed64(value: bigint): void {\n for (let i = 0; i < 8; i++) this.push(Number((value >> BigInt(8 * i)) & 0xffn));\n }\n\n double(value: number): void {\n const buf = new ArrayBuffer(8);\n new DataView(buf).setFloat64(0, value, true);\n for (const b of new Uint8Array(buf)) this.push(b);\n }\n\n bytes(field: number, value: Uint8Array): void {\n this.tag(field, LEN);\n this.varint(BigInt(value.length));\n for (const b of value) this.push(b);\n }\n\n string(field: number, value: string): void {\n this.bytes(field, textEncoder.encode(value));\n }\n\n message(field: number, value: Uint8Array): void {\n this.bytes(field, value);\n }\n\n finish(): Uint8Array {\n return Uint8Array.from(this.out);\n }\n}\n\nfunction hexToBytes(hex: string | undefined): Uint8Array {\n if (!hex) return new Uint8Array(0);\n const clean = hex.length % 2 === 0 ? hex : '0' + hex;\n const out = new Uint8Array(clean.length / 2);\n for (let i = 0; i < out.length; i++) out[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);\n return out;\n}\n\ninterface JsonAnyValue {\n stringValue?: string;\n boolValue?: boolean;\n intValue?: string | number;\n doubleValue?: number;\n arrayValue?: { values?: JsonAnyValue[] };\n kvlistValue?: { values?: JsonKeyValue[] };\n bytesValue?: string;\n}\ninterface JsonKeyValue {\n key?: string;\n value?: JsonAnyValue;\n}\n\nfunction encodeAnyValue(v: JsonAnyValue): Uint8Array {\n const w = new Writer();\n if (v.stringValue !== undefined) w.string(1, v.stringValue);\n if (v.boolValue !== undefined) {\n w.tag(2, VARINT);\n w.varint(v.boolValue ? 1n : 0n);\n }\n if (v.intValue !== undefined) {\n w.tag(3, VARINT);\n w.varint(BigInt(v.intValue));\n }\n if (v.doubleValue !== undefined) {\n w.tag(4, I64);\n w.double(v.doubleValue);\n }\n if (v.arrayValue) {\n const inner = new Writer();\n for (const item of v.arrayValue.values ?? []) inner.message(1, encodeAnyValue(item));\n w.message(5, inner.finish());\n }\n if (v.kvlistValue) {\n const inner = new Writer();\n for (const kv of v.kvlistValue.values ?? []) inner.message(1, encodeKeyValue(kv));\n w.message(6, inner.finish());\n }\n if (v.bytesValue !== undefined) w.bytes(7, hexToBytes(v.bytesValue));\n return w.finish();\n}\n\nfunction encodeKeyValue(kv: JsonKeyValue): Uint8Array {\n const w = new Writer();\n if (kv.key !== undefined) w.string(1, kv.key);\n if (kv.value) w.message(2, encodeAnyValue(kv.value));\n return w.finish();\n}\n\ninterface JsonSpan {\n traceId?: string;\n spanId?: string;\n parentSpanId?: string;\n name?: string;\n kind?: number;\n startTimeUnixNano?: string;\n endTimeUnixNano?: string;\n attributes?: JsonKeyValue[];\n status?: { code?: number; message?: string };\n}\n\nfunction encodeSpan(span: JsonSpan): Uint8Array {\n const w = new Writer();\n if (span.traceId) w.bytes(1, hexToBytes(span.traceId));\n if (span.spanId) w.bytes(2, hexToBytes(span.spanId));\n if (span.parentSpanId) w.bytes(4, hexToBytes(span.parentSpanId));\n if (span.name !== undefined) w.string(5, span.name);\n if (span.kind !== undefined) {\n w.tag(6, VARINT);\n w.varint(BigInt(span.kind));\n }\n if (span.startTimeUnixNano !== undefined) {\n w.tag(7, I64);\n w.fixed64(BigInt(span.startTimeUnixNano));\n }\n if (span.endTimeUnixNano !== undefined) {\n w.tag(8, I64);\n w.fixed64(BigInt(span.endTimeUnixNano));\n }\n for (const attr of span.attributes ?? []) w.message(9, encodeKeyValue(attr));\n if (span.status) {\n const s = new Writer();\n if (span.status.message !== undefined) s.string(2, span.status.message);\n if (span.status.code !== undefined) {\n s.tag(3, VARINT);\n s.varint(BigInt(span.status.code));\n }\n w.message(15, s.finish());\n }\n return w.finish();\n}\n\n/**\n * Encode a JSON `ExportTraceServiceRequest` (hex ids, string nanos) into\n * OTLP/protobuf bytes. The inverse of {@link decodeProtobufTraces}.\n */\nexport function encodeProtobufTraces(request: ExportTraceServiceRequest): Uint8Array {\n const top = new Writer();\n for (const rs of request.resourceSpans ?? []) {\n const rsw = new Writer();\n if (rs.resource) {\n const res = new Writer();\n for (const attr of rs.resource.attributes ?? []) res.message(1, encodeKeyValue(attr));\n rsw.message(1, res.finish());\n }\n for (const ss of rs.scopeSpans ?? []) {\n const ssw = new Writer();\n if (ss.scope) {\n const scope = new Writer();\n if (ss.scope.name !== undefined) scope.string(1, ss.scope.name);\n if (ss.scope.version !== undefined) scope.string(2, ss.scope.version);\n ssw.message(1, scope.finish());\n }\n for (const span of ss.spans ?? []) ssw.message(2, encodeSpan(span as JsonSpan));\n rsw.message(2, ssw.finish());\n }\n top.message(1, rsw.finish());\n }\n return top.finish();\n}\n","import { createWriteStream, mkdirSync, readFileSync, type WriteStream } from 'node:fs';\nimport { dirname } from 'node:path';\nimport {\n parseSession,\n runMatches,\n serializeRun,\n StatusCode,\n type Run,\n type TraceNode,\n} from '@tracebird/core';\n\nexport interface RunFilter {\n /** Deep text search across summary, prompts, completions, tool I/O. */\n query?: string;\n /** Restrict by status; `'all'` (default) keeps everything. */\n status?: 'all' | 'ok' | 'error' | 'unset';\n}\n\n/** Lightweight run summary for list views (no heavy prompt/completion payloads). */\nexport interface RunSummary {\n id: string;\n traceId: string;\n summary: string;\n startTimeUnixNano: string;\n durationMs: number;\n status: 'ok' | 'error' | 'unset';\n tokens: Run['tokens'];\n costUsd: number | null;\n service?: string;\n nodeCount: number;\n}\n\nfunction statusLabel(code: StatusCode): RunSummary['status'] {\n if (code === StatusCode.Error) return 'error';\n if (code === StatusCode.Ok) return 'ok';\n return 'unset';\n}\n\nfunction countNodes(node: TraceNode): number {\n return 1 + node.children.reduce((sum, child) => sum + countNodes(child), 0);\n}\n\n/**\n * Holds the runs for one session in memory and (optionally) appends them to a\n * `.jsonl` file. Backs both `live` capture (append mode) and `open` (read-only).\n */\nexport class SessionStore {\n private readonly runs: Run[] = [];\n private readonly byId = new Map<string, Run>();\n private stream?: WriteStream;\n readonly filePath?: string;\n\n constructor(filePath?: string) {\n if (filePath) {\n mkdirSync(dirname(filePath), { recursive: true });\n this.filePath = filePath;\n this.stream = createWriteStream(filePath, { flags: 'a' });\n }\n }\n\n /** Load an existing session file read-only (for `tracebird open`). */\n static load(filePath: string): SessionStore {\n const store = new SessionStore();\n const text = readFileSync(filePath, 'utf8');\n for (const run of parseSession(text)) store.addRun(run, { persist: false });\n return store;\n }\n\n addRun(run: Run, options: { persist?: boolean } = {}): void {\n this.runs.push(run);\n this.byId.set(run.id, run);\n if (options.persist !== false) this.stream?.write(serializeRun(run) + '\\n');\n }\n\n get(id: string): Run | undefined {\n return this.byId.get(id);\n }\n\n all(): Run[] {\n return this.runs;\n }\n\n /** Run summaries, newest first, optionally filtered by text and status. */\n list(filter: RunFilter = {}): RunSummary[] {\n const status = filter.status ?? 'all';\n const query = filter.query ?? '';\n return this.runs\n .filter((run) => status === 'all' || statusLabel(run.status.code) === status)\n .filter((run) => runMatches(run, query))\n .map((run) => ({\n id: run.id,\n traceId: run.traceId,\n summary: run.summary,\n startTimeUnixNano: run.startTimeUnixNano,\n durationMs: run.durationMs,\n status: statusLabel(run.status.code),\n tokens: run.tokens,\n costUsd: run.costUsd,\n ...(run.service ? { service: run.service } : {}),\n nodeCount: countNodes(run.root),\n }))\n .sort((a, b) => (a.startTimeUnixNano < b.startTimeUnixNano ? 1 : -1));\n }\n\n get size(): number {\n return this.runs.length;\n }\n\n async close(): Promise<void> {\n const stream = this.stream;\n if (!stream) return;\n await new Promise<void>((resolve, reject) => {\n stream.end((err?: Error | null) => (err ? reject(err) : resolve()));\n });\n }\n}\n","import type { Span } from '@tracebird/core';\n\nexport interface TraceBufferOptions {\n /** Flush a trace after this many ms with no new spans. Default 1500. */\n idleMs?: number;\n /** Called with all buffered spans for a trace once it goes idle. */\n onComplete: (traceId: string, spans: Span[]) => void;\n}\n\n/**\n * Buffers incoming spans per trace id and flushes a trace once it has been idle\n * for `idleMs`. OTLP gives us no explicit \"trace complete\" signal, so idle\n * detection is the pragmatic trigger; `flushAll` forces completion on shutdown.\n */\nexport class TraceBuffer {\n private readonly idleMs: number;\n private readonly onComplete: TraceBufferOptions['onComplete'];\n private readonly traces = new Map<string, { spans: Span[]; timer: NodeJS.Timeout }>();\n\n constructor(options: TraceBufferOptions) {\n this.idleMs = options.idleMs ?? 1500;\n this.onComplete = options.onComplete;\n }\n\n add(spans: Span[]): void {\n const grouped = new Map<string, Span[]>();\n for (const span of spans) {\n const list = grouped.get(span.traceId) ?? [];\n list.push(span);\n grouped.set(span.traceId, list);\n }\n for (const [traceId, group] of grouped) {\n const entry = this.traces.get(traceId);\n if (entry) {\n entry.spans.push(...group);\n clearTimeout(entry.timer);\n entry.timer = this.schedule(traceId);\n } else {\n this.traces.set(traceId, { spans: group, timer: this.schedule(traceId) });\n }\n }\n }\n\n private schedule(traceId: string): NodeJS.Timeout {\n const timer = setTimeout(() => this.flush(traceId), this.idleMs);\n // Don't keep the event loop alive solely for a pending flush.\n timer.unref?.();\n return timer;\n }\n\n /** Flush a single trace now, if buffered. */\n flush(traceId: string): void {\n const entry = this.traces.get(traceId);\n if (!entry) return;\n clearTimeout(entry.timer);\n this.traces.delete(traceId);\n this.onComplete(traceId, entry.spans);\n }\n\n /** Flush every buffered trace (e.g. on shutdown). */\n flushAll(): void {\n for (const traceId of [...this.traces.keys()]) this.flush(traceId);\n }\n\n get pending(): number {\n return this.traces.size;\n }\n}\n","import { StatusCode, type LlmCall, type Run, type ToolCall, type TraceNode } from '@tracebird/core';\nimport { formatCost, formatDuration, formatTokens } from './format.js';\n\n/** Render a reconstructed {@link Run} as an indented tree for the terminal. */\n\nconst ICON: Record<TraceNode['kind'], string> = {\n run: '⏺',\n agent: '◆',\n llm: '✦',\n tool: '⚙',\n step: '▫',\n};\n\nfunction metrics(node: TraceNode): string {\n const parts: string[] = [formatDuration(node.durationMs)];\n if (node.kind === 'llm') {\n const llm = node as LlmCall;\n const tok = formatTokens(llm.usage.total ?? llm.usage.input);\n if (tok) parts.push(tok);\n const cost = formatCost(llm.costUsd);\n if (cost) parts.push(cost);\n if (llm.model) parts.push(llm.model);\n }\n if (node.kind === 'tool' && (node as ToolCall).isError) parts.push('ERROR');\n return parts.join(' ');\n}\n\nfunction label(node: TraceNode): string {\n return `${ICON[node.kind]} ${node.name} ${metrics(node)}`;\n}\n\nfunction renderChildren(nodes: TraceNode[], prefix: string, lines: string[]): void {\n nodes.forEach((node, i) => {\n const last = i === nodes.length - 1;\n lines.push(`${prefix}${last ? '└─ ' : '├─ '}${label(node)}`);\n renderChildren(node.children, prefix + (last ? ' ' : '│ '), lines);\n });\n}\n\nexport function renderRunTree(run: Run): string {\n const header: string[] = [run.summary, formatDuration(run.durationMs)];\n const tok = formatTokens(run.tokens.total);\n if (tok) header.push(tok);\n const cost = formatCost(run.costUsd);\n if (cost) header.push(cost);\n if (run.status.code === StatusCode.Error) header.push('ERROR');\n\n const lines: string[] = [header.join(' · ')];\n renderChildren(run.root.children, '', lines);\n return lines.join('\\n');\n}\n","/** Compact formatters for terminal output. */\n\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms) || ms < 0) return '—';\n if (ms < 1000) return `${Math.round(ms)}ms`;\n const seconds = ms / 1000;\n if (seconds < 60) return `${seconds.toFixed(2).replace(/\\.?0+$/, '')}s`;\n const mins = Math.floor(seconds / 60);\n const rem = Math.round(seconds % 60);\n return `${mins}m ${rem}s`;\n}\n\nexport function formatTokens(tokens: number | undefined): string | undefined {\n return tokens == null ? undefined : `${tokens.toLocaleString('en-US')} tok`;\n}\n\nexport function formatCost(usd: number | null | undefined): string | undefined {\n if (usd == null) return undefined;\n if (usd === 0) return '$0';\n if (usd < 0.01) return `$${usd.toFixed(4)}`;\n return `$${usd.toFixed(2)}`;\n}\n","import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport { diffRuns, type Run } from '@tracebird/core';\nimport type { SessionStore } from './storage/session-store.js';\nimport { buildHtmlSnapshot, exportJsonl } from './export.js';\n\n/**\n * The JSON API the UI reads. Pure delegation to the {@link SessionStore} (which\n * delegates reconstruction/diff to `@tracebird/core`); no business logic here.\n *\n * GET /api/session → { live, filePath, count }\n * GET /api/runs → RunSummary[]\n * GET /api/runs/:id → Run\n */\n\nexport interface ApiContext {\n store: SessionStore;\n live: boolean;\n /** Directory of the built UI assets (needed for HTML snapshot export). */\n uiDir?: string;\n}\n\nfunction json(res: ServerResponse, status: number, payload: unknown): void {\n res.writeHead(status, { 'content-type': 'application/json', 'cache-control': 'no-store' });\n res.end(JSON.stringify(payload));\n}\n\n/** Handle an `/api/*` request. Returns false if the path isn't an API route. */\nexport function handleApi(ctx: ApiContext, req: IncomingMessage, res: ServerResponse): boolean {\n const url = (req.url ?? '/').split('?')[0];\n if (!url.startsWith('/api/')) return false;\n\n if (req.method !== 'GET') {\n json(res, 405, { error: 'method not allowed' });\n return true;\n }\n\n if (url === '/api/session') {\n json(res, 200, {\n live: ctx.live,\n filePath: ctx.store.filePath ?? null,\n count: ctx.store.size,\n });\n return true;\n }\n\n if (url === '/api/runs') {\n const params = new URL(req.url ?? '', 'http://localhost').searchParams;\n const query = params.get('q') ?? undefined;\n const statusParam = params.get('status');\n const status =\n statusParam === 'ok' || statusParam === 'error' || statusParam === 'unset'\n ? statusParam\n : 'all';\n json(res, 200, ctx.store.list({ query, status }));\n return true;\n }\n\n if (url === '/api/diff') {\n const params = new URL(req.url ?? '', 'http://localhost').searchParams;\n const aId = params.get('a');\n const bId = params.get('b');\n if (!aId || !bId) {\n json(res, 400, { error: 'diff requires ?a=<runId>&b=<runId>' });\n return true;\n }\n const a = ctx.store.get(aId);\n const b = ctx.store.get(bId);\n if (!a || !b) {\n json(res, 404, { error: `run not found: ${!a ? aId : bId}` });\n return true;\n }\n json(res, 200, diffRuns(a, b));\n return true;\n }\n\n if (url === '/api/export') {\n const params = new URL(req.url ?? '', 'http://localhost').searchParams;\n const id = params.get('id');\n const format = params.get('format') === 'jsonl' ? 'jsonl' : 'html';\n\n let runs: Run[];\n let name: string;\n if (id) {\n const run = ctx.store.get(id);\n if (!run) {\n json(res, 404, { error: `run not found: ${id}` });\n return true;\n }\n runs = [run];\n name = `tracebird-run-${run.traceId.slice(0, 8) || 'export'}`;\n } else {\n runs = ctx.store.all();\n name = 'tracebird-session';\n }\n\n if (format === 'jsonl') {\n res.writeHead(200, {\n 'content-type': 'application/x-ndjson; charset=utf-8',\n 'content-disposition': `attachment; filename=\"${name}.jsonl\"`,\n });\n res.end(exportJsonl(runs));\n return true;\n }\n\n if (!ctx.uiDir || !existsSync(join(ctx.uiDir, 'index.html'))) {\n json(res, 503, { error: 'UI assets not available for HTML export' });\n return true;\n }\n res.writeHead(200, {\n 'content-type': 'text/html; charset=utf-8',\n 'content-disposition': `attachment; filename=\"${name}.html\"`,\n });\n res.end(buildHtmlSnapshot(ctx.uiDir, runs));\n return true;\n }\n\n const match = /^\\/api\\/runs\\/([^/]+)$/.exec(url);\n if (match) {\n const id = decodeURIComponent(match[1]);\n const run = ctx.store.get(id);\n if (!run) json(res, 404, { error: `run not found: ${id}` });\n else json(res, 200, run);\n return true;\n }\n\n json(res, 404, { error: 'unknown api route' });\n return true;\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { serializeSession, type Run } from '@tracebird/core';\nimport { SessionStore } from './storage/session-store.js';\n\n/**\n * Shareable-run export. Two formats:\n * - `jsonl` — the run(s) as a session file (re-openable with `tracebird open`).\n * - `html` — a single self-contained page that inlines the UI bundle + the run\n * data, so a coworker can open it offline with no install.\n */\n\nexport function exportJsonl(runs: Run[]): string {\n return serializeSession(runs);\n}\n\nfunction inlineAssets(uiDir: string, html: string): string {\n const withJs = html.replace(\n /<script\\b[^>]*\\bsrc=\"(\\.?\\/?assets\\/[^\"]+\\.js)\"[^>]*><\\/script>/g,\n (_match, src: string) => {\n const code = readFileSync(join(uiDir, src.replace(/^\\.?\\//, '')), 'utf8').replace(\n /<\\/(script)/gi,\n '<\\\\/$1',\n );\n return `<script type=\"module\">${code}</script>`;\n },\n );\n return withJs.replace(\n /<link\\b[^>]*\\bhref=\"(\\.?\\/?assets\\/[^\"]+\\.css)\"[^>]*>/g,\n (_match, href: string) => {\n const css = readFileSync(join(uiDir, href.replace(/^\\.?\\//, '')), 'utf8');\n return `<style>${css}</style>`;\n },\n );\n}\n\n/** Produce a self-contained HTML snapshot of the given runs. */\nexport function buildHtmlSnapshot(uiDir: string, runs: Run[]): string {\n const store = new SessionStore();\n for (const run of runs) store.addRun(run, { persist: false });\n\n const snapshot = {\n session: { live: false, filePath: null, count: runs.length },\n runs: store.list(),\n runsById: Object.fromEntries(runs.map((r) => [r.id, r])),\n };\n // Escape `</` so the JSON can't break out of the <script> element.\n const json = JSON.stringify(snapshot).replace(/<\\//g, '<\\\\/');\n const inject = `<script>window.__TRACEBIRD_SNAPSHOT__=${json}</script>`;\n\n const html = inlineAssets(uiDir, readFileSync(join(uiDir, 'index.html'), 'utf8'));\n if (html.includes('<script type=\"module\">')) {\n return html.replace('<script type=\"module\">', `${inject}<script type=\"module\">`);\n }\n return html.replace('</head>', `${inject}</head>`);\n}\n","import { createReadStream, existsSync, statSync } from 'node:fs';\nimport { join, normalize, extname } from 'node:path';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'text/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.ico': 'image/x-icon',\n '.woff2': 'font/woff2',\n '.map': 'application/json; charset=utf-8',\n};\n\n/**\n * Serve the pre-built UI static assets from `rootDir`, with SPA fallback to\n * `index.html`. Returns false if `rootDir` doesn't exist (UI not bundled).\n */\nexport function serveStatic(rootDir: string, req: IncomingMessage, res: ServerResponse): boolean {\n if (!existsSync(rootDir)) return false;\n if (req.method !== 'GET' && req.method !== 'HEAD') return false;\n\n const urlPath = decodeURIComponent((req.url ?? '/').split('?')[0]);\n // Resolve within rootDir; reject path traversal.\n const rel = normalize(urlPath).replace(/^(\\.\\.[/\\\\])+/, '');\n let filePath = join(rootDir, rel);\n if (!filePath.startsWith(rootDir)) filePath = join(rootDir, 'index.html');\n\n if (!existsSync(filePath) || statSync(filePath).isDirectory()) {\n filePath = join(rootDir, 'index.html'); // SPA fallback\n }\n if (!existsSync(filePath)) return false;\n\n const type = MIME[extname(filePath)] ?? 'application/octet-stream';\n res.writeHead(200, { 'content-type': type });\n if (req.method === 'HEAD') {\n res.end();\n return true;\n }\n createReadStream(filePath).pipe(res);\n return true;\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport { handleApi, type ApiContext } from './api.js';\nimport { serveStatic } from './static-files.js';\nimport type { SseHub } from './sse.js';\n\n/**\n * Build the combined UI/API request handler passed to the server as its\n * `extraHandler`: the SSE stream and API routes first, then the static UI\n * (with SPA fallback).\n */\nexport function createAppHandler(ctx: ApiContext, uiDir: string, sse?: SseHub) {\n const apiCtx: ApiContext = { ...ctx, uiDir };\n return (req: IncomingMessage, res: ServerResponse): boolean => {\n const url = (req.url ?? '/').split('?')[0];\n if (sse && req.method === 'GET' && url === '/api/stream') {\n sse.handle(req, res);\n return true;\n }\n if (handleApi(apiCtx, req, res)) return true;\n if (serveStatic(uiDir, req, res)) return true;\n return false;\n };\n}\n","import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Locate the pre-built UI assets. In the published package they sit next to the\n * bundled `cli.js` at `dist/ui`; in the dev tree they're at `packages/ui/dist`.\n */\nexport function resolveUiDir(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(here, 'ui'), // dist/ui (published / built)\n join(here, '..', '..', 'ui', 'dist'), // packages/cli/dist → packages/ui/dist\n ];\n return candidates.find((dir) => existsSync(join(dir, 'index.html'))) ?? candidates[0];\n}\n","import { spawn } from 'node:child_process';\n\n/** Best-effort: open a URL in the user's default browser. Never throws. */\nexport function openBrowser(url: string): void {\n const platform = process.platform;\n const command = platform === 'darwin' ? 'open' : platform === 'win32' ? 'cmd' : 'xdg-open';\n const args = platform === 'win32' ? ['/c', 'start', '\"\"', url] : [url];\n try {\n const child = spawn(command, args, { stdio: 'ignore', detached: true });\n child.on('error', () => undefined);\n child.unref();\n } catch {\n // Headless environment, etc. — the URL is printed for the user anyway.\n }\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http';\n\n/**\n * A tiny Server-Sent-Events hub. The UI subscribes once to `GET /api/stream`\n * and is pushed `activity` (spans arriving) and `run` (a run completed) events,\n * so it updates instantly instead of polling.\n */\nexport class SseHub {\n private readonly clients = new Set<ServerResponse>();\n private heartbeat?: ReturnType<typeof setInterval>;\n\n /** Register a long-lived SSE connection. */\n handle(req: IncomingMessage, res: ServerResponse): void {\n res.writeHead(200, {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-cache, no-transform',\n connection: 'keep-alive',\n 'x-accel-buffering': 'no',\n });\n res.write('retry: 2000\\n\\n');\n this.clients.add(res);\n req.on('close', () => this.clients.delete(res));\n\n if (!this.heartbeat) {\n this.heartbeat = setInterval(() => this.write(':ping\\n\\n'), 15000);\n this.heartbeat.unref?.();\n }\n }\n\n /** Push a named event with a JSON payload to every connected client. */\n broadcast(event: string, data: unknown = {}): void {\n this.write(`event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`);\n }\n\n private write(text: string): void {\n for (const res of this.clients) {\n try {\n res.write(text);\n } catch {\n this.clients.delete(res);\n }\n }\n }\n\n get size(): number {\n return this.clients.size;\n }\n\n close(): void {\n if (this.heartbeat) clearInterval(this.heartbeat);\n for (const res of this.clients) {\n try {\n res.end();\n } catch {\n /* client already gone */\n }\n }\n this.clients.clear();\n }\n}\n","import { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { createServer, listen } from '../server.js';\nimport { SessionStore } from '../storage/session-store.js';\nimport { createAppHandler } from '../app.js';\nimport { resolveUiDir } from '../ui-dir.js';\nimport { openBrowser } from '../open-browser.js';\n\nexport interface OpenOptions {\n file: string;\n port: number;\n host: string;\n open: boolean;\n}\n\n/**\n * `tracebird open <file.jsonl>` — load a saved session and serve the UI with no\n * receiver. The \"drag a run to a coworker\" loop.\n */\nexport async function runOpen(options: OpenOptions): Promise<void> {\n const file = resolve(options.file);\n if (!existsSync(file)) {\n process.stderr.write(`tracebird: session file not found: ${file}\\n`);\n process.exitCode = 1;\n return;\n }\n\n let store: SessionStore;\n try {\n store = SessionStore.load(file);\n } catch (err) {\n process.stderr.write(`tracebird: failed to load session: ${(err as Error).message}\\n`);\n process.exitCode = 1;\n return;\n }\n\n const server = createServer({\n extraHandler: createAppHandler({ store, live: false }, resolveUiDir()),\n });\n\n const boundPort = await listen(server, options.port, options.host);\n const endpoint = `http://${options.host}:${boundPort}`;\n\n process.stdout.write(\n [\n '',\n ` tracebird — serving ${store.size} run(s) from`,\n ` ${file}`,\n '',\n ` UI ${endpoint}`,\n '',\n ' (Ctrl-C to stop)',\n '',\n ].join('\\n') + '\\n',\n );\n\n if (options.open) openBrowser(endpoint);\n\n await new Promise<void>((resolveShutdown) => {\n const shutdown = () => {\n process.stdout.write('\\n Stopping…\\n');\n server.close(() => resolveShutdown());\n };\n process.once('SIGINT', shutdown);\n process.once('SIGTERM', shutdown);\n });\n}\n","import { buildRuns, parseOtlp } from '@tracebird/core';\nimport { otlpFixtures } from '@tracebird/fixtures';\nimport { createServer, listen } from '../server.js';\nimport { SessionStore } from '../storage/session-store.js';\nimport { createAppHandler } from '../app.js';\nimport { resolveUiDir } from '../ui-dir.js';\nimport { openBrowser } from '../open-browser.js';\n\nexport interface DemoOptions {\n port: number;\n host: string;\n open: boolean;\n}\n\n/**\n * `tracebird demo` — serve the UI pre-loaded with the bundled sample runs\n * (a multi-tool run, a tool error, and a diff pair) so you can explore the\n * inspector, scrubber, and diff without wiring up a real agent.\n */\nexport async function runDemo(options: DemoOptions): Promise<void> {\n const store = new SessionStore();\n for (const payload of Object.values(otlpFixtures)) {\n for (const run of buildRuns(parseOtlp(payload))) store.addRun(run, { persist: false });\n }\n\n const server = createServer({\n extraHandler: createAppHandler({ store, live: false }, resolveUiDir()),\n });\n const boundPort = await listen(server, options.port, options.host);\n const endpoint = `http://${options.host}:${boundPort}`;\n\n process.stdout.write(\n [\n '',\n ` tracebird — demo mode, ${store.size} sample run(s) loaded`,\n '',\n ` UI ${endpoint}`,\n '',\n ' Try the Diff tab (the two support-triage runs differ on one decision),',\n ' and drag the scrubber to time-travel through a run.',\n '',\n ' (Ctrl-C to stop)',\n '',\n ].join('\\n') + '\\n',\n );\n\n if (options.open) openBrowser(endpoint);\n\n await new Promise<void>((resolveShutdown) => {\n const shutdown = () => {\n process.stdout.write('\\n Stopping…\\n');\n server.close(() => resolveShutdown());\n };\n process.once('SIGINT', shutdown);\n process.once('SIGTERM', shutdown);\n });\n}\n","/**\n * Tiny builders for assembling OTLP/HTTP JSON trace payloads by hand.\n *\n * Intentionally self-contained — fixtures import nothing internal so the\n * project graph stays acyclic (core's tests depend on fixtures, not vice-versa).\n * The emitted shape matches the OTLP/JSON protobuf mapping that\n * `@tracebird/core`'s `parseOtlp` consumes.\n */\n\nexport interface AnyValue {\n stringValue?: string;\n boolValue?: boolean;\n intValue?: string;\n doubleValue?: number;\n arrayValue?: { values: AnyValue[] };\n}\n\nexport interface KeyValue {\n key: string;\n value: AnyValue;\n}\n\nexport type AttrInput = string | number | boolean;\n\nfunction toAnyValue(v: AttrInput): AnyValue {\n if (typeof v === 'string') return { stringValue: v };\n if (typeof v === 'boolean') return { boolValue: v };\n return Number.isInteger(v) ? { intValue: String(v) } : { doubleValue: v };\n}\n\n/** Convert a flat record into an OTLP `KeyValue[]`. */\nexport function attrs(record: Record<string, AttrInput>): KeyValue[] {\n return Object.entries(record).map(([key, v]) => ({ key, value: toAnyValue(v) }));\n}\n\nexport interface SpanInput {\n traceId: string;\n spanId: string;\n parentSpanId?: string;\n name: string;\n kind?: number;\n startTimeUnixNano: string;\n endTimeUnixNano: string;\n attributes?: Record<string, AttrInput>;\n /** OTLP status code: 0 unset, 1 ok, 2 error. */\n statusCode?: number;\n statusMessage?: string;\n}\n\nexport interface OtlpSpanJson {\n traceId: string;\n spanId: string;\n parentSpanId?: string;\n name: string;\n kind: number;\n startTimeUnixNano: string;\n endTimeUnixNano: string;\n attributes: KeyValue[];\n status: { code: number; message?: string };\n}\n\nexport function span(input: SpanInput): OtlpSpanJson {\n return {\n traceId: input.traceId,\n spanId: input.spanId,\n ...(input.parentSpanId ? { parentSpanId: input.parentSpanId } : {}),\n name: input.name,\n kind: input.kind ?? 1,\n startTimeUnixNano: input.startTimeUnixNano,\n endTimeUnixNano: input.endTimeUnixNano,\n attributes: attrs(input.attributes ?? {}),\n status: {\n code: input.statusCode ?? 0,\n ...(input.statusMessage ? { message: input.statusMessage } : {}),\n },\n };\n}\n\nexport interface TraceRequestInput {\n serviceName: string;\n scopeName: string;\n scopeVersion?: string;\n spans: OtlpSpanJson[];\n}\n\n/** Wrap spans into a complete `ExportTraceServiceRequest` JSON payload. */\nexport function traceRequest(input: TraceRequestInput) {\n return {\n resourceSpans: [\n {\n resource: {\n attributes: attrs({ 'service.name': input.serviceName }),\n },\n scopeSpans: [\n {\n scope: {\n name: input.scopeName,\n ...(input.scopeVersion ? { version: input.scopeVersion } : {}),\n },\n spans: input.spans,\n },\n ],\n },\n ],\n };\n}\n\n/** Nanosecond timestamp helper: base epoch-nanos + a millisecond offset. */\nexport function at(baseNano: bigint, offsetMs: number): string {\n return (baseNano + BigInt(offsetMs) * 1_000_000n).toString();\n}\n","import { at, span, traceRequest } from './builders.js';\n\n/**\n * Happy-path, multi-tool agent run: a weather assistant that makes one planning\n * LLM call, fans out to two tools (get_weather, get_forecast), then makes a\n * final LLM call to compose the answer. Uses the OpenLLMetry-style buffered\n * prompt/completion attributes (`gen_ai.prompt.N.*` / `gen_ai.completion.N.*`).\n */\n\nconst BASE = 1733000000000000000n;\nconst TRACE = '0af7651916cd43dd8448eb211c80319c';\n\nconst ROOT = '1111111111111111';\nconst LLM1 = '2222222222222222';\nconst TOOL1 = '3333333333333333';\nconst TOOL2 = '4444444444444444';\nconst LLM2 = '5555555555555555';\n\nexport const weatherHappyPath = traceRequest({\n serviceName: 'weather-assistant',\n scopeName: 'opentelemetry.instrumentation.openai',\n scopeVersion: '0.30.0',\n spans: [\n span({\n traceId: TRACE,\n spanId: ROOT,\n name: 'invoke_agent weather-assistant',\n startTimeUnixNano: at(BASE, 0),\n endTimeUnixNano: at(BASE, 1300),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'invoke_agent',\n 'gen_ai.agent.name': 'weather-assistant',\n 'gen_ai.system': 'openai',\n },\n }),\n span({\n traceId: TRACE,\n spanId: LLM1,\n parentSpanId: ROOT,\n name: 'chat gpt-4o',\n startTimeUnixNano: at(BASE, 10),\n endTimeUnixNano: at(BASE, 520),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'chat',\n 'gen_ai.system': 'openai',\n 'gen_ai.request.model': 'gpt-4o',\n 'gen_ai.response.model': 'gpt-4o-2024-08-06',\n 'gen_ai.request.temperature': 0.7,\n 'gen_ai.usage.input_tokens': 58,\n 'gen_ai.usage.output_tokens': 34,\n 'gen_ai.prompt.0.role': 'system',\n 'gen_ai.prompt.0.content':\n 'You are a helpful weather assistant. Use tools to look up live data before answering.',\n 'gen_ai.prompt.1.role': 'user',\n 'gen_ai.prompt.1.content': 'What should I wear in Paris today?',\n 'gen_ai.completion.0.role': 'assistant',\n 'gen_ai.completion.0.content': '',\n 'gen_ai.completion.0.tool_calls.0.id': 'call_weather',\n 'gen_ai.completion.0.tool_calls.0.name': 'get_weather',\n 'gen_ai.completion.0.tool_calls.0.arguments': '{\"location\":\"Paris\"}',\n 'gen_ai.completion.0.tool_calls.1.id': 'call_forecast',\n 'gen_ai.completion.0.tool_calls.1.name': 'get_forecast',\n 'gen_ai.completion.0.tool_calls.1.arguments': '{\"location\":\"Paris\",\"hours\":12}',\n },\n }),\n span({\n traceId: TRACE,\n spanId: TOOL1,\n parentSpanId: ROOT,\n name: 'execute_tool get_weather',\n startTimeUnixNano: at(BASE, 530),\n endTimeUnixNano: at(BASE, 548),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'execute_tool',\n 'gen_ai.tool.name': 'get_weather',\n 'gen_ai.tool.call.id': 'call_weather',\n 'gen_ai.tool.call.arguments': '{\"location\":\"Paris\"}',\n 'gen_ai.tool.call.result': '{\"tempC\":18,\"condition\":\"sunny\",\"humidity\":0.41}',\n },\n }),\n span({\n traceId: TRACE,\n spanId: TOOL2,\n parentSpanId: ROOT,\n name: 'execute_tool get_forecast',\n startTimeUnixNano: at(BASE, 532),\n endTimeUnixNano: at(BASE, 560),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'execute_tool',\n 'gen_ai.tool.name': 'get_forecast',\n 'gen_ai.tool.call.id': 'call_forecast',\n 'gen_ai.tool.call.arguments': '{\"location\":\"Paris\",\"hours\":12}',\n 'gen_ai.tool.call.result': '{\"highC\":21,\"lowC\":12,\"rain\":false}',\n },\n }),\n span({\n traceId: TRACE,\n spanId: LLM2,\n parentSpanId: ROOT,\n name: 'chat gpt-4o',\n startTimeUnixNano: at(BASE, 580),\n endTimeUnixNano: at(BASE, 1290),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'chat',\n 'gen_ai.system': 'openai',\n 'gen_ai.request.model': 'gpt-4o',\n 'gen_ai.response.model': 'gpt-4o-2024-08-06',\n 'gen_ai.request.temperature': 0.7,\n 'gen_ai.usage.input_tokens': 140,\n 'gen_ai.usage.output_tokens': 42,\n 'gen_ai.prompt.0.role': 'system',\n 'gen_ai.prompt.0.content':\n 'You are a helpful weather assistant. Use tools to look up live data before answering.',\n 'gen_ai.prompt.1.role': 'user',\n 'gen_ai.prompt.1.content': 'What should I wear in Paris today?',\n 'gen_ai.prompt.2.role': 'tool',\n 'gen_ai.prompt.2.content': '{\"tempC\":18,\"condition\":\"sunny\",\"humidity\":0.41}',\n 'gen_ai.prompt.3.role': 'tool',\n 'gen_ai.prompt.3.content': '{\"highC\":21,\"lowC\":12,\"rain\":false}',\n 'gen_ai.completion.0.role': 'assistant',\n 'gen_ai.completion.0.content':\n \"It's 18°C and sunny in Paris, with a high of 21°C and no rain expected. \" +\n \"A light jacket or long sleeves will be perfect — you won't need an umbrella.\",\n },\n }),\n ],\n});\n","import { at, span, traceRequest } from './builders.js';\n\n/**\n * A run where a tool call fails: the model asks for weather in a place the tool\n * can't resolve, the `execute_tool` span carries an ERROR status, and the agent\n * recovers with an apology. Exercises error propagation in the tree.\n */\n\nconst BASE = 1733000100000000000n;\nconst TRACE = 'b2c3d4e5f60718293a4b5c6d7e8f9012';\n\nconst ROOT = 'aa00000000000001';\nconst LLM1 = 'aa00000000000002';\nconst TOOL1 = 'aa00000000000003';\nconst LLM2 = 'aa00000000000004';\n\nexport const toolError = traceRequest({\n serviceName: 'weather-assistant',\n scopeName: 'opentelemetry.instrumentation.openai',\n scopeVersion: '0.30.0',\n spans: [\n span({\n traceId: TRACE,\n spanId: ROOT,\n name: 'invoke_agent weather-assistant',\n startTimeUnixNano: at(BASE, 0),\n endTimeUnixNano: at(BASE, 900),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'invoke_agent',\n 'gen_ai.agent.name': 'weather-assistant',\n 'gen_ai.system': 'openai',\n },\n }),\n span({\n traceId: TRACE,\n spanId: LLM1,\n parentSpanId: ROOT,\n name: 'chat gpt-4o',\n startTimeUnixNano: at(BASE, 8),\n endTimeUnixNano: at(BASE, 410),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'chat',\n 'gen_ai.system': 'openai',\n 'gen_ai.request.model': 'gpt-4o',\n 'gen_ai.response.model': 'gpt-4o-2024-08-06',\n 'gen_ai.usage.input_tokens': 52,\n 'gen_ai.usage.output_tokens': 16,\n 'gen_ai.prompt.0.role': 'user',\n 'gen_ai.prompt.0.content': \"What's the weather in Atlantis?\",\n 'gen_ai.completion.0.role': 'assistant',\n 'gen_ai.completion.0.content': '',\n 'gen_ai.completion.0.tool_calls.0.id': 'call_weather',\n 'gen_ai.completion.0.tool_calls.0.name': 'get_weather',\n 'gen_ai.completion.0.tool_calls.0.arguments': '{\"location\":\"Atlantis\"}',\n },\n }),\n span({\n traceId: TRACE,\n spanId: TOOL1,\n parentSpanId: ROOT,\n name: 'execute_tool get_weather',\n startTimeUnixNano: at(BASE, 420),\n endTimeUnixNano: at(BASE, 438),\n statusCode: 2,\n statusMessage: 'UnknownLocationError: no such location \"Atlantis\"',\n attributes: {\n 'gen_ai.operation.name': 'execute_tool',\n 'gen_ai.tool.name': 'get_weather',\n 'gen_ai.tool.call.id': 'call_weather',\n 'gen_ai.tool.call.arguments': '{\"location\":\"Atlantis\"}',\n 'error.type': 'UnknownLocationError',\n 'gen_ai.tool.call.result': '{\"error\":\"no such location \\\\\"Atlantis\\\\\"\"}',\n },\n }),\n span({\n traceId: TRACE,\n spanId: LLM2,\n parentSpanId: ROOT,\n name: 'chat gpt-4o',\n startTimeUnixNano: at(BASE, 450),\n endTimeUnixNano: at(BASE, 890),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'chat',\n 'gen_ai.system': 'openai',\n 'gen_ai.request.model': 'gpt-4o',\n 'gen_ai.response.model': 'gpt-4o-2024-08-06',\n 'gen_ai.usage.input_tokens': 88,\n 'gen_ai.usage.output_tokens': 28,\n 'gen_ai.prompt.0.role': 'user',\n 'gen_ai.prompt.0.content': \"What's the weather in Atlantis?\",\n 'gen_ai.prompt.1.role': 'tool',\n 'gen_ai.prompt.1.content': '{\"error\":\"no such location \\\\\"Atlantis\\\\\"\"}',\n 'gen_ai.completion.0.role': 'assistant',\n 'gen_ai.completion.0.content':\n 'I couldn\\'t find a place called \"Atlantis\" to look up the weather. Could you double-check the spelling or give me a nearby city?',\n },\n }),\n ],\n});\n","import { at, span, traceRequest } from './builders.js';\n\n/**\n * Two near-identical triage runs over the same support ticket that diverge on a\n * single decision: run A (gpt-4o) assigns priority P1; run B (gpt-4o-mini)\n * assigns P2. Same prompt, same shape — ideal for the diff demo.\n */\n\nconst TICKET =\n 'Customer reports the checkout page returns a 500 error intermittently on mobile Safari. ' +\n 'They have tried twice. No charge was made.';\n\nconst SYSTEM =\n 'You are a support triage agent. Read the ticket and assign a priority from P1 (urgent) to P4 (low).';\n\nfunction triageRun(opts: {\n base: bigint;\n trace: string;\n rootId: string;\n llmId: string;\n model: string;\n responseModel: string;\n outputTokens: number;\n endMs: number;\n completion: string;\n}) {\n return traceRequest({\n serviceName: 'support-triage',\n scopeName: 'opentelemetry.instrumentation.openai',\n scopeVersion: '0.30.0',\n spans: [\n span({\n traceId: opts.trace,\n spanId: opts.rootId,\n name: 'invoke_agent support-triage',\n startTimeUnixNano: at(opts.base, 0),\n endTimeUnixNano: at(opts.base, opts.endMs),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'invoke_agent',\n 'gen_ai.agent.name': 'support-triage',\n 'gen_ai.system': 'openai',\n },\n }),\n span({\n traceId: opts.trace,\n spanId: opts.llmId,\n parentSpanId: opts.rootId,\n name: `chat ${opts.model}`,\n startTimeUnixNano: at(opts.base, 6),\n endTimeUnixNano: at(opts.base, opts.endMs - 4),\n statusCode: 1,\n attributes: {\n 'gen_ai.operation.name': 'chat',\n 'gen_ai.system': 'openai',\n 'gen_ai.request.model': opts.model,\n 'gen_ai.response.model': opts.responseModel,\n 'gen_ai.request.temperature': 0.2,\n 'gen_ai.usage.input_tokens': 96,\n 'gen_ai.usage.output_tokens': opts.outputTokens,\n 'gen_ai.prompt.0.role': 'system',\n 'gen_ai.prompt.0.content': SYSTEM,\n 'gen_ai.prompt.1.role': 'user',\n 'gen_ai.prompt.1.content': TICKET,\n 'gen_ai.completion.0.role': 'assistant',\n 'gen_ai.completion.0.content': opts.completion,\n },\n }),\n ],\n });\n}\n\nexport const diffPairA = triageRun({\n base: 1733000200000000000n,\n trace: 'c1000000000000000000000000000a01',\n rootId: 'c100000000000a01',\n llmId: 'c100000000000a02',\n model: 'gpt-4o',\n responseModel: 'gpt-4o-2024-08-06',\n outputTokens: 54,\n endMs: 640,\n completion:\n 'Priority: P1. A 500 error at checkout blocks revenue and affects all mobile Safari ' +\n 'users intermittently. Escalate to the payments team immediately.',\n});\n\nexport const diffPairB = triageRun({\n base: 1733000300000000000n,\n trace: 'c2000000000000000000000000000b01',\n rootId: 'c200000000000b01',\n llmId: 'c200000000000b02',\n model: 'gpt-4o-mini',\n responseModel: 'gpt-4o-mini-2024-07-18',\n outputTokens: 48,\n endMs: 410,\n completion:\n 'Priority: P2. Checkout returns a 500 on mobile Safari intermittently, but no charge ' +\n 'was made and a retry path exists. Route to the web team for investigation.',\n});\n","import { at, span, traceRequest } from './builders.js';\n\n/**\n * OpenInference (Arize Phoenix) dialect: `openinference.span.kind` + `llm.*` /\n * `tool.*` / `input.value` attributes. A small agent that calls one tool.\n */\n\nconst BASE = 1733000400000000000n;\nconst TRACE = 'd1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1';\nconst ROOT = 'd1000000000000a1';\nconst LLM = 'd1000000000000a2';\nconst TOOL = 'd1000000000000a3';\n\nexport const openinferenceAgent = traceRequest({\n serviceName: 'docs-assistant',\n scopeName: 'openinference.instrumentation.openai',\n scopeVersion: '0.1.0',\n spans: [\n span({\n traceId: TRACE,\n spanId: ROOT,\n name: 'agent',\n startTimeUnixNano: at(BASE, 0),\n endTimeUnixNano: at(BASE, 900),\n statusCode: 1,\n attributes: { 'openinference.span.kind': 'AGENT' },\n }),\n span({\n traceId: TRACE,\n spanId: LLM,\n parentSpanId: ROOT,\n name: 'ChatCompletion',\n startTimeUnixNano: at(BASE, 10),\n endTimeUnixNano: at(BASE, 460),\n statusCode: 1,\n attributes: {\n 'openinference.span.kind': 'LLM',\n 'llm.model_name': 'gpt-4o',\n 'llm.provider': 'openai',\n 'llm.token_count.prompt': 42,\n 'llm.token_count.completion': 18,\n 'llm.input_messages.0.message.role': 'system',\n 'llm.input_messages.0.message.content': 'You answer questions about the docs.',\n 'llm.input_messages.1.message.role': 'user',\n 'llm.input_messages.1.message.content': 'How do I enable telemetry?',\n 'llm.output_messages.0.message.role': 'assistant',\n 'llm.output_messages.0.message.content': '',\n 'llm.output_messages.0.message.tool_calls.0.tool_call.function.name': 'search_docs',\n 'llm.output_messages.0.message.tool_calls.0.tool_call.function.arguments':\n '{\"query\":\"enable telemetry\"}',\n },\n }),\n span({\n traceId: TRACE,\n spanId: TOOL,\n parentSpanId: ROOT,\n name: 'search_docs',\n startTimeUnixNano: at(BASE, 470),\n endTimeUnixNano: at(BASE, 500),\n statusCode: 1,\n attributes: {\n 'openinference.span.kind': 'TOOL',\n 'tool.name': 'search_docs',\n 'input.value': '{\"query\":\"enable telemetry\"}',\n 'output.value': '{\"hits\":[\"Set OTEL_EXPORTER_OTLP_ENDPOINT=…\"]}',\n },\n }),\n ],\n});\n","import { at, span, traceRequest } from './builders.js';\n\n/**\n * Vercel AI SDK dialect: `ai.generateText` wrapper, an inner `.doGenerate`\n * model call, and an `ai.toolCall` span — the shape emitted by\n * `experimental_telemetry`.\n */\n\nconst BASE = 1733000500000000000n;\nconst TRACE = 'e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1';\nconst ROOT = 'e1000000000000b1';\nconst GEN = 'e1000000000000b2';\nconst TOOL = 'e1000000000000b3';\n\nexport const vercelAiSdk = traceRequest({\n serviceName: 'ai-sdk-app',\n scopeName: 'ai',\n scopeVersion: '4.0.0',\n spans: [\n span({\n traceId: TRACE,\n spanId: ROOT,\n name: 'ai.generateText',\n startTimeUnixNano: at(BASE, 0),\n endTimeUnixNano: at(BASE, 1100),\n statusCode: 1,\n attributes: {\n 'ai.model.id': 'gpt-4o',\n 'ai.model.provider': 'openai.chat',\n 'ai.usage.promptTokens': 64,\n 'ai.usage.completionTokens': 30,\n },\n }),\n span({\n traceId: TRACE,\n spanId: GEN,\n parentSpanId: ROOT,\n name: 'ai.generateText.doGenerate',\n startTimeUnixNano: at(BASE, 20),\n endTimeUnixNano: at(BASE, 540),\n statusCode: 1,\n attributes: {\n 'ai.model.id': 'gpt-4o',\n 'ai.model.provider': 'openai.chat',\n 'ai.usage.promptTokens': 64,\n 'ai.usage.completionTokens': 30,\n 'ai.prompt.messages':\n '[{\"role\":\"user\",\"content\":\"What is the weather in San Francisco?\"}]',\n 'ai.response.text': 'Let me check the current conditions in San Francisco.',\n },\n }),\n span({\n traceId: TRACE,\n spanId: TOOL,\n parentSpanId: ROOT,\n name: 'ai.toolCall',\n startTimeUnixNano: at(BASE, 560),\n endTimeUnixNano: at(BASE, 600),\n statusCode: 1,\n attributes: {\n 'ai.toolCall.name': 'getWeather',\n 'ai.toolCall.args': '{\"city\":\"San Francisco\"}',\n 'ai.toolCall.result': '{\"tempC\":17,\"condition\":\"foggy\"}',\n },\n }),\n ],\n});\n","import { at, span, traceRequest } from './builders.js';\n\n/**\n * Claude Code (CLI) enhanced-telemetry dialect: `claude_code.interaction`,\n * `claude_code.llm_request`, `claude_code.tool` spans with bare token counts\n * and `tool_name` / `user_prompt` attributes.\n */\n\nconst BASE = 1733000600000000000n;\nconst TRACE = 'f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1';\nconst ROOT = 'f1000000000000c1';\nconst LLM = 'f1000000000000c2';\nconst TOOL = 'f1000000000000c3';\n\nexport const claudeCodeSession = traceRequest({\n serviceName: 'claude-code',\n scopeName: 'com.anthropic.claude_code',\n scopeVersion: '2.0.0',\n spans: [\n span({\n traceId: TRACE,\n spanId: ROOT,\n name: 'claude_code.interaction',\n startTimeUnixNano: at(BASE, 0),\n endTimeUnixNano: at(BASE, 4200),\n statusCode: 1,\n attributes: {\n 'user_prompt': 'Add a --json flag to the parser CLI',\n 'interaction.sequence': 1,\n },\n }),\n span({\n traceId: TRACE,\n spanId: LLM,\n parentSpanId: ROOT,\n name: 'claude_code.llm_request',\n startTimeUnixNano: at(BASE, 30),\n endTimeUnixNano: at(BASE, 2600),\n statusCode: 1,\n attributes: {\n 'gen_ai.system': 'anthropic',\n 'gen_ai.request.model': 'claude-sonnet-4',\n 'input_tokens': 1840,\n 'output_tokens': 420,\n 'cache_read_tokens': 12000,\n 'gen_ai.response.finish_reasons': 'tool_use',\n 'user_prompt': 'Add a --json flag to the parser CLI',\n },\n }),\n span({\n traceId: TRACE,\n spanId: TOOL,\n parentSpanId: ROOT,\n name: 'claude_code.tool',\n startTimeUnixNano: at(BASE, 2650),\n endTimeUnixNano: at(BASE, 2710),\n statusCode: 1,\n attributes: {\n 'tool_name': 'Edit',\n 'file_path': 'packages/cli/src/parser.ts',\n 'tool_output': 'Applied 1 edit to packages/cli/src/parser.ts',\n },\n }),\n ],\n});\n","/**\n * @tracebird/fixtures — sample OTLP payloads and recorded sessions used by\n * core/cli tests and as demo data for `tracebird open`.\n */\n\nexport * from './otlp/builders.js';\nexport { weatherHappyPath } from './otlp/weather-happy-path.js';\nexport { toolError } from './otlp/tool-error.js';\nexport { diffPairA, diffPairB } from './otlp/diff-pair.js';\nexport { openinferenceAgent } from './otlp/openinference.js';\nexport { vercelAiSdk } from './otlp/vercel-ai-sdk.js';\nexport { claudeCodeSession } from './otlp/claude-code.js';\n\nimport { weatherHappyPath } from './otlp/weather-happy-path.js';\nimport { toolError } from './otlp/tool-error.js';\nimport { diffPairA, diffPairB } from './otlp/diff-pair.js';\nimport { openinferenceAgent } from './otlp/openinference.js';\nimport { vercelAiSdk } from './otlp/vercel-ai-sdk.js';\nimport { claudeCodeSession } from './otlp/claude-code.js';\n\n/** All OTLP request fixtures, keyed by a short name. */\nexport const otlpFixtures = {\n weatherHappyPath,\n toolError,\n diffPairA,\n diffPairB,\n openinferenceAgent,\n vercelAiSdk,\n claudeCodeSession,\n} as const;\n\nexport type OtlpFixtureName = keyof typeof otlpFixtures;\n"],"mappings":"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","names":["resolve","join","span","resolve","resolve","span","StatusCode","StatusCode","join","readFileSync","readFileSync","json","join","existsSync","join","existsSync","dirname","join","join","existsSync","existsSync","parseOtlp","BASE","TRACE","ROOT","LLM1","TOOL1","LLM2","BASE","TRACE","ROOT","BASE","TRACE","ROOT","TOOL","BASE","TRACE","ROOT","LLM","TOOL","parseOtlp","resolve"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tracebird/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "tracebird CLI — a local OTLP receiver and time-travel UI for AI agent runs.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "utsabpanta",
|
|
@@ -37,8 +37,7 @@
|
|
|
37
37
|
"node": ">=20"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"
|
|
41
|
-
"@tracebird/core": "0.1.0"
|
|
40
|
+
"@tracebird/core": "0.1.1"
|
|
42
41
|
},
|
|
43
42
|
"devDependencies": {
|
|
44
43
|
"@tracebird/fixtures": "0.0.1"
|