@yaag/tui 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/tree-render.ts +23 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaag/tui",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -19,6 +19,6 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@earendil-works/pi-tui": "^0.84.0",
22
- "@yaag/runtime": "0.5.0"
22
+ "@yaag/runtime": "0.5.2"
23
23
  }
24
24
  }
@@ -24,11 +24,23 @@ export interface TreeRenderOptions {
24
24
  readonly fold?: FoldState;
25
25
  /** The settled Run's Result, or the error plus bounded stderr tail. */
26
26
  readonly result?: string;
27
+ /**
28
+ * Draws the chrome that only an interactive surface can use: the key footer,
29
+ * the closing rule below the Result, and the ruled tree band of a Run that
30
+ * spawned no Agent. A surface that takes no input sets it to `false` and gets
31
+ * the header, the tree, the details pane of a selected node, and the Result.
32
+ * It defaults to `true`.
33
+ */
34
+ readonly interactive?: boolean;
27
35
  }
28
36
 
29
37
  /**
30
- * Renders the four stacked regions — header, tree, details pane, key footer —
31
- * as unstyled terminal lines, every line truncated to `width`.
38
+ * Renders the four-region frame — header, tree, details pane, key footer — plus
39
+ * the Result of a settled Run, as unstyled terminal lines, every line truncated
40
+ * to `width`. `interactive: false` drops the regions a surface that takes no
41
+ * input has no use for. A tree that has rows keeps the rule above it and the
42
+ * rule below it; the Result is then the last region, and it gets no rule below
43
+ * it.
32
44
  *
33
45
  * Pure over the state: two calls with the same state and options return equal
34
46
  * arrays. Every untrusted string passes `sanitizeTerminalLine` first, so a
@@ -39,7 +51,11 @@ export function renderTree(state: TreeState, options: TreeRenderOptions): readon
39
51
  const rows = visibleRows(tree, options.fold ?? emptyFold());
40
52
  const rule = "─".repeat(Math.max(1, Math.floor(options.width)));
41
53
  const selected = selectedNode(rows, options.selectedPath);
42
- const lines = [headerLine(state, options), rule, ...treeLines(rows, options), rule];
54
+ const interactive = options.interactive ?? true;
55
+ const collapseTreeBand = rows.length === 0 && !interactive;
56
+ const lines = collapseTreeBand
57
+ ? [headerLine(state, options)]
58
+ : [headerLine(state, options), rule, ...treeLines(rows, options), rule];
43
59
  const details = renderDetailsPane(selected, {
44
60
  width: options.width,
45
61
  outputTail: selected === undefined ? [] : state.outputTail(agentOfPath(selected.path)),
@@ -50,9 +66,11 @@ export function renderTree(state: TreeState, options: TreeRenderOptions): readon
50
66
  lines.push(clampToWidth("Result:", options.width));
51
67
  for (const line of result.split("\n"))
52
68
  lines.push(clampToWidth(` ${sanitizeTerminalLine(line)}`, options.width));
53
- lines.push(rule);
69
+ // The Result is the last region a non-interactive surface draws, so its
70
+ // closing rule would only separate it from nothing.
71
+ if (interactive) lines.push(rule);
54
72
  }
55
- lines.push(clampToWidth(FOOTER, options.width));
73
+ if (interactive) lines.push(clampToWidth(FOOTER, options.width));
56
74
  return lines;
57
75
  }
58
76