@elaraai/e3-ui-cli 1.0.71 → 1.0.73

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 (219) hide show
  1. package/README.md +46 -21
  2. package/dist/app/assets/{engine-BKZbmXkC-hslJZfFw.js → engine-Bm-cIDd_-DwUdGcTZ.js} +1 -1
  3. package/dist/app/assets/{index-8USNHP31.js → index-mj-YVVN1.js} +92 -92
  4. package/dist/app/index.html +1 -1
  5. package/dist/cli.js +36 -5
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/tui.d.ts +84 -0
  8. package/dist/commands/tui.d.ts.map +1 -0
  9. package/dist/commands/tui.js +86 -0
  10. package/dist/commands/tui.js.map +1 -0
  11. package/dist/tui/api.d.ts +108 -0
  12. package/dist/tui/api.d.ts.map +1 -0
  13. package/dist/tui/api.js +130 -0
  14. package/dist/tui/api.js.map +1 -0
  15. package/dist/tui/app.d.ts +23 -0
  16. package/dist/tui/app.d.ts.map +1 -0
  17. package/dist/tui/app.js +241 -0
  18. package/dist/tui/app.js.map +1 -0
  19. package/dist/tui/controller.d.ts +116 -0
  20. package/dist/tui/controller.d.ts.map +1 -0
  21. package/dist/tui/controller.js +620 -0
  22. package/dist/tui/controller.js.map +1 -0
  23. package/dist/tui/data/dataflow.d.ts +68 -0
  24. package/dist/tui/data/dataflow.d.ts.map +1 -0
  25. package/dist/tui/data/dataflow.js +137 -0
  26. package/dist/tui/data/dataflow.js.map +1 -0
  27. package/dist/tui/data/dataset.d.ts +80 -0
  28. package/dist/tui/data/dataset.d.ts.map +1 -0
  29. package/dist/tui/data/dataset.js +297 -0
  30. package/dist/tui/data/dataset.js.map +1 -0
  31. package/dist/tui/data/edit-buffer.d.ts +74 -0
  32. package/dist/tui/data/edit-buffer.d.ts.map +1 -0
  33. package/dist/tui/data/edit-buffer.js +120 -0
  34. package/dist/tui/data/edit-buffer.js.map +1 -0
  35. package/dist/tui/data/feeds.d.ts +45 -0
  36. package/dist/tui/data/feeds.d.ts.map +1 -0
  37. package/dist/tui/data/feeds.js +318 -0
  38. package/dist/tui/data/feeds.js.map +1 -0
  39. package/dist/tui/data/logs.d.ts +68 -0
  40. package/dist/tui/data/logs.d.ts.map +1 -0
  41. package/dist/tui/data/logs.js +134 -0
  42. package/dist/tui/data/logs.js.map +1 -0
  43. package/dist/tui/input/commands.d.ts +159 -0
  44. package/dist/tui/input/commands.d.ts.map +1 -0
  45. package/dist/tui/input/commands.js +259 -0
  46. package/dist/tui/input/commands.js.map +1 -0
  47. package/dist/tui/input/completion.d.ts +63 -0
  48. package/dist/tui/input/completion.d.ts.map +1 -0
  49. package/dist/tui/input/completion.js +128 -0
  50. package/dist/tui/input/completion.js.map +1 -0
  51. package/dist/tui/input/keymap.d.ts +153 -0
  52. package/dist/tui/input/keymap.d.ts.map +1 -0
  53. package/dist/tui/input/keymap.js +206 -0
  54. package/dist/tui/input/keymap.js.map +1 -0
  55. package/dist/tui/input/mouse.d.ts +52 -0
  56. package/dist/tui/input/mouse.d.ts.map +1 -0
  57. package/dist/tui/input/mouse.js +55 -0
  58. package/dist/tui/input/mouse.js.map +1 -0
  59. package/dist/tui/lifecycle.d.ts +61 -0
  60. package/dist/tui/lifecycle.d.ts.map +1 -0
  61. package/dist/tui/lifecycle.js +99 -0
  62. package/dist/tui/lifecycle.js.map +1 -0
  63. package/dist/tui/model/catalogue.d.ts +28 -0
  64. package/dist/tui/model/catalogue.d.ts.map +1 -0
  65. package/dist/tui/model/catalogue.js +94 -0
  66. package/dist/tui/model/catalogue.js.map +1 -0
  67. package/dist/tui/model/help.d.ts +37 -0
  68. package/dist/tui/model/help.d.ts.map +1 -0
  69. package/dist/tui/model/help.js +210 -0
  70. package/dist/tui/model/help.js.map +1 -0
  71. package/dist/tui/model/index.d.ts +42 -0
  72. package/dist/tui/model/index.d.ts.map +1 -0
  73. package/dist/tui/model/index.js +50 -0
  74. package/dist/tui/model/index.js.map +1 -0
  75. package/dist/tui/model/status.d.ts +88 -0
  76. package/dist/tui/model/status.d.ts.map +1 -0
  77. package/dist/tui/model/status.js +137 -0
  78. package/dist/tui/model/status.js.map +1 -0
  79. package/dist/tui/model/tree.d.ts +112 -0
  80. package/dist/tui/model/tree.d.ts.map +1 -0
  81. package/dist/tui/model/tree.js +178 -0
  82. package/dist/tui/model/tree.js.map +1 -0
  83. package/dist/tui/model/types.d.ts +21 -0
  84. package/dist/tui/model/types.d.ts.map +1 -0
  85. package/dist/tui/model/types.js +46 -0
  86. package/dist/tui/model/types.js.map +1 -0
  87. package/dist/tui/render/glyphs.d.ts +122 -0
  88. package/dist/tui/render/glyphs.d.ts.map +1 -0
  89. package/dist/tui/render/glyphs.js +122 -0
  90. package/dist/tui/render/glyphs.js.map +1 -0
  91. package/dist/tui/render/layout.d.ts +145 -0
  92. package/dist/tui/render/layout.d.ts.map +1 -0
  93. package/dist/tui/render/layout.js +209 -0
  94. package/dist/tui/render/layout.js.map +1 -0
  95. package/dist/tui/render/text.d.ts +149 -0
  96. package/dist/tui/render/text.d.ts.map +1 -0
  97. package/dist/tui/render/text.js +288 -0
  98. package/dist/tui/render/text.js.map +1 -0
  99. package/dist/tui/render/theme.d.ts +88 -0
  100. package/dist/tui/render/theme.d.ts.map +1 -0
  101. package/dist/tui/render/theme.js +145 -0
  102. package/dist/tui/render/theme.js.map +1 -0
  103. package/dist/tui/session.d.ts +78 -0
  104. package/dist/tui/session.d.ts.map +1 -0
  105. package/dist/tui/session.js +237 -0
  106. package/dist/tui/session.js.map +1 -0
  107. package/dist/tui/state/actions.d.ts +584 -0
  108. package/dist/tui/state/actions.d.ts.map +1 -0
  109. package/dist/tui/state/actions.js +62 -0
  110. package/dist/tui/state/actions.js.map +1 -0
  111. package/dist/tui/state/persist.d.ts +114 -0
  112. package/dist/tui/state/persist.d.ts.map +1 -0
  113. package/dist/tui/state/persist.js +187 -0
  114. package/dist/tui/state/persist.js.map +1 -0
  115. package/dist/tui/state/poll.d.ts +99 -0
  116. package/dist/tui/state/poll.d.ts.map +1 -0
  117. package/dist/tui/state/poll.js +160 -0
  118. package/dist/tui/state/poll.js.map +1 -0
  119. package/dist/tui/state/reducer.d.ts +16 -0
  120. package/dist/tui/state/reducer.d.ts.map +1 -0
  121. package/dist/tui/state/reducer.js +363 -0
  122. package/dist/tui/state/reducer.js.map +1 -0
  123. package/dist/tui/state/store.d.ts +37 -0
  124. package/dist/tui/state/store.d.ts.map +1 -0
  125. package/dist/tui/state/store.js +84 -0
  126. package/dist/tui/state/store.js.map +1 -0
  127. package/dist/tui/suspend.d.ts +17 -0
  128. package/dist/tui/suspend.d.ts.map +1 -0
  129. package/dist/tui/suspend.js +33 -0
  130. package/dist/tui/suspend.js.map +1 -0
  131. package/dist/tui/ui/App.d.ts +41 -0
  132. package/dist/tui/ui/App.d.ts.map +1 -0
  133. package/dist/tui/ui/App.js +92 -0
  134. package/dist/tui/ui/App.js.map +1 -0
  135. package/dist/tui/ui/frame.d.ts +86 -0
  136. package/dist/tui/ui/frame.d.ts.map +1 -0
  137. package/dist/tui/ui/frame.js +42 -0
  138. package/dist/tui/ui/frame.js.map +1 -0
  139. package/dist/tui/ui/lines.d.ts +92 -0
  140. package/dist/tui/ui/lines.d.ts.map +1 -0
  141. package/dist/tui/ui/lines.js +94 -0
  142. package/dist/tui/ui/lines.js.map +1 -0
  143. package/dist/tui/ui/shell/chrome.d.ts +61 -0
  144. package/dist/tui/ui/shell/chrome.d.ts.map +1 -0
  145. package/dist/tui/ui/shell/chrome.js +272 -0
  146. package/dist/tui/ui/shell/chrome.js.map +1 -0
  147. package/dist/tui/ui/shell/widgets.d.ts +75 -0
  148. package/dist/tui/ui/shell/widgets.d.ts.map +1 -0
  149. package/dist/tui/ui/shell/widgets.js +160 -0
  150. package/dist/tui/ui/shell/widgets.js.map +1 -0
  151. package/dist/tui/ui/views/about.d.ts +20 -0
  152. package/dist/tui/ui/views/about.d.ts.map +1 -0
  153. package/dist/tui/ui/views/about.js +40 -0
  154. package/dist/tui/ui/views/about.js.map +1 -0
  155. package/dist/tui/ui/views/all.d.ts +17 -0
  156. package/dist/tui/ui/views/all.d.ts.map +1 -0
  157. package/dist/tui/ui/views/all.js +17 -0
  158. package/dist/tui/ui/views/all.js.map +1 -0
  159. package/dist/tui/ui/views/dashboard.d.ts +156 -0
  160. package/dist/tui/ui/views/dashboard.d.ts.map +1 -0
  161. package/dist/tui/ui/views/dashboard.js +599 -0
  162. package/dist/tui/ui/views/dashboard.js.map +1 -0
  163. package/dist/tui/ui/views/help.d.ts +17 -0
  164. package/dist/tui/ui/views/help.d.ts.map +1 -0
  165. package/dist/tui/ui/views/help.js +65 -0
  166. package/dist/tui/ui/views/help.js.map +1 -0
  167. package/dist/tui/ui/views/index.d.ts +42 -0
  168. package/dist/tui/ui/views/index.d.ts.map +1 -0
  169. package/dist/tui/ui/views/index.js +42 -0
  170. package/dist/tui/ui/views/index.js.map +1 -0
  171. package/dist/tui/ui/views/input.d.ts +6 -0
  172. package/dist/tui/ui/views/input.d.ts.map +1 -0
  173. package/dist/tui/ui/views/input.js +494 -0
  174. package/dist/tui/ui/views/input.js.map +1 -0
  175. package/dist/tui/ui/views/launch.d.ts +16 -0
  176. package/dist/tui/ui/views/launch.d.ts.map +1 -0
  177. package/dist/tui/ui/views/launch.js +43 -0
  178. package/dist/tui/ui/views/launch.js.map +1 -0
  179. package/dist/tui/ui/views/refusal.d.ts +20 -0
  180. package/dist/tui/ui/views/refusal.d.ts.map +1 -0
  181. package/dist/tui/ui/views/refusal.js +47 -0
  182. package/dist/tui/ui/views/refusal.js.map +1 -0
  183. package/dist/tui/ui/views/repos.d.ts +10 -0
  184. package/dist/tui/ui/views/repos.d.ts.map +1 -0
  185. package/dist/tui/ui/views/repos.js +93 -0
  186. package/dist/tui/ui/views/repos.js.map +1 -0
  187. package/dist/tui/ui/views/task.d.ts +17 -0
  188. package/dist/tui/ui/views/task.d.ts.map +1 -0
  189. package/dist/tui/ui/views/task.js +309 -0
  190. package/dist/tui/ui/views/task.js.map +1 -0
  191. package/dist/tui/ui/views/wordmark.d.ts +15 -0
  192. package/dist/tui/ui/views/wordmark.d.ts.map +1 -0
  193. package/dist/tui/ui/views/wordmark.js +50 -0
  194. package/dist/tui/ui/views/wordmark.js.map +1 -0
  195. package/dist/tui/ui/views/workspaces.d.ts +17 -0
  196. package/dist/tui/ui/views/workspaces.d.ts.map +1 -0
  197. package/dist/tui/ui/views/workspaces.js +127 -0
  198. package/dist/tui/ui/views/workspaces.js.map +1 -0
  199. package/dist/tui/ui/widgets/leaf-editor.d.ts +58 -0
  200. package/dist/tui/ui/widgets/leaf-editor.d.ts.map +1 -0
  201. package/dist/tui/ui/widgets/leaf-editor.js +119 -0
  202. package/dist/tui/ui/widgets/leaf-editor.js.map +1 -0
  203. package/dist/tui/ui/widgets/logs.d.ts +99 -0
  204. package/dist/tui/ui/widgets/logs.d.ts.map +1 -0
  205. package/dist/tui/ui/widgets/logs.js +291 -0
  206. package/dist/tui/ui/widgets/logs.js.map +1 -0
  207. package/dist/tui/ui/widgets/reads.d.ts +62 -0
  208. package/dist/tui/ui/widgets/reads.d.ts.map +1 -0
  209. package/dist/tui/ui/widgets/reads.js +122 -0
  210. package/dist/tui/ui/widgets/reads.js.map +1 -0
  211. package/dist/tui/ui/widgets/runs.d.ts +51 -0
  212. package/dist/tui/ui/widgets/runs.d.ts.map +1 -0
  213. package/dist/tui/ui/widgets/runs.js +86 -0
  214. package/dist/tui/ui/widgets/runs.js.map +1 -0
  215. package/dist/tui/ui/widgets/tree.d.ts +149 -0
  216. package/dist/tui/ui/widgets/tree.d.ts.map +1 -0
  217. package/dist/tui/ui/widgets/tree.js +584 -0
  218. package/dist/tui/ui/widgets/tree.js.map +1 -0
  219. package/package.json +22 -12
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
+ */
5
+ /** The kind name of a type (`Struct`, `String`, …). */
6
+ function kindOf(tv) {
7
+ if (tv.type === 'Variant') {
8
+ const cases = tv.value.map(c => c.name);
9
+ if (cases.length === 2 && cases.includes('some') && cases.includes('none'))
10
+ return 'Option';
11
+ }
12
+ return tv.type;
13
+ }
14
+ /**
15
+ * The compact text of a type.
16
+ *
17
+ * @param tv - The type value
18
+ * @param ui - Whether the dataset is a `ui` task's output (printed `UIComponentType`)
19
+ * @returns The compact text
20
+ */
21
+ export function compactType(tv, ui = false) {
22
+ if (ui)
23
+ return 'UIComponentType';
24
+ switch (tv.type) {
25
+ case 'Array':
26
+ case 'Set':
27
+ return `${tv.type}<${kindOf(tv.value)}>`;
28
+ case 'Dict': {
29
+ const { key, value } = tv.value;
30
+ return `Dict<${kindOf(key)}, ${kindOf(value)}>`;
31
+ }
32
+ case 'Variant': {
33
+ const kind = kindOf(tv);
34
+ if (kind === 'Option') {
35
+ const someCase = tv.value.find(c => c.name === 'some');
36
+ return someCase !== undefined ? `Option<${kindOf(someCase.type)}>` : 'Option';
37
+ }
38
+ return 'Variant';
39
+ }
40
+ case 'Recursive':
41
+ return 'Recursive';
42
+ default:
43
+ return tv.type;
44
+ }
45
+ }
46
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/tui/model/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH,uDAAuD;AACvD,SAAS,MAAM,CAAC,EAAiB;IAC7B,IAAI,EAAE,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,KAAK,GAAI,EAAE,CAAC,KAA4B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAChE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,QAAQ,CAAC;IAChG,CAAC;IACD,OAAO,EAAE,CAAC,IAAI,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,EAAiB,EAAE,EAAE,GAAG,KAAK;IACrD,IAAI,EAAE;QAAE,OAAO,iBAAiB,CAAC;IACjC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QACd,KAAK,OAAO,CAAC;QACb,KAAK,KAAK;YACN,OAAO,GAAG,EAAE,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,CAAC,KAAsB,CAAC,GAAG,CAAC;QAC9D,KAAK,MAAM,CAAC,CAAC,CAAC;YACV,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,KAAqD,CAAC;YAChF,OAAO,QAAQ,MAAM,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;QACpD,CAAC;QACD,KAAK,SAAS,CAAC,CAAC,CAAC;YACb,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;YACxB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACpB,MAAM,QAAQ,GAAI,EAAE,CAAC,KAAiD,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;gBACpG,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;YAClF,CAAC;YACD,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,KAAK,WAAW;YACZ,OAAO,WAAW,CAAC;QACvB;YACI,OAAO,EAAE,CAAC,IAAI,CAAC;IACvB,CAAC;AACL,CAAC"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
+ */
5
+ /**
6
+ * The glyph sets — one unicode, one ASCII — every view draws with. Chosen
7
+ * once at start-up by {@link selectGlyphs}: `--ascii`, `E3_UI_ASCII=1`, a
8
+ * non-UTF-8 locale or `TERM=linux` select the ASCII set.
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+ /**
13
+ * The named glyphs of a set.
14
+ *
15
+ * @property expanded - An expanded tree row's twist (`▾`)
16
+ * @property collapsed - A collapsed tree row's twist (`▸`)
17
+ * @property leaf - A leaf row's marker (`·`)
18
+ * @property add - The append ghost row's marker (`+`)
19
+ * @property dot - Complete / up-to-date / connected (`●`)
20
+ * @property half - Waiting / stale / reconnecting (`◐`)
21
+ * @property quarter - In progress / running (`◔`)
22
+ * @property empty - Ready / unset / never (`○`)
23
+ * @property cross - Failed / error / offline (`✗`)
24
+ * @property diamond - Dirty / pending edits (`◆`)
25
+ * @property sel - The selection bar (`▌`)
26
+ * @property tabL - The active tab's left bracket (`▌`)
27
+ * @property tabR - The active tab's right bracket (`▐`)
28
+ * @property rule - The full-width rule (`─`)
29
+ * @property dashed - The dashed section rule (`┄`)
30
+ * @property vbar - The scrollbar track (`│`)
31
+ * @property scrollUp - The scrollbar's top cap (`▲`)
32
+ * @property thumb - The scrollbar's thumb (`█`)
33
+ * @property scrollDown - The scrollbar's bottom cap (`▼`)
34
+ * @property placeholder - An unloaded row's fill (`░`)
35
+ * @property loading - The loading marker (`▒`)
36
+ * @property spinner - The braille spinner frames
37
+ * @property crumb - The breadcrumb separator (`›`)
38
+ * @property prompt - The command box prompt (`›`)
39
+ * @property sep - The inline separator (`·`)
40
+ * @property enter - The Enter key (`⏎`)
41
+ * @property up - The up arrow (`↑`)
42
+ * @property down - The down arrow (`↓`)
43
+ * @property left - The left arrow (`←`)
44
+ * @property right - The right arrow (`→`)
45
+ * @property backspace - The backspace key (`⌫`)
46
+ * @property shift - The shift key (`⇧`)
47
+ * @property edited - The changed-row marker (`┆`)
48
+ * @property square - The stop marker (`■`)
49
+ * @property bullet - The note marker (`▪`)
50
+ * @property bars - The accounted bar's steps, low to high (`▁▃▅▇`)
51
+ * @property ellipsis - The truncation marker (`…`)
52
+ * @property cursor - The command box caret (`_`)
53
+ * @property hidden - A hidden collapsed marker for the shift-left hint
54
+ */
55
+ export interface Glyphs {
56
+ expanded: string;
57
+ collapsed: string;
58
+ leaf: string;
59
+ add: string;
60
+ dot: string;
61
+ half: string;
62
+ quarter: string;
63
+ empty: string;
64
+ cross: string;
65
+ diamond: string;
66
+ sel: string;
67
+ tabL: string;
68
+ tabR: string;
69
+ rule: string;
70
+ dashed: string;
71
+ vbar: string;
72
+ scrollUp: string;
73
+ thumb: string;
74
+ scrollDown: string;
75
+ placeholder: string;
76
+ loading: string;
77
+ spinner: readonly string[];
78
+ crumb: string;
79
+ prompt: string;
80
+ sep: string;
81
+ enter: string;
82
+ up: string;
83
+ down: string;
84
+ left: string;
85
+ right: string;
86
+ backspace: string;
87
+ shift: string;
88
+ edited: string;
89
+ square: string;
90
+ bullet: string;
91
+ bars: readonly string[];
92
+ ellipsis: string;
93
+ cursor: string;
94
+ }
95
+ /** The unicode glyph set (the design's mocks). */
96
+ export declare const UNICODE: Glyphs;
97
+ /** The ASCII glyph set (`--ascii`, `E3_UI_ASCII=1`, non-UTF-8 locales, `TERM=linux`). */
98
+ export declare const ASCII: Glyphs;
99
+ /** What {@link selectGlyphs} looks at. */
100
+ export interface GlyphSelection {
101
+ /** `--ascii` was given. */
102
+ ascii?: boolean | undefined;
103
+ /** The environment (`E3_UI_ASCII`, `LANG` / `LC_ALL` / `LC_CTYPE`, `TERM`). */
104
+ env: NodeJS.ProcessEnv;
105
+ }
106
+ /**
107
+ * Whether the locale declares a UTF-8 charset (a missing locale counts as
108
+ * UTF-8 — every modern terminal is — while an explicit non-UTF-8 charset
109
+ * selects ASCII).
110
+ *
111
+ * @param env - The environment
112
+ * @returns `true` unless a locale variable names a non-UTF-8 charset
113
+ */
114
+ export declare function localeIsUtf8(env: NodeJS.ProcessEnv): boolean;
115
+ /**
116
+ * Selects the glyph set for this session.
117
+ *
118
+ * @param selection - The flag and the environment
119
+ * @returns {@link ASCII} for `--ascii`, `E3_UI_ASCII=1`, a non-UTF-8 locale or `TERM=linux`; else {@link UNICODE}
120
+ */
121
+ export declare function selectGlyphs(selection: GlyphSelection): Glyphs;
122
+ //# sourceMappingURL=glyphs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glyphs.d.ts","sourceRoot":"","sources":["../../../src/tui/render/glyphs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,WAAW,MAAM;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,kDAAkD;AAClD,eAAO,MAAM,OAAO,EAAE,MAuCrB,CAAC;AAEF,yFAAyF;AACzF,eAAO,MAAM,KAAK,EAAE,MAuCnB,CAAC;AAEF,0CAA0C;AAC1C,MAAM,WAAW,cAAc;IAC3B,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,+EAA+E;IAC/E,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAO5D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,cAAc,GAAG,MAAM,CAM9D"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
+ */
5
+ /** The unicode glyph set (the design's mocks). */
6
+ export const UNICODE = {
7
+ expanded: '▾',
8
+ collapsed: '▸',
9
+ leaf: '·',
10
+ add: '+',
11
+ dot: '●',
12
+ half: '◐',
13
+ quarter: '◔',
14
+ empty: '○',
15
+ cross: '✗',
16
+ diamond: '◆',
17
+ sel: '▌',
18
+ tabL: '▌',
19
+ tabR: '▐',
20
+ rule: '─',
21
+ dashed: '┄',
22
+ vbar: '│',
23
+ scrollUp: '▲',
24
+ thumb: '█',
25
+ scrollDown: '▼',
26
+ placeholder: '░',
27
+ loading: '▒',
28
+ spinner: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],
29
+ crumb: '›',
30
+ prompt: '›',
31
+ sep: '·',
32
+ enter: '⏎',
33
+ up: '↑',
34
+ down: '↓',
35
+ left: '←',
36
+ right: '→',
37
+ backspace: '⌫',
38
+ shift: '⇧',
39
+ edited: '┆',
40
+ square: '■',
41
+ bullet: '▪',
42
+ bars: ['▁', '▃', '▅', '▇'],
43
+ ellipsis: '…',
44
+ cursor: '_',
45
+ };
46
+ /** The ASCII glyph set (`--ascii`, `E3_UI_ASCII=1`, non-UTF-8 locales, `TERM=linux`). */
47
+ export const ASCII = {
48
+ expanded: 'v',
49
+ collapsed: '>',
50
+ leaf: '-',
51
+ add: '+',
52
+ dot: '*',
53
+ half: 'o',
54
+ quarter: 'o',
55
+ empty: '.',
56
+ cross: 'x',
57
+ diamond: '+',
58
+ sel: '>',
59
+ tabL: '[',
60
+ tabR: ']',
61
+ rule: '-',
62
+ dashed: '.',
63
+ vbar: '|',
64
+ scrollUp: '^',
65
+ thumb: '#',
66
+ scrollDown: 'v',
67
+ placeholder: ':',
68
+ loading: ';',
69
+ spinner: ['-', '\\', '|', '/'],
70
+ crumb: '>',
71
+ prompt: '>',
72
+ sep: '.',
73
+ enter: 'Enter',
74
+ up: 'Up',
75
+ down: 'Down',
76
+ left: 'Left',
77
+ right: 'Right',
78
+ backspace: 'Bksp',
79
+ shift: 'Shift-',
80
+ edited: '|',
81
+ square: '#',
82
+ bullet: '*',
83
+ bars: ['_', '.', ':', '|'],
84
+ ellipsis: '...',
85
+ cursor: '_',
86
+ };
87
+ /**
88
+ * Whether the locale declares a UTF-8 charset (a missing locale counts as
89
+ * UTF-8 — every modern terminal is — while an explicit non-UTF-8 charset
90
+ * selects ASCII).
91
+ *
92
+ * @param env - The environment
93
+ * @returns `true` unless a locale variable names a non-UTF-8 charset
94
+ */
95
+ export function localeIsUtf8(env) {
96
+ const locale = env['LC_ALL'] || env['LC_CTYPE'] || env['LANG'];
97
+ if (locale === undefined || locale === '' || locale === 'C' || locale === 'POSIX')
98
+ return true;
99
+ const dot = locale.indexOf('.');
100
+ if (dot === -1)
101
+ return true;
102
+ const charset = locale.slice(dot + 1).toLowerCase().replace(/[^a-z0-9]/g, '');
103
+ return charset === 'utf8';
104
+ }
105
+ /**
106
+ * Selects the glyph set for this session.
107
+ *
108
+ * @param selection - The flag and the environment
109
+ * @returns {@link ASCII} for `--ascii`, `E3_UI_ASCII=1`, a non-UTF-8 locale or `TERM=linux`; else {@link UNICODE}
110
+ */
111
+ export function selectGlyphs(selection) {
112
+ if (selection.ascii === true)
113
+ return ASCII;
114
+ if (selection.env['E3_UI_ASCII'] === '1')
115
+ return ASCII;
116
+ if (selection.env['TERM'] === 'linux')
117
+ return ASCII;
118
+ if (!localeIsUtf8(selection.env))
119
+ return ASCII;
120
+ return UNICODE;
121
+ }
122
+ //# sourceMappingURL=glyphs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glyphs.js","sourceRoot":"","sources":["../../../src/tui/render/glyphs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
+ */
5
+ /**
6
+ * Layout arithmetic — the shell's fixed rows, the breakpoints, the column
7
+ * plans of every table, and the scrollbar geometry.
8
+ *
9
+ * Every row is exactly one terminal line (no wrapping) so scroll math is
10
+ * exact and the frame never exceeds the viewport: the shell is one header
11
+ * row, a rule, the body, then — bottom-anchored — an optional commit bar,
12
+ * an optional completion list, the three-row command box and one hint
13
+ * row. Widths ≥ 100 columns get the full tables, 80–99 tighter columns,
14
+ * 60–79 drop the secondary columns, and below 60×16 the app refuses.
15
+ *
16
+ * @packageDocumentation
17
+ */
18
+ /** The smallest terminal the app runs in. */
19
+ export declare const MIN_COLUMNS = 60;
20
+ /** The smallest terminal the app runs in. */
21
+ export declare const MIN_ROWS = 16;
22
+ /** Completion rows above the command box, at most. */
23
+ export declare const MAX_COMPLETION_ROWS = 8;
24
+ /** A terminal size in cells. */
25
+ export interface Size {
26
+ columns: number;
27
+ rows: number;
28
+ }
29
+ /** The width class: `wide` ≥ 100, `medium` 80–99, `narrow` 60–79, `refuse` below 60 (or under 16 rows). */
30
+ export type Breakpoint = 'wide' | 'medium' | 'narrow' | 'refuse';
31
+ /**
32
+ * The width class of a terminal size.
33
+ *
34
+ * @param size - The terminal size
35
+ * @returns The breakpoint
36
+ */
37
+ export declare function breakpoint(size: Size): Breakpoint;
38
+ /**
39
+ * The shell's row plan for a size and the bottom-anchored extras.
40
+ *
41
+ * @property columns - Terminal columns
42
+ * @property rows - Terminal rows
43
+ * @property bodyTop - The first body row (below the header and its rule)
44
+ * @property bodyRows - Rows the view body may draw
45
+ * @property commitRows - Rows of the commit bar (0 or 2: a dashed rule + the bar)
46
+ * @property completionRows - Rows of the completion list
47
+ * @property commandTop - The first row of the command box (its top rule)
48
+ * @property hintRow - The hint row (the last row)
49
+ */
50
+ export interface ShellLayout {
51
+ columns: number;
52
+ rows: number;
53
+ bodyTop: number;
54
+ bodyRows: number;
55
+ commitRows: number;
56
+ completionRows: number;
57
+ commandTop: number;
58
+ hintRow: number;
59
+ }
60
+ /**
61
+ * Computes the shell's row plan.
62
+ *
63
+ * @param size - The terminal size
64
+ * @param extras - Whether the commit bar shows, and how many completion rows
65
+ * @returns The plan (the body absorbs the remainder, never below 0)
66
+ */
67
+ export declare function shellLayout(size: Size, extras: {
68
+ commit: boolean;
69
+ completion: number;
70
+ }): ShellLayout;
71
+ /**
72
+ * The scrollbar geometry of the design (§8): the thumb spans
73
+ * `max(1, round(track · visible / total))` cells at
74
+ * `round((track − thumb) · top / (total − visible))`.
75
+ *
76
+ * @param track - The track height in cells (between the caps)
77
+ * @param total - Total rows
78
+ * @param visible - Visible rows
79
+ * @param top - The first visible row
80
+ * @returns The thumb size and its offset within the track (`null` when everything fits)
81
+ */
82
+ export declare function scrollbar(track: number, total: number, visible: number, top: number): {
83
+ thumb: number;
84
+ pos: number;
85
+ } | null;
86
+ /**
87
+ * One column of a table plan.
88
+ *
89
+ * @property key - The column identity
90
+ * @property title - The header text
91
+ * @property width - The width in cells (`0` = the remaining width)
92
+ * @property align - Text alignment
93
+ * @property grow - When set, the column widens to its longest cell plus a gap, up to this many cells
94
+ */
95
+ export interface ColumnSpec {
96
+ key: string;
97
+ title: string;
98
+ width: number;
99
+ align?: 'left' | 'right' | undefined;
100
+ grow?: number | undefined;
101
+ }
102
+ /** The tables with a per-breakpoint column plan. */
103
+ export type TableKind = 'tasks' | 'inputs' | 'workspaces' | 'repos' | 'runs' | 'completion' | 'jump';
104
+ /**
105
+ * The column plan of a table at a width class. Widths are the design's
106
+ * (120 columns); the last column takes the remaining width.
107
+ *
108
+ * @param table - The table
109
+ * @param bp - The width class
110
+ * @returns The columns, secondary ones dropped as the terminal narrows
111
+ */
112
+ export declare function columnPlan(table: TableKind, bp: Breakpoint): ColumnSpec[];
113
+ /**
114
+ * Fits a plan to a row width: while the fixed columns plus the gutter leave
115
+ * the remainder column fewer than `minRemainder` cells, the widest fixed
116
+ * column after the first is narrowed (never below 8). At the design width
117
+ * every plan is untouched.
118
+ *
119
+ * @param plan - The column plan
120
+ * @param width - The row width
121
+ * @param minRemainder - Cells the remainder column keeps at least (default 12)
122
+ * @param gutter - Cells before the first column (default 2: the margin + selection bar)
123
+ * @returns The fitted plan (a copy)
124
+ */
125
+ export declare function fitPlan(plan: ColumnSpec[], width: number, minRemainder?: number, gutter?: number): ColumnSpec[];
126
+ /**
127
+ * The value tree's label column width — at most 45 % of the row, the
128
+ * design's `LW = 44` at 120 columns.
129
+ *
130
+ * @param columns - The row width
131
+ * @returns The label width in cells
132
+ */
133
+ export declare function labelWidth(columns: number): number;
134
+ /**
135
+ * Keeps a selection visible: the top row that shows `sel` within `visible`
136
+ * rows, moving as little as possible from the current `top`.
137
+ *
138
+ * @param top - The current first visible row
139
+ * @param sel - The selected row
140
+ * @param visible - Visible rows
141
+ * @param total - Total rows
142
+ * @returns The new top
143
+ */
144
+ export declare function scrollIntoView(top: number, sel: number, visible: number, total: number): number;
145
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/tui/render/layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;GAYG;AAEH,6CAA6C;AAC7C,eAAO,MAAM,WAAW,KAAK,CAAC;AAC9B,6CAA6C;AAC7C,eAAO,MAAM,QAAQ,KAAK,CAAC;AAC3B,sDAAsD;AACtD,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,gCAAgC;AAChC,MAAM,WAAW,IAAI;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,2GAA2G;AAC3G,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEjE;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,CAKjD;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,CAepG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAK3H;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,oDAAoD;AACpD,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,YAAY,GAAG,MAAM,CAAC;AAErG;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,GAAG,UAAU,EAAE,CA8DzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,SAAK,EAAE,MAAM,SAAI,GAAG,UAAU,EAAE,CAYtG;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAO/F"}
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
+ */
5
+ /**
6
+ * Layout arithmetic — the shell's fixed rows, the breakpoints, the column
7
+ * plans of every table, and the scrollbar geometry.
8
+ *
9
+ * Every row is exactly one terminal line (no wrapping) so scroll math is
10
+ * exact and the frame never exceeds the viewport: the shell is one header
11
+ * row, a rule, the body, then — bottom-anchored — an optional commit bar,
12
+ * an optional completion list, the three-row command box and one hint
13
+ * row. Widths ≥ 100 columns get the full tables, 80–99 tighter columns,
14
+ * 60–79 drop the secondary columns, and below 60×16 the app refuses.
15
+ *
16
+ * @packageDocumentation
17
+ */
18
+ /** The smallest terminal the app runs in. */
19
+ export const MIN_COLUMNS = 60;
20
+ /** The smallest terminal the app runs in. */
21
+ export const MIN_ROWS = 16;
22
+ /** Completion rows above the command box, at most. */
23
+ export const MAX_COMPLETION_ROWS = 8;
24
+ /**
25
+ * The width class of a terminal size.
26
+ *
27
+ * @param size - The terminal size
28
+ * @returns The breakpoint
29
+ */
30
+ export function breakpoint(size) {
31
+ if (size.columns < MIN_COLUMNS || size.rows < MIN_ROWS)
32
+ return 'refuse';
33
+ if (size.columns >= 100)
34
+ return 'wide';
35
+ if (size.columns >= 80)
36
+ return 'medium';
37
+ return 'narrow';
38
+ }
39
+ /**
40
+ * Computes the shell's row plan.
41
+ *
42
+ * @param size - The terminal size
43
+ * @param extras - Whether the commit bar shows, and how many completion rows
44
+ * @returns The plan (the body absorbs the remainder, never below 0)
45
+ */
46
+ export function shellLayout(size, extras) {
47
+ const commitRows = extras.commit ? 2 : 0;
48
+ const completionRows = Math.max(0, Math.min(MAX_COMPLETION_ROWS, extras.completion));
49
+ const chrome = 2 + commitRows + completionRows + 3 + 1;
50
+ const bodyRows = Math.max(0, size.rows - chrome);
51
+ return {
52
+ columns: size.columns,
53
+ rows: size.rows,
54
+ bodyTop: 2,
55
+ bodyRows,
56
+ commitRows,
57
+ completionRows,
58
+ commandTop: 2 + bodyRows + commitRows + completionRows,
59
+ hintRow: size.rows - 1,
60
+ };
61
+ }
62
+ /**
63
+ * The scrollbar geometry of the design (§8): the thumb spans
64
+ * `max(1, round(track · visible / total))` cells at
65
+ * `round((track − thumb) · top / (total − visible))`.
66
+ *
67
+ * @param track - The track height in cells (between the caps)
68
+ * @param total - Total rows
69
+ * @param visible - Visible rows
70
+ * @param top - The first visible row
71
+ * @returns The thumb size and its offset within the track (`null` when everything fits)
72
+ */
73
+ export function scrollbar(track, total, visible, top) {
74
+ if (track <= 0 || total <= visible)
75
+ return null;
76
+ const thumb = Math.max(1, Math.round(track * Math.min(1, visible / total)));
77
+ const pos = Math.round((track - thumb) * (Math.min(top, total - visible) / (total - visible)));
78
+ return { thumb, pos: Math.max(0, Math.min(track - thumb, pos)) };
79
+ }
80
+ /**
81
+ * The column plan of a table at a width class. Widths are the design's
82
+ * (120 columns); the last column takes the remaining width.
83
+ *
84
+ * @param table - The table
85
+ * @param bp - The width class
86
+ * @returns The columns, secondary ones dropped as the terminal narrows
87
+ */
88
+ export function columnPlan(table, bp) {
89
+ const narrow = bp === 'narrow';
90
+ const medium = bp === 'medium';
91
+ switch (table) {
92
+ case 'tasks':
93
+ return [
94
+ { key: 'name', title: 'NAME', width: 12, grow: 24 },
95
+ { key: 'status', title: 'STATUS', width: narrow ? 16 : 20 },
96
+ ...(narrow ? [] : [{ key: 'dependsOn', title: 'DEPENDS ON', width: medium ? 14 : 20 }]),
97
+ ...(narrow || medium ? [] : [{ key: 'inputs', title: 'INPUTS', width: 18 }]),
98
+ { key: 'output', title: 'OUTPUT', width: narrow || medium ? 16 : 26 },
99
+ { key: 'size', title: 'SIZE · LAST RUN', width: 0 },
100
+ ];
101
+ case 'inputs':
102
+ return [
103
+ { key: 'name', title: 'NAME', width: 14, grow: 24 },
104
+ { key: 'status', title: 'STATUS', width: 16 },
105
+ { key: 'type', title: 'TYPE', width: narrow ? 18 : medium ? 22 : 26 },
106
+ { key: 'size', title: 'SIZE', width: narrow ? 0 : 10 },
107
+ ...(narrow ? [] : [{ key: 'hash', title: 'HASH', width: 0 }]),
108
+ ];
109
+ case 'workspaces':
110
+ return [
111
+ { key: 'name', title: 'NAME', width: narrow || medium ? 12 : 14, grow: 24 },
112
+ { key: 'state', title: 'STATE', width: narrow || medium ? 12 : 14 },
113
+ { key: 'package', title: 'PACKAGE', width: narrow || medium ? 16 : 22 },
114
+ ...(narrow ? [] : [{ key: 'tasks', title: 'TASKS', width: medium ? 16 : 30 }]),
115
+ { key: 'lastRun', title: 'LAST RUN', width: 0 },
116
+ ];
117
+ case 'repos':
118
+ return [
119
+ { key: 'name', title: 'NAME', width: narrow || medium ? 18 : 22 },
120
+ { key: 'workspaces', title: 'WORKSPACES', width: narrow || medium ? 12 : 14 },
121
+ { key: 'packages', title: 'PACKAGES', width: narrow || medium ? 10 : 12 },
122
+ ...(narrow ? [] : [{ key: 'objects', title: 'OBJECTS', width: medium ? 10 : 12 }]),
123
+ { key: 'lastDeploy', title: 'LAST DEPLOY', width: 0 },
124
+ ];
125
+ case 'runs':
126
+ return [
127
+ { key: 'status', title: 'STATUS', width: 12 },
128
+ { key: 'started', title: 'STARTED', width: 22 },
129
+ { key: 'duration', title: 'DURATION', width: 10 },
130
+ { key: 'exit', title: 'EXIT', width: 6 },
131
+ { key: 'inputs', title: 'INPUTS', width: narrow ? 0 : 14 },
132
+ ...(narrow ? [] : [{ key: 'note', title: '', width: 0 }]),
133
+ ];
134
+ case 'completion':
135
+ return [
136
+ { key: 'command', title: '', width: 12 },
137
+ { key: 'name', title: '', width: 14 },
138
+ { key: 'status', title: '', width: 18 },
139
+ ...(narrow ? [] : [{ key: 'type', title: '', width: 24 }]),
140
+ { key: 'detail', title: '', width: 0 },
141
+ ];
142
+ case 'jump':
143
+ return [
144
+ { key: 'kind', title: '', width: 12 },
145
+ { key: 'name', title: '', width: 16 },
146
+ { key: 'workspace', title: '', width: 10 },
147
+ { key: 'detail', title: '', width: 0 },
148
+ ];
149
+ }
150
+ }
151
+ /**
152
+ * Fits a plan to a row width: while the fixed columns plus the gutter leave
153
+ * the remainder column fewer than `minRemainder` cells, the widest fixed
154
+ * column after the first is narrowed (never below 8). At the design width
155
+ * every plan is untouched.
156
+ *
157
+ * @param plan - The column plan
158
+ * @param width - The row width
159
+ * @param minRemainder - Cells the remainder column keeps at least (default 12)
160
+ * @param gutter - Cells before the first column (default 2: the margin + selection bar)
161
+ * @returns The fitted plan (a copy)
162
+ */
163
+ export function fitPlan(plan, width, minRemainder = 12, gutter = 2) {
164
+ const out = plan.map(c => ({ ...c }));
165
+ const fixed = () => out.reduce((n, c) => n + c.width, 0) + gutter;
166
+ for (let guard = 0; guard < 4096 && fixed() + minRemainder > width; guard++) {
167
+ let widest = null;
168
+ for (const c of out.slice(1)) {
169
+ if (c.width > 8 && (widest === null || c.width > widest.width))
170
+ widest = c;
171
+ }
172
+ if (widest === null)
173
+ break;
174
+ widest.width--;
175
+ }
176
+ return out;
177
+ }
178
+ /**
179
+ * The value tree's label column width — at most 45 % of the row, the
180
+ * design's `LW = 44` at 120 columns.
181
+ *
182
+ * @param columns - The row width
183
+ * @returns The label width in cells
184
+ */
185
+ export function labelWidth(columns) {
186
+ return Math.min(44, Math.max(16, Math.floor(columns * 0.45) - 10));
187
+ }
188
+ /**
189
+ * Keeps a selection visible: the top row that shows `sel` within `visible`
190
+ * rows, moving as little as possible from the current `top`.
191
+ *
192
+ * @param top - The current first visible row
193
+ * @param sel - The selected row
194
+ * @param visible - Visible rows
195
+ * @param total - Total rows
196
+ * @returns The new top
197
+ */
198
+ export function scrollIntoView(top, sel, visible, total) {
199
+ const maxTop = Math.max(0, total - visible);
200
+ let next = Math.max(0, Math.min(top, maxTop));
201
+ if (visible <= 0)
202
+ return next;
203
+ if (sel < next)
204
+ next = sel;
205
+ else if (sel >= next + visible)
206
+ next = sel - visible + 1;
207
+ return Math.max(0, Math.min(next, maxTop));
208
+ }
209
+ //# sourceMappingURL=layout.js.map