@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,318 @@
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 { describeError, isApiCode } from '../api.js';
6
+ import { createDatasetLoader, viewDataset } from './dataset.js';
7
+ import { createLogsLoader } from './logs.js';
8
+ import { isLogTab } from '../state/actions.js';
9
+ import { connectionState, createPoller } from '../state/poll.js';
10
+ /** The workspace a view is about, if any. */
11
+ export function viewWorkspace(state) {
12
+ const v = state.view;
13
+ if (v.kind === 'dashboard' || v.kind === 'task' || v.kind === 'input')
14
+ return v.ws;
15
+ return null;
16
+ }
17
+ /**
18
+ * Creates the feed manager.
19
+ *
20
+ * @param deps - The store, the API accessor, timers
21
+ * @returns The feeds (not started)
22
+ */
23
+ export function createFeeds(deps) {
24
+ const { store } = deps;
25
+ const running = new Map();
26
+ let unsubscribe = null;
27
+ let lastSignature = '';
28
+ const executionCursor = new Map();
29
+ const repoStatusRequested = new Set();
30
+ const datasets = createDatasetLoader({ store, api: deps.api, log: deps.log });
31
+ const logs = createLogsLoader({ store, api: deps.api, log: deps.log });
32
+ /** A repository's counts and its latest deployment (the repositories view's lazy columns). */
33
+ const repoFacts = async (api, name) => {
34
+ const status = await api.repoStatus(name);
35
+ store.dispatch({ type: 'data/repoStatus', repo: name, status });
36
+ const bound = api.withRepo(name);
37
+ let latest = null;
38
+ try {
39
+ const workspaces = await bound.workspaceList();
40
+ for (const ws of workspaces) {
41
+ if (!ws.deployed)
42
+ continue;
43
+ const wsState = await bound.workspaceGet(ws.name);
44
+ if (wsState === null)
45
+ continue;
46
+ if (latest === null || wsState.deployedAt.getTime() > latest.deployedAt.getTime()) {
47
+ latest = { workspace: ws.name, packageName: wsState.packageName, packageVersion: wsState.packageVersion, deployedAt: wsState.deployedAt };
48
+ }
49
+ }
50
+ }
51
+ catch (err) {
52
+ deps.log?.(`repo ${name} facts failed: ${describeError(err)}`);
53
+ }
54
+ store.dispatch({ type: 'data/repoDeploy', repo: name, deploy: latest });
55
+ };
56
+ const dispatchConnection = () => {
57
+ store.dispatch({ type: 'connection', connection: connectionState([...running.values()]) });
58
+ };
59
+ const specs = (state, api) => {
60
+ const out = [];
61
+ const session = state.session;
62
+ if (session === null)
63
+ return out;
64
+ const view = state.view;
65
+ if (session.kind === 'origin' || view.kind === 'repos') {
66
+ out.push({
67
+ key: 'repos',
68
+ intervalMs: 5_000,
69
+ run: async () => {
70
+ const names = await api.repoList();
71
+ store.dispatch({ type: 'data/repos', names });
72
+ for (const name of names) {
73
+ if (repoStatusRequested.has(name))
74
+ continue;
75
+ repoStatusRequested.add(name);
76
+ void repoFacts(api, name)
77
+ .catch(() => repoStatusRequested.delete(name));
78
+ }
79
+ },
80
+ });
81
+ }
82
+ if (session.repo === null)
83
+ return out;
84
+ out.push({
85
+ key: 'workspaces',
86
+ intervalMs: 5_000,
87
+ run: async () => {
88
+ const workspaces = await api.workspaceList();
89
+ store.dispatch({ type: 'data/workspaces', workspaces });
90
+ },
91
+ });
92
+ if (view.kind === 'workspaces') {
93
+ out.push({
94
+ key: 'workspaces:summaries',
95
+ intervalMs: 5_000,
96
+ run: async (signal) => {
97
+ let workspaces = store.getState().data.workspaces;
98
+ if (workspaces === null) {
99
+ workspaces = await api.workspaceList();
100
+ if (signal.aborted)
101
+ return;
102
+ store.dispatch({ type: 'data/workspaces', workspaces });
103
+ }
104
+ for (const ws of workspaces.map(w => w.name)) {
105
+ if (signal.aborted)
106
+ return;
107
+ try {
108
+ const [result, wsState] = await Promise.all([api.workspaceStatus(ws), api.workspaceGet(ws)]);
109
+ if (signal.aborted)
110
+ return;
111
+ store.dispatch({ type: 'data/status', ws, result, at: (deps.clock?.now ?? Date.now)() });
112
+ store.dispatch({ type: 'data/workspaceState', ws, state: wsState });
113
+ }
114
+ catch (err) {
115
+ if (isApiCode(err, 'workspace_not_deployed')) {
116
+ store.dispatch({ type: 'data/workspaceState', ws, state: null });
117
+ continue;
118
+ }
119
+ throw err;
120
+ }
121
+ // The last run, for the LAST RUN column (never run is not an error).
122
+ try {
123
+ const execution = await api.dataflowExecutePoll(ws, 0);
124
+ if (signal.aborted)
125
+ return;
126
+ executionCursor.set(ws, { startedAt: execution.startedAt, events: [...execution.events] });
127
+ store.dispatch({ type: 'data/execution', ws, state: execution, events: [...execution.events], startedAt: execution.startedAt });
128
+ }
129
+ catch (err) {
130
+ if (!isApiCode(err, 'execution_not_found'))
131
+ throw err;
132
+ store.dispatch({ type: 'data/execution', ws, state: null, events: [], startedAt: null });
133
+ }
134
+ }
135
+ },
136
+ });
137
+ }
138
+ const ws = viewWorkspace(state);
139
+ if (ws !== null) {
140
+ out.push({
141
+ key: `status:${ws}`,
142
+ intervalMs: 1_000,
143
+ run: async () => {
144
+ try {
145
+ const result = await api.workspaceStatus(ws);
146
+ store.dispatch({ type: 'data/status', ws, result, at: (deps.clock?.now ?? Date.now)() });
147
+ }
148
+ catch (err) {
149
+ store.dispatch({ type: 'data/statusError', ws, error: describeError(err) });
150
+ throw err;
151
+ }
152
+ },
153
+ });
154
+ const execution = state.data.execution[ws];
155
+ const active = execution?.state?.status.type === 'running' || execution?.settling === true || execution?.stopping === true;
156
+ out.push({
157
+ key: `execution:${ws}`,
158
+ intervalMs: active ? 1_000 : 5_000,
159
+ run: async () => {
160
+ const cursor = executionCursor.get(ws) ?? { startedAt: null, events: [] };
161
+ let result;
162
+ try {
163
+ result = await api.dataflowExecutePoll(ws, cursor.events.length);
164
+ }
165
+ catch (err) {
166
+ if (isApiCode(err, 'execution_not_found')) {
167
+ executionCursor.set(ws, { startedAt: null, events: [] });
168
+ store.dispatch({ type: 'data/execution', ws, state: null, events: [], startedAt: null });
169
+ return;
170
+ }
171
+ throw err;
172
+ }
173
+ let events = cursor.events;
174
+ if (result.startedAt !== cursor.startedAt) {
175
+ // A new execution: its events restart at 0.
176
+ const fresh = cursor.events.length === 0 ? result : await api.dataflowExecutePoll(ws, 0);
177
+ events = [...fresh.events];
178
+ result = fresh;
179
+ }
180
+ else {
181
+ events = [...cursor.events, ...result.events];
182
+ }
183
+ executionCursor.set(ws, { startedAt: result.startedAt, events });
184
+ store.dispatch({ type: 'data/execution', ws, state: result, events, startedAt: result.startedAt });
185
+ },
186
+ });
187
+ out.push({
188
+ key: `datasets:${ws}`,
189
+ intervalMs: 5_000,
190
+ run: async () => {
191
+ const entries = await api.datasetList(ws);
192
+ store.dispatch({ type: 'data/datasets', ws, entries });
193
+ },
194
+ });
195
+ out.push({
196
+ key: `taskList:${ws}`,
197
+ intervalMs: 30_000,
198
+ run: async () => {
199
+ const tasks = await api.taskList(ws);
200
+ store.dispatch({ type: 'data/taskList', ws, tasks });
201
+ },
202
+ });
203
+ out.push({
204
+ key: `workspaceState:${ws}`,
205
+ intervalMs: 30_000,
206
+ run: async () => {
207
+ const wsState = await api.workspaceGet(ws);
208
+ store.dispatch({ type: 'data/workspaceState', ws, state: wsState });
209
+ },
210
+ });
211
+ }
212
+ const shown = viewDataset(state);
213
+ if (shown !== null) {
214
+ out.push({
215
+ key: `dataset:${shown.ws}:${shown.path}`,
216
+ intervalMs: 5_000,
217
+ run: () => datasets.tick(shown.ws, shown.path),
218
+ });
219
+ }
220
+ if (view.kind === 'task') {
221
+ const { task } = view;
222
+ out.push({
223
+ key: `taskDetails:${ws}/${task}`,
224
+ intervalMs: 60_000,
225
+ run: async () => {
226
+ const details = await api.taskGet(view.ws, task);
227
+ store.dispatch({ type: 'data/taskDetails', ws: view.ws, task, details });
228
+ },
229
+ });
230
+ // The runs tab lists them; the title line's inputs hash reads the newest on every tab.
231
+ out.push({
232
+ key: `executions:${ws}/${task}`,
233
+ intervalMs: view.tab === 'runs' ? 5_000 : 30_000,
234
+ run: async () => {
235
+ const executions = await api.taskExecutionList(view.ws, task);
236
+ store.dispatch({ type: 'data/executions', ws: view.ws, task, executions });
237
+ },
238
+ });
239
+ // The shown stream every second; stderr every five seconds on every tab, so the
240
+ // Stderr tab's line count is there before the tab is visited.
241
+ const logTab = isLogTab(view.tab) ? view.tab : null;
242
+ for (const stream of ['stdout', 'stderr']) {
243
+ if (stream !== logTab && stream === 'stdout')
244
+ continue;
245
+ out.push({ key: `logs:${ws}/${task}/${stream}`, intervalMs: stream === logTab ? 1_000 : 5_000, run: () => logs.tick(view.ws, task, stream) });
246
+ }
247
+ }
248
+ return out;
249
+ };
250
+ const sync = () => {
251
+ const state = store.getState();
252
+ const api = deps.api();
253
+ const wanted = api === null ? [] : specs(state, api);
254
+ const signature = wanted.map(s => `${s.key}@${s.intervalMs}`).join('|');
255
+ if (signature === lastSignature)
256
+ return;
257
+ lastSignature = signature;
258
+ const wantedKeys = new Set(wanted.map(s => s.key));
259
+ for (const [key, poller] of running) {
260
+ if (!wantedKeys.has(key)) {
261
+ poller.stop();
262
+ running.delete(key);
263
+ }
264
+ }
265
+ for (const spec of wanted) {
266
+ const existing = running.get(spec.key);
267
+ if (existing !== undefined) {
268
+ existing.setInterval(spec.intervalMs);
269
+ continue;
270
+ }
271
+ const poller = createPoller({
272
+ key: spec.key,
273
+ intervalMs: spec.intervalMs,
274
+ clock: deps.clock,
275
+ run: spec.run,
276
+ onResult: () => dispatchConnection(),
277
+ onError: (error, failures) => {
278
+ deps.log?.(`feed ${spec.key} failed (${failures}): ${describeError(error)}`);
279
+ dispatchConnection();
280
+ },
281
+ });
282
+ running.set(spec.key, poller);
283
+ poller.start();
284
+ }
285
+ dispatchConnection();
286
+ };
287
+ return {
288
+ start() {
289
+ if (unsubscribe !== null)
290
+ return;
291
+ unsubscribe = store.subscribe(sync);
292
+ sync();
293
+ },
294
+ stop() {
295
+ unsubscribe?.();
296
+ unsubscribe = null;
297
+ for (const poller of running.values())
298
+ poller.stop();
299
+ running.clear();
300
+ lastSignature = '';
301
+ executionCursor.clear();
302
+ repoStatusRequested.clear();
303
+ datasets.reset();
304
+ logs.reset();
305
+ },
306
+ refresh() {
307
+ for (const poller of running.values())
308
+ poller.fireNow();
309
+ },
310
+ fire(key) {
311
+ running.get(key)?.fireNow();
312
+ },
313
+ pollers: () => [...running.values()],
314
+ sync,
315
+ datasets,
316
+ };
317
+ }
318
+ //# sourceMappingURL=feeds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feeds.js","sourceRoot":"","sources":["../../../src/tui/data/feeds.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
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
+ * Task logs — `taskLogs` in 64 KB chunks (`offset += size`) up to a 10 MB
7
+ * cap, polled every second for the stream on screen (and every five for
8
+ * stderr on every task tab, for the Stderr tab's line count). A stream that has
9
+ * no run yet reads as empty with `execution_not_found` noted; a chunk
10
+ * failure keeps what was fetched and notes the error.
11
+ *
12
+ * @packageDocumentation
13
+ */
14
+ import { type Api } from '../api.js';
15
+ import type { LogsData } from '../state/actions.js';
16
+ import type { Store } from '../state/store.js';
17
+ /** Bytes fetched per request. */
18
+ export declare const LOG_CHUNK: number;
19
+ /** Bytes kept per stream at most. */
20
+ export declare const LOG_CAP: number;
21
+ /** A stream name. */
22
+ export type LogStream = 'stdout' | 'stderr';
23
+ /** An empty stream record. */
24
+ export declare function emptyLogs(): LogsData;
25
+ /** What the loader needs. */
26
+ export interface LogsLoaderDeps {
27
+ store: Store;
28
+ api: () => Api | null;
29
+ log?: ((line: string) => void) | undefined;
30
+ }
31
+ /** The logs loader. */
32
+ export interface LogsLoader {
33
+ /** Fetches the next chunks of a stream (up to a few per tick) and appends them. */
34
+ tick(ws: string, task: string, stream: LogStream): Promise<void>;
35
+ /** Drops the in-flight bookkeeping. */
36
+ reset(): void;
37
+ }
38
+ /**
39
+ * Creates the loader.
40
+ *
41
+ * @param deps - The store, the API accessor, the log
42
+ * @returns The loader
43
+ */
44
+ export declare function createLogsLoader(deps: LogsLoaderDeps): LogsLoader;
45
+ /**
46
+ * The lines of a stream's text (a trailing newline does not add an empty line).
47
+ *
48
+ * @param text - The text
49
+ * @returns The lines
50
+ */
51
+ export declare function logLines(text: string): string[];
52
+ /**
53
+ * The number of lines in a stream's text, as {@link logLines} counts them,
54
+ * without splitting it (the Stderr tab's badge, every frame).
55
+ *
56
+ * @param text - The text
57
+ * @returns The line count
58
+ */
59
+ export declare function countLines(text: string): number;
60
+ /**
61
+ * The line indices containing `needle` (case-insensitive).
62
+ *
63
+ * @param lines - The lines
64
+ * @param needle - The search text
65
+ * @returns The matching line indices
66
+ */
67
+ export declare function findInLines(lines: readonly string[], needle: string): number[];
68
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/tui/data/logs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;GAQG;AAEH,OAAO,EAA4B,KAAK,GAAG,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,iCAAiC;AACjC,eAAO,MAAM,SAAS,QAAY,CAAC;AACnC,qCAAqC;AACrC,eAAO,MAAM,OAAO,QAAmB,CAAC;AAIxC,qBAAqB;AACrB,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE5C,8BAA8B;AAC9B,wBAAgB,SAAS,IAAI,QAAQ,CAEpC;AAED,6BAA6B;AAC7B,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,CAAC;IACtB,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC9C;AAED,uBAAuB;AACvB,MAAM,WAAW,UAAU;IACvB,mFAAmF;IACnF,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,uCAAuC;IACvC,KAAK,IAAI,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CAiDjE;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAK/C;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAM9E"}
@@ -0,0 +1,134 @@
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
+ * Task logs — `taskLogs` in 64 KB chunks (`offset += size`) up to a 10 MB
7
+ * cap, polled every second for the stream on screen (and every five for
8
+ * stderr on every task tab, for the Stderr tab's line count). A stream that has
9
+ * no run yet reads as empty with `execution_not_found` noted; a chunk
10
+ * failure keeps what was fetched and notes the error.
11
+ *
12
+ * @packageDocumentation
13
+ */
14
+ import { describeError, isApiCode } from '../api.js';
15
+ /** Bytes fetched per request. */
16
+ export const LOG_CHUNK = 64 * 1024;
17
+ /** Bytes kept per stream at most. */
18
+ export const LOG_CAP = 10 * 1024 * 1024;
19
+ /** Chunks fetched per tick at most (a 5 MB backlog arrives over a few ticks, never in one). */
20
+ const CHUNKS_PER_TICK = 16;
21
+ /** An empty stream record. */
22
+ export function emptyLogs() {
23
+ return { text: '', offset: 0, totalSize: 0, complete: false, capped: false, error: null };
24
+ }
25
+ /**
26
+ * Creates the loader.
27
+ *
28
+ * @param deps - The store, the API accessor, the log
29
+ * @returns The loader
30
+ */
31
+ export function createLogsLoader(deps) {
32
+ const { store } = deps;
33
+ const inflight = new Set();
34
+ const current = (ws, task, stream) => store.getState().data.logs[ws]?.[task]?.[stream] ?? emptyLogs();
35
+ return {
36
+ async tick(ws, task, stream) {
37
+ const api = deps.api();
38
+ if (api === null)
39
+ return;
40
+ const key = `${ws}\n${task}\n${stream}`;
41
+ if (inflight.has(key))
42
+ return;
43
+ inflight.add(key);
44
+ try {
45
+ for (let i = 0; i < CHUNKS_PER_TICK; i++) {
46
+ const before = current(ws, task, stream);
47
+ if (before.capped)
48
+ return;
49
+ let chunk;
50
+ try {
51
+ chunk = await api.taskLogs(ws, task, { stream, offset: before.offset, limit: LOG_CHUNK });
52
+ }
53
+ catch (err) {
54
+ if (isApiCode(err, 'execution_not_found')) {
55
+ if (before.error !== 'no run yet' || before.totalSize !== 0)
56
+ store.dispatch({ type: 'data/logs', ws, task, stream, logs: { ...before, complete: true, error: 'no run yet' } });
57
+ return;
58
+ }
59
+ deps.log?.(`logs ${ws}/${task}/${stream} failed: ${describeError(err)}`);
60
+ store.dispatch({ type: 'data/logs', ws, task, stream, logs: { ...before, error: describeError(err) } });
61
+ return;
62
+ }
63
+ const size = Number(chunk.size);
64
+ const totalSize = Number(chunk.totalSize);
65
+ const offset = Number(chunk.offset) + size;
66
+ // A shorter total than what we hold means the log was truncated (a new run): start over from zero.
67
+ if (totalSize < before.offset) {
68
+ store.dispatch({ type: 'data/logs', ws, task, stream, logs: { ...emptyLogs(), totalSize } });
69
+ continue;
70
+ }
71
+ const capped = offset >= LOG_CAP;
72
+ const next = { text: before.text + chunk.data, offset, totalSize, complete: chunk.complete, capped, error: null };
73
+ const unchanged = size === 0 && before.totalSize === totalSize && before.complete === chunk.complete && before.error === null;
74
+ if (!unchanged)
75
+ store.dispatch({ type: 'data/logs', ws, task, stream, logs: next });
76
+ if (chunk.complete || size === 0 || capped)
77
+ return;
78
+ }
79
+ }
80
+ finally {
81
+ inflight.delete(key);
82
+ }
83
+ },
84
+ reset() {
85
+ inflight.clear();
86
+ },
87
+ };
88
+ }
89
+ /**
90
+ * The lines of a stream's text (a trailing newline does not add an empty line).
91
+ *
92
+ * @param text - The text
93
+ * @returns The lines
94
+ */
95
+ export function logLines(text) {
96
+ if (text === '')
97
+ return [];
98
+ const lines = text.split('\n');
99
+ if (lines[lines.length - 1] === '')
100
+ lines.pop();
101
+ return lines;
102
+ }
103
+ /**
104
+ * The number of lines in a stream's text, as {@link logLines} counts them,
105
+ * without splitting it (the Stderr tab's badge, every frame).
106
+ *
107
+ * @param text - The text
108
+ * @returns The line count
109
+ */
110
+ export function countLines(text) {
111
+ if (text === '')
112
+ return 0;
113
+ let n = 0;
114
+ for (let i = text.indexOf('\n'); i !== -1; i = text.indexOf('\n', i + 1))
115
+ n++;
116
+ return text.endsWith('\n') ? n : n + 1;
117
+ }
118
+ /**
119
+ * The line indices containing `needle` (case-insensitive).
120
+ *
121
+ * @param lines - The lines
122
+ * @param needle - The search text
123
+ * @returns The matching line indices
124
+ */
125
+ export function findInLines(lines, needle) {
126
+ const q = needle.toLowerCase();
127
+ if (q === '')
128
+ return [];
129
+ const out = [];
130
+ lines.forEach((line, i) => { if (line.toLowerCase().includes(q))
131
+ out.push(i); });
132
+ return out;
133
+ }
134
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../../src/tui/data/logs.ts"],"names":[],"mappings":"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"}