@elaraai/e3-ui-cli 1.0.72 → 1.0.74

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 (220) hide show
  1. package/README.md +46 -21
  2. package/bin/e3-ui.mjs +6 -0
  3. package/dist/app/assets/{engine-BKZbmXkC-DmcCFcnb.js → engine-Bm-cIDd_-DwUdGcTZ.js} +1 -1
  4. package/dist/app/assets/{index-BJNWHnRv.js → index-mj-YVVN1.js} +91 -91
  5. package/dist/app/index.html +1 -1
  6. package/dist/cli.js +36 -5
  7. package/dist/cli.js.map +1 -1
  8. package/dist/commands/tui.d.ts +84 -0
  9. package/dist/commands/tui.d.ts.map +1 -0
  10. package/dist/commands/tui.js +89 -0
  11. package/dist/commands/tui.js.map +1 -0
  12. package/dist/tui/api.d.ts +108 -0
  13. package/dist/tui/api.d.ts.map +1 -0
  14. package/dist/tui/api.js +130 -0
  15. package/dist/tui/api.js.map +1 -0
  16. package/dist/tui/app.d.ts +23 -0
  17. package/dist/tui/app.d.ts.map +1 -0
  18. package/dist/tui/app.js +244 -0
  19. package/dist/tui/app.js.map +1 -0
  20. package/dist/tui/controller.d.ts +116 -0
  21. package/dist/tui/controller.d.ts.map +1 -0
  22. package/dist/tui/controller.js +644 -0
  23. package/dist/tui/controller.js.map +1 -0
  24. package/dist/tui/data/dataflow.d.ts +68 -0
  25. package/dist/tui/data/dataflow.d.ts.map +1 -0
  26. package/dist/tui/data/dataflow.js +137 -0
  27. package/dist/tui/data/dataflow.js.map +1 -0
  28. package/dist/tui/data/dataset.d.ts +80 -0
  29. package/dist/tui/data/dataset.d.ts.map +1 -0
  30. package/dist/tui/data/dataset.js +297 -0
  31. package/dist/tui/data/dataset.js.map +1 -0
  32. package/dist/tui/data/edit-buffer.d.ts +74 -0
  33. package/dist/tui/data/edit-buffer.d.ts.map +1 -0
  34. package/dist/tui/data/edit-buffer.js +120 -0
  35. package/dist/tui/data/edit-buffer.js.map +1 -0
  36. package/dist/tui/data/feeds.d.ts +45 -0
  37. package/dist/tui/data/feeds.d.ts.map +1 -0
  38. package/dist/tui/data/feeds.js +318 -0
  39. package/dist/tui/data/feeds.js.map +1 -0
  40. package/dist/tui/data/logs.d.ts +68 -0
  41. package/dist/tui/data/logs.d.ts.map +1 -0
  42. package/dist/tui/data/logs.js +134 -0
  43. package/dist/tui/data/logs.js.map +1 -0
  44. package/dist/tui/input/commands.d.ts +159 -0
  45. package/dist/tui/input/commands.d.ts.map +1 -0
  46. package/dist/tui/input/commands.js +259 -0
  47. package/dist/tui/input/commands.js.map +1 -0
  48. package/dist/tui/input/completion.d.ts +63 -0
  49. package/dist/tui/input/completion.d.ts.map +1 -0
  50. package/dist/tui/input/completion.js +128 -0
  51. package/dist/tui/input/completion.js.map +1 -0
  52. package/dist/tui/input/keymap.d.ts +153 -0
  53. package/dist/tui/input/keymap.d.ts.map +1 -0
  54. package/dist/tui/input/keymap.js +206 -0
  55. package/dist/tui/input/keymap.js.map +1 -0
  56. package/dist/tui/input/mouse.d.ts +52 -0
  57. package/dist/tui/input/mouse.d.ts.map +1 -0
  58. package/dist/tui/input/mouse.js +55 -0
  59. package/dist/tui/input/mouse.js.map +1 -0
  60. package/dist/tui/lifecycle.d.ts +61 -0
  61. package/dist/tui/lifecycle.d.ts.map +1 -0
  62. package/dist/tui/lifecycle.js +99 -0
  63. package/dist/tui/lifecycle.js.map +1 -0
  64. package/dist/tui/model/catalogue.d.ts +28 -0
  65. package/dist/tui/model/catalogue.d.ts.map +1 -0
  66. package/dist/tui/model/catalogue.js +94 -0
  67. package/dist/tui/model/catalogue.js.map +1 -0
  68. package/dist/tui/model/help.d.ts +37 -0
  69. package/dist/tui/model/help.d.ts.map +1 -0
  70. package/dist/tui/model/help.js +210 -0
  71. package/dist/tui/model/help.js.map +1 -0
  72. package/dist/tui/model/index.d.ts +42 -0
  73. package/dist/tui/model/index.d.ts.map +1 -0
  74. package/dist/tui/model/index.js +50 -0
  75. package/dist/tui/model/index.js.map +1 -0
  76. package/dist/tui/model/status.d.ts +88 -0
  77. package/dist/tui/model/status.d.ts.map +1 -0
  78. package/dist/tui/model/status.js +137 -0
  79. package/dist/tui/model/status.js.map +1 -0
  80. package/dist/tui/model/tree.d.ts +126 -0
  81. package/dist/tui/model/tree.d.ts.map +1 -0
  82. package/dist/tui/model/tree.js +217 -0
  83. package/dist/tui/model/tree.js.map +1 -0
  84. package/dist/tui/model/types.d.ts +21 -0
  85. package/dist/tui/model/types.d.ts.map +1 -0
  86. package/dist/tui/model/types.js +46 -0
  87. package/dist/tui/model/types.js.map +1 -0
  88. package/dist/tui/render/glyphs.d.ts +122 -0
  89. package/dist/tui/render/glyphs.d.ts.map +1 -0
  90. package/dist/tui/render/glyphs.js +122 -0
  91. package/dist/tui/render/glyphs.js.map +1 -0
  92. package/dist/tui/render/layout.d.ts +145 -0
  93. package/dist/tui/render/layout.d.ts.map +1 -0
  94. package/dist/tui/render/layout.js +209 -0
  95. package/dist/tui/render/layout.js.map +1 -0
  96. package/dist/tui/render/text.d.ts +153 -0
  97. package/dist/tui/render/text.d.ts.map +1 -0
  98. package/dist/tui/render/text.js +320 -0
  99. package/dist/tui/render/text.js.map +1 -0
  100. package/dist/tui/render/theme.d.ts +88 -0
  101. package/dist/tui/render/theme.d.ts.map +1 -0
  102. package/dist/tui/render/theme.js +145 -0
  103. package/dist/tui/render/theme.js.map +1 -0
  104. package/dist/tui/session.d.ts +78 -0
  105. package/dist/tui/session.d.ts.map +1 -0
  106. package/dist/tui/session.js +237 -0
  107. package/dist/tui/session.js.map +1 -0
  108. package/dist/tui/state/actions.d.ts +584 -0
  109. package/dist/tui/state/actions.d.ts.map +1 -0
  110. package/dist/tui/state/actions.js +62 -0
  111. package/dist/tui/state/actions.js.map +1 -0
  112. package/dist/tui/state/persist.d.ts +114 -0
  113. package/dist/tui/state/persist.d.ts.map +1 -0
  114. package/dist/tui/state/persist.js +187 -0
  115. package/dist/tui/state/persist.js.map +1 -0
  116. package/dist/tui/state/poll.d.ts +99 -0
  117. package/dist/tui/state/poll.d.ts.map +1 -0
  118. package/dist/tui/state/poll.js +160 -0
  119. package/dist/tui/state/poll.js.map +1 -0
  120. package/dist/tui/state/reducer.d.ts +16 -0
  121. package/dist/tui/state/reducer.d.ts.map +1 -0
  122. package/dist/tui/state/reducer.js +363 -0
  123. package/dist/tui/state/reducer.js.map +1 -0
  124. package/dist/tui/state/store.d.ts +37 -0
  125. package/dist/tui/state/store.d.ts.map +1 -0
  126. package/dist/tui/state/store.js +84 -0
  127. package/dist/tui/state/store.js.map +1 -0
  128. package/dist/tui/suspend.d.ts +17 -0
  129. package/dist/tui/suspend.d.ts.map +1 -0
  130. package/dist/tui/suspend.js +33 -0
  131. package/dist/tui/suspend.js.map +1 -0
  132. package/dist/tui/ui/App.d.ts +44 -0
  133. package/dist/tui/ui/App.d.ts.map +1 -0
  134. package/dist/tui/ui/App.js +105 -0
  135. package/dist/tui/ui/App.js.map +1 -0
  136. package/dist/tui/ui/frame.d.ts +86 -0
  137. package/dist/tui/ui/frame.d.ts.map +1 -0
  138. package/dist/tui/ui/frame.js +42 -0
  139. package/dist/tui/ui/frame.js.map +1 -0
  140. package/dist/tui/ui/lines.d.ts +92 -0
  141. package/dist/tui/ui/lines.d.ts.map +1 -0
  142. package/dist/tui/ui/lines.js +94 -0
  143. package/dist/tui/ui/lines.js.map +1 -0
  144. package/dist/tui/ui/shell/chrome.d.ts +61 -0
  145. package/dist/tui/ui/shell/chrome.d.ts.map +1 -0
  146. package/dist/tui/ui/shell/chrome.js +272 -0
  147. package/dist/tui/ui/shell/chrome.js.map +1 -0
  148. package/dist/tui/ui/shell/widgets.d.ts +116 -0
  149. package/dist/tui/ui/shell/widgets.d.ts.map +1 -0
  150. package/dist/tui/ui/shell/widgets.js +183 -0
  151. package/dist/tui/ui/shell/widgets.js.map +1 -0
  152. package/dist/tui/ui/views/about.d.ts +20 -0
  153. package/dist/tui/ui/views/about.d.ts.map +1 -0
  154. package/dist/tui/ui/views/about.js +40 -0
  155. package/dist/tui/ui/views/about.js.map +1 -0
  156. package/dist/tui/ui/views/all.d.ts +17 -0
  157. package/dist/tui/ui/views/all.d.ts.map +1 -0
  158. package/dist/tui/ui/views/all.js +17 -0
  159. package/dist/tui/ui/views/all.js.map +1 -0
  160. package/dist/tui/ui/views/dashboard.d.ts +211 -0
  161. package/dist/tui/ui/views/dashboard.d.ts.map +1 -0
  162. package/dist/tui/ui/views/dashboard.js +651 -0
  163. package/dist/tui/ui/views/dashboard.js.map +1 -0
  164. package/dist/tui/ui/views/help.d.ts +17 -0
  165. package/dist/tui/ui/views/help.d.ts.map +1 -0
  166. package/dist/tui/ui/views/help.js +65 -0
  167. package/dist/tui/ui/views/help.js.map +1 -0
  168. package/dist/tui/ui/views/index.d.ts +42 -0
  169. package/dist/tui/ui/views/index.d.ts.map +1 -0
  170. package/dist/tui/ui/views/index.js +42 -0
  171. package/dist/tui/ui/views/index.js.map +1 -0
  172. package/dist/tui/ui/views/input.d.ts +6 -0
  173. package/dist/tui/ui/views/input.d.ts.map +1 -0
  174. package/dist/tui/ui/views/input.js +494 -0
  175. package/dist/tui/ui/views/input.js.map +1 -0
  176. package/dist/tui/ui/views/launch.d.ts +16 -0
  177. package/dist/tui/ui/views/launch.d.ts.map +1 -0
  178. package/dist/tui/ui/views/launch.js +43 -0
  179. package/dist/tui/ui/views/launch.js.map +1 -0
  180. package/dist/tui/ui/views/refusal.d.ts +20 -0
  181. package/dist/tui/ui/views/refusal.d.ts.map +1 -0
  182. package/dist/tui/ui/views/refusal.js +47 -0
  183. package/dist/tui/ui/views/refusal.js.map +1 -0
  184. package/dist/tui/ui/views/repos.d.ts +10 -0
  185. package/dist/tui/ui/views/repos.d.ts.map +1 -0
  186. package/dist/tui/ui/views/repos.js +93 -0
  187. package/dist/tui/ui/views/repos.js.map +1 -0
  188. package/dist/tui/ui/views/task.d.ts +17 -0
  189. package/dist/tui/ui/views/task.d.ts.map +1 -0
  190. package/dist/tui/ui/views/task.js +309 -0
  191. package/dist/tui/ui/views/task.js.map +1 -0
  192. package/dist/tui/ui/views/wordmark.d.ts +15 -0
  193. package/dist/tui/ui/views/wordmark.d.ts.map +1 -0
  194. package/dist/tui/ui/views/wordmark.js +50 -0
  195. package/dist/tui/ui/views/wordmark.js.map +1 -0
  196. package/dist/tui/ui/views/workspaces.d.ts +17 -0
  197. package/dist/tui/ui/views/workspaces.d.ts.map +1 -0
  198. package/dist/tui/ui/views/workspaces.js +127 -0
  199. package/dist/tui/ui/views/workspaces.js.map +1 -0
  200. package/dist/tui/ui/widgets/leaf-editor.d.ts +58 -0
  201. package/dist/tui/ui/widgets/leaf-editor.d.ts.map +1 -0
  202. package/dist/tui/ui/widgets/leaf-editor.js +119 -0
  203. package/dist/tui/ui/widgets/leaf-editor.js.map +1 -0
  204. package/dist/tui/ui/widgets/logs.d.ts +99 -0
  205. package/dist/tui/ui/widgets/logs.d.ts.map +1 -0
  206. package/dist/tui/ui/widgets/logs.js +291 -0
  207. package/dist/tui/ui/widgets/logs.js.map +1 -0
  208. package/dist/tui/ui/widgets/reads.d.ts +62 -0
  209. package/dist/tui/ui/widgets/reads.d.ts.map +1 -0
  210. package/dist/tui/ui/widgets/reads.js +122 -0
  211. package/dist/tui/ui/widgets/reads.js.map +1 -0
  212. package/dist/tui/ui/widgets/runs.d.ts +51 -0
  213. package/dist/tui/ui/widgets/runs.d.ts.map +1 -0
  214. package/dist/tui/ui/widgets/runs.js +86 -0
  215. package/dist/tui/ui/widgets/runs.js.map +1 -0
  216. package/dist/tui/ui/widgets/tree.d.ts +149 -0
  217. package/dist/tui/ui/widgets/tree.d.ts.map +1 -0
  218. package/dist/tui/ui/widgets/tree.js +584 -0
  219. package/dist/tui/ui/widgets/tree.js.map +1 -0
  220. package/package.json +22 -12
@@ -0,0 +1,137 @@
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
+ import { formatDuration } from '../render/text.js';
6
+ /** `● up-to-date`, `✗ failed · exit 2`, … */
7
+ export function statusText(cell, sep = ' · ') {
8
+ return `${cell.glyph} ${cell.word}${cell.detail !== '' ? `${sep}${cell.detail}` : ''}`;
9
+ }
10
+ /**
11
+ * A task's status cell.
12
+ *
13
+ * @param status - The task status variant
14
+ * @param g - The glyph set
15
+ * @returns The cell
16
+ */
17
+ export function taskStatusCell(status, g) {
18
+ switch (status.type) {
19
+ case 'up-to-date':
20
+ return { glyph: g.dot, tone: 'pos', word: 'up-to-date', detail: status.value.cached ? 'cached' : '' };
21
+ case 'ready':
22
+ return { glyph: g.empty, tone: 'muted', word: 'ready', detail: '' };
23
+ case 'waiting':
24
+ return { glyph: g.half, tone: 'warn', word: 'waiting', detail: status.value.reason };
25
+ case 'in-progress':
26
+ return { glyph: g.quarter, tone: 'info', word: 'in-progress', detail: status.value.pid.type === 'some' ? `pid ${status.value.pid.value}` : '' };
27
+ case 'failed':
28
+ return { glyph: g.cross, tone: 'neg', word: 'failed', detail: `exit ${status.value.exitCode}` };
29
+ case 'error':
30
+ return { glyph: g.cross, tone: 'neg', word: 'error', detail: status.value.message };
31
+ case 'stale-running':
32
+ return { glyph: g.half, tone: 'warn', word: 'stale-running', detail: status.value.pid.type === 'some' ? `pid ${status.value.pid.value} gone` : '' };
33
+ }
34
+ }
35
+ /**
36
+ * A dataset's status cell.
37
+ *
38
+ * @param status - `unset` / `stale` / `up-to-date`
39
+ * @param g - The glyph set
40
+ * @returns The cell
41
+ */
42
+ export function datasetStatusCell(status, g) {
43
+ switch (status) {
44
+ case 'up-to-date': return { glyph: g.dot, tone: 'pos', word: 'up-to-date', detail: '' };
45
+ case 'stale': return { glyph: g.half, tone: 'warn', word: 'stale', detail: '' };
46
+ default: return { glyph: g.empty, tone: 'muted', word: 'unset', detail: '' };
47
+ }
48
+ }
49
+ /**
50
+ * An execution's status cell (`✗ FAILED`, `◔ RUNNING`, `● COMPLETED`, `■ ABORTED`).
51
+ *
52
+ * @param status - The execution status
53
+ * @param g - The glyph set
54
+ * @returns The cell
55
+ */
56
+ export function executionStatusCell(status, g) {
57
+ switch (status) {
58
+ case 'running': return { glyph: g.quarter, tone: 'info', word: 'RUNNING', detail: '' };
59
+ case 'completed': return { glyph: g.dot, tone: 'pos', word: 'COMPLETED', detail: '' };
60
+ case 'failed': return { glyph: g.cross, tone: 'neg', word: 'FAILED', detail: '' };
61
+ case 'aborted': return { glyph: g.square, tone: 'warn', word: 'ABORTED', detail: '' };
62
+ }
63
+ }
64
+ /**
65
+ * A run-history item's status cell.
66
+ *
67
+ * @param status - The history status
68
+ * @param g - The glyph set
69
+ * @returns The cell
70
+ */
71
+ export function historyStatusCell(status, g) {
72
+ switch (status) {
73
+ case 'running': return { glyph: g.quarter, tone: 'info', word: 'running', detail: '' };
74
+ case 'success': return { glyph: g.dot, tone: 'pos', word: 'success', detail: '' };
75
+ case 'failed': return { glyph: g.cross, tone: 'neg', word: 'failed', detail: '' };
76
+ case 'error': return { glyph: g.half, tone: 'warn', word: 'error', detail: '' };
77
+ }
78
+ }
79
+ /**
80
+ * The connection pill.
81
+ *
82
+ * @param connection - The connection state
83
+ * @param g - The glyph set
84
+ * @returns The cell (`● CONNECTED`, `◐ RECONNECTING 3/4`, `✗ OFFLINE`)
85
+ */
86
+ export function connectionCell(connection, g) {
87
+ switch (connection.kind) {
88
+ case 'connected': return { glyph: g.dot, tone: 'pos', word: 'CONNECTED', detail: '' };
89
+ case 'reconnecting': return { glyph: g.half, tone: 'warn', word: `RECONNECTING ${connection.attempt}/${connection.of}`, detail: '' };
90
+ case 'offline': return { glyph: g.cross, tone: 'neg', word: 'OFFLINE', detail: '' };
91
+ default: return null;
92
+ }
93
+ }
94
+ /**
95
+ * An execution's wall-clock duration in milliseconds: the summary's, or
96
+ * `completedAt − startedAt` when the summary reports none (the server
97
+ * only times the runs it launched itself).
98
+ *
99
+ * @param state - The execution state
100
+ * @returns The duration, or `null` while it is still running
101
+ */
102
+ export function executionDuration(state) {
103
+ if (state.summary.type === 'some' && state.summary.value.duration > 0)
104
+ return state.summary.value.duration;
105
+ if (state.completedAt.type === 'some') {
106
+ const ms = Date.parse(state.completedAt.value) - Date.parse(state.startedAt);
107
+ if (Number.isFinite(ms) && ms >= 0)
108
+ return ms;
109
+ }
110
+ return state.summary.type === 'some' ? state.summary.value.duration : null;
111
+ }
112
+ /**
113
+ * One dataflow event as the feed shows it — the cloud UI's
114
+ * `formatEventMessage` cases: the dot + word, the task, and the detail
115
+ * (duration, exit code, message, reason).
116
+ *
117
+ * @param event - The event
118
+ * @param g - The glyph set
119
+ * @returns The cell plus the task name
120
+ */
121
+ export function eventCell(event, g) {
122
+ switch (event.type) {
123
+ case 'start':
124
+ return { glyph: g.quarter, tone: 'info', word: 'start', detail: '', task: event.value.task, timestamp: event.value.timestamp };
125
+ case 'complete':
126
+ return { glyph: g.dot, tone: 'pos', word: 'complete', detail: formatDuration(event.value.duration), task: event.value.task, timestamp: event.value.timestamp };
127
+ case 'cached':
128
+ return { glyph: g.dot, tone: 'pos', word: 'cached', detail: '', task: event.value.task, timestamp: event.value.timestamp };
129
+ case 'failed':
130
+ return { glyph: g.cross, tone: 'neg', word: 'failed', detail: `exit ${event.value.exitCode} · ${formatDuration(event.value.duration)}`, task: event.value.task, timestamp: event.value.timestamp };
131
+ case 'error':
132
+ return { glyph: g.cross, tone: 'neg', word: 'error', detail: event.value.message, task: event.value.task, timestamp: event.value.timestamp };
133
+ case 'input_unavailable':
134
+ return { glyph: g.half, tone: 'warn', word: 'waiting', detail: event.value.reason, task: event.value.task, timestamp: event.value.timestamp };
135
+ }
136
+ }
137
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/tui/model/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
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 value tree's model — the flat rows a dataset's content becomes
7
+ * (`flattenRows` inline, `flattenPaged` paged, from the row model
8
+ * `@elaraai/east-ui` shares with the browser), and the *anchor* that keeps
9
+ * the selection on the same logical row while pages arrive and leave: a
10
+ * paged tree's flat indices shift whenever a placeholder root becomes its
11
+ * expanded rows (or the reverse), so the selection is remembered as a
12
+ * global root row plus an offset into its subtree and re-applied after
13
+ * every page change. The model is memoized on what the flatten reads, so
14
+ * a keypress that only moves the selection never re-flattens the value
15
+ * ({@link treeModel}).
16
+ *
17
+ * @packageDocumentation
18
+ */
19
+ import type { EastTypeValue } from '@elaraai/east';
20
+ import { type PagedFlat, type RowModel, type ValueTreePaging } from '@elaraai/east-ui/internal';
21
+ import type { DatasetData, TreeUi, TuiState, View } from '../state/actions.js';
22
+ /** Root rows fetched per page. */
23
+ export declare const PAGE_SIZE = 500;
24
+ /** Whether a dataset root type pages (Array / Set / Dict). */
25
+ export declare function isCollectionType(type: EastTypeValue): boolean;
26
+ /**
27
+ * The key type of a keyed collection (`/find` works over it).
28
+ *
29
+ * @param type - The dataset's root type
30
+ * @returns The Dict key type / Set element type, or null
31
+ */
32
+ export declare function keyTypeOf(type: EastTypeValue): EastTypeValue | null;
33
+ /**
34
+ * The keys of a decoded keyed collection in canonical order (the inline
35
+ * counterpart of the server's row space).
36
+ *
37
+ * @param type - The dataset's root type
38
+ * @param decoded - The decoded value
39
+ * @returns The keys, or null for a non-keyed root
40
+ */
41
+ export declare function collectionKeys(type: EastTypeValue, decoded: unknown): unknown[] | null;
42
+ /** The dataset a view shows, if any. */
43
+ export declare function viewDataset(state: TuiState): {
44
+ ws: string;
45
+ path: string;
46
+ editable: boolean;
47
+ } | null;
48
+ /** The tree's flat rows: inline (all loaded) or paged (loaded pages + placeholders). */
49
+ export interface TreeModel {
50
+ /** Flat rows in total. */
51
+ total: number;
52
+ /** The loaded rows in flat order (every row when inline). */
53
+ rows: RowModel[];
54
+ paged: {
55
+ flat: PagedFlat;
56
+ paging: ValueTreePaging;
57
+ } | null;
58
+ /** Root rows (depth 0) in total. */
59
+ rootCount: number;
60
+ /** The row at a flat index. */
61
+ at(index: number): {
62
+ kind: 'model';
63
+ row: RowModel;
64
+ } | {
65
+ kind: 'placeholder';
66
+ globalRow: number;
67
+ } | null;
68
+ /** The flat index of a root row ordinal. */
69
+ flatOfRoot(root: number): number | undefined;
70
+ /** The flat index of a row id, when loaded. */
71
+ flatOfId(id: string): number | undefined;
72
+ keyType: EastTypeValue | null;
73
+ }
74
+ /**
75
+ * How many times the tree model has been flattened — the memo's misses.
76
+ * A pure move (selection, scroll, page request) must not add to it; a
77
+ * toggle, a page arriving, or a new value adds one.
78
+ *
79
+ * @returns The build count since the module loaded
80
+ */
81
+ export declare function treeModelBuilds(): number;
82
+ /**
83
+ * The tree model for a dataset's current content — flattened once per
84
+ * (content, expand-set, base depth, editable) and shared by everything
85
+ * that reads it in one keypress: the key handler, the list model, the
86
+ * rows renderer and the mouse pane. A single-entry memo suffices: the
87
+ * TUI shows one tree at a time, and every reader asks for the same one.
88
+ *
89
+ * @param data - The dataset data
90
+ * @param tree - The tree UI (expand-set, base depth)
91
+ * @param editable - Whether append / remove rows are offered
92
+ * @returns The model, or null when the content is not a tree
93
+ */
94
+ export declare function treeModel(data: DatasetData | undefined, tree: TreeUi, editable: boolean): TreeModel | null;
95
+ /** The selection of a paged tree as a logical position. */
96
+ export interface TreeAnchor {
97
+ ws: string;
98
+ path: string;
99
+ /** The global root row the selection sits under. */
100
+ root: number;
101
+ /** Flat rows from that root to the selection. */
102
+ offset: number;
103
+ /** Flat rows from the window's top to the selection. */
104
+ topOffset: number;
105
+ }
106
+ /**
107
+ * Captures where the selection of the shown paged tree sits, before its
108
+ * pages change.
109
+ *
110
+ * @param state - The store state
111
+ * @param ws - The dataset's workspace
112
+ * @param path - The dataset's path
113
+ * @returns The anchor, or null when the view shows something else
114
+ */
115
+ export declare function captureAnchor(state: TuiState, ws: string, path: string): TreeAnchor | null;
116
+ /**
117
+ * Re-applies an anchor after the pages changed: the selection lands on
118
+ * the same root (at the same offset into its subtree, clamped) and the
119
+ * window keeps it on the same screen line.
120
+ *
121
+ * @param state - The store state after the change
122
+ * @param anchor - The captured anchor
123
+ * @returns The view to set, or null when nothing moves
124
+ */
125
+ export declare function applyAnchor(state: TuiState, anchor: TreeAnchor): View | null;
126
+ //# sourceMappingURL=tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../../src/tui/model/tree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAOH,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,eAAe,EACvB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE/E,kCAAkC;AAClC,eAAO,MAAM,SAAS,MAAM,CAAC;AAE7B,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAE7D;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,GAAG,IAAI,CAInE;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,GAAG,IAAI,CAItF;AAED,wCAAwC;AACxC,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAKnG;AAED,wFAAwF;AACxF,MAAM,WAAW,SAAS;IACtB,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,KAAK,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,eAAe,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3D,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,QAAQ,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,aAAa,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACxG,4CAA4C;IAC5C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC7C,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACzC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;CACjC;AAgCD;;;;;;GAMG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAwCD;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAmB1G;AAED,2DAA2D;AAC3D,MAAM,WAAW,UAAU;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAoB1F;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAyB5E"}
@@ -0,0 +1,217 @@
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
+ import { DEFAULT_OPEN_DEPTH, flatIndexOfRoot, flattenPaged, flattenRows, pagedFlatIndexOfRoot, pagedRowAt, } from '@elaraai/east-ui/internal';
6
+ /** Root rows fetched per page. */
7
+ export const PAGE_SIZE = 500;
8
+ /** Whether a dataset root type pages (Array / Set / Dict). */
9
+ export function isCollectionType(type) {
10
+ return type.type === 'Array' || type.type === 'Set' || type.type === 'Dict';
11
+ }
12
+ /**
13
+ * The key type of a keyed collection (`/find` works over it).
14
+ *
15
+ * @param type - The dataset's root type
16
+ * @returns The Dict key type / Set element type, or null
17
+ */
18
+ export function keyTypeOf(type) {
19
+ if (type.type === 'Dict')
20
+ return type.value.key;
21
+ if (type.type === 'Set')
22
+ return type.value;
23
+ return null;
24
+ }
25
+ /**
26
+ * The keys of a decoded keyed collection in canonical order (the inline
27
+ * counterpart of the server's row space).
28
+ *
29
+ * @param type - The dataset's root type
30
+ * @param decoded - The decoded value
31
+ * @returns The keys, or null for a non-keyed root
32
+ */
33
+ export function collectionKeys(type, decoded) {
34
+ if (type.type === 'Dict')
35
+ return [...decoded.keys()];
36
+ if (type.type === 'Set')
37
+ return [...decoded.values()];
38
+ return null;
39
+ }
40
+ /** The dataset a view shows, if any. */
41
+ export function viewDataset(state) {
42
+ const v = state.view;
43
+ if (v.kind === 'task' && v.tab === 'output')
44
+ return { ws: v.ws, path: `.tasks.${v.task}.output`, editable: false };
45
+ if (v.kind === 'input')
46
+ return { ws: v.ws, path: `.inputs.${v.name}`, editable: true };
47
+ return null;
48
+ }
49
+ let memo = null;
50
+ let builds = 0;
51
+ function sameKey(a, b) {
52
+ return a.type === b.type && a.kind === b.kind && a.root === b.root && a.pages === b.pages && a.totalRows === b.totalRows
53
+ && a.open === b.open && a.baseDepth === b.baseDepth && a.editable === b.editable;
54
+ }
55
+ /**
56
+ * How many times the tree model has been flattened — the memo's misses.
57
+ * A pure move (selection, scroll, page request) must not add to it; a
58
+ * toggle, a page arriving, or a new value adds one.
59
+ *
60
+ * @returns The build count since the module loaded
61
+ */
62
+ export function treeModelBuilds() {
63
+ return builds;
64
+ }
65
+ /** Flattens the content into a model (the memo's miss path). */
66
+ function buildTreeModel(type, mode, tree, editable) {
67
+ const openDepth = tree.baseDepth ?? DEFAULT_OPEN_DEPTH;
68
+ const keyType = keyTypeOf(type);
69
+ if (mode.kind === 'inline') {
70
+ const rows = flattenRows(mode.root, tree.open, openDepth, editable, editable);
71
+ const roots = rows.filter(r => r.depth === 0).length;
72
+ return {
73
+ total: rows.length,
74
+ rows,
75
+ paged: null,
76
+ rootCount: roots,
77
+ at: (i) => (i >= 0 && i < rows.length ? { kind: 'model', row: rows[i] } : null),
78
+ flatOfRoot: (root) => flatIndexOfRoot(rows, root),
79
+ flatOfId: (id) => { const i = rows.findIndex(r => r.id === id); return i === -1 ? undefined : i; },
80
+ keyType,
81
+ };
82
+ }
83
+ const paging = { totalRows: mode.totalRows, pageSize: PAGE_SIZE, pages: mode.pages, onNeedRows: () => undefined };
84
+ const flat = flattenPaged(paging, tree.open, openDepth);
85
+ return {
86
+ total: flat.totalFlat,
87
+ rows: flat.loadedRows,
88
+ paged: { flat, paging },
89
+ rootCount: mode.totalRows,
90
+ at: (i) => (i >= 0 && i < flat.totalFlat ? pagedRowAt(flat, paging, i) : null),
91
+ flatOfRoot: (root) => pagedFlatIndexOfRoot(flat, paging, root),
92
+ flatOfId: (id) => {
93
+ for (const [p, models] of flat.pageModels) {
94
+ const j = models.findIndex(r => r.id === id);
95
+ if (j !== -1)
96
+ return flat.prefix[p] + j;
97
+ }
98
+ return undefined;
99
+ },
100
+ keyType,
101
+ };
102
+ }
103
+ /**
104
+ * The tree model for a dataset's current content — flattened once per
105
+ * (content, expand-set, base depth, editable) and shared by everything
106
+ * that reads it in one keypress: the key handler, the list model, the
107
+ * rows renderer and the mouse pane. A single-entry memo suffices: the
108
+ * TUI shows one tree at a time, and every reader asks for the same one.
109
+ *
110
+ * @param data - The dataset data
111
+ * @param tree - The tree UI (expand-set, base depth)
112
+ * @param editable - Whether append / remove rows are offered
113
+ * @returns The model, or null when the content is not a tree
114
+ */
115
+ export function treeModel(data, tree, editable) {
116
+ if (data === undefined || data.type === null)
117
+ return null;
118
+ const mode = data.mode;
119
+ if (mode.kind !== 'inline' && mode.kind !== 'paged')
120
+ return null;
121
+ const key = {
122
+ type: data.type,
123
+ kind: mode.kind,
124
+ root: mode.kind === 'inline' ? mode.root : null,
125
+ pages: mode.kind === 'paged' ? mode.pages : null,
126
+ totalRows: mode.kind === 'paged' ? mode.totalRows : 0,
127
+ open: tree.open,
128
+ baseDepth: tree.baseDepth,
129
+ editable,
130
+ };
131
+ if (memo !== null && sameKey(memo.key, key))
132
+ return memo.model;
133
+ builds += 1;
134
+ const model = buildTreeModel(data.type, mode, tree, editable);
135
+ memo = { key, model };
136
+ return model;
137
+ }
138
+ /**
139
+ * Captures where the selection of the shown paged tree sits, before its
140
+ * pages change.
141
+ *
142
+ * @param state - The store state
143
+ * @param ws - The dataset's workspace
144
+ * @param path - The dataset's path
145
+ * @returns The anchor, or null when the view shows something else
146
+ */
147
+ export function captureAnchor(state, ws, path) {
148
+ const shown = viewDataset(state);
149
+ const v = state.view;
150
+ if (shown === null || shown.ws !== ws || shown.path !== path || (v.kind !== 'task' && v.kind !== 'input'))
151
+ return null;
152
+ const data = state.data.dataset[ws]?.[path];
153
+ if (data?.mode.kind !== 'paged')
154
+ return null;
155
+ const model = treeModel(data, v.tree, shown.editable);
156
+ if (model === null || model.total === 0)
157
+ return null;
158
+ const sel = Math.max(0, Math.min(v.tree.sel, model.total - 1));
159
+ const at = model.at(sel);
160
+ if (at === null)
161
+ return null;
162
+ if (at.kind === 'placeholder')
163
+ return { ws, path, root: at.globalRow, offset: 0, topOffset: sel - v.tree.top };
164
+ // The nearest depth-0 row at or before the selection is its root.
165
+ for (let i = sel; i >= 0; i--) {
166
+ const row = model.at(i);
167
+ if (row === null)
168
+ break;
169
+ if (row.kind === 'placeholder')
170
+ return { ws, path, root: row.globalRow, offset: 0, topOffset: sel - v.tree.top };
171
+ if (row.row.depth === 0)
172
+ return { ws, path, root: row.row.posinset - 1, offset: sel - i, topOffset: sel - v.tree.top };
173
+ }
174
+ return null;
175
+ }
176
+ /**
177
+ * Re-applies an anchor after the pages changed: the selection lands on
178
+ * the same root (at the same offset into its subtree, clamped) and the
179
+ * window keeps it on the same screen line.
180
+ *
181
+ * @param state - The store state after the change
182
+ * @param anchor - The captured anchor
183
+ * @returns The view to set, or null when nothing moves
184
+ */
185
+ export function applyAnchor(state, anchor) {
186
+ const shown = viewDataset(state);
187
+ const v = state.view;
188
+ if (shown === null || shown.ws !== anchor.ws || shown.path !== anchor.path || (v.kind !== 'task' && v.kind !== 'input'))
189
+ return null;
190
+ const data = state.data.dataset[anchor.ws]?.[anchor.path];
191
+ if (data?.mode.kind !== 'paged')
192
+ return null;
193
+ const model = treeModel(data, v.tree, shown.editable);
194
+ if (model === null || model.total === 0)
195
+ return null;
196
+ const flat = model.flatOfRoot(anchor.root);
197
+ if (flat === undefined)
198
+ return null;
199
+ let sel = flat;
200
+ const at = model.at(flat);
201
+ if (at !== null && at.kind === 'model') {
202
+ // Stay inside the root's subtree.
203
+ let end = flat;
204
+ while (end + 1 < model.total) {
205
+ const next = model.at(end + 1);
206
+ if (next === null || next.kind === 'placeholder' || next.row.depth === 0)
207
+ break;
208
+ end++;
209
+ }
210
+ sel = Math.min(flat + anchor.offset, end);
211
+ }
212
+ const top = Math.max(0, Math.min(sel - anchor.topOffset, Math.max(0, model.total - 1)));
213
+ if (sel === v.tree.sel && top === v.tree.top)
214
+ return null;
215
+ return { ...v, tree: { ...v.tree, sel, top } };
216
+ }
217
+ //# sourceMappingURL=tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.js","sourceRoot":"","sources":["../../../src/tui/model/tree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
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
+ * East type text for tables — `Array<Struct>`, `Dict<String, Struct>`,
7
+ * `UIComponentType`: the top-level kind with its generic arguments' kinds
8
+ * only, so a type fits a column.
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+ import type { EastTypeValue } from '@elaraai/east';
13
+ /**
14
+ * The compact text of a type.
15
+ *
16
+ * @param tv - The type value
17
+ * @param ui - Whether the dataset is a `ui` task's output (printed `UIComponentType`)
18
+ * @returns The compact text
19
+ */
20
+ export declare function compactType(tv: EastTypeValue, ui?: boolean): string;
21
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tui/model/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAWnD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,aAAa,EAAE,EAAE,UAAQ,GAAG,MAAM,CAuBjE"}
@@ -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"}