@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.
@@ -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
- function collectVisible(roots, expanded, out) {
134
- for (const n of roots) {
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
- function formatDur(ms) {
156
- if (ms === void 0 || !Number.isFinite(ms)) return "-";
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
- if (!process.stdout.isTTY || !process.stdin.isTTY) {
300
- throw new Error(TTY_MSG);
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;
@@ -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
- declare function TraceViewerApp(props: TraceViewerAppProps): React.ReactElement;
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, TraceViewerApp, type TraceViewerAppProps, type TuiAction, type TuiTraceModel, type TuiTraceNode, buildTuiTraceModel, countTreeSteps, initialExpandedSet, loadTraceForTui, mapInputToAction, runTraceViewer };
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
- declare function TraceViewerApp(props: TraceViewerAppProps): React.ReactElement;
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, TraceViewerApp, type TraceViewerAppProps, type TuiAction, type TuiTraceModel, type TuiTraceNode, buildTuiTraceModel, countTreeSteps, initialExpandedSet, loadTraceForTui, mapInputToAction, runTraceViewer };
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/keymap.ts
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
- React2.createElement(TraceViewerApp, { model })
126
+ React.createElement(TraceViewerApp, { model })
302
127
  );
303
128
  await waitUntilExit();
304
129
  }
305
130
 
306
- export { TraceViewerApp, buildTuiTraceModel, countTreeSteps, initialExpandedSet, loadTraceForTui, mapInputToAction, runTraceViewer };
131
+ export { buildTuiTraceModel, countTreeSteps, loadTraceForTui, runTraceViewer };
307
132
  //# sourceMappingURL=index.mjs.map
308
133
  //# sourceMappingURL=index.mjs.map
@@ -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":"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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","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.6.0",
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.6.0"
39
+ "agent-inspect": "1.8.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/react": "^18.3.18"