@agent-inspect/tui 1.6.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-7ZRVYDDE.mjs +159 -0
- package/dist/app-7ZRVYDDE.mjs.map +1 -0
- package/dist/chunk-Z4JCXEIO.mjs +35 -0
- package/dist/chunk-Z4JCXEIO.mjs.map +1 -0
- package/dist/index.cjs +7 -170
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -5
- package/dist/index.d.ts +4 -5
- package/dist/index.mjs +9 -184
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { initialExpandedSet, mapInputToAction } from './chunk-Z4JCXEIO.mjs';
|
|
2
|
+
import { useState, useMemo, useEffect } from 'react';
|
|
3
|
+
import { useApp, useInput, Box, Text } from 'ink';
|
|
4
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
function collectVisible(roots, expanded, out) {
|
|
7
|
+
for (const n of roots) {
|
|
8
|
+
out.push(n);
|
|
9
|
+
if (n.children.length > 0 && expanded.has(n.id)) {
|
|
10
|
+
collectVisible(n.children, expanded, out);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function formatDur(ms) {
|
|
15
|
+
if (ms === void 0 || !Number.isFinite(ms)) return "-";
|
|
16
|
+
if (ms < 1e3) return `${Math.round(ms)}ms`;
|
|
17
|
+
return `${(ms / 1e3).toFixed(2)}s`;
|
|
18
|
+
}
|
|
19
|
+
function TraceViewerApp(props) {
|
|
20
|
+
const { model, onExit } = props;
|
|
21
|
+
const { exit } = useApp();
|
|
22
|
+
const [expanded, setExpanded] = useState(() => initialExpandedSet(model));
|
|
23
|
+
const [sel, setSel] = useState(0);
|
|
24
|
+
const [showHelp, setShowHelp] = useState(false);
|
|
25
|
+
const [showDetails, setShowDetails] = useState(true);
|
|
26
|
+
const visible = useMemo(() => {
|
|
27
|
+
const out = [];
|
|
28
|
+
collectVisible(model.nodes, expanded, out);
|
|
29
|
+
return out;
|
|
30
|
+
}, [model.nodes, expanded]);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (visible.length === 0) {
|
|
33
|
+
setSel(0);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
setSel((i) => Math.min(i, visible.length - 1));
|
|
37
|
+
}, [visible.length]);
|
|
38
|
+
const safeSel = visible.length === 0 ? 0 : Math.min(sel, visible.length - 1);
|
|
39
|
+
const selected = visible[safeSel];
|
|
40
|
+
useInput((input, key) => {
|
|
41
|
+
const action = mapInputToAction(input, key);
|
|
42
|
+
switch (action) {
|
|
43
|
+
case "quit":
|
|
44
|
+
onExit?.();
|
|
45
|
+
exit();
|
|
46
|
+
break;
|
|
47
|
+
case "help":
|
|
48
|
+
setShowHelp((h) => !h);
|
|
49
|
+
break;
|
|
50
|
+
case "details":
|
|
51
|
+
setShowDetails((d) => !d);
|
|
52
|
+
break;
|
|
53
|
+
case "up":
|
|
54
|
+
setSel((i) => Math.max(0, i - 1));
|
|
55
|
+
break;
|
|
56
|
+
case "down":
|
|
57
|
+
setSel((i) => Math.min(Math.max(0, visible.length - 1), i + 1));
|
|
58
|
+
break;
|
|
59
|
+
case "expand": {
|
|
60
|
+
const cur = visible.length === 0 ? void 0 : visible[safeSel];
|
|
61
|
+
if (cur?.children.length) {
|
|
62
|
+
setExpanded((prev) => new Set(prev).add(cur.id));
|
|
63
|
+
}
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case "collapse": {
|
|
67
|
+
const cur = visible.length === 0 ? void 0 : visible[safeSel];
|
|
68
|
+
if (cur && expanded.has(cur.id)) {
|
|
69
|
+
setExpanded((prev) => {
|
|
70
|
+
const n = new Set(prev);
|
|
71
|
+
n.delete(cur.id);
|
|
72
|
+
return n;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case "toggle": {
|
|
78
|
+
const cur = visible.length === 0 ? void 0 : visible[safeSel];
|
|
79
|
+
if (cur?.children.length) {
|
|
80
|
+
setExpanded((prev) => {
|
|
81
|
+
const n = new Set(prev);
|
|
82
|
+
if (n.has(cur.id)) n.delete(cur.id);
|
|
83
|
+
else n.add(cur.id);
|
|
84
|
+
return n;
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
const indent = (d) => " ".repeat(d);
|
|
92
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
93
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
94
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "AgentInspect Trace Viewer" }),
|
|
95
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
96
|
+
model.name ?? "(unnamed)",
|
|
97
|
+
" \xB7 ",
|
|
98
|
+
model.runId,
|
|
99
|
+
" \xB7 ",
|
|
100
|
+
model.status ?? "unknown",
|
|
101
|
+
" \xB7",
|
|
102
|
+
" ",
|
|
103
|
+
formatDur(model.durationMs)
|
|
104
|
+
] })
|
|
105
|
+
] }),
|
|
106
|
+
showHelp ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, borderStyle: "round", paddingX: 1, children: [
|
|
107
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Keys" }),
|
|
108
|
+
/* @__PURE__ */ jsx(Text, { children: "\u2191/\u2193 or j/k \u2014 move \xB7 \u2190/\u2192 or h/l \u2014 collapse/expand \xB7 space \u2014 toggle branch" }),
|
|
109
|
+
/* @__PURE__ */ jsx(Text, { children: "enter \u2014 expand \xB7 d \u2014 toggle details \xB7 ? \u2014 this help \xB7 q / Ctrl+C / esc \u2014 quit" })
|
|
110
|
+
] }) : null,
|
|
111
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
|
|
112
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: "55%", children: [
|
|
113
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Execution tree" }),
|
|
114
|
+
visible.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No steps recorded" }) : visible.map((n, i) => {
|
|
115
|
+
const branch = n.children.length === 0 ? " " : expanded.has(n.id) ? "\u25BC " : "\u25B6 ";
|
|
116
|
+
const row = `${indent(n.depth)}${branch}${n.name}`;
|
|
117
|
+
const mark = i === safeSel ? "\u203A " : " ";
|
|
118
|
+
const status = n.status ?? "?";
|
|
119
|
+
const line = `${mark}${row} (${status})`;
|
|
120
|
+
return /* @__PURE__ */ jsx(Text, { inverse: i === safeSel, children: line }, n.id);
|
|
121
|
+
})
|
|
122
|
+
] }),
|
|
123
|
+
showDetails ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingLeft: 2, width: "45%", children: [
|
|
124
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Details" }),
|
|
125
|
+
selected ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
126
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
127
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "name: " }),
|
|
128
|
+
selected.name
|
|
129
|
+
] }),
|
|
130
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
131
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "type: " }),
|
|
132
|
+
selected.type ?? "-"
|
|
133
|
+
] }),
|
|
134
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
135
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "status: " }),
|
|
136
|
+
selected.status ?? "-"
|
|
137
|
+
] }),
|
|
138
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
139
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "duration: " }),
|
|
140
|
+
formatDur(selected.durationMs)
|
|
141
|
+
] }),
|
|
142
|
+
selected.error ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
143
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "error: " }),
|
|
144
|
+
selected.error
|
|
145
|
+
] }) : null,
|
|
146
|
+
selected.metadata && Object.keys(selected.metadata).length > 0 ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
147
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "metadata: " }),
|
|
148
|
+
JSON.stringify(selected.metadata)
|
|
149
|
+
] }) : null
|
|
150
|
+
] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Select a step" })
|
|
151
|
+
] }) : null
|
|
152
|
+
] }),
|
|
153
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 or j/k move \xB7 enter/space expand \xB7 h/l collapse/expand \xB7 d details \xB7 ? help \xB7 q quit" }) })
|
|
154
|
+
] });
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export { TraceViewerApp };
|
|
158
|
+
//# sourceMappingURL=app-7ZRVYDDE.mjs.map
|
|
159
|
+
//# sourceMappingURL=app-7ZRVYDDE.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/app.tsx"],"names":[],"mappings":"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","file":"app-7ZRVYDDE.mjs","sourcesContent":["import React, { useEffect, useMemo, useState } from \"react\";\nimport { Box, Text, useApp, useInput } from \"ink\";\n\nimport { initialExpandedSet } from \"./expand.js\";\nimport { mapInputToAction } from \"./keymap.js\";\nimport type { TuiTraceModel, TuiTraceNode } from \"./types.js\";\n\nfunction collectVisible(\n roots: TuiTraceNode[],\n expanded: ReadonlySet<string>,\n out: TuiTraceNode[],\n): void {\n for (const n of roots) {\n out.push(n);\n if (n.children.length > 0 && expanded.has(n.id)) {\n collectVisible(n.children, expanded, out);\n }\n }\n}\n\nfunction formatDur(ms: number | undefined): string {\n if (ms === undefined || !Number.isFinite(ms)) return \"-\";\n if (ms < 1000) return `${Math.round(ms)}ms`;\n return `${(ms / 1000).toFixed(2)}s`;\n}\n\nexport interface TraceViewerAppProps {\n model: TuiTraceModel;\n onExit?: () => void;\n}\n\nexport function TraceViewerApp(props: TraceViewerAppProps): React.ReactElement {\n const { model, onExit } = props;\n const { exit } = useApp();\n const [expanded, setExpanded] = useState(() => initialExpandedSet(model));\n const [sel, setSel] = useState(0);\n const [showHelp, setShowHelp] = useState(false);\n const [showDetails, setShowDetails] = useState(true);\n\n const visible = useMemo(() => {\n const out: TuiTraceNode[] = [];\n collectVisible(model.nodes, expanded, out);\n return out;\n }, [model.nodes, expanded]);\n\n useEffect(() => {\n if (visible.length === 0) {\n setSel(0);\n return;\n }\n setSel((i) => Math.min(i, visible.length - 1));\n }, [visible.length]);\n\n const safeSel = visible.length === 0 ? 0 : Math.min(sel, visible.length - 1);\n const selected = visible[safeSel];\n\n useInput((input, key) => {\n const action = mapInputToAction(input, key);\n switch (action) {\n case \"quit\":\n onExit?.();\n exit();\n break;\n case \"help\":\n setShowHelp((h) => !h);\n break;\n case \"details\":\n setShowDetails((d) => !d);\n break;\n case \"up\":\n setSel((i) => Math.max(0, i - 1));\n break;\n case \"down\":\n setSel((i) => Math.min(Math.max(0, visible.length - 1), i + 1));\n break;\n case \"expand\": {\n const cur = visible.length === 0 ? undefined : visible[safeSel];\n if (cur?.children.length) {\n setExpanded((prev) => new Set(prev).add(cur.id));\n }\n break;\n }\n case \"collapse\": {\n const cur = visible.length === 0 ? undefined : visible[safeSel];\n if (cur && expanded.has(cur.id)) {\n setExpanded((prev) => {\n const n = new Set(prev);\n n.delete(cur.id);\n return n;\n });\n }\n break;\n }\n case \"toggle\": {\n const cur = visible.length === 0 ? undefined : visible[safeSel];\n if (cur?.children.length) {\n setExpanded((prev) => {\n const n = new Set(prev);\n if (n.has(cur.id)) n.delete(cur.id);\n else n.add(cur.id);\n return n;\n });\n }\n break;\n }\n default:\n break;\n }\n });\n\n const indent = (d: number) => \" \".repeat(d);\n\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold>AgentInspect Trace Viewer</Text>\n <Text>\n {model.name ?? \"(unnamed)\"} · {model.runId} · {model.status ?? \"unknown\"} ·{\" \"}\n {formatDur(model.durationMs)}\n </Text>\n </Box>\n\n {showHelp ? (\n <Box flexDirection=\"column\" marginBottom={1} borderStyle=\"round\" paddingX={1}>\n <Text bold>Keys</Text>\n <Text>↑/↓ or j/k — move · ←/→ or h/l — collapse/expand · space — toggle branch</Text>\n <Text>enter — expand · d — toggle details · ? — this help · q / Ctrl+C / esc — quit</Text>\n </Box>\n ) : null}\n\n <Box flexDirection=\"row\">\n <Box flexDirection=\"column\" width=\"55%\">\n <Text dimColor>Execution tree</Text>\n {visible.length === 0 ? (\n <Text dimColor>No steps recorded</Text>\n ) : (\n visible.map((n, i) => {\n const branch =\n n.children.length === 0\n ? \" \"\n : expanded.has(n.id)\n ? \"▼ \"\n : \"▶ \";\n const row = `${indent(n.depth)}${branch}${n.name}`;\n const mark = i === safeSel ? \"› \" : \" \";\n const status = n.status ?? \"?\";\n const line = `${mark}${row} (${status})`;\n return (\n <Text key={n.id} inverse={i === safeSel}>\n {line}\n </Text>\n );\n })\n )}\n </Box>\n\n {showDetails ? (\n <Box flexDirection=\"column\" paddingLeft={2} width=\"45%\">\n <Text dimColor>Details</Text>\n {selected ? (\n <>\n <Text>\n <Text bold>name: </Text>\n {selected.name}\n </Text>\n <Text>\n <Text bold>type: </Text>\n {selected.type ?? \"-\"}\n </Text>\n <Text>\n <Text bold>status: </Text>\n {selected.status ?? \"-\"}\n </Text>\n <Text>\n <Text bold>duration: </Text>\n {formatDur(selected.durationMs)}\n </Text>\n {selected.error ? (\n <Text>\n <Text bold>error: </Text>\n {selected.error}\n </Text>\n ) : null}\n {selected.metadata && Object.keys(selected.metadata).length > 0 ? (\n <Text>\n <Text bold>metadata: </Text>\n {JSON.stringify(selected.metadata)}\n </Text>\n ) : null}\n </>\n ) : (\n <Text dimColor>Select a step</Text>\n )}\n </Box>\n ) : null}\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n ↑/↓ or j/k move · enter/space expand · h/l collapse/expand · d details · ? help · q quit\n </Text>\n </Box>\n </Box>\n );\n}\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// packages/tui/src/keymap.ts
|
|
2
|
+
function mapInputToAction(input, key = {}) {
|
|
3
|
+
if (key.escape === true) return "quit";
|
|
4
|
+
if (key.ctrl === true && input === "c") return "quit";
|
|
5
|
+
if (input === "q" || input === "Q") return "quit";
|
|
6
|
+
if (input === "?") return "help";
|
|
7
|
+
if (input === "d" || input === "D") return "details";
|
|
8
|
+
if (key.return === true) return "expand";
|
|
9
|
+
if (input === " ") return "toggle";
|
|
10
|
+
if (key.upArrow === true || input === "k") return "up";
|
|
11
|
+
if (key.downArrow === true || input === "j") return "down";
|
|
12
|
+
if (key.rightArrow === true || input === "l") return "expand";
|
|
13
|
+
if (key.leftArrow === true || input === "h") return "collapse";
|
|
14
|
+
return "unknown";
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// packages/tui/src/expand.ts
|
|
18
|
+
function initialExpandedSet(model) {
|
|
19
|
+
const s = /* @__PURE__ */ new Set();
|
|
20
|
+
const small = model.flatNodes.length <= 15;
|
|
21
|
+
if (small) {
|
|
22
|
+
for (const n of model.flatNodes) {
|
|
23
|
+
if (n.children.length > 0) s.add(n.id);
|
|
24
|
+
}
|
|
25
|
+
return s;
|
|
26
|
+
}
|
|
27
|
+
for (const r of model.nodes) {
|
|
28
|
+
if (r.children.length > 0) s.add(r.id);
|
|
29
|
+
}
|
|
30
|
+
return s;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { initialExpandedSet, mapInputToAction };
|
|
34
|
+
//# sourceMappingURL=chunk-Z4JCXEIO.mjs.map
|
|
35
|
+
//# sourceMappingURL=chunk-Z4JCXEIO.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/keymap.ts","../src/expand.ts"],"names":[],"mappings":";AAYO,SAAS,gBAAA,CACd,KAAA,EACA,GAAA,GAWK,EAAC,EACK;AACX,EAAA,IAAI,GAAA,CAAI,MAAA,KAAW,IAAA,EAAM,OAAO,MAAA;AAChC,EAAA,IAAI,GAAA,CAAI,IAAA,KAAS,IAAA,IAAQ,KAAA,KAAU,KAAK,OAAO,MAAA;AAE/C,EAAA,IAAI,KAAA,KAAU,GAAA,IAAO,KAAA,KAAU,GAAA,EAAK,OAAO,MAAA;AAE3C,EAAA,IAAI,KAAA,KAAU,KAAK,OAAO,MAAA;AAE1B,EAAA,IAAI,KAAA,KAAU,GAAA,IAAO,KAAA,KAAU,GAAA,EAAK,OAAO,SAAA;AAE3C,EAAA,IAAI,GAAA,CAAI,MAAA,KAAW,IAAA,EAAM,OAAO,QAAA;AAEhC,EAAA,IAAI,KAAA,KAAU,KAAK,OAAO,QAAA;AAE1B,EAAA,IAAI,GAAA,CAAI,OAAA,KAAY,IAAA,IAAQ,KAAA,KAAU,KAAK,OAAO,IAAA;AAClD,EAAA,IAAI,GAAA,CAAI,SAAA,KAAc,IAAA,IAAQ,KAAA,KAAU,KAAK,OAAO,MAAA;AACpD,EAAA,IAAI,GAAA,CAAI,UAAA,KAAe,IAAA,IAAQ,KAAA,KAAU,KAAK,OAAO,QAAA;AACrD,EAAA,IAAI,GAAA,CAAI,SAAA,KAAc,IAAA,IAAQ,KAAA,KAAU,KAAK,OAAO,UAAA;AAEpD,EAAA,OAAO,SAAA;AACT;;;AC3CO,SAAS,mBAAmB,KAAA,EAAmC;AACpE,EAAA,MAAM,CAAA,uBAAQ,GAAA,EAAY;AAC1B,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,SAAA,CAAU,MAAA,IAAU,EAAA;AACxC,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,KAAA,MAAW,CAAA,IAAK,MAAM,SAAA,EAAW;AAC/B,MAAA,IAAI,EAAE,QAAA,CAAS,MAAA,GAAS,GAAG,CAAA,CAAE,GAAA,CAAI,EAAE,EAAE,CAAA;AAAA,IACvC;AACA,IAAA,OAAO,CAAA;AAAA,EACT;AACA,EAAA,KAAA,MAAW,CAAA,IAAK,MAAM,KAAA,EAAO;AAC3B,IAAA,IAAI,EAAE,QAAA,CAAS,MAAA,GAAS,GAAG,CAAA,CAAE,GAAA,CAAI,EAAE,EAAE,CAAA;AAAA,EACvC;AACA,EAAA,OAAO,CAAA;AACT","file":"chunk-Z4JCXEIO.mjs","sourcesContent":["export type TuiAction =\n | \"up\"\n | \"down\"\n | \"expand\"\n | \"collapse\"\n | \"toggle\"\n | \"details\"\n | \"help\"\n | \"quit\"\n | \"unknown\";\n\n/** Map Ink `useInput` args to a semantic action. Pure helper for tests. */\nexport function mapInputToAction(\n input: string,\n key: Partial<{\n name: string;\n ctrl: boolean;\n meta: boolean;\n shift: boolean;\n return: boolean;\n escape: boolean;\n upArrow: boolean;\n downArrow: boolean;\n leftArrow: boolean;\n rightArrow: boolean;\n }> = {},\n): TuiAction {\n if (key.escape === true) return \"quit\";\n if (key.ctrl === true && input === \"c\") return \"quit\";\n\n if (input === \"q\" || input === \"Q\") return \"quit\";\n\n if (input === \"?\") return \"help\";\n\n if (input === \"d\" || input === \"D\") return \"details\";\n\n if (key.return === true) return \"expand\";\n\n if (input === \" \") return \"toggle\";\n\n if (key.upArrow === true || input === \"k\") return \"up\";\n if (key.downArrow === true || input === \"j\") return \"down\";\n if (key.rightArrow === true || input === \"l\") return \"expand\";\n if (key.leftArrow === true || input === \"h\") return \"collapse\";\n\n return \"unknown\";\n}\n","import type { TuiTraceModel } from \"./types.js\";\n\n/** Small traces: expand all branches. Larger traces: only root rows expanded (show first nesting level). */\nexport function initialExpandedSet(model: TuiTraceModel): Set<string> {\n const s = new Set<string>();\n const small = model.flatNodes.length <= 15;\n if (small) {\n for (const n of model.flatNodes) {\n if (n.children.length > 0) s.add(n.id);\n }\n return s;\n }\n for (const r of model.nodes) {\n if (r.children.length > 0) s.add(r.id);\n }\n return s;\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var agentInspect = require('agent-inspect');
|
|
4
|
-
var React2 = require('react');
|
|
5
|
-
var ink = require('ink');
|
|
6
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
-
|
|
8
|
-
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
-
|
|
10
|
-
var React2__default = /*#__PURE__*/_interopDefault(React2);
|
|
11
4
|
|
|
12
5
|
// packages/tui/src/tree-model.ts
|
|
13
6
|
function dfsFlat(roots, out) {
|
|
@@ -130,14 +123,8 @@ function mapInputToAction(input, key = {}) {
|
|
|
130
123
|
if (key.leftArrow === true || input === "h") return "collapse";
|
|
131
124
|
return "unknown";
|
|
132
125
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
out.push(n);
|
|
136
|
-
if (n.children.length > 0 && expanded.has(n.id)) {
|
|
137
|
-
collectVisible(n.children, expanded, out);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
126
|
+
|
|
127
|
+
// packages/tui/src/expand.ts
|
|
141
128
|
function initialExpandedSet(model) {
|
|
142
129
|
const s = /* @__PURE__ */ new Set();
|
|
143
130
|
const small = model.flatNodes.length <= 15;
|
|
@@ -152,164 +139,14 @@ function initialExpandedSet(model) {
|
|
|
152
139
|
}
|
|
153
140
|
return s;
|
|
154
141
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (ms < 1e3) return `${Math.round(ms)}ms`;
|
|
158
|
-
return `${(ms / 1e3).toFixed(2)}s`;
|
|
159
|
-
}
|
|
160
|
-
function TraceViewerApp(props) {
|
|
161
|
-
const { model, onExit } = props;
|
|
162
|
-
const { exit } = ink.useApp();
|
|
163
|
-
const [expanded, setExpanded] = React2.useState(() => initialExpandedSet(model));
|
|
164
|
-
const [sel, setSel] = React2.useState(0);
|
|
165
|
-
const [showHelp, setShowHelp] = React2.useState(false);
|
|
166
|
-
const [showDetails, setShowDetails] = React2.useState(true);
|
|
167
|
-
const visible = React2.useMemo(() => {
|
|
168
|
-
const out = [];
|
|
169
|
-
collectVisible(model.nodes, expanded, out);
|
|
170
|
-
return out;
|
|
171
|
-
}, [model.nodes, expanded]);
|
|
172
|
-
React2.useEffect(() => {
|
|
173
|
-
if (visible.length === 0) {
|
|
174
|
-
setSel(0);
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
setSel((i) => Math.min(i, visible.length - 1));
|
|
178
|
-
}, [visible.length]);
|
|
179
|
-
const safeSel = visible.length === 0 ? 0 : Math.min(sel, visible.length - 1);
|
|
180
|
-
const selected = visible[safeSel];
|
|
181
|
-
ink.useInput((input, key) => {
|
|
182
|
-
const action = mapInputToAction(input, key);
|
|
183
|
-
switch (action) {
|
|
184
|
-
case "quit":
|
|
185
|
-
onExit?.();
|
|
186
|
-
exit();
|
|
187
|
-
break;
|
|
188
|
-
case "help":
|
|
189
|
-
setShowHelp((h) => !h);
|
|
190
|
-
break;
|
|
191
|
-
case "details":
|
|
192
|
-
setShowDetails((d) => !d);
|
|
193
|
-
break;
|
|
194
|
-
case "up":
|
|
195
|
-
setSel((i) => Math.max(0, i - 1));
|
|
196
|
-
break;
|
|
197
|
-
case "down":
|
|
198
|
-
setSel((i) => Math.min(Math.max(0, visible.length - 1), i + 1));
|
|
199
|
-
break;
|
|
200
|
-
case "expand": {
|
|
201
|
-
const cur = visible.length === 0 ? void 0 : visible[safeSel];
|
|
202
|
-
if (cur?.children.length) {
|
|
203
|
-
setExpanded((prev) => new Set(prev).add(cur.id));
|
|
204
|
-
}
|
|
205
|
-
break;
|
|
206
|
-
}
|
|
207
|
-
case "collapse": {
|
|
208
|
-
const cur = visible.length === 0 ? void 0 : visible[safeSel];
|
|
209
|
-
if (cur && expanded.has(cur.id)) {
|
|
210
|
-
setExpanded((prev) => {
|
|
211
|
-
const n = new Set(prev);
|
|
212
|
-
n.delete(cur.id);
|
|
213
|
-
return n;
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
break;
|
|
217
|
-
}
|
|
218
|
-
case "toggle": {
|
|
219
|
-
const cur = visible.length === 0 ? void 0 : visible[safeSel];
|
|
220
|
-
if (cur?.children.length) {
|
|
221
|
-
setExpanded((prev) => {
|
|
222
|
-
const n = new Set(prev);
|
|
223
|
-
if (n.has(cur.id)) n.delete(cur.id);
|
|
224
|
-
else n.add(cur.id);
|
|
225
|
-
return n;
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
const indent = (d) => " ".repeat(d);
|
|
233
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [
|
|
234
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
235
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { bold: true, children: "AgentInspect Trace Viewer" }),
|
|
236
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { children: [
|
|
237
|
-
model.name ?? "(unnamed)",
|
|
238
|
-
" \xB7 ",
|
|
239
|
-
model.runId,
|
|
240
|
-
" \xB7 ",
|
|
241
|
-
model.status ?? "unknown",
|
|
242
|
-
" \xB7",
|
|
243
|
-
" ",
|
|
244
|
-
formatDur(model.durationMs)
|
|
245
|
-
] })
|
|
246
|
-
] }),
|
|
247
|
-
showHelp ? /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { flexDirection: "column", marginBottom: 1, borderStyle: "round", paddingX: 1, children: [
|
|
248
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { bold: true, children: "Keys" }),
|
|
249
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { children: "\u2191/\u2193 or j/k \u2014 move \xB7 \u2190/\u2192 or h/l \u2014 collapse/expand \xB7 space \u2014 toggle branch" }),
|
|
250
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { children: "enter \u2014 expand \xB7 d \u2014 toggle details \xB7 ? \u2014 this help \xB7 q / Ctrl+C / esc \u2014 quit" })
|
|
251
|
-
] }) : null,
|
|
252
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { flexDirection: "row", children: [
|
|
253
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { flexDirection: "column", width: "55%", children: [
|
|
254
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { dimColor: true, children: "Execution tree" }),
|
|
255
|
-
visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { dimColor: true, children: "No steps recorded" }) : visible.map((n, i) => {
|
|
256
|
-
const branch = n.children.length === 0 ? " " : expanded.has(n.id) ? "\u25BC " : "\u25B6 ";
|
|
257
|
-
const row = `${indent(n.depth)}${branch}${n.name}`;
|
|
258
|
-
const mark = i === safeSel ? "\u203A " : " ";
|
|
259
|
-
const status = n.status ?? "?";
|
|
260
|
-
const line = `${mark}${row} (${status})`;
|
|
261
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { inverse: i === safeSel, children: line }, n.id);
|
|
262
|
-
})
|
|
263
|
-
] }),
|
|
264
|
-
showDetails ? /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { flexDirection: "column", paddingLeft: 2, width: "45%", children: [
|
|
265
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { dimColor: true, children: "Details" }),
|
|
266
|
-
selected ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
267
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { children: [
|
|
268
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { bold: true, children: "name: " }),
|
|
269
|
-
selected.name
|
|
270
|
-
] }),
|
|
271
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { children: [
|
|
272
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { bold: true, children: "type: " }),
|
|
273
|
-
selected.type ?? "-"
|
|
274
|
-
] }),
|
|
275
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { children: [
|
|
276
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { bold: true, children: "status: " }),
|
|
277
|
-
selected.status ?? "-"
|
|
278
|
-
] }),
|
|
279
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { children: [
|
|
280
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { bold: true, children: "duration: " }),
|
|
281
|
-
formatDur(selected.durationMs)
|
|
282
|
-
] }),
|
|
283
|
-
selected.error ? /* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { children: [
|
|
284
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { bold: true, children: "error: " }),
|
|
285
|
-
selected.error
|
|
286
|
-
] }) : null,
|
|
287
|
-
selected.metadata && Object.keys(selected.metadata).length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { children: [
|
|
288
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Text, { bold: true, children: "metadata: " }),
|
|
289
|
-
JSON.stringify(selected.metadata)
|
|
290
|
-
] }) : null
|
|
291
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { dimColor: true, children: "Select a step" })
|
|
292
|
-
] }) : null
|
|
293
|
-
] }),
|
|
294
|
-
/* @__PURE__ */ jsxRuntime.jsx(ink.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { dimColor: true, children: "\u2191/\u2193 or j/k move \xB7 enter/space expand \xB7 h/l collapse/expand \xB7 d details \xB7 ? help \xB7 q quit" }) })
|
|
295
|
-
] });
|
|
296
|
-
}
|
|
297
|
-
var TTY_MSG = "TUI requires an interactive terminal. Use agent-inspect view without --tui for plain output.";
|
|
142
|
+
|
|
143
|
+
// packages/tui/src/index-cjs.ts
|
|
298
144
|
async function runTraceViewer(options) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
const model = await loadTraceForTui({
|
|
303
|
-
runId: options.runId,
|
|
304
|
-
dir: options.dir
|
|
305
|
-
});
|
|
306
|
-
const { waitUntilExit } = ink.render(
|
|
307
|
-
React2__default.default.createElement(TraceViewerApp, { model })
|
|
308
|
-
);
|
|
309
|
-
await waitUntilExit();
|
|
145
|
+
const esmEntry = "./index.mjs";
|
|
146
|
+
const mod = await import(esmEntry);
|
|
147
|
+
return mod.runTraceViewer(options);
|
|
310
148
|
}
|
|
311
149
|
|
|
312
|
-
exports.TraceViewerApp = TraceViewerApp;
|
|
313
150
|
exports.buildTuiTraceModel = buildTuiTraceModel;
|
|
314
151
|
exports.countTreeSteps = countTreeSteps;
|
|
315
152
|
exports.initialExpandedSet = initialExpandedSet;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tree-model.ts","../src/trace-loader.ts","../src/keymap.ts","../src/app.tsx","../src/run-viewer.ts"],"names":["resolveTraceDir","readTraceEvents","useApp","useState","useMemo","useEffect","useInput","jsxs","Box","jsx","Text","Fragment","render","React"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n RunCompletedEvent,\n RunStartedEvent,\n StepCompletedEvent,\n StepStartedEvent,\n TraceEvent,\n} from \"agent-inspect\";\n\nimport type { TuiTraceModel, TuiTraceNode } from \"./types.js\";\n\ntype StepBuild = {\n id: string;\n parentId?: string;\n name: string;\n type: string;\n status: string;\n durationMs?: number;\n startedAt: number;\n error?: string;\n metadata?: Record<string, unknown>;\n children: StepBuild[];\n};\n\nfunction dfsFlat(roots: TuiTraceNode[], out: TuiTraceNode[]): void {\n for (const n of roots) {\n out.push(n);\n if (n.children.length > 0) dfsFlat(n.children, out);\n }\n}\n\nfunction toTuiNodes(builds: StepBuild[], depth: number): TuiTraceNode[] {\n return builds.map((b) => ({\n id: b.id,\n name: b.name,\n type: b.type,\n status: b.status,\n durationMs: b.durationMs,\n depth,\n parentId: b.parentId,\n error: b.error,\n metadata: b.metadata,\n children: toTuiNodes(b.children, depth + 1),\n }));\n}\n\n/**\n * Build a navigable tree model from v0.1 JSONL trace events.\n * Does not mutate the input array or event objects.\n */\nexport function buildTuiTraceModel(events: TraceEvent[]): TuiTraceModel {\n const started = events.find((e): e is RunStartedEvent => e.event === \"run_started\");\n if (!started) {\n throw new Error(\"Invalid trace: missing run_started\");\n }\n\n const runId = started.runId;\n const runName = started.name;\n\n const completedAll = events.filter((e): e is RunCompletedEvent => e.event === \"run_completed\");\n const lastCompleted = completedAll[completedAll.length - 1];\n const runStatus = lastCompleted ? lastCompleted.status : \"running\";\n const runDurationMs =\n lastCompleted !== undefined && Number.isFinite(lastCompleted.durationMs)\n ? lastCompleted.durationMs\n : undefined;\n\n const nodes = new Map<string, StepBuild>();\n\n for (const e of events) {\n if (e.event !== \"step_started\") continue;\n const s = e as StepStartedEvent;\n nodes.set(s.stepId, {\n id: s.stepId,\n parentId: s.parentId,\n name: s.name,\n type: s.type,\n status: \"running\",\n startedAt: s.startTime,\n metadata: s.metadata as Record<string, unknown> | undefined,\n children: [],\n });\n }\n\n for (const e of events) {\n if (e.event !== \"step_completed\") continue;\n const c = e as StepCompletedEvent;\n const node = nodes.get(c.stepId);\n if (!node) continue;\n node.status = c.status;\n node.durationMs = c.durationMs;\n node.error =\n c.error !== undefined && typeof c.error.message === \"string\"\n ? c.error.message\n : undefined;\n }\n\n const roots: StepBuild[] = [];\n const sortByStarted = (a: StepBuild, b: StepBuild) => a.startedAt - b.startedAt;\n\n for (const n of nodes.values()) {\n if (n.parentId !== undefined && nodes.has(n.parentId)) {\n nodes.get(n.parentId)!.children.push(n);\n } else {\n roots.push(n);\n }\n }\n\n roots.sort(sortByStarted);\n for (const n of nodes.values()) {\n n.children.sort(sortByStarted);\n }\n\n const treeRoots = toTuiNodes(roots, 0);\n const flatNodes: TuiTraceNode[] = [];\n dfsFlat(treeRoots, flatNodes);\n\n return {\n runId,\n name: runName,\n status: runStatus,\n durationMs: runDurationMs,\n nodes: treeRoots,\n flatNodes,\n };\n}\n\n/** Total step count in tree (for default expand policy). Exported for tests. */\nexport function countTreeSteps(roots: TuiTraceNode[]): number {\n let n = 0;\n for (const r of roots) {\n n += 1 + countSubtree(r.children);\n }\n return n;\n}\n\nfunction countSubtree(children: TuiTraceNode[]): number {\n let n = 0;\n for (const c of children) {\n n += 1 + countSubtree(c.children);\n }\n return n;\n}\n","import { readTraceEvents, resolveTraceDir } from \"agent-inspect\";\n\nimport { buildTuiTraceModel } from \"./tree-model.js\";\nimport type { TuiTraceModel } from \"./types.js\";\n\nexport interface LoadTraceForTuiOptions {\n runId: string;\n dir?: string;\n}\n\n/**\n * Load JSONL trace events and build a TUI model. Does not write or mutate trace files.\n */\nexport async function loadTraceForTui(options: LoadTraceForTuiOptions): Promise<TuiTraceModel> {\n const traceDir = resolveTraceDir({ dir: options.dir });\n const events = await readTraceEvents(options.runId, traceDir);\n\n if (events.length === 0) {\n throw new Error(\n `Run not found or trace is empty: ${options.runId} (directory: ${traceDir})`,\n );\n }\n\n return buildTuiTraceModel(events);\n}\n","export type TuiAction =\n | \"up\"\n | \"down\"\n | \"expand\"\n | \"collapse\"\n | \"toggle\"\n | \"details\"\n | \"help\"\n | \"quit\"\n | \"unknown\";\n\n/** Map Ink `useInput` args to a semantic action. Pure helper for tests. */\nexport function mapInputToAction(\n input: string,\n key: Partial<{\n name: string;\n ctrl: boolean;\n meta: boolean;\n shift: boolean;\n return: boolean;\n escape: boolean;\n upArrow: boolean;\n downArrow: boolean;\n leftArrow: boolean;\n rightArrow: boolean;\n }> = {},\n): TuiAction {\n if (key.escape === true) return \"quit\";\n if (key.ctrl === true && input === \"c\") return \"quit\";\n\n if (input === \"q\" || input === \"Q\") return \"quit\";\n\n if (input === \"?\") return \"help\";\n\n if (input === \"d\" || input === \"D\") return \"details\";\n\n if (key.return === true) return \"expand\";\n\n if (input === \" \") return \"toggle\";\n\n if (key.upArrow === true || input === \"k\") return \"up\";\n if (key.downArrow === true || input === \"j\") return \"down\";\n if (key.rightArrow === true || input === \"l\") return \"expand\";\n if (key.leftArrow === true || input === \"h\") return \"collapse\";\n\n return \"unknown\";\n}\n","import React, { useEffect, useMemo, useState } from \"react\";\nimport { Box, Text, useApp, useInput } from \"ink\";\n\nimport { mapInputToAction } from \"./keymap.js\";\nimport type { TuiTraceModel, TuiTraceNode } from \"./types.js\";\n\nfunction collectVisible(\n roots: TuiTraceNode[],\n expanded: ReadonlySet<string>,\n out: TuiTraceNode[],\n): void {\n for (const n of roots) {\n out.push(n);\n if (n.children.length > 0 && expanded.has(n.id)) {\n collectVisible(n.children, expanded, out);\n }\n }\n}\n\n/** Small traces: expand all branches. Larger traces: only root rows expanded (show first nesting level). */\nexport function initialExpandedSet(model: TuiTraceModel): Set<string> {\n const s = new Set<string>();\n const small = model.flatNodes.length <= 15;\n if (small) {\n for (const n of model.flatNodes) {\n if (n.children.length > 0) s.add(n.id);\n }\n return s;\n }\n for (const r of model.nodes) {\n if (r.children.length > 0) s.add(r.id);\n }\n return s;\n}\n\nfunction formatDur(ms: number | undefined): string {\n if (ms === undefined || !Number.isFinite(ms)) return \"-\";\n if (ms < 1000) return `${Math.round(ms)}ms`;\n return `${(ms / 1000).toFixed(2)}s`;\n}\n\nexport interface TraceViewerAppProps {\n model: TuiTraceModel;\n onExit?: () => void;\n}\n\nexport function TraceViewerApp(props: TraceViewerAppProps): React.ReactElement {\n const { model, onExit } = props;\n const { exit } = useApp();\n const [expanded, setExpanded] = useState(() => initialExpandedSet(model));\n const [sel, setSel] = useState(0);\n const [showHelp, setShowHelp] = useState(false);\n const [showDetails, setShowDetails] = useState(true);\n\n const visible = useMemo(() => {\n const out: TuiTraceNode[] = [];\n collectVisible(model.nodes, expanded, out);\n return out;\n }, [model.nodes, expanded]);\n\n useEffect(() => {\n if (visible.length === 0) {\n setSel(0);\n return;\n }\n setSel((i) => Math.min(i, visible.length - 1));\n }, [visible.length]);\n\n const safeSel = visible.length === 0 ? 0 : Math.min(sel, visible.length - 1);\n const selected = visible[safeSel];\n\n useInput((input, key) => {\n const action = mapInputToAction(input, key);\n switch (action) {\n case \"quit\":\n onExit?.();\n exit();\n break;\n case \"help\":\n setShowHelp((h) => !h);\n break;\n case \"details\":\n setShowDetails((d) => !d);\n break;\n case \"up\":\n setSel((i) => Math.max(0, i - 1));\n break;\n case \"down\":\n setSel((i) => Math.min(Math.max(0, visible.length - 1), i + 1));\n break;\n case \"expand\": {\n const cur = visible.length === 0 ? undefined : visible[safeSel];\n if (cur?.children.length) {\n setExpanded((prev) => new Set(prev).add(cur.id));\n }\n break;\n }\n case \"collapse\": {\n const cur = visible.length === 0 ? undefined : visible[safeSel];\n if (cur && expanded.has(cur.id)) {\n setExpanded((prev) => {\n const n = new Set(prev);\n n.delete(cur.id);\n return n;\n });\n }\n break;\n }\n case \"toggle\": {\n const cur = visible.length === 0 ? undefined : visible[safeSel];\n if (cur?.children.length) {\n setExpanded((prev) => {\n const n = new Set(prev);\n if (n.has(cur.id)) n.delete(cur.id);\n else n.add(cur.id);\n return n;\n });\n }\n break;\n }\n default:\n break;\n }\n });\n\n const indent = (d: number) => \" \".repeat(d);\n\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold>AgentInspect Trace Viewer</Text>\n <Text>\n {model.name ?? \"(unnamed)\"} · {model.runId} · {model.status ?? \"unknown\"} ·{\" \"}\n {formatDur(model.durationMs)}\n </Text>\n </Box>\n\n {showHelp ? (\n <Box flexDirection=\"column\" marginBottom={1} borderStyle=\"round\" paddingX={1}>\n <Text bold>Keys</Text>\n <Text>↑/↓ or j/k — move · ←/→ or h/l — collapse/expand · space — toggle branch</Text>\n <Text>enter — expand · d — toggle details · ? — this help · q / Ctrl+C / esc — quit</Text>\n </Box>\n ) : null}\n\n <Box flexDirection=\"row\">\n <Box flexDirection=\"column\" width=\"55%\">\n <Text dimColor>Execution tree</Text>\n {visible.length === 0 ? (\n <Text dimColor>No steps recorded</Text>\n ) : (\n visible.map((n, i) => {\n const branch =\n n.children.length === 0\n ? \" \"\n : expanded.has(n.id)\n ? \"▼ \"\n : \"▶ \";\n const row = `${indent(n.depth)}${branch}${n.name}`;\n const mark = i === safeSel ? \"› \" : \" \";\n const status = n.status ?? \"?\";\n const line = `${mark}${row} (${status})`;\n return (\n <Text key={n.id} inverse={i === safeSel}>\n {line}\n </Text>\n );\n })\n )}\n </Box>\n\n {showDetails ? (\n <Box flexDirection=\"column\" paddingLeft={2} width=\"45%\">\n <Text dimColor>Details</Text>\n {selected ? (\n <>\n <Text>\n <Text bold>name: </Text>\n {selected.name}\n </Text>\n <Text>\n <Text bold>type: </Text>\n {selected.type ?? \"-\"}\n </Text>\n <Text>\n <Text bold>status: </Text>\n {selected.status ?? \"-\"}\n </Text>\n <Text>\n <Text bold>duration: </Text>\n {formatDur(selected.durationMs)}\n </Text>\n {selected.error ? (\n <Text>\n <Text bold>error: </Text>\n {selected.error}\n </Text>\n ) : null}\n {selected.metadata && Object.keys(selected.metadata).length > 0 ? (\n <Text>\n <Text bold>metadata: </Text>\n {JSON.stringify(selected.metadata)}\n </Text>\n ) : null}\n </>\n ) : (\n <Text dimColor>Select a step</Text>\n )}\n </Box>\n ) : null}\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n ↑/↓ or j/k move · enter/space expand · h/l collapse/expand · d details · ? help · q quit\n </Text>\n </Box>\n </Box>\n );\n}\n","import React from \"react\";\nimport { render } from \"ink\";\n\nimport { TraceViewerApp } from \"./app.js\";\nimport { loadTraceForTui } from \"./trace-loader.js\";\n\nexport interface RunTraceViewerOptions {\n runId: string;\n dir?: string;\n}\n\nconst TTY_MSG =\n \"TUI requires an interactive terminal. Use agent-inspect view without --tui for plain output.\";\n\nexport async function runTraceViewer(options: RunTraceViewerOptions): Promise<void> {\n if (!process.stdout.isTTY || !process.stdin.isTTY) {\n throw new Error(TTY_MSG);\n }\n\n const model = await loadTraceForTui({\n runId: options.runId,\n dir: options.dir,\n });\n\n const { waitUntilExit } = render(\n React.createElement(TraceViewerApp, { model }),\n );\n await waitUntilExit();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/tree-model.ts","../src/trace-loader.ts","../src/keymap.ts","../src/expand.ts","../src/index-cjs.ts"],"names":["resolveTraceDir","readTraceEvents"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n RunCompletedEvent,\n RunStartedEvent,\n StepCompletedEvent,\n StepStartedEvent,\n TraceEvent,\n} from \"agent-inspect\";\n\nimport type { TuiTraceModel, TuiTraceNode } from \"./types.js\";\n\ntype StepBuild = {\n id: string;\n parentId?: string;\n name: string;\n type: string;\n status: string;\n durationMs?: number;\n startedAt: number;\n error?: string;\n metadata?: Record<string, unknown>;\n children: StepBuild[];\n};\n\nfunction dfsFlat(roots: TuiTraceNode[], out: TuiTraceNode[]): void {\n for (const n of roots) {\n out.push(n);\n if (n.children.length > 0) dfsFlat(n.children, out);\n }\n}\n\nfunction toTuiNodes(builds: StepBuild[], depth: number): TuiTraceNode[] {\n return builds.map((b) => ({\n id: b.id,\n name: b.name,\n type: b.type,\n status: b.status,\n durationMs: b.durationMs,\n depth,\n parentId: b.parentId,\n error: b.error,\n metadata: b.metadata,\n children: toTuiNodes(b.children, depth + 1),\n }));\n}\n\n/**\n * Build a navigable tree model from v0.1 JSONL trace events.\n * Does not mutate the input array or event objects.\n */\nexport function buildTuiTraceModel(events: TraceEvent[]): TuiTraceModel {\n const started = events.find((e): e is RunStartedEvent => e.event === \"run_started\");\n if (!started) {\n throw new Error(\"Invalid trace: missing run_started\");\n }\n\n const runId = started.runId;\n const runName = started.name;\n\n const completedAll = events.filter((e): e is RunCompletedEvent => e.event === \"run_completed\");\n const lastCompleted = completedAll[completedAll.length - 1];\n const runStatus = lastCompleted ? lastCompleted.status : \"running\";\n const runDurationMs =\n lastCompleted !== undefined && Number.isFinite(lastCompleted.durationMs)\n ? lastCompleted.durationMs\n : undefined;\n\n const nodes = new Map<string, StepBuild>();\n\n for (const e of events) {\n if (e.event !== \"step_started\") continue;\n const s = e as StepStartedEvent;\n nodes.set(s.stepId, {\n id: s.stepId,\n parentId: s.parentId,\n name: s.name,\n type: s.type,\n status: \"running\",\n startedAt: s.startTime,\n metadata: s.metadata as Record<string, unknown> | undefined,\n children: [],\n });\n }\n\n for (const e of events) {\n if (e.event !== \"step_completed\") continue;\n const c = e as StepCompletedEvent;\n const node = nodes.get(c.stepId);\n if (!node) continue;\n node.status = c.status;\n node.durationMs = c.durationMs;\n node.error =\n c.error !== undefined && typeof c.error.message === \"string\"\n ? c.error.message\n : undefined;\n }\n\n const roots: StepBuild[] = [];\n const sortByStarted = (a: StepBuild, b: StepBuild) => a.startedAt - b.startedAt;\n\n for (const n of nodes.values()) {\n if (n.parentId !== undefined && nodes.has(n.parentId)) {\n nodes.get(n.parentId)!.children.push(n);\n } else {\n roots.push(n);\n }\n }\n\n roots.sort(sortByStarted);\n for (const n of nodes.values()) {\n n.children.sort(sortByStarted);\n }\n\n const treeRoots = toTuiNodes(roots, 0);\n const flatNodes: TuiTraceNode[] = [];\n dfsFlat(treeRoots, flatNodes);\n\n return {\n runId,\n name: runName,\n status: runStatus,\n durationMs: runDurationMs,\n nodes: treeRoots,\n flatNodes,\n };\n}\n\n/** Total step count in tree (for default expand policy). Exported for tests. */\nexport function countTreeSteps(roots: TuiTraceNode[]): number {\n let n = 0;\n for (const r of roots) {\n n += 1 + countSubtree(r.children);\n }\n return n;\n}\n\nfunction countSubtree(children: TuiTraceNode[]): number {\n let n = 0;\n for (const c of children) {\n n += 1 + countSubtree(c.children);\n }\n return n;\n}\n","import { readTraceEvents, resolveTraceDir } from \"agent-inspect\";\n\nimport { buildTuiTraceModel } from \"./tree-model.js\";\nimport type { TuiTraceModel } from \"./types.js\";\n\nexport interface LoadTraceForTuiOptions {\n runId: string;\n dir?: string;\n}\n\n/**\n * Load JSONL trace events and build a TUI model. Does not write or mutate trace files.\n */\nexport async function loadTraceForTui(options: LoadTraceForTuiOptions): Promise<TuiTraceModel> {\n const traceDir = resolveTraceDir({ dir: options.dir });\n const events = await readTraceEvents(options.runId, traceDir);\n\n if (events.length === 0) {\n throw new Error(\n `Run not found or trace is empty: ${options.runId} (directory: ${traceDir})`,\n );\n }\n\n return buildTuiTraceModel(events);\n}\n","export type TuiAction =\n | \"up\"\n | \"down\"\n | \"expand\"\n | \"collapse\"\n | \"toggle\"\n | \"details\"\n | \"help\"\n | \"quit\"\n | \"unknown\";\n\n/** Map Ink `useInput` args to a semantic action. Pure helper for tests. */\nexport function mapInputToAction(\n input: string,\n key: Partial<{\n name: string;\n ctrl: boolean;\n meta: boolean;\n shift: boolean;\n return: boolean;\n escape: boolean;\n upArrow: boolean;\n downArrow: boolean;\n leftArrow: boolean;\n rightArrow: boolean;\n }> = {},\n): TuiAction {\n if (key.escape === true) return \"quit\";\n if (key.ctrl === true && input === \"c\") return \"quit\";\n\n if (input === \"q\" || input === \"Q\") return \"quit\";\n\n if (input === \"?\") return \"help\";\n\n if (input === \"d\" || input === \"D\") return \"details\";\n\n if (key.return === true) return \"expand\";\n\n if (input === \" \") return \"toggle\";\n\n if (key.upArrow === true || input === \"k\") return \"up\";\n if (key.downArrow === true || input === \"j\") return \"down\";\n if (key.rightArrow === true || input === \"l\") return \"expand\";\n if (key.leftArrow === true || input === \"h\") return \"collapse\";\n\n return \"unknown\";\n}\n","import type { TuiTraceModel } from \"./types.js\";\n\n/** Small traces: expand all branches. Larger traces: only root rows expanded (show first nesting level). */\nexport function initialExpandedSet(model: TuiTraceModel): Set<string> {\n const s = new Set<string>();\n const small = model.flatNodes.length <= 15;\n if (small) {\n for (const n of model.flatNodes) {\n if (n.children.length > 0) s.add(n.id);\n }\n return s;\n }\n for (const r of model.nodes) {\n if (r.children.length > 0) s.add(r.id);\n }\n return s;\n}\n","/**\n * @experimental Optional TUI package CommonJS entry.\n *\n * Keep this entry free of eager Ink imports so `require(\"@agent-inspect/tui\")`\n * can load pure helpers even though Ink is ESM with top-level await.\n */\nexport type { TuiTraceModel, TuiTraceNode } from \"./types.js\";\nexport { buildTuiTraceModel, countTreeSteps } from \"./tree-model.js\";\nexport type { LoadTraceForTuiOptions } from \"./trace-loader.js\";\nexport { loadTraceForTui } from \"./trace-loader.js\";\nexport type { TuiAction } from \"./keymap.js\";\nexport { mapInputToAction } from \"./keymap.js\";\nexport type { TraceViewerAppProps } from \"./app.js\";\nexport { initialExpandedSet } from \"./expand.js\";\nexport type { RunTraceViewerOptions } from \"./run-viewer.js\";\n\nimport type { RunTraceViewerOptions } from \"./run-viewer.js\";\n\nexport async function runTraceViewer(options: RunTraceViewerOptions): Promise<void> {\n const esmEntry = \"./index.mjs\";\n const mod = await import(esmEntry) as {\n runTraceViewer(options: RunTraceViewerOptions): Promise<void>;\n };\n return mod.runTraceViewer(options);\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { TraceEvent } from 'agent-inspect';
|
|
2
|
-
import React from 'react';
|
|
3
2
|
|
|
4
3
|
interface TuiTraceNode {
|
|
5
4
|
id: string;
|
|
@@ -54,18 +53,26 @@ declare function mapInputToAction(input: string, key?: Partial<{
|
|
|
54
53
|
rightArrow: boolean;
|
|
55
54
|
}>): TuiAction;
|
|
56
55
|
|
|
57
|
-
/** Small traces: expand all branches. Larger traces: only root rows expanded (show first nesting level). */
|
|
58
|
-
declare function initialExpandedSet(model: TuiTraceModel): Set<string>;
|
|
59
56
|
interface TraceViewerAppProps {
|
|
60
57
|
model: TuiTraceModel;
|
|
61
58
|
onExit?: () => void;
|
|
62
59
|
}
|
|
63
|
-
|
|
60
|
+
|
|
61
|
+
/** Small traces: expand all branches. Larger traces: only root rows expanded (show first nesting level). */
|
|
62
|
+
declare function initialExpandedSet(model: TuiTraceModel): Set<string>;
|
|
64
63
|
|
|
65
64
|
interface RunTraceViewerOptions {
|
|
66
65
|
runId: string;
|
|
67
66
|
dir?: string;
|
|
68
67
|
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @experimental Optional TUI package CommonJS entry.
|
|
71
|
+
*
|
|
72
|
+
* Keep this entry free of eager Ink imports so `require("@agent-inspect/tui")`
|
|
73
|
+
* can load pure helpers even though Ink is ESM with top-level await.
|
|
74
|
+
*/
|
|
75
|
+
|
|
69
76
|
declare function runTraceViewer(options: RunTraceViewerOptions): Promise<void>;
|
|
70
77
|
|
|
71
|
-
export { type LoadTraceForTuiOptions, type RunTraceViewerOptions,
|
|
78
|
+
export { type LoadTraceForTuiOptions, type RunTraceViewerOptions, type TraceViewerAppProps, type TuiAction, type TuiTraceModel, type TuiTraceNode, buildTuiTraceModel, countTreeSteps, initialExpandedSet, loadTraceForTui, mapInputToAction, runTraceViewer };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { TraceEvent } from 'agent-inspect';
|
|
2
|
-
import React from 'react';
|
|
3
2
|
|
|
4
3
|
interface TuiTraceNode {
|
|
5
4
|
id: string;
|
|
@@ -54,13 +53,13 @@ declare function mapInputToAction(input: string, key?: Partial<{
|
|
|
54
53
|
rightArrow: boolean;
|
|
55
54
|
}>): TuiAction;
|
|
56
55
|
|
|
57
|
-
/** Small traces: expand all branches. Larger traces: only root rows expanded (show first nesting level). */
|
|
58
|
-
declare function initialExpandedSet(model: TuiTraceModel): Set<string>;
|
|
59
56
|
interface TraceViewerAppProps {
|
|
60
57
|
model: TuiTraceModel;
|
|
61
58
|
onExit?: () => void;
|
|
62
59
|
}
|
|
63
|
-
|
|
60
|
+
|
|
61
|
+
/** Small traces: expand all branches. Larger traces: only root rows expanded (show first nesting level). */
|
|
62
|
+
declare function initialExpandedSet(model: TuiTraceModel): Set<string>;
|
|
64
63
|
|
|
65
64
|
interface RunTraceViewerOptions {
|
|
66
65
|
runId: string;
|
|
@@ -68,4 +67,4 @@ interface RunTraceViewerOptions {
|
|
|
68
67
|
}
|
|
69
68
|
declare function runTraceViewer(options: RunTraceViewerOptions): Promise<void>;
|
|
70
69
|
|
|
71
|
-
export { type LoadTraceForTuiOptions, type RunTraceViewerOptions,
|
|
70
|
+
export { type LoadTraceForTuiOptions, type RunTraceViewerOptions, type TraceViewerAppProps, type TuiAction, type TuiTraceModel, type TuiTraceNode, buildTuiTraceModel, countTreeSteps, initialExpandedSet, loadTraceForTui, mapInputToAction, runTraceViewer };
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
+
export { initialExpandedSet, mapInputToAction } from './chunk-Z4JCXEIO.mjs';
|
|
1
2
|
import { resolveTraceDir, readTraceEvents } from 'agent-inspect';
|
|
2
|
-
import React2, { useState, useMemo, useEffect } from 'react';
|
|
3
|
-
import { useApp, useInput, Box, Text, render } from 'ink';
|
|
4
|
-
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
5
3
|
|
|
6
4
|
// packages/tui/src/tree-model.ts
|
|
7
5
|
function dfsFlat(roots, out) {
|
|
@@ -109,185 +107,7 @@ async function loadTraceForTui(options) {
|
|
|
109
107
|
return buildTuiTraceModel(events);
|
|
110
108
|
}
|
|
111
109
|
|
|
112
|
-
// packages/tui/src/
|
|
113
|
-
function mapInputToAction(input, key = {}) {
|
|
114
|
-
if (key.escape === true) return "quit";
|
|
115
|
-
if (key.ctrl === true && input === "c") return "quit";
|
|
116
|
-
if (input === "q" || input === "Q") return "quit";
|
|
117
|
-
if (input === "?") return "help";
|
|
118
|
-
if (input === "d" || input === "D") return "details";
|
|
119
|
-
if (key.return === true) return "expand";
|
|
120
|
-
if (input === " ") return "toggle";
|
|
121
|
-
if (key.upArrow === true || input === "k") return "up";
|
|
122
|
-
if (key.downArrow === true || input === "j") return "down";
|
|
123
|
-
if (key.rightArrow === true || input === "l") return "expand";
|
|
124
|
-
if (key.leftArrow === true || input === "h") return "collapse";
|
|
125
|
-
return "unknown";
|
|
126
|
-
}
|
|
127
|
-
function collectVisible(roots, expanded, out) {
|
|
128
|
-
for (const n of roots) {
|
|
129
|
-
out.push(n);
|
|
130
|
-
if (n.children.length > 0 && expanded.has(n.id)) {
|
|
131
|
-
collectVisible(n.children, expanded, out);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
function initialExpandedSet(model) {
|
|
136
|
-
const s = /* @__PURE__ */ new Set();
|
|
137
|
-
const small = model.flatNodes.length <= 15;
|
|
138
|
-
if (small) {
|
|
139
|
-
for (const n of model.flatNodes) {
|
|
140
|
-
if (n.children.length > 0) s.add(n.id);
|
|
141
|
-
}
|
|
142
|
-
return s;
|
|
143
|
-
}
|
|
144
|
-
for (const r of model.nodes) {
|
|
145
|
-
if (r.children.length > 0) s.add(r.id);
|
|
146
|
-
}
|
|
147
|
-
return s;
|
|
148
|
-
}
|
|
149
|
-
function formatDur(ms) {
|
|
150
|
-
if (ms === void 0 || !Number.isFinite(ms)) return "-";
|
|
151
|
-
if (ms < 1e3) return `${Math.round(ms)}ms`;
|
|
152
|
-
return `${(ms / 1e3).toFixed(2)}s`;
|
|
153
|
-
}
|
|
154
|
-
function TraceViewerApp(props) {
|
|
155
|
-
const { model, onExit } = props;
|
|
156
|
-
const { exit } = useApp();
|
|
157
|
-
const [expanded, setExpanded] = useState(() => initialExpandedSet(model));
|
|
158
|
-
const [sel, setSel] = useState(0);
|
|
159
|
-
const [showHelp, setShowHelp] = useState(false);
|
|
160
|
-
const [showDetails, setShowDetails] = useState(true);
|
|
161
|
-
const visible = useMemo(() => {
|
|
162
|
-
const out = [];
|
|
163
|
-
collectVisible(model.nodes, expanded, out);
|
|
164
|
-
return out;
|
|
165
|
-
}, [model.nodes, expanded]);
|
|
166
|
-
useEffect(() => {
|
|
167
|
-
if (visible.length === 0) {
|
|
168
|
-
setSel(0);
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
setSel((i) => Math.min(i, visible.length - 1));
|
|
172
|
-
}, [visible.length]);
|
|
173
|
-
const safeSel = visible.length === 0 ? 0 : Math.min(sel, visible.length - 1);
|
|
174
|
-
const selected = visible[safeSel];
|
|
175
|
-
useInput((input, key) => {
|
|
176
|
-
const action = mapInputToAction(input, key);
|
|
177
|
-
switch (action) {
|
|
178
|
-
case "quit":
|
|
179
|
-
onExit?.();
|
|
180
|
-
exit();
|
|
181
|
-
break;
|
|
182
|
-
case "help":
|
|
183
|
-
setShowHelp((h) => !h);
|
|
184
|
-
break;
|
|
185
|
-
case "details":
|
|
186
|
-
setShowDetails((d) => !d);
|
|
187
|
-
break;
|
|
188
|
-
case "up":
|
|
189
|
-
setSel((i) => Math.max(0, i - 1));
|
|
190
|
-
break;
|
|
191
|
-
case "down":
|
|
192
|
-
setSel((i) => Math.min(Math.max(0, visible.length - 1), i + 1));
|
|
193
|
-
break;
|
|
194
|
-
case "expand": {
|
|
195
|
-
const cur = visible.length === 0 ? void 0 : visible[safeSel];
|
|
196
|
-
if (cur?.children.length) {
|
|
197
|
-
setExpanded((prev) => new Set(prev).add(cur.id));
|
|
198
|
-
}
|
|
199
|
-
break;
|
|
200
|
-
}
|
|
201
|
-
case "collapse": {
|
|
202
|
-
const cur = visible.length === 0 ? void 0 : visible[safeSel];
|
|
203
|
-
if (cur && expanded.has(cur.id)) {
|
|
204
|
-
setExpanded((prev) => {
|
|
205
|
-
const n = new Set(prev);
|
|
206
|
-
n.delete(cur.id);
|
|
207
|
-
return n;
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
case "toggle": {
|
|
213
|
-
const cur = visible.length === 0 ? void 0 : visible[safeSel];
|
|
214
|
-
if (cur?.children.length) {
|
|
215
|
-
setExpanded((prev) => {
|
|
216
|
-
const n = new Set(prev);
|
|
217
|
-
if (n.has(cur.id)) n.delete(cur.id);
|
|
218
|
-
else n.add(cur.id);
|
|
219
|
-
return n;
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
break;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
const indent = (d) => " ".repeat(d);
|
|
227
|
-
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
228
|
-
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
229
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children: "AgentInspect Trace Viewer" }),
|
|
230
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
231
|
-
model.name ?? "(unnamed)",
|
|
232
|
-
" \xB7 ",
|
|
233
|
-
model.runId,
|
|
234
|
-
" \xB7 ",
|
|
235
|
-
model.status ?? "unknown",
|
|
236
|
-
" \xB7",
|
|
237
|
-
" ",
|
|
238
|
-
formatDur(model.durationMs)
|
|
239
|
-
] })
|
|
240
|
-
] }),
|
|
241
|
-
showHelp ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, borderStyle: "round", paddingX: 1, children: [
|
|
242
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children: "Keys" }),
|
|
243
|
-
/* @__PURE__ */ jsx(Text, { children: "\u2191/\u2193 or j/k \u2014 move \xB7 \u2190/\u2192 or h/l \u2014 collapse/expand \xB7 space \u2014 toggle branch" }),
|
|
244
|
-
/* @__PURE__ */ jsx(Text, { children: "enter \u2014 expand \xB7 d \u2014 toggle details \xB7 ? \u2014 this help \xB7 q / Ctrl+C / esc \u2014 quit" })
|
|
245
|
-
] }) : null,
|
|
246
|
-
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
|
|
247
|
-
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: "55%", children: [
|
|
248
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Execution tree" }),
|
|
249
|
-
visible.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No steps recorded" }) : visible.map((n, i) => {
|
|
250
|
-
const branch = n.children.length === 0 ? " " : expanded.has(n.id) ? "\u25BC " : "\u25B6 ";
|
|
251
|
-
const row = `${indent(n.depth)}${branch}${n.name}`;
|
|
252
|
-
const mark = i === safeSel ? "\u203A " : " ";
|
|
253
|
-
const status = n.status ?? "?";
|
|
254
|
-
const line = `${mark}${row} (${status})`;
|
|
255
|
-
return /* @__PURE__ */ jsx(Text, { inverse: i === safeSel, children: line }, n.id);
|
|
256
|
-
})
|
|
257
|
-
] }),
|
|
258
|
-
showDetails ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingLeft: 2, width: "45%", children: [
|
|
259
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Details" }),
|
|
260
|
-
selected ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
261
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
262
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children: "name: " }),
|
|
263
|
-
selected.name
|
|
264
|
-
] }),
|
|
265
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
266
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children: "type: " }),
|
|
267
|
-
selected.type ?? "-"
|
|
268
|
-
] }),
|
|
269
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
270
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children: "status: " }),
|
|
271
|
-
selected.status ?? "-"
|
|
272
|
-
] }),
|
|
273
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
274
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children: "duration: " }),
|
|
275
|
-
formatDur(selected.durationMs)
|
|
276
|
-
] }),
|
|
277
|
-
selected.error ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
278
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children: "error: " }),
|
|
279
|
-
selected.error
|
|
280
|
-
] }) : null,
|
|
281
|
-
selected.metadata && Object.keys(selected.metadata).length > 0 ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
282
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children: "metadata: " }),
|
|
283
|
-
JSON.stringify(selected.metadata)
|
|
284
|
-
] }) : null
|
|
285
|
-
] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Select a step" })
|
|
286
|
-
] }) : null
|
|
287
|
-
] }),
|
|
288
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 or j/k move \xB7 enter/space expand \xB7 h/l collapse/expand \xB7 d details \xB7 ? help \xB7 q quit" }) })
|
|
289
|
-
] });
|
|
290
|
-
}
|
|
110
|
+
// packages/tui/src/run-viewer.ts
|
|
291
111
|
var TTY_MSG = "TUI requires an interactive terminal. Use agent-inspect view without --tui for plain output.";
|
|
292
112
|
async function runTraceViewer(options) {
|
|
293
113
|
if (!process.stdout.isTTY || !process.stdin.isTTY) {
|
|
@@ -297,12 +117,17 @@ async function runTraceViewer(options) {
|
|
|
297
117
|
runId: options.runId,
|
|
298
118
|
dir: options.dir
|
|
299
119
|
});
|
|
120
|
+
const [{ default: React }, { render }, { TraceViewerApp }] = await Promise.all([
|
|
121
|
+
import('react'),
|
|
122
|
+
import('ink'),
|
|
123
|
+
import('./app-7ZRVYDDE.mjs')
|
|
124
|
+
]);
|
|
300
125
|
const { waitUntilExit } = render(
|
|
301
|
-
|
|
126
|
+
React.createElement(TraceViewerApp, { model })
|
|
302
127
|
);
|
|
303
128
|
await waitUntilExit();
|
|
304
129
|
}
|
|
305
130
|
|
|
306
|
-
export {
|
|
131
|
+
export { buildTuiTraceModel, countTreeSteps, loadTraceForTui, runTraceViewer };
|
|
307
132
|
//# sourceMappingURL=index.mjs.map
|
|
308
133
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tree-model.ts","../src/trace-loader.ts","../src/keymap.ts","../src/app.tsx","../src/run-viewer.ts"],"names":["React"],"mappings":";;;;;;AAuBA,SAAS,OAAA,CAAQ,OAAuB,GAAA,EAA2B;AACjE,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,IAAA,GAAA,CAAI,KAAK,CAAC,CAAA;AACV,IAAA,IAAI,EAAE,QAAA,CAAS,MAAA,GAAS,GAAG,OAAA,CAAQ,CAAA,CAAE,UAAU,GAAG,CAAA;AAAA,EACpD;AACF;AAEA,SAAS,UAAA,CAAW,QAAqB,KAAA,EAA+B;AACtE,EAAA,OAAO,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,IACxB,IAAI,CAAA,CAAE,EAAA;AAAA,IACN,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,QAAQ,CAAA,CAAE,MAAA;AAAA,IACV,YAAY,CAAA,CAAE,UAAA;AAAA,IACd,KAAA;AAAA,IACA,UAAU,CAAA,CAAE,QAAA;AAAA,IACZ,OAAO,CAAA,CAAE,KAAA;AAAA,IACT,UAAU,CAAA,CAAE,QAAA;AAAA,IACZ,QAAA,EAAU,UAAA,CAAW,CAAA,CAAE,QAAA,EAAU,QAAQ,CAAC;AAAA,GAC5C,CAAE,CAAA;AACJ;AAMO,SAAS,mBAAmB,MAAA,EAAqC;AACtE,EAAA,MAAM,UAAU,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAA4B,CAAA,CAAE,UAAU,aAAa,CAAA;AAClF,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,oCAAoC,CAAA;AAAA,EACtD;AAEA,EAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA;AACtB,EAAA,MAAM,UAAU,OAAA,CAAQ,IAAA;AAExB,EAAA,MAAM,eAAe,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAA8B,CAAA,CAAE,UAAU,eAAe,CAAA;AAC7F,EAAA,MAAM,aAAA,GAAgB,YAAA,CAAa,YAAA,CAAa,MAAA,GAAS,CAAC,CAAA;AAC1D,EAAA,MAAM,SAAA,GAAY,aAAA,GAAgB,aAAA,CAAc,MAAA,GAAS,SAAA;AACzD,EAAA,MAAM,aAAA,GACJ,kBAAkB,MAAA,IAAa,MAAA,CAAO,SAAS,aAAA,CAAc,UAAU,CAAA,GACnE,aAAA,CAAc,UAAA,GACd,MAAA;AAEN,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAuB;AAEzC,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,IAAI,CAAA,CAAE,UAAU,cAAA,EAAgB;AAChC,IAAA,MAAM,CAAA,GAAI,CAAA;AACV,IAAA,KAAA,CAAM,GAAA,CAAI,EAAE,MAAA,EAAQ;AAAA,MAClB,IAAI,CAAA,CAAE,MAAA;AAAA,MACN,UAAU,CAAA,CAAE,QAAA;AAAA,MACZ,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,MAAA,EAAQ,SAAA;AAAA,MACR,WAAW,CAAA,CAAE,SAAA;AAAA,MACb,UAAU,CAAA,CAAE,QAAA;AAAA,MACZ,UAAU;AAAC,KACZ,CAAA;AAAA,EACH;AAEA,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,IAAI,CAAA,CAAE,UAAU,gBAAA,EAAkB;AAClC,IAAA,MAAM,CAAA,GAAI,CAAA;AACV,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA;AAC/B,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA;AAChB,IAAA,IAAA,CAAK,aAAa,CAAA,CAAE,UAAA;AACpB,IAAA,IAAA,CAAK,KAAA,GACH,CAAA,CAAE,KAAA,KAAU,MAAA,IAAa,OAAO,CAAA,CAAE,KAAA,CAAM,OAAA,KAAY,QAAA,GAChD,CAAA,CAAE,KAAA,CAAM,OAAA,GACR,MAAA;AAAA,EACR;AAEA,EAAA,MAAM,QAAqB,EAAC;AAC5B,EAAA,MAAM,gBAAgB,CAAC,CAAA,EAAc,CAAA,KAAiB,CAAA,CAAE,YAAY,CAAA,CAAE,SAAA;AAEtE,EAAA,KAAA,MAAW,CAAA,IAAK,KAAA,CAAM,MAAA,EAAO,EAAG;AAC9B,IAAA,IAAI,EAAE,QAAA,KAAa,MAAA,IAAa,MAAM,GAAA,CAAI,CAAA,CAAE,QAAQ,CAAA,EAAG;AACrD,MAAA,KAAA,CAAM,IAAI,CAAA,CAAE,QAAQ,CAAA,CAAG,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,IACxC,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,IACd;AAAA,EACF;AAEA,EAAA,KAAA,CAAM,KAAK,aAAa,CAAA;AACxB,EAAA,KAAA,MAAW,CAAA,IAAK,KAAA,CAAM,MAAA,EAAO,EAAG;AAC9B,IAAA,CAAA,CAAE,QAAA,CAAS,KAAK,aAAa,CAAA;AAAA,EAC/B;AAEA,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,KAAA,EAAO,CAAC,CAAA;AACrC,EAAA,MAAM,YAA4B,EAAC;AACnC,EAAA,OAAA,CAAQ,WAAW,SAAS,CAAA;AAE5B,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,IAAA,EAAM,OAAA;AAAA,IACN,MAAA,EAAQ,SAAA;AAAA,IACR,UAAA,EAAY,aAAA;AAAA,IACZ,KAAA,EAAO,SAAA;AAAA,IACP;AAAA,GACF;AACF;AAGO,SAAS,eAAe,KAAA,EAA+B;AAC5D,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,IAAA,CAAA,IAAK,CAAA,GAAI,YAAA,CAAa,CAAA,CAAE,QAAQ,CAAA;AAAA,EAClC;AACA,EAAA,OAAO,CAAA;AACT;AAEA,SAAS,aAAa,QAAA,EAAkC;AACtD,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,CAAA,IAAK,CAAA,GAAI,YAAA,CAAa,CAAA,CAAE,QAAQ,CAAA;AAAA,EAClC;AACA,EAAA,OAAO,CAAA;AACT;AChIA,eAAsB,gBAAgB,OAAA,EAAyD;AAC7F,EAAA,MAAM,WAAW,eAAA,CAAgB,EAAE,GAAA,EAAK,OAAA,CAAQ,KAAK,CAAA;AACrD,EAAA,MAAM,MAAA,GAAS,MAAM,eAAA,CAAgB,OAAA,CAAQ,OAAO,QAAQ,CAAA;AAE5D,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,iCAAA,EAAoC,OAAA,CAAQ,KAAK,CAAA,aAAA,EAAgB,QAAQ,CAAA,CAAA;AAAA,KAC3E;AAAA,EACF;AAEA,EAAA,OAAO,mBAAmB,MAAM,CAAA;AAClC;;;ACZO,SAAS,gBAAA,CACd,KAAA,EACA,GAAA,GAWK,EAAC,EACK;AACX,EAAA,IAAI,GAAA,CAAI,MAAA,KAAW,IAAA,EAAM,OAAO,MAAA;AAChC,EAAA,IAAI,GAAA,CAAI,IAAA,KAAS,IAAA,IAAQ,KAAA,KAAU,KAAK,OAAO,MAAA;AAE/C,EAAA,IAAI,KAAA,KAAU,GAAA,IAAO,KAAA,KAAU,GAAA,EAAK,OAAO,MAAA;AAE3C,EAAA,IAAI,KAAA,KAAU,KAAK,OAAO,MAAA;AAE1B,EAAA,IAAI,KAAA,KAAU,GAAA,IAAO,KAAA,KAAU,GAAA,EAAK,OAAO,SAAA;AAE3C,EAAA,IAAI,GAAA,CAAI,MAAA,KAAW,IAAA,EAAM,OAAO,QAAA;AAEhC,EAAA,IAAI,KAAA,KAAU,KAAK,OAAO,QAAA;AAE1B,EAAA,IAAI,GAAA,CAAI,OAAA,KAAY,IAAA,IAAQ,KAAA,KAAU,KAAK,OAAO,IAAA;AAClD,EAAA,IAAI,GAAA,CAAI,SAAA,KAAc,IAAA,IAAQ,KAAA,KAAU,KAAK,OAAO,MAAA;AACpD,EAAA,IAAI,GAAA,CAAI,UAAA,KAAe,IAAA,IAAQ,KAAA,KAAU,KAAK,OAAO,QAAA;AACrD,EAAA,IAAI,GAAA,CAAI,SAAA,KAAc,IAAA,IAAQ,KAAA,KAAU,KAAK,OAAO,UAAA;AAEpD,EAAA,OAAO,SAAA;AACT;ACxCA,SAAS,cAAA,CACP,KAAA,EACA,QAAA,EACA,GAAA,EACM;AACN,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,IAAA,GAAA,CAAI,KAAK,CAAC,CAAA;AACV,IAAA,IAAI,CAAA,CAAE,SAAS,MAAA,GAAS,CAAA,IAAK,SAAS,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,EAAG;AAC/C,MAAA,cAAA,CAAe,CAAA,CAAE,QAAA,EAAU,QAAA,EAAU,GAAG,CAAA;AAAA,IAC1C;AAAA,EACF;AACF;AAGO,SAAS,mBAAmB,KAAA,EAAmC;AACpE,EAAA,MAAM,CAAA,uBAAQ,GAAA,EAAY;AAC1B,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,SAAA,CAAU,MAAA,IAAU,EAAA;AACxC,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,KAAA,MAAW,CAAA,IAAK,MAAM,SAAA,EAAW;AAC/B,MAAA,IAAI,EAAE,QAAA,CAAS,MAAA,GAAS,GAAG,CAAA,CAAE,GAAA,CAAI,EAAE,EAAE,CAAA;AAAA,IACvC;AACA,IAAA,OAAO,CAAA;AAAA,EACT;AACA,EAAA,KAAA,MAAW,CAAA,IAAK,MAAM,KAAA,EAAO;AAC3B,IAAA,IAAI,EAAE,QAAA,CAAS,MAAA,GAAS,GAAG,CAAA,CAAE,GAAA,CAAI,EAAE,EAAE,CAAA;AAAA,EACvC;AACA,EAAA,OAAO,CAAA;AACT;AAEA,SAAS,UAAU,EAAA,EAAgC;AACjD,EAAA,IAAI,OAAO,MAAA,IAAa,CAAC,OAAO,QAAA,CAAS,EAAE,GAAG,OAAO,GAAA;AACrD,EAAA,IAAI,KAAK,GAAA,EAAM,OAAO,GAAG,IAAA,CAAK,KAAA,CAAM,EAAE,CAAC,CAAA,EAAA,CAAA;AACvC,EAAA,OAAO,CAAA,EAAA,CAAI,EAAA,GAAK,GAAA,EAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA;AAClC;AAOO,SAAS,eAAe,KAAA,EAAgD;AAC7E,EAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,KAAA;AAC1B,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAA,EAAO;AACxB,EAAA,MAAM,CAAC,UAAU,WAAW,CAAA,GAAI,SAAS,MAAM,kBAAA,CAAmB,KAAK,CAAC,CAAA;AACxE,EAAA,MAAM,CAAC,GAAA,EAAK,MAAM,CAAA,GAAI,SAAS,CAAC,CAAA;AAChC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA;AAC9C,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,IAAI,CAAA;AAEnD,EAAA,MAAM,OAAA,GAAU,QAAQ,MAAM;AAC5B,IAAA,MAAM,MAAsB,EAAC;AAC7B,IAAA,cAAA,CAAe,KAAA,CAAM,KAAA,EAAO,QAAA,EAAU,GAAG,CAAA;AACzC,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,EAAG,CAAC,KAAA,CAAM,KAAA,EAAO,QAAQ,CAAC,CAAA;AAE1B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,MAAA,MAAA,CAAO,CAAC,CAAA;AACR,MAAA;AAAA,IACF;AACA,IAAA,MAAA,CAAO,CAAC,MAAM,IAAA,CAAK,GAAA,CAAI,GAAG,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAC,CAAA;AAAA,EAC/C,CAAA,EAAG,CAAC,OAAA,CAAQ,MAAM,CAAC,CAAA;AAEnB,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,MAAA,KAAW,CAAA,GAAI,CAAA,GAAI,KAAK,GAAA,CAAI,GAAA,EAAK,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA;AAC3E,EAAA,MAAM,QAAA,GAAW,QAAQ,OAAO,CAAA;AAEhC,EAAA,QAAA,CAAS,CAAC,OAAO,GAAA,KAAQ;AACvB,IAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,KAAA,EAAO,GAAG,CAAA;AAC1C,IAAA,QAAQ,MAAA;AAAQ,MACd,KAAK,MAAA;AACH,QAAA,MAAA,IAAS;AACT,QAAA,IAAA,EAAK;AACL,QAAA;AAAA,MACF,KAAK,MAAA;AACH,QAAA,WAAA,CAAY,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AACrB,QAAA;AAAA,MACF,KAAK,SAAA;AACH,QAAA,cAAA,CAAe,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AACxB,QAAA;AAAA,MACF,KAAK,IAAA;AACH,QAAA,MAAA,CAAO,CAAC,CAAA,KAAM,IAAA,CAAK,IAAI,CAAA,EAAG,CAAA,GAAI,CAAC,CAAC,CAAA;AAChC,QAAA;AAAA,MACF,KAAK,MAAA;AACH,QAAA,MAAA,CAAO,CAAC,CAAA,KAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA,EAAG,CAAA,GAAI,CAAC,CAAC,CAAA;AAC9D,QAAA;AAAA,MACF,KAAK,QAAA,EAAU;AACb,QAAA,MAAM,MAAM,OAAA,CAAQ,MAAA,KAAW,CAAA,GAAI,MAAA,GAAY,QAAQ,OAAO,CAAA;AAC9D,QAAA,IAAI,GAAA,EAAK,SAAS,MAAA,EAAQ;AACxB,UAAA,WAAA,CAAY,CAAC,SAAS,IAAI,GAAA,CAAI,IAAI,CAAA,CAAE,GAAA,CAAI,GAAA,CAAI,EAAE,CAAC,CAAA;AAAA,QACjD;AACA,QAAA;AAAA,MACF;AAAA,MACA,KAAK,UAAA,EAAY;AACf,QAAA,MAAM,MAAM,OAAA,CAAQ,MAAA,KAAW,CAAA,GAAI,MAAA,GAAY,QAAQ,OAAO,CAAA;AAC9D,QAAA,IAAI,GAAA,IAAO,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,EAAG;AAC/B,UAAA,WAAA,CAAY,CAAC,IAAA,KAAS;AACpB,YAAA,MAAM,CAAA,GAAI,IAAI,GAAA,CAAI,IAAI,CAAA;AACtB,YAAA,CAAA,CAAE,MAAA,CAAO,IAAI,EAAE,CAAA;AACf,YAAA,OAAO,CAAA;AAAA,UACT,CAAC,CAAA;AAAA,QACH;AACA,QAAA;AAAA,MACF;AAAA,MACA,KAAK,QAAA,EAAU;AACb,QAAA,MAAM,MAAM,OAAA,CAAQ,MAAA,KAAW,CAAA,GAAI,MAAA,GAAY,QAAQ,OAAO,CAAA;AAC9D,QAAA,IAAI,GAAA,EAAK,SAAS,MAAA,EAAQ;AACxB,UAAA,WAAA,CAAY,CAAC,IAAA,KAAS;AACpB,YAAA,MAAM,CAAA,GAAI,IAAI,GAAA,CAAI,IAAI,CAAA;AACtB,YAAA,IAAI,CAAA,CAAE,IAAI,GAAA,CAAI,EAAE,GAAG,CAAA,CAAE,MAAA,CAAO,IAAI,EAAE,CAAA;AAAA,iBAC7B,CAAA,CAAE,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AACjB,YAAA,OAAO,CAAA;AAAA,UACT,CAAC,CAAA;AAAA,QACH;AACA,QAAA;AAAA,MACF;AAEE;AACJ,EACF,CAAC,CAAA;AAED,EAAA,MAAM,MAAA,GAAS,CAAC,CAAA,KAAc,IAAA,CAAK,OAAO,CAAC,CAAA;AAE3C,EAAA,uBACE,IAAA,CAAC,GAAA,EAAA,EAAI,aAAA,EAAc,QAAA,EACjB,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,GAAA,EAAA,EAAI,aAAA,EAAc,QAAA,EAAS,YAAA,EAAc,CAAA,EACxC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,QAAA,EAAA,2BAAA,EAAyB,CAAA;AAAA,2BACnC,IAAA,EAAA,EACE,QAAA,EAAA;AAAA,QAAA,KAAA,CAAM,IAAA,IAAQ,WAAA;AAAA,QAAY,QAAA;AAAA,QAAI,KAAA,CAAM,KAAA;AAAA,QAAM,QAAA;AAAA,QAAI,MAAM,MAAA,IAAU,SAAA;AAAA,QAAU,OAAA;AAAA,QAAG,GAAA;AAAA,QAC3E,SAAA,CAAU,MAAM,UAAU;AAAA,OAAA,EAC7B;AAAA,KAAA,EACF,CAAA;AAAA,IAEC,QAAA,mBACC,IAAA,CAAC,GAAA,EAAA,EAAI,aAAA,EAAc,QAAA,EAAS,cAAc,CAAA,EAAG,WAAA,EAAY,OAAA,EAAQ,QAAA,EAAU,CAAA,EACzE,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,QAAA,EAAA,MAAA,EAAI,CAAA;AAAA,sBACf,GAAA,CAAC,QAAK,QAAA,EAAA,mHAAA,EAAwE,CAAA;AAAA,sBAC9E,GAAA,CAAC,QAAK,QAAA,EAAA,4GAAA,EAA6E;AAAA,KAAA,EACrF,CAAA,GACE,IAAA;AAAA,oBAEJ,IAAA,CAAC,GAAA,EAAA,EAAI,aAAA,EAAc,KAAA,EACjB,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,GAAA,EAAA,EAAI,aAAA,EAAc,QAAA,EAAS,KAAA,EAAM,KAAA,EAChC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,QAAA,EAAQ,IAAA,EAAC,QAAA,EAAA,gBAAA,EAAc,CAAA;AAAA,QAC5B,OAAA,CAAQ,MAAA,KAAW,CAAA,mBAClB,GAAA,CAAC,IAAA,EAAA,EAAK,QAAA,EAAQ,IAAA,EAAC,QAAA,EAAA,mBAAA,EAAiB,CAAA,GAEhC,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAG,CAAA,KAAM;AACpB,UAAA,MAAM,MAAA,GACJ,CAAA,CAAE,QAAA,CAAS,MAAA,KAAW,CAAA,GAClB,IAAA,GACA,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,GACf,SAAA,GACA,SAAA;AACR,UAAA,MAAM,GAAA,GAAM,CAAA,EAAG,MAAA,CAAO,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,CAAA;AAChD,UAAA,MAAM,IAAA,GAAO,CAAA,KAAM,OAAA,GAAU,SAAA,GAAO,IAAA;AACpC,UAAA,MAAM,MAAA,GAAS,EAAE,MAAA,IAAU,GAAA;AAC3B,UAAA,MAAM,OAAO,CAAA,EAAG,IAAI,CAAA,EAAG,GAAG,KAAK,MAAM,CAAA,CAAA,CAAA;AACrC,UAAA,2BACG,IAAA,EAAA,EAAgB,OAAA,EAAS,MAAM,OAAA,EAC7B,QAAA,EAAA,IAAA,EAAA,EADQ,EAAE,EAEb,CAAA;AAAA,QAEJ,CAAC;AAAA,OAAA,EAEL,CAAA;AAAA,MAEC,WAAA,wBACE,GAAA,EAAA,EAAI,aAAA,EAAc,UAAS,WAAA,EAAa,CAAA,EAAG,OAAM,KAAA,EAChD,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,QAAA,EAAQ,IAAA,EAAC,QAAA,EAAA,SAAA,EAAO,CAAA;AAAA,QACrB,2BACC,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,QAAA,EAAA,QAAA,EAAM,CAAA;AAAA,YAChB,QAAA,CAAS;AAAA,WAAA,EACZ,CAAA;AAAA,+BACC,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,QAAA,EAAA,QAAA,EAAM,CAAA;AAAA,YAChB,SAAS,IAAA,IAAQ;AAAA,WAAA,EACpB,CAAA;AAAA,+BACC,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,QAAA,EAAA,UAAA,EAAQ,CAAA;AAAA,YAClB,SAAS,MAAA,IAAU;AAAA,WAAA,EACtB,CAAA;AAAA,+BACC,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,QAAA,EAAA,YAAA,EAAU,CAAA;AAAA,YACpB,SAAA,CAAU,SAAS,UAAU;AAAA,WAAA,EAChC,CAAA;AAAA,UACC,QAAA,CAAS,KAAA,mBACR,IAAA,CAAC,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,QAAA,EAAA,SAAA,EAAO,CAAA;AAAA,YACjB,QAAA,CAAS;AAAA,WAAA,EACZ,CAAA,GACE,IAAA;AAAA,UACH,QAAA,CAAS,QAAA,IAAY,MAAA,CAAO,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,CAAE,MAAA,GAAS,CAAA,mBAC5D,IAAA,CAAC,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,QAAA,EAAA,YAAA,EAAU,CAAA;AAAA,YACpB,IAAA,CAAK,SAAA,CAAU,QAAA,CAAS,QAAQ;AAAA,WAAA,EACnC,CAAA,GACE;AAAA,SAAA,EACN,CAAA,mBAEA,GAAA,CAAC,IAAA,EAAA,EAAK,QAAA,EAAQ,MAAC,QAAA,EAAA,eAAA,EAAa;AAAA,OAAA,EAEhC,CAAA,GACE;AAAA,KAAA,EACN,CAAA;AAAA,oBAEA,GAAA,CAAC,OAAI,SAAA,EAAW,CAAA,EACd,8BAAC,IAAA,EAAA,EAAK,QAAA,EAAQ,IAAA,EAAC,QAAA,EAAA,mHAAA,EAEf,CAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;AChNA,IAAM,OAAA,GACJ,8FAAA;AAEF,eAAsB,eAAe,OAAA,EAA+C;AAClF,EAAA,IAAI,CAAC,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAC,OAAA,CAAQ,MAAM,KAAA,EAAO;AACjD,IAAA,MAAM,IAAI,MAAM,OAAO,CAAA;AAAA,EACzB;AAEA,EAAA,MAAM,KAAA,GAAQ,MAAM,eAAA,CAAgB;AAAA,IAClC,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,KAAK,OAAA,CAAQ;AAAA,GACd,CAAA;AAED,EAAA,MAAM,EAAE,eAAc,GAAI,MAAA;AAAA,IACxBA,MAAAA,CAAM,aAAA,CAAc,cAAA,EAAgB,EAAE,OAAO;AAAA,GAC/C;AACA,EAAA,MAAM,aAAA,EAAc;AACtB","file":"index.mjs","sourcesContent":["import type {\n RunCompletedEvent,\n RunStartedEvent,\n StepCompletedEvent,\n StepStartedEvent,\n TraceEvent,\n} from \"agent-inspect\";\n\nimport type { TuiTraceModel, TuiTraceNode } from \"./types.js\";\n\ntype StepBuild = {\n id: string;\n parentId?: string;\n name: string;\n type: string;\n status: string;\n durationMs?: number;\n startedAt: number;\n error?: string;\n metadata?: Record<string, unknown>;\n children: StepBuild[];\n};\n\nfunction dfsFlat(roots: TuiTraceNode[], out: TuiTraceNode[]): void {\n for (const n of roots) {\n out.push(n);\n if (n.children.length > 0) dfsFlat(n.children, out);\n }\n}\n\nfunction toTuiNodes(builds: StepBuild[], depth: number): TuiTraceNode[] {\n return builds.map((b) => ({\n id: b.id,\n name: b.name,\n type: b.type,\n status: b.status,\n durationMs: b.durationMs,\n depth,\n parentId: b.parentId,\n error: b.error,\n metadata: b.metadata,\n children: toTuiNodes(b.children, depth + 1),\n }));\n}\n\n/**\n * Build a navigable tree model from v0.1 JSONL trace events.\n * Does not mutate the input array or event objects.\n */\nexport function buildTuiTraceModel(events: TraceEvent[]): TuiTraceModel {\n const started = events.find((e): e is RunStartedEvent => e.event === \"run_started\");\n if (!started) {\n throw new Error(\"Invalid trace: missing run_started\");\n }\n\n const runId = started.runId;\n const runName = started.name;\n\n const completedAll = events.filter((e): e is RunCompletedEvent => e.event === \"run_completed\");\n const lastCompleted = completedAll[completedAll.length - 1];\n const runStatus = lastCompleted ? lastCompleted.status : \"running\";\n const runDurationMs =\n lastCompleted !== undefined && Number.isFinite(lastCompleted.durationMs)\n ? lastCompleted.durationMs\n : undefined;\n\n const nodes = new Map<string, StepBuild>();\n\n for (const e of events) {\n if (e.event !== \"step_started\") continue;\n const s = e as StepStartedEvent;\n nodes.set(s.stepId, {\n id: s.stepId,\n parentId: s.parentId,\n name: s.name,\n type: s.type,\n status: \"running\",\n startedAt: s.startTime,\n metadata: s.metadata as Record<string, unknown> | undefined,\n children: [],\n });\n }\n\n for (const e of events) {\n if (e.event !== \"step_completed\") continue;\n const c = e as StepCompletedEvent;\n const node = nodes.get(c.stepId);\n if (!node) continue;\n node.status = c.status;\n node.durationMs = c.durationMs;\n node.error =\n c.error !== undefined && typeof c.error.message === \"string\"\n ? c.error.message\n : undefined;\n }\n\n const roots: StepBuild[] = [];\n const sortByStarted = (a: StepBuild, b: StepBuild) => a.startedAt - b.startedAt;\n\n for (const n of nodes.values()) {\n if (n.parentId !== undefined && nodes.has(n.parentId)) {\n nodes.get(n.parentId)!.children.push(n);\n } else {\n roots.push(n);\n }\n }\n\n roots.sort(sortByStarted);\n for (const n of nodes.values()) {\n n.children.sort(sortByStarted);\n }\n\n const treeRoots = toTuiNodes(roots, 0);\n const flatNodes: TuiTraceNode[] = [];\n dfsFlat(treeRoots, flatNodes);\n\n return {\n runId,\n name: runName,\n status: runStatus,\n durationMs: runDurationMs,\n nodes: treeRoots,\n flatNodes,\n };\n}\n\n/** Total step count in tree (for default expand policy). Exported for tests. */\nexport function countTreeSteps(roots: TuiTraceNode[]): number {\n let n = 0;\n for (const r of roots) {\n n += 1 + countSubtree(r.children);\n }\n return n;\n}\n\nfunction countSubtree(children: TuiTraceNode[]): number {\n let n = 0;\n for (const c of children) {\n n += 1 + countSubtree(c.children);\n }\n return n;\n}\n","import { readTraceEvents, resolveTraceDir } from \"agent-inspect\";\n\nimport { buildTuiTraceModel } from \"./tree-model.js\";\nimport type { TuiTraceModel } from \"./types.js\";\n\nexport interface LoadTraceForTuiOptions {\n runId: string;\n dir?: string;\n}\n\n/**\n * Load JSONL trace events and build a TUI model. Does not write or mutate trace files.\n */\nexport async function loadTraceForTui(options: LoadTraceForTuiOptions): Promise<TuiTraceModel> {\n const traceDir = resolveTraceDir({ dir: options.dir });\n const events = await readTraceEvents(options.runId, traceDir);\n\n if (events.length === 0) {\n throw new Error(\n `Run not found or trace is empty: ${options.runId} (directory: ${traceDir})`,\n );\n }\n\n return buildTuiTraceModel(events);\n}\n","export type TuiAction =\n | \"up\"\n | \"down\"\n | \"expand\"\n | \"collapse\"\n | \"toggle\"\n | \"details\"\n | \"help\"\n | \"quit\"\n | \"unknown\";\n\n/** Map Ink `useInput` args to a semantic action. Pure helper for tests. */\nexport function mapInputToAction(\n input: string,\n key: Partial<{\n name: string;\n ctrl: boolean;\n meta: boolean;\n shift: boolean;\n return: boolean;\n escape: boolean;\n upArrow: boolean;\n downArrow: boolean;\n leftArrow: boolean;\n rightArrow: boolean;\n }> = {},\n): TuiAction {\n if (key.escape === true) return \"quit\";\n if (key.ctrl === true && input === \"c\") return \"quit\";\n\n if (input === \"q\" || input === \"Q\") return \"quit\";\n\n if (input === \"?\") return \"help\";\n\n if (input === \"d\" || input === \"D\") return \"details\";\n\n if (key.return === true) return \"expand\";\n\n if (input === \" \") return \"toggle\";\n\n if (key.upArrow === true || input === \"k\") return \"up\";\n if (key.downArrow === true || input === \"j\") return \"down\";\n if (key.rightArrow === true || input === \"l\") return \"expand\";\n if (key.leftArrow === true || input === \"h\") return \"collapse\";\n\n return \"unknown\";\n}\n","import React, { useEffect, useMemo, useState } from \"react\";\nimport { Box, Text, useApp, useInput } from \"ink\";\n\nimport { mapInputToAction } from \"./keymap.js\";\nimport type { TuiTraceModel, TuiTraceNode } from \"./types.js\";\n\nfunction collectVisible(\n roots: TuiTraceNode[],\n expanded: ReadonlySet<string>,\n out: TuiTraceNode[],\n): void {\n for (const n of roots) {\n out.push(n);\n if (n.children.length > 0 && expanded.has(n.id)) {\n collectVisible(n.children, expanded, out);\n }\n }\n}\n\n/** Small traces: expand all branches. Larger traces: only root rows expanded (show first nesting level). */\nexport function initialExpandedSet(model: TuiTraceModel): Set<string> {\n const s = new Set<string>();\n const small = model.flatNodes.length <= 15;\n if (small) {\n for (const n of model.flatNodes) {\n if (n.children.length > 0) s.add(n.id);\n }\n return s;\n }\n for (const r of model.nodes) {\n if (r.children.length > 0) s.add(r.id);\n }\n return s;\n}\n\nfunction formatDur(ms: number | undefined): string {\n if (ms === undefined || !Number.isFinite(ms)) return \"-\";\n if (ms < 1000) return `${Math.round(ms)}ms`;\n return `${(ms / 1000).toFixed(2)}s`;\n}\n\nexport interface TraceViewerAppProps {\n model: TuiTraceModel;\n onExit?: () => void;\n}\n\nexport function TraceViewerApp(props: TraceViewerAppProps): React.ReactElement {\n const { model, onExit } = props;\n const { exit } = useApp();\n const [expanded, setExpanded] = useState(() => initialExpandedSet(model));\n const [sel, setSel] = useState(0);\n const [showHelp, setShowHelp] = useState(false);\n const [showDetails, setShowDetails] = useState(true);\n\n const visible = useMemo(() => {\n const out: TuiTraceNode[] = [];\n collectVisible(model.nodes, expanded, out);\n return out;\n }, [model.nodes, expanded]);\n\n useEffect(() => {\n if (visible.length === 0) {\n setSel(0);\n return;\n }\n setSel((i) => Math.min(i, visible.length - 1));\n }, [visible.length]);\n\n const safeSel = visible.length === 0 ? 0 : Math.min(sel, visible.length - 1);\n const selected = visible[safeSel];\n\n useInput((input, key) => {\n const action = mapInputToAction(input, key);\n switch (action) {\n case \"quit\":\n onExit?.();\n exit();\n break;\n case \"help\":\n setShowHelp((h) => !h);\n break;\n case \"details\":\n setShowDetails((d) => !d);\n break;\n case \"up\":\n setSel((i) => Math.max(0, i - 1));\n break;\n case \"down\":\n setSel((i) => Math.min(Math.max(0, visible.length - 1), i + 1));\n break;\n case \"expand\": {\n const cur = visible.length === 0 ? undefined : visible[safeSel];\n if (cur?.children.length) {\n setExpanded((prev) => new Set(prev).add(cur.id));\n }\n break;\n }\n case \"collapse\": {\n const cur = visible.length === 0 ? undefined : visible[safeSel];\n if (cur && expanded.has(cur.id)) {\n setExpanded((prev) => {\n const n = new Set(prev);\n n.delete(cur.id);\n return n;\n });\n }\n break;\n }\n case \"toggle\": {\n const cur = visible.length === 0 ? undefined : visible[safeSel];\n if (cur?.children.length) {\n setExpanded((prev) => {\n const n = new Set(prev);\n if (n.has(cur.id)) n.delete(cur.id);\n else n.add(cur.id);\n return n;\n });\n }\n break;\n }\n default:\n break;\n }\n });\n\n const indent = (d: number) => \" \".repeat(d);\n\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold>AgentInspect Trace Viewer</Text>\n <Text>\n {model.name ?? \"(unnamed)\"} · {model.runId} · {model.status ?? \"unknown\"} ·{\" \"}\n {formatDur(model.durationMs)}\n </Text>\n </Box>\n\n {showHelp ? (\n <Box flexDirection=\"column\" marginBottom={1} borderStyle=\"round\" paddingX={1}>\n <Text bold>Keys</Text>\n <Text>↑/↓ or j/k — move · ←/→ or h/l — collapse/expand · space — toggle branch</Text>\n <Text>enter — expand · d — toggle details · ? — this help · q / Ctrl+C / esc — quit</Text>\n </Box>\n ) : null}\n\n <Box flexDirection=\"row\">\n <Box flexDirection=\"column\" width=\"55%\">\n <Text dimColor>Execution tree</Text>\n {visible.length === 0 ? (\n <Text dimColor>No steps recorded</Text>\n ) : (\n visible.map((n, i) => {\n const branch =\n n.children.length === 0\n ? \" \"\n : expanded.has(n.id)\n ? \"▼ \"\n : \"▶ \";\n const row = `${indent(n.depth)}${branch}${n.name}`;\n const mark = i === safeSel ? \"› \" : \" \";\n const status = n.status ?? \"?\";\n const line = `${mark}${row} (${status})`;\n return (\n <Text key={n.id} inverse={i === safeSel}>\n {line}\n </Text>\n );\n })\n )}\n </Box>\n\n {showDetails ? (\n <Box flexDirection=\"column\" paddingLeft={2} width=\"45%\">\n <Text dimColor>Details</Text>\n {selected ? (\n <>\n <Text>\n <Text bold>name: </Text>\n {selected.name}\n </Text>\n <Text>\n <Text bold>type: </Text>\n {selected.type ?? \"-\"}\n </Text>\n <Text>\n <Text bold>status: </Text>\n {selected.status ?? \"-\"}\n </Text>\n <Text>\n <Text bold>duration: </Text>\n {formatDur(selected.durationMs)}\n </Text>\n {selected.error ? (\n <Text>\n <Text bold>error: </Text>\n {selected.error}\n </Text>\n ) : null}\n {selected.metadata && Object.keys(selected.metadata).length > 0 ? (\n <Text>\n <Text bold>metadata: </Text>\n {JSON.stringify(selected.metadata)}\n </Text>\n ) : null}\n </>\n ) : (\n <Text dimColor>Select a step</Text>\n )}\n </Box>\n ) : null}\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n ↑/↓ or j/k move · enter/space expand · h/l collapse/expand · d details · ? help · q quit\n </Text>\n </Box>\n </Box>\n );\n}\n","import React from \"react\";\nimport { render } from \"ink\";\n\nimport { TraceViewerApp } from \"./app.js\";\nimport { loadTraceForTui } from \"./trace-loader.js\";\n\nexport interface RunTraceViewerOptions {\n runId: string;\n dir?: string;\n}\n\nconst TTY_MSG =\n \"TUI requires an interactive terminal. Use agent-inspect view without --tui for plain output.\";\n\nexport async function runTraceViewer(options: RunTraceViewerOptions): Promise<void> {\n if (!process.stdout.isTTY || !process.stdin.isTTY) {\n throw new Error(TTY_MSG);\n }\n\n const model = await loadTraceForTui({\n runId: options.runId,\n dir: options.dir,\n });\n\n const { waitUntilExit } = render(\n React.createElement(TraceViewerApp, { model }),\n );\n await waitUntilExit();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/tree-model.ts","../src/trace-loader.ts","../src/run-viewer.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type {\n RunCompletedEvent,\n RunStartedEvent,\n StepCompletedEvent,\n StepStartedEvent,\n TraceEvent,\n} from \"agent-inspect\";\n\nimport type { TuiTraceModel, TuiTraceNode } from \"./types.js\";\n\ntype StepBuild = {\n id: string;\n parentId?: string;\n name: string;\n type: string;\n status: string;\n durationMs?: number;\n startedAt: number;\n error?: string;\n metadata?: Record<string, unknown>;\n children: StepBuild[];\n};\n\nfunction dfsFlat(roots: TuiTraceNode[], out: TuiTraceNode[]): void {\n for (const n of roots) {\n out.push(n);\n if (n.children.length > 0) dfsFlat(n.children, out);\n }\n}\n\nfunction toTuiNodes(builds: StepBuild[], depth: number): TuiTraceNode[] {\n return builds.map((b) => ({\n id: b.id,\n name: b.name,\n type: b.type,\n status: b.status,\n durationMs: b.durationMs,\n depth,\n parentId: b.parentId,\n error: b.error,\n metadata: b.metadata,\n children: toTuiNodes(b.children, depth + 1),\n }));\n}\n\n/**\n * Build a navigable tree model from v0.1 JSONL trace events.\n * Does not mutate the input array or event objects.\n */\nexport function buildTuiTraceModel(events: TraceEvent[]): TuiTraceModel {\n const started = events.find((e): e is RunStartedEvent => e.event === \"run_started\");\n if (!started) {\n throw new Error(\"Invalid trace: missing run_started\");\n }\n\n const runId = started.runId;\n const runName = started.name;\n\n const completedAll = events.filter((e): e is RunCompletedEvent => e.event === \"run_completed\");\n const lastCompleted = completedAll[completedAll.length - 1];\n const runStatus = lastCompleted ? lastCompleted.status : \"running\";\n const runDurationMs =\n lastCompleted !== undefined && Number.isFinite(lastCompleted.durationMs)\n ? lastCompleted.durationMs\n : undefined;\n\n const nodes = new Map<string, StepBuild>();\n\n for (const e of events) {\n if (e.event !== \"step_started\") continue;\n const s = e as StepStartedEvent;\n nodes.set(s.stepId, {\n id: s.stepId,\n parentId: s.parentId,\n name: s.name,\n type: s.type,\n status: \"running\",\n startedAt: s.startTime,\n metadata: s.metadata as Record<string, unknown> | undefined,\n children: [],\n });\n }\n\n for (const e of events) {\n if (e.event !== \"step_completed\") continue;\n const c = e as StepCompletedEvent;\n const node = nodes.get(c.stepId);\n if (!node) continue;\n node.status = c.status;\n node.durationMs = c.durationMs;\n node.error =\n c.error !== undefined && typeof c.error.message === \"string\"\n ? c.error.message\n : undefined;\n }\n\n const roots: StepBuild[] = [];\n const sortByStarted = (a: StepBuild, b: StepBuild) => a.startedAt - b.startedAt;\n\n for (const n of nodes.values()) {\n if (n.parentId !== undefined && nodes.has(n.parentId)) {\n nodes.get(n.parentId)!.children.push(n);\n } else {\n roots.push(n);\n }\n }\n\n roots.sort(sortByStarted);\n for (const n of nodes.values()) {\n n.children.sort(sortByStarted);\n }\n\n const treeRoots = toTuiNodes(roots, 0);\n const flatNodes: TuiTraceNode[] = [];\n dfsFlat(treeRoots, flatNodes);\n\n return {\n runId,\n name: runName,\n status: runStatus,\n durationMs: runDurationMs,\n nodes: treeRoots,\n flatNodes,\n };\n}\n\n/** Total step count in tree (for default expand policy). Exported for tests. */\nexport function countTreeSteps(roots: TuiTraceNode[]): number {\n let n = 0;\n for (const r of roots) {\n n += 1 + countSubtree(r.children);\n }\n return n;\n}\n\nfunction countSubtree(children: TuiTraceNode[]): number {\n let n = 0;\n for (const c of children) {\n n += 1 + countSubtree(c.children);\n }\n return n;\n}\n","import { readTraceEvents, resolveTraceDir } from \"agent-inspect\";\n\nimport { buildTuiTraceModel } from \"./tree-model.js\";\nimport type { TuiTraceModel } from \"./types.js\";\n\nexport interface LoadTraceForTuiOptions {\n runId: string;\n dir?: string;\n}\n\n/**\n * Load JSONL trace events and build a TUI model. Does not write or mutate trace files.\n */\nexport async function loadTraceForTui(options: LoadTraceForTuiOptions): Promise<TuiTraceModel> {\n const traceDir = resolveTraceDir({ dir: options.dir });\n const events = await readTraceEvents(options.runId, traceDir);\n\n if (events.length === 0) {\n throw new Error(\n `Run not found or trace is empty: ${options.runId} (directory: ${traceDir})`,\n );\n }\n\n return buildTuiTraceModel(events);\n}\n","import { loadTraceForTui } from \"./trace-loader.js\";\n\nexport interface RunTraceViewerOptions {\n runId: string;\n dir?: string;\n}\n\nconst TTY_MSG =\n \"TUI requires an interactive terminal. Use agent-inspect view without --tui for plain output.\";\n\nexport async function runTraceViewer(options: RunTraceViewerOptions): Promise<void> {\n if (!process.stdout.isTTY || !process.stdin.isTTY) {\n throw new Error(TTY_MSG);\n }\n\n const model = await loadTraceForTui({\n runId: options.runId,\n dir: options.dir,\n });\n const [{ default: React }, { render }, { TraceViewerApp }] = await Promise.all([\n import(\"react\"),\n import(\"ink\"),\n import(\"./app.js\"),\n ]);\n\n const { waitUntilExit } = render(\n React.createElement(TraceViewerApp, { model }),\n );\n await waitUntilExit();\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-inspect/tui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"ink": "^5.0.1",
|
|
38
38
|
"react": "^18.3.1",
|
|
39
|
-
"agent-inspect": "1.
|
|
39
|
+
"agent-inspect": "1.8.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/react": "^18.3.18"
|