@osolmaz/pi-workflows 0.1.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.
Files changed (113) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +182 -0
  3. package/dist/extension/executor.d.ts +58 -0
  4. package/dist/extension/executor.js +201 -0
  5. package/dist/extension/executor.js.map +1 -0
  6. package/dist/extension/index.d.ts +17 -0
  7. package/dist/extension/index.js +504 -0
  8. package/dist/extension/index.js.map +1 -0
  9. package/dist/extension/widget.d.ts +21 -0
  10. package/dist/extension/widget.js +142 -0
  11. package/dist/extension/widget.js.map +1 -0
  12. package/dist/render/ansi.d.ts +16 -0
  13. package/dist/render/ansi.js +42 -0
  14. package/dist/render/ansi.js.map +1 -0
  15. package/dist/render/canvas.d.ts +40 -0
  16. package/dist/render/canvas.js +177 -0
  17. package/dist/render/canvas.js.map +1 -0
  18. package/dist/render/format.d.ts +3 -0
  19. package/dist/render/format.js +17 -0
  20. package/dist/render/format.js.map +1 -0
  21. package/dist/render/graph-render.d.ts +22 -0
  22. package/dist/render/graph-render.js +520 -0
  23. package/dist/render/graph-render.js.map +1 -0
  24. package/dist/render/graph.d.ts +46 -0
  25. package/dist/render/graph.js +272 -0
  26. package/dist/render/graph.js.map +1 -0
  27. package/dist/viewer/cli.d.ts +10 -0
  28. package/dist/viewer/cli.js +132 -0
  29. package/dist/viewer/cli.js.map +1 -0
  30. package/dist/viewer/render.d.ts +19 -0
  31. package/dist/viewer/render.js +162 -0
  32. package/dist/viewer/render.js.map +1 -0
  33. package/dist/viewer/tui.d.ts +11 -0
  34. package/dist/viewer/tui.js +140 -0
  35. package/dist/viewer/tui.js.map +1 -0
  36. package/dist/viewer/watch.d.ts +9 -0
  37. package/dist/viewer/watch.js +46 -0
  38. package/dist/viewer/watch.js.map +1 -0
  39. package/dist/workflows/decision.d.ts +25 -0
  40. package/dist/workflows/decision.js +96 -0
  41. package/dist/workflows/decision.js.map +1 -0
  42. package/dist/workflows/definition.d.ts +9 -0
  43. package/dist/workflows/definition.js +61 -0
  44. package/dist/workflows/definition.js.map +1 -0
  45. package/dist/workflows/engine.d.ts +65 -0
  46. package/dist/workflows/engine.js +574 -0
  47. package/dist/workflows/engine.js.map +1 -0
  48. package/dist/workflows/errors.d.ts +9 -0
  49. package/dist/workflows/errors.js +24 -0
  50. package/dist/workflows/errors.js.map +1 -0
  51. package/dist/workflows/graph.d.ts +17 -0
  52. package/dist/workflows/graph.js +127 -0
  53. package/dist/workflows/graph.js.map +1 -0
  54. package/dist/workflows/index.d.ts +11 -0
  55. package/dist/workflows/index.js +11 -0
  56. package/dist/workflows/index.js.map +1 -0
  57. package/dist/workflows/json.d.ts +14 -0
  58. package/dist/workflows/json.js +134 -0
  59. package/dist/workflows/json.js.map +1 -0
  60. package/dist/workflows/loader.d.ts +28 -0
  61. package/dist/workflows/loader.js +94 -0
  62. package/dist/workflows/loader.js.map +1 -0
  63. package/dist/workflows/schema.d.ts +7 -0
  64. package/dist/workflows/schema.js +176 -0
  65. package/dist/workflows/schema.js.map +1 -0
  66. package/dist/workflows/shell.d.ts +9 -0
  67. package/dist/workflows/shell.js +177 -0
  68. package/dist/workflows/shell.js.map +1 -0
  69. package/dist/workflows/store.d.ts +35 -0
  70. package/dist/workflows/store.js +181 -0
  71. package/dist/workflows/store.js.map +1 -0
  72. package/dist/workflows/text.d.ts +10 -0
  73. package/dist/workflows/text.js +32 -0
  74. package/dist/workflows/text.js.map +1 -0
  75. package/dist/workflows/types.d.ts +280 -0
  76. package/dist/workflows/types.js +2 -0
  77. package/dist/workflows/types.js.map +1 -0
  78. package/docs/development.md +130 -0
  79. package/docs/run-bundles.md +114 -0
  80. package/docs/workflows.md +311 -0
  81. package/examples/workflows/autoimplement.workflow.ts +92 -0
  82. package/examples/workflows/autoresearch.workflow.ts +139 -0
  83. package/examples/workflows/branch.workflow.ts +63 -0
  84. package/examples/workflows/echo.workflow.ts +23 -0
  85. package/examples/workflows/elegant-solution.workflow.ts +95 -0
  86. package/examples/workflows/shell.workflow.ts +31 -0
  87. package/examples/workflows/two-turn.workflow.ts +64 -0
  88. package/package.json +80 -0
  89. package/src/extension/executor.ts +251 -0
  90. package/src/extension/index.ts +627 -0
  91. package/src/extension/widget.ts +183 -0
  92. package/src/render/ansi.ts +47 -0
  93. package/src/render/canvas.ts +196 -0
  94. package/src/render/format.ts +19 -0
  95. package/src/render/graph-render.ts +738 -0
  96. package/src/render/graph.ts +341 -0
  97. package/src/viewer/cli.ts +150 -0
  98. package/src/viewer/render.ts +236 -0
  99. package/src/viewer/tui.ts +159 -0
  100. package/src/viewer/watch.ts +55 -0
  101. package/src/workflows/decision.ts +127 -0
  102. package/src/workflows/definition.ts +104 -0
  103. package/src/workflows/engine.ts +793 -0
  104. package/src/workflows/errors.ts +27 -0
  105. package/src/workflows/graph.ts +161 -0
  106. package/src/workflows/index.ts +76 -0
  107. package/src/workflows/json.ts +155 -0
  108. package/src/workflows/loader.ts +123 -0
  109. package/src/workflows/schema.ts +218 -0
  110. package/src/workflows/shell.ts +199 -0
  111. package/src/workflows/store.ts +234 -0
  112. package/src/workflows/text.ts +34 -0
  113. package/src/workflows/types.ts +318 -0
@@ -0,0 +1,272 @@
1
+ export function expandEdges(snapshot) {
2
+ return snapshot.edges.flatMap((edge, index) => {
3
+ if ("to" in edge) {
4
+ return [
5
+ {
6
+ edgeId: `${edge.from}->${edge.to}#${index}.0`,
7
+ from: edge.from,
8
+ to: edge.to,
9
+ isBackEdge: false,
10
+ },
11
+ ];
12
+ }
13
+ return Object.entries(edge.switch.cases).map(([caseKey, target], branch) => ({
14
+ edgeId: `${edge.from}->${target}#${index}.${branch}`,
15
+ from: edge.from,
16
+ to: target,
17
+ label: caseKey,
18
+ isBackEdge: false,
19
+ }));
20
+ });
21
+ }
22
+ function bfsOrder(snapshot, edges) {
23
+ const queue = [snapshot.startAt];
24
+ const visited = new Set();
25
+ const ordered = [];
26
+ while (queue.length > 0) {
27
+ const nodeId = queue.shift();
28
+ if (visited.has(nodeId)) {
29
+ continue;
30
+ }
31
+ visited.add(nodeId);
32
+ ordered.push(nodeId);
33
+ for (const edge of edges) {
34
+ if (edge.from === nodeId) {
35
+ queue.push(edge.to);
36
+ }
37
+ }
38
+ }
39
+ for (const nodeId of Object.keys(snapshot.nodes)) {
40
+ if (!visited.has(nodeId)) {
41
+ visited.add(nodeId);
42
+ ordered.push(nodeId);
43
+ }
44
+ }
45
+ return ordered;
46
+ }
47
+ /**
48
+ * DFS cycle detection: an edge is a back edge only when it closes a real
49
+ * cycle (its target is an ancestor on the DFS stack). This improves on the
50
+ * acpx viewer's shortest-level heuristic, which misclassifies the rejoining
51
+ * edge of an uneven diamond as a loop.
52
+ */
53
+ function markBackEdges(edges, orderedNodeIds) {
54
+ const color = new Map();
55
+ const visit = (nodeId) => {
56
+ color.set(nodeId, "gray");
57
+ for (const edge of edges) {
58
+ if (edge.from !== nodeId) {
59
+ continue;
60
+ }
61
+ const targetColor = color.get(edge.to);
62
+ if (targetColor === "gray") {
63
+ edge.isBackEdge = true;
64
+ }
65
+ else if (targetColor === undefined) {
66
+ visit(edge.to);
67
+ }
68
+ }
69
+ color.set(nodeId, "black");
70
+ };
71
+ for (const nodeId of orderedNodeIds) {
72
+ if (!color.has(nodeId)) {
73
+ visit(nodeId);
74
+ }
75
+ }
76
+ }
77
+ function computeLongestLevels(startAt, orderedNodeIds, forwardEdges) {
78
+ // orderedNodeIds is BFS order; iterate repeatedly until fixed point to get
79
+ // longest-path levels without a separate topological sort (graphs are tiny).
80
+ const levels = new Map([[startAt, 0]]);
81
+ for (let pass = 0; pass < orderedNodeIds.length + 1; pass += 1) {
82
+ let changed = false;
83
+ for (const edge of forwardEdges) {
84
+ const fromLevel = levels.get(edge.from);
85
+ if (fromLevel === undefined) {
86
+ continue;
87
+ }
88
+ const proposed = fromLevel + 1;
89
+ if (proposed > (levels.get(edge.to) ?? -1)) {
90
+ levels.set(edge.to, proposed);
91
+ changed = true;
92
+ }
93
+ }
94
+ if (!changed) {
95
+ break;
96
+ }
97
+ }
98
+ return levels;
99
+ }
100
+ /**
101
+ * Nodes on a straight single-path tail into a terminal node sink to the
102
+ * bottom ranks, matching the acpx viewer's tail pull-down.
103
+ */
104
+ function computeTailDepths(orderedNodeIds, forwardEdges, terminalNodeIds) {
105
+ const outgoing = new Map();
106
+ for (const edge of forwardEdges) {
107
+ outgoing.set(edge.from, [...(outgoing.get(edge.from) ?? []), edge.to]);
108
+ }
109
+ const memo = new Map();
110
+ const visit = (nodeId) => {
111
+ const existing = memo.get(nodeId);
112
+ if (existing !== undefined) {
113
+ return existing;
114
+ }
115
+ if (terminalNodeIds.has(nodeId)) {
116
+ memo.set(nodeId, 0);
117
+ return 0;
118
+ }
119
+ const targets = outgoing.get(nodeId) ?? [];
120
+ if (targets.length !== 1) {
121
+ memo.set(nodeId, null);
122
+ return null;
123
+ }
124
+ // Break potential cycles before recursing.
125
+ memo.set(nodeId, null);
126
+ const childDepth = visit(targets[0]);
127
+ const depth = childDepth === null ? null : childDepth + 1;
128
+ memo.set(nodeId, depth);
129
+ return depth;
130
+ };
131
+ for (const nodeId of orderedNodeIds) {
132
+ visit(nodeId);
133
+ }
134
+ const depths = new Map();
135
+ for (const [nodeId, depth] of memo) {
136
+ if (depth !== null) {
137
+ depths.set(nodeId, depth);
138
+ }
139
+ }
140
+ return depths;
141
+ }
142
+ function computeNodeRanks(snapshot, orderedNodeIds, edges) {
143
+ const forwardEdges = edges.filter((edge) => !edge.isBackEdge);
144
+ const longest = computeLongestLevels(snapshot.startAt, orderedNodeIds, forwardEdges);
145
+ const outgoingCounts = new Map();
146
+ for (const edge of forwardEdges) {
147
+ outgoingCounts.set(edge.from, (outgoingCounts.get(edge.from) ?? 0) + 1);
148
+ }
149
+ const terminalNodeIds = new Set(orderedNodeIds.filter((nodeId) => (outgoingCounts.get(nodeId) ?? 0) === 0));
150
+ const tailDepths = computeTailDepths(orderedNodeIds, forwardEdges, terminalNodeIds);
151
+ const rankOfNode = new Map();
152
+ let fallback = Math.max(0, ...longest.values());
153
+ for (const nodeId of orderedNodeIds) {
154
+ const base = longest.get(nodeId);
155
+ if (base === undefined) {
156
+ fallback += 1;
157
+ rankOfNode.set(nodeId, fallback);
158
+ }
159
+ else {
160
+ rankOfNode.set(nodeId, base);
161
+ }
162
+ }
163
+ const maxRank = Math.max(0, ...rankOfNode.values());
164
+ for (const nodeId of orderedNodeIds) {
165
+ const tailDepth = tailDepths.get(nodeId);
166
+ if (tailDepth !== undefined) {
167
+ rankOfNode.set(nodeId, Math.max(rankOfNode.get(nodeId) ?? 0, maxRank - tailDepth));
168
+ }
169
+ }
170
+ return rankOfNode;
171
+ }
172
+ /**
173
+ * Build ranks with virtual pass-through cells so every forward edge connects
174
+ * adjacent ranks, then order cells within ranks by neighbor barycenter.
175
+ */
176
+ export function layoutGraph(snapshot) {
177
+ const edges = expandEdges(snapshot);
178
+ const orderedNodeIds = bfsOrder(snapshot, edges);
179
+ markBackEdges(edges, orderedNodeIds);
180
+ const rankOfNode = computeNodeRanks(snapshot, orderedNodeIds, edges);
181
+ const rankCount = Math.max(0, ...rankOfNode.values()) + 1;
182
+ const ranks = Array.from({ length: rankCount }, () => []);
183
+ const cellRef = new Map();
184
+ for (const nodeId of orderedNodeIds) {
185
+ const rank = rankOfNode.get(nodeId) ?? 0;
186
+ cellRef.set(nodeId, { rank, index: ranks[rank].length });
187
+ ranks[rank].push({ kind: "node", nodeId });
188
+ }
189
+ // Chain each long forward edge through virtual cells in intermediate ranks.
190
+ const segments = [];
191
+ for (const edge of edges) {
192
+ if (edge.isBackEdge) {
193
+ continue;
194
+ }
195
+ const fromRank = rankOfNode.get(edge.from);
196
+ const toRank = rankOfNode.get(edge.to);
197
+ if (fromRank === undefined || toRank === undefined || toRank <= fromRank) {
198
+ continue;
199
+ }
200
+ let previous = cellRef.get(edge.from);
201
+ for (let rank = fromRank + 1; rank < toRank; rank += 1) {
202
+ const index = ranks[rank].length;
203
+ ranks[rank].push({ kind: "virtual", edgeId: edge.edgeId });
204
+ segments.push({
205
+ edgeId: edge.edgeId,
206
+ rank: previous.rank,
207
+ fromCell: previous.index,
208
+ toCell: index,
209
+ ...(previous.rank === fromRank && edge.label !== undefined ? { label: edge.label } : {}),
210
+ });
211
+ previous = { rank, index };
212
+ }
213
+ const target = cellRef.get(edge.to);
214
+ segments.push({
215
+ edgeId: edge.edgeId,
216
+ rank: previous.rank,
217
+ fromCell: previous.index,
218
+ toCell: target.index,
219
+ ...(previous.rank === fromRank && edge.label !== undefined ? { label: edge.label } : {}),
220
+ });
221
+ }
222
+ orderRanksByBarycenter(ranks, segments);
223
+ return { ranks, edges, segments, rankOfNode };
224
+ }
225
+ /** Sweep up and down, sorting each rank by the mean position of neighbors. */
226
+ function orderRanksByBarycenter(ranks, segments) {
227
+ const reindex = (rank, order) => {
228
+ const cells = ranks[rank];
229
+ const inverse = new Map(order.map((oldIndex, newIndex) => [oldIndex, newIndex]));
230
+ ranks[rank] = order.map((oldIndex) => cells[oldIndex]);
231
+ for (const segment of segments) {
232
+ if (segment.rank === rank) {
233
+ segment.fromCell = inverse.get(segment.fromCell);
234
+ }
235
+ if (segment.rank === rank - 1) {
236
+ segment.toCell = inverse.get(segment.toCell);
237
+ }
238
+ }
239
+ };
240
+ const sortRank = (rank, direction) => {
241
+ const cells = ranks[rank];
242
+ if (cells.length < 2) {
243
+ return;
244
+ }
245
+ const scores = cells.map((_cell, index) => {
246
+ const neighbors = segments
247
+ .filter((segment) => direction === "down"
248
+ ? segment.rank === rank - 1 && segment.toCell === index
249
+ : segment.rank === rank && segment.fromCell === index)
250
+ .map((segment) => (direction === "down" ? segment.fromCell : segment.toCell));
251
+ const score = neighbors.length === 0
252
+ ? Number.MAX_SAFE_INTEGER
253
+ : neighbors.reduce((sum, value) => sum + value, 0) / neighbors.length;
254
+ return { index, score };
255
+ });
256
+ const order = scores
257
+ .toSorted((left, right) => left.score - right.score || left.index - right.index)
258
+ .map((entry) => entry.index);
259
+ if (order.some((oldIndex, newIndex) => oldIndex !== newIndex)) {
260
+ reindex(rank, order);
261
+ }
262
+ };
263
+ for (let pass = 0; pass < 4; pass += 1) {
264
+ for (let rank = 1; rank < ranks.length; rank += 1) {
265
+ sortRank(rank, "down");
266
+ }
267
+ for (let rank = ranks.length - 2; rank >= 0; rank -= 1) {
268
+ sortRank(rank, "up");
269
+ }
270
+ }
271
+ }
272
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/render/graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ type CliArgs = {
3
+ command: string;
4
+ runId?: string | undefined;
5
+ dir: string;
6
+ once: boolean;
7
+ };
8
+ export declare function parseCliArgs(argv: string[]): CliArgs;
9
+ export declare function main(argv?: string[]): Promise<number>;
10
+ export {};
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env node
2
+ import { realpathSync } from "node:fs";
3
+ import { pathToFileURL } from "node:url";
4
+ import { sanitizeText } from "../render/ansi.js";
5
+ import { listRunBundles, readRunBundle, workflowRunsBaseDir } from "../workflows/store.js";
6
+ import { formatDuration, renderRunDetailLines, renderRunListLines, runElapsedMs, statusLabel, } from "./render.js";
7
+ import { runViewer } from "./tui.js";
8
+ const USAGE = `pi-workflows — live terminal viewer for pi workflow runs
9
+
10
+ Usage:
11
+ pi-workflows view [runId] [--dir <runsDir>] [--once]
12
+ pi-workflows runs [--dir <runsDir>]
13
+
14
+ Commands:
15
+ view Open the live TUI viewer. With --once, print a snapshot and exit.
16
+ runs List recent workflow runs.
17
+
18
+ Options:
19
+ --dir <runsDir> Runs directory (default: ~/.pi/agent/workflows/runs)
20
+ --once Render once to stdout without the interactive TUI
21
+ `;
22
+ export function parseCliArgs(argv) {
23
+ const args = [...argv];
24
+ const command = args[0] && !args[0].startsWith("-") ? args.shift() : "view";
25
+ let dir = workflowRunsBaseDir();
26
+ let once = false;
27
+ let runId;
28
+ while (args.length > 0) {
29
+ const arg = args.shift();
30
+ if (arg === "--dir") {
31
+ const value = args.shift();
32
+ if (!value) {
33
+ throw new Error("--dir requires a path");
34
+ }
35
+ dir = value;
36
+ }
37
+ else if (arg === "--once") {
38
+ once = true;
39
+ }
40
+ else if (arg === "--help" || arg === "-h") {
41
+ return { command: "help", dir, once };
42
+ }
43
+ else if (!arg.startsWith("-") && runId === undefined) {
44
+ runId = arg;
45
+ }
46
+ else {
47
+ throw new Error(`Unknown argument: ${arg}`);
48
+ }
49
+ }
50
+ return { command, runId, dir, once };
51
+ }
52
+ async function printRuns(dir) {
53
+ const bundles = await listRunBundles(dir);
54
+ if (bundles.length === 0) {
55
+ process.stdout.write(`No workflow runs found in ${dir}\n`);
56
+ return;
57
+ }
58
+ for (const bundle of bundles) {
59
+ const state = bundle.state;
60
+ // Titles can interpolate untrusted run input; strip control sequences.
61
+ const title = state.runTitle ? ` — ${sanitizeText(state.runTitle)}` : "";
62
+ process.stdout.write(`${statusLabel(state.status)} ${sanitizeText(state.workflowName)}${title} ${state.runId} ${formatDuration(runElapsedMs(state))}\n`);
63
+ }
64
+ }
65
+ async function printOnce(dir, runId) {
66
+ const bundles = await listRunBundles(dir);
67
+ const size = { width: process.stdout.columns ?? 100, height: 1_000 };
68
+ if (runId === undefined) {
69
+ process.stdout.write(`${renderRunListLines(bundles, 0, size).join("\n")}\n`);
70
+ return;
71
+ }
72
+ const match = bundles.find((bundle) => bundle.state.runId === runId);
73
+ if (!match) {
74
+ throw new Error(`Run not found: ${runId}`);
75
+ }
76
+ const bundle = await readRunBundle(match.runDir);
77
+ if (!bundle) {
78
+ throw new Error(`Run bundle unreadable: ${match.runDir}`);
79
+ }
80
+ process.stdout.write(`${renderRunDetailLines(bundle, size).join("\n")}\n`);
81
+ }
82
+ export async function main(argv = process.argv.slice(2)) {
83
+ let args;
84
+ try {
85
+ args = parseCliArgs(argv);
86
+ }
87
+ catch (error) {
88
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n\n${USAGE}`);
89
+ return 2;
90
+ }
91
+ try {
92
+ if (args.command === "help") {
93
+ process.stdout.write(USAGE);
94
+ return 0;
95
+ }
96
+ if (args.command === "runs") {
97
+ await printRuns(args.dir);
98
+ return 0;
99
+ }
100
+ if (args.command === "view") {
101
+ if (args.once || !process.stdout.isTTY) {
102
+ await printOnce(args.dir, args.runId);
103
+ return 0;
104
+ }
105
+ await runViewer({ runsDir: args.dir, runId: args.runId });
106
+ return 0;
107
+ }
108
+ process.stderr.write(`Unknown command: ${args.command}\n\n${USAGE}`);
109
+ return 2;
110
+ }
111
+ catch (error) {
112
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
113
+ return 1;
114
+ }
115
+ }
116
+ const entryPath = process.argv[1];
117
+ // realpath so invocation through a bin symlink (npm link) still matches.
118
+ const resolvedEntry = entryPath !== undefined ? realpathSyncSafe(entryPath) : undefined;
119
+ if (resolvedEntry !== undefined && import.meta.url === pathToFileURL(resolvedEntry).href) {
120
+ main().then((code) => {
121
+ process.exitCode = code;
122
+ });
123
+ }
124
+ function realpathSyncSafe(target) {
125
+ try {
126
+ return realpathSync(target);
127
+ }
128
+ catch {
129
+ return target;
130
+ }
131
+ }
132
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/viewer/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { formatDuration, runElapsedMs } from "../render/format.js";
2
+ import type { LoadedRunBundle } from "../workflows/store.js";
3
+ import type { WorkflowRunStatus } from "../workflows/types.js";
4
+ export { formatDuration, runElapsedMs };
5
+ export type ViewportSize = {
6
+ width: number;
7
+ height: number;
8
+ };
9
+ export declare function statusLabel(status: WorkflowRunStatus): string;
10
+ /** One line per run for the run picker. */
11
+ export declare function renderRunListLines(bundles: LoadedRunBundle[], selectedIndex: number, size: ViewportSize, now?: Date): string[];
12
+ /**
13
+ * Full-run detail view: header, graph pane, step timeline, inspector.
14
+ * `scroll` shifts the viewport down over the full body; `selectedStepIndex`
15
+ * scrubs the replay position (defaults to the latest step, i.e. live).
16
+ */
17
+ export declare function renderRunDetailLines(bundle: LoadedRunBundle, size: ViewportSize, now?: Date, scroll?: number, selectedStepIndex?: number | null): string[];
18
+ /** Highest useful `scroll` value for the detail view of `bundle`. */
19
+ export declare function maxDetailScroll(bundle: LoadedRunBundle, size: ViewportSize, selectedStepIndex?: number | null): number;
@@ -0,0 +1,162 @@
1
+ import { ansi, fitWidth, sanitizeText } from "../render/ansi.js";
2
+ import { formatDuration, runElapsedMs } from "../render/format.js";
3
+ import { renderGraphLines } from "../render/graph-render.js";
4
+ export { formatDuration, runElapsedMs };
5
+ const STATUS_COLORS = {
6
+ running: ansi.cyan,
7
+ waiting: ansi.yellow,
8
+ completed: ansi.green,
9
+ failed: ansi.red,
10
+ timed_out: ansi.red,
11
+ cancelled: ansi.yellow,
12
+ };
13
+ export function statusLabel(status) {
14
+ return STATUS_COLORS[status](status);
15
+ }
16
+ function previewValue(value, maxLength) {
17
+ if (value === undefined) {
18
+ return "";
19
+ }
20
+ const text = typeof value === "string" ? value : JSON.stringify(value);
21
+ // Model-controlled values must not carry escape sequences into the terminal.
22
+ const singleLine = sanitizeText(text ?? "")
23
+ .replaceAll(/\s+/g, " ")
24
+ .trim();
25
+ return singleLine.length <= maxLength ? singleLine : `${singleLine.slice(0, maxLength - 1)}…`;
26
+ }
27
+ /** One line per run for the run picker. */
28
+ export function renderRunListLines(bundles, selectedIndex, size, now = new Date()) {
29
+ const lines = [];
30
+ lines.push(ansi.bold("pi-workflows — runs"));
31
+ lines.push(ansi.dim("↑/↓ select · enter open · q quit"));
32
+ lines.push("");
33
+ if (bundles.length === 0) {
34
+ lines.push(ansi.dim("No workflow runs found."));
35
+ return lines.map((line) => fitWidth(line, size.width));
36
+ }
37
+ const visible = Math.max(1, size.height - lines.length - 1);
38
+ const start = Math.min(Math.max(0, selectedIndex - Math.floor(visible / 2)), Math.max(0, bundles.length - visible));
39
+ for (const [offset, bundle] of bundles.slice(start, start + visible).entries()) {
40
+ const index = start + offset;
41
+ const state = bundle.state;
42
+ const marker = index === selectedIndex ? ansi.cyan("›") : " ";
43
+ const elapsed = formatDuration(runElapsedMs(state, now));
44
+ const title = state.runTitle ? ` — ${sanitizeText(state.runTitle)}` : "";
45
+ lines.push(fitWidth(`${marker} ${statusLabel(state.status)} ${ansi.bold(state.workflowName)}${title} ${ansi.dim(`${state.runId} · ${elapsed}`)}`, size.width));
46
+ }
47
+ return lines;
48
+ }
49
+ function stepLine(step, index, selectedStepIndex, width) {
50
+ const durationMs = Date.parse(step.finishedAt) - Date.parse(step.startedAt);
51
+ const glyph = step.outcome === "ok" ? ansi.green("✓") : ansi.red("✗");
52
+ const marker = index === selectedStepIndex ? ansi.cyan("›") : " ";
53
+ const preview = step.error !== undefined
54
+ ? ansi.red(previewValue(step.error, 60))
55
+ : ansi.dim(previewValue(step.output, 60));
56
+ return fitWidth(` ${marker}${glyph} ${step.nodeId} ${ansi.dim(`(${step.nodeType}, ${formatDuration(durationMs)})`)} ${preview}`, width);
57
+ }
58
+ /** Fallback node status list for bundles without a definition snapshot. */
59
+ function nodeStatusLine(bundle, nodeId, width, now) {
60
+ const state = bundle.state;
61
+ const nodeType = bundle.snapshot?.nodes[nodeId]?.nodeType ?? "?";
62
+ const result = state.results[nodeId];
63
+ let glyph = ansi.dim("·");
64
+ let suffix = "";
65
+ if (state.currentNode === nodeId) {
66
+ glyph = ansi.cyan("◐");
67
+ const startedAt = state.currentNodeStartedAt
68
+ ? Date.parse(state.currentNodeStartedAt)
69
+ : now.getTime();
70
+ const detail = state.statusDetail ? ` · ${sanitizeText(state.statusDetail)}` : "";
71
+ suffix = ansi.cyan(` running ${formatDuration(now.getTime() - startedAt)}${detail}`);
72
+ }
73
+ else if (state.waitingOn === nodeId) {
74
+ glyph = ansi.yellow("⏸");
75
+ suffix = ansi.yellow(" waiting");
76
+ }
77
+ else if (result) {
78
+ glyph = result.outcome === "ok" ? ansi.green("✓") : ansi.red("✗");
79
+ suffix = ansi.dim(` ${formatDuration(result.durationMs)}`);
80
+ }
81
+ return fitWidth(` ${glyph} ${nodeId} ${ansi.dim(`[${nodeType}]`)}${suffix}`, width);
82
+ }
83
+ /** Pretty-printed JSON body of the selected step for the inspector pane. */
84
+ function inspectorLines(step, width) {
85
+ const lines = [];
86
+ const body = step.error !== undefined ? step.error : step.output;
87
+ const rendered = typeof body === "string" && step.error !== undefined ? body : JSON.stringify(body, null, 2);
88
+ for (const raw of (rendered ?? "null").split("\n")) {
89
+ lines.push(fitWidth(` ${sanitizeText(raw)}`, width));
90
+ }
91
+ if (step.action) {
92
+ const receipt = [
93
+ step.action.actionType,
94
+ step.action.command,
95
+ ...(step.action.args ?? []),
96
+ step.action.exitCode !== undefined ? `→ exit ${step.action.exitCode}` : "",
97
+ ]
98
+ .filter((part) => part !== undefined && part !== "")
99
+ .join(" ");
100
+ lines.push(fitWidth(ansi.dim(` ${sanitizeText(receipt)}`), width));
101
+ }
102
+ return lines;
103
+ }
104
+ /**
105
+ * Full-run detail view: header, graph pane, step timeline, inspector.
106
+ * `scroll` shifts the viewport down over the full body; `selectedStepIndex`
107
+ * scrubs the replay position (defaults to the latest step, i.e. live).
108
+ */
109
+ export function renderRunDetailLines(bundle, size, now = new Date(), scroll = 0, selectedStepIndex = null) {
110
+ const state = bundle.state;
111
+ const steps = state.steps;
112
+ const selected = selectedStepIndex === null ? steps.length - 1 : selectedStepIndex;
113
+ const lines = [];
114
+ const title = state.runTitle ? ` — ${sanitizeText(state.runTitle)}` : "";
115
+ lines.push(fitWidth(`${ansi.bold(`workflow ${sanitizeText(state.workflowName)}`)}${title}`, size.width));
116
+ const position = selectedStepIndex === null || steps.length === 0
117
+ ? ""
118
+ : ` · step ${Math.min(selected, steps.length - 1) + 1}/${steps.length}`;
119
+ const paused = state.paused ? ` · ${ansi.yellow("paused")}` : "";
120
+ lines.push(fitWidth(`${statusLabel(state.status)}${paused} · run ${state.runId} · elapsed ${formatDuration(runElapsedMs(state, now))}${position}`, size.width));
121
+ lines.push(ansi.dim("q back · r refresh · ↑/↓ scroll · ←/→ replay steps"));
122
+ lines.push("");
123
+ const graph = renderGraphLines(bundle, selected, now, { nodeStyle: "box" }).map((line) => fitWidth(line, size.width));
124
+ if (graph.length > 0) {
125
+ lines.push(...graph);
126
+ }
127
+ else {
128
+ // No definition snapshot: fall back to a flat executed-node list.
129
+ for (const nodeId of Object.keys(state.results)) {
130
+ lines.push(nodeStatusLine(bundle, nodeId, size.width, now));
131
+ }
132
+ }
133
+ if (steps.length > 0) {
134
+ lines.push("");
135
+ lines.push(ansi.bold("steps"));
136
+ for (const [index, step] of steps.entries()) {
137
+ lines.push(stepLine(step, index, Math.min(selected, steps.length - 1), size.width));
138
+ }
139
+ const inspected = steps[Math.min(Math.max(selected, 0), steps.length - 1)];
140
+ if (inspected) {
141
+ lines.push("");
142
+ lines.push(ansi.bold(`step output — ${sanitizeText(inspected.nodeId)} (${inspected.outcome})`));
143
+ lines.push(...inspectorLines(inspected, size.width));
144
+ }
145
+ }
146
+ if (state.error) {
147
+ lines.push("");
148
+ lines.push(fitWidth(ansi.red(`error: ${sanitizeText(state.error)}`), size.width));
149
+ }
150
+ if (state.status === "completed" && state.finalOutput !== undefined) {
151
+ lines.push("");
152
+ lines.push(fitWidth(`${ansi.bold("output")} ${previewValue(state.finalOutput, size.width - 8)}`, size.width));
153
+ }
154
+ const start = Math.max(0, Math.min(scroll, lines.length - size.height));
155
+ return lines.slice(start, start + size.height);
156
+ }
157
+ /** Highest useful `scroll` value for the detail view of `bundle`. */
158
+ export function maxDetailScroll(bundle, size, selectedStepIndex = null) {
159
+ const total = renderRunDetailLines(bundle, { width: size.width, height: Number.MAX_SAFE_INTEGER }, new Date(), 0, selectedStepIndex).length;
160
+ return Math.max(0, total - size.height);
161
+ }
162
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/viewer/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAI7D,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC;AAOxC,MAAM,aAAa,GAAwD;IACzE,OAAO,EAAE,IAAI,CAAC,IAAI;IAClB,OAAO,EAAE,IAAI,CAAC,MAAM;IACpB,SAAS,EAAE,IAAI,CAAC,KAAK;IACrB,MAAM,EAAE,IAAI,CAAC,GAAG;IAChB,SAAS,EAAE,IAAI,CAAC,GAAG;IACnB,SAAS,EAAE,IAAI,CAAC,MAAM;CACvB,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,MAAyB;IACnD,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,YAAY,CAAC,KAAc,EAAE,SAAiB;IACrD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACvE,6EAA6E;IAC7E,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,IAAI,EAAE,CAAC;SACxC,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC;SACvB,IAAI,EAAE,CAAC;IACV,OAAO,UAAU,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC;AAChG,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,kBAAkB,CAChC,OAA0B,EAC1B,aAAqB,EACrB,IAAkB,EAClB,GAAG,GAAS,IAAI,IAAI,EAAE;IAEtB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC7C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAChD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EACpD,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,CACtC,CAAC;IACF,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/E,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,MAAM,MAAM,GAAG,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9D,MAAM,OAAO,GAAG,cAAc,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,KAAK,CAAC,IAAI,CACR,QAAQ,CACN,GAAG,MAAM,IAAI,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,KAAK,KAAK,IAAI,CAAC,GAAG,CAC3F,GAAG,KAAK,CAAC,KAAK,MAAM,OAAO,EAAE,CAC9B,EAAE,EACH,IAAI,CAAC,KAAK,CACX,CACF,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CACf,IAAwB,EACxB,KAAa,EACb,iBAAyB,EACzB,KAAa;IAEb,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,KAAK,KAAK,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAClE,MAAM,OAAO,GACX,IAAI,CAAC,KAAK,KAAK,SAAS;QACtB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACxC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9C,OAAO,QAAQ,CACb,IAAI,MAAM,GAAG,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,KAAK,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,EAAE,EAC/G,KAAK,CACN,CAAC;AACJ,CAAC;AAED,2EAA2E;AAC3E,SAAS,cAAc,CAAC,MAAuB,EAAE,MAAc,EAAE,KAAa,EAAE,GAAS;IACvF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,QAAQ,IAAI,GAAG,CAAC;IACjE,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,KAAK,CAAC,WAAW,KAAK,MAAM,EAAE,CAAC;QACjC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,MAAM,SAAS,GAAG,KAAK,CAAC,oBAAoB;YAC1C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC;YACxC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClF,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC;IACvF,CAAC;SAAM,IAAI,KAAK,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;QACtC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;SAAM,IAAI,MAAM,EAAE,CAAC;QAClB,KAAK,GAAG,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClE,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC,GAAG,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC;AACvF,CAAC;AAED,4EAA4E;AAC5E,SAAS,cAAc,CAAC,IAAwB,EAAE,KAAa;IAC7D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;IACjE,MAAM,QAAQ,GACZ,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9F,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG;YACd,IAAI,CAAC,MAAM,CAAC,UAAU;YACtB,IAAI,CAAC,MAAM,CAAC,OAAO;YACnB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YAC3B,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE;SAC3E;aACE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE,CAAC;aACnD,IAAI,CAAC,GAAG,CAAC,CAAC;QACb,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAuB,EACvB,IAAkB,EAClB,GAAG,GAAS,IAAI,IAAI,EAAE,EACtB,MAAM,GAAG,CAAC,EACV,iBAAiB,GAAkB,IAAI;IAEvC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC1B,MAAM,QAAQ,GAAG,iBAAiB,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC;IACnF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,KAAK,CAAC,IAAI,CACR,QAAQ,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAC7F,CAAC;IACF,MAAM,QAAQ,GACZ,iBAAiB,KAAK,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAC9C,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,WAAW,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;IAC5E,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,KAAK,CAAC,IAAI,CACR,QAAQ,CACN,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,UAAU,KAAK,CAAC,KAAK,cAAc,cAAc,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,EAC7H,IAAI,CAAC,KAAK,CACX,CACF,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC,CAAC;IAC3E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACvF,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAC3B,CAAC;IACF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;IACvB,CAAC;SAAM,CAAC;QACN,kEAAkE;QAClE,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YAChD,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAC/B,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5C,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACtF,CAAC;QACD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3E,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CACR,IAAI,CAAC,IAAI,CAAC,iBAAiB,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC,OAAO,GAAG,CAAC,CACpF,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACpE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CACR,QAAQ,CACN,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,EAC3E,IAAI,CAAC,KAAK,CACX,CACF,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACxE,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;AACjD,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,eAAe,CAC7B,MAAuB,EACvB,IAAkB,EAClB,iBAAiB,GAAkB,IAAI;IAEvC,MAAM,KAAK,GAAG,oBAAoB,CAChC,MAAM,EACN,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,gBAAgB,EAAE,EACtD,IAAI,IAAI,EAAE,EACV,CAAC,EACD,iBAAiB,CAClB,CAAC,MAAM,CAAC;IACT,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,11 @@
1
+ export type ViewerOptions = {
2
+ runsDir: string;
3
+ runId?: string | undefined;
4
+ /** Redraw interval for elapsed timers while a run is active. */
5
+ tickMs?: number;
6
+ };
7
+ /**
8
+ * Interactive live viewer. Watches the runs directory and re-renders as run
9
+ * bundles change on disk. Returns when the user quits.
10
+ */
11
+ export declare function runViewer(options: ViewerOptions): Promise<void>;