@kal-elsam/kairo-runtime 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/runtime-mvp-smoke.sh +152 -0
- package/src/cli.js +77 -4
- package/src/global/ink/orchestrator-app.js +355 -81
- package/src/global/ink/orchestrator-state.js +196 -65
- package/src/global/orchestrator.js +8 -39
- package/src/global/paths.js +13 -0
- package/src/global/profile.js +17 -2
- package/src/global/runtime/execution-adapters/claude.js +65 -0
- package/src/global/runtime/execution-adapters/codex.js +78 -0
- package/src/global/runtime/execution-adapters/create-execution-adapter.js +92 -0
- package/src/global/runtime/execution-adapters/cursor.js +104 -0
- package/src/global/runtime/execution-adapters/index.js +36 -0
- package/src/global/runtime/execution-adapters/opencode.js +38 -0
- package/src/global/runtime/run-cancel-signal.js +29 -0
- package/src/global/runtime/run-cli.js +221 -0
- package/src/global/runtime/run-events.js +144 -0
- package/src/global/runtime/run-handoff.js +71 -0
- package/src/global/runtime/run-liveness.js +28 -0
- package/src/global/runtime/run-manager.js +271 -0
- package/src/global/runtime/run-profile.js +93 -0
- package/src/global/runtime/run-redact.js +66 -0
- package/src/global/runtime/run-starting.js +13 -0
- package/src/global/runtime/run-store.js +159 -0
- package/src/global/runtime/run-supervisor-lock.js +37 -0
- package/src/global/runtime/run-supervisor-worker.js +12 -0
- package/src/global/runtime/run-supervisor.js +289 -0
- package/src/global/runtime/run-types.js +117 -0
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
import React, { useEffect, useState } from "react";
|
|
2
2
|
import { Box, Text, useApp, useInput } from "ink";
|
|
3
3
|
import { BRAND } from "../brand/index.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { buildReadOnlyDiagnostics } from "../action-planner.js";
|
|
5
|
+
import { buildRuntimeDashboardData } from "../runtime/run-cli.js";
|
|
6
|
+
import { readRunEvents } from "../runtime/run-store.js";
|
|
7
|
+
import { stopRun } from "../runtime/run-manager.js";
|
|
8
|
+
import { startRun } from "../runtime/run-manager.js";
|
|
6
9
|
import {
|
|
7
10
|
ORCHESTRATOR_MENU,
|
|
8
11
|
ORCHESTRATOR_VIEWS,
|
|
9
|
-
|
|
12
|
+
LAUNCH_WIZARD_STEPS,
|
|
13
|
+
LAUNCH_PERMISSION_OPTIONS,
|
|
14
|
+
createLaunchDraft,
|
|
15
|
+
formatDashboardSnapshot,
|
|
10
16
|
formatDiagnosticsLines,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
formatLaunchWizardLines,
|
|
18
|
+
formatProviderLines,
|
|
19
|
+
formatRunDetailLines,
|
|
20
|
+
formatRunLines,
|
|
21
|
+
isRunCancellable,
|
|
22
|
+
resolveLaunchPermissions,
|
|
23
|
+
resolveLaunchableAgents,
|
|
14
24
|
resolveMenuItem,
|
|
15
25
|
resolveMenuItemView,
|
|
26
|
+
retreatLaunchWizardStep,
|
|
27
|
+
selectRunFromList,
|
|
16
28
|
shiftMenuIndex
|
|
17
29
|
} from "./orchestrator-state.js";
|
|
18
30
|
|
|
@@ -35,25 +47,36 @@ export function OrchestratorApp({
|
|
|
35
47
|
const { exit } = useApp();
|
|
36
48
|
const [view, setView] = useState(ORCHESTRATOR_VIEWS.HOME);
|
|
37
49
|
const [menuIndex, setMenuIndex] = useState(0);
|
|
50
|
+
const [listIndex, setListIndex] = useState(0);
|
|
51
|
+
const [launchAgentIndex, setLaunchAgentIndex] = useState(0);
|
|
52
|
+
const [launchStep, setLaunchStep] = useState(LAUNCH_WIZARD_STEPS.AGENT);
|
|
53
|
+
const [launchDraft, setLaunchDraft] = useState(createLaunchDraft);
|
|
54
|
+
const [launchPermissionIndex, setLaunchPermissionIndex] = useState(0);
|
|
38
55
|
const [loading, setLoading] = useState(true);
|
|
56
|
+
const [busy, setBusy] = useState(false);
|
|
39
57
|
const [error, setError] = useState(null);
|
|
58
|
+
const [dashboard, setDashboard] = useState(null);
|
|
40
59
|
const [diagnostics, setDiagnostics] = useState(null);
|
|
41
|
-
const [
|
|
42
|
-
const [
|
|
60
|
+
const [selectedRun, setSelectedRun] = useState(null);
|
|
61
|
+
const [selectedEvents, setSelectedEvents] = useState([]);
|
|
62
|
+
const [statusMessage, setStatusMessage] = useState(null);
|
|
63
|
+
|
|
64
|
+
const reload = async () => {
|
|
65
|
+
const [dash, diag] = await Promise.all([
|
|
66
|
+
buildRuntimeDashboardData({ homeDir, workspaceRoot, cliVersion }),
|
|
67
|
+
buildReadOnlyDiagnostics({ homeDir, workspaceRoot, packageName, packageRoot, cliVersion })
|
|
68
|
+
]);
|
|
69
|
+
setDashboard(dash);
|
|
70
|
+
setDiagnostics(diag);
|
|
71
|
+
};
|
|
43
72
|
|
|
44
73
|
useEffect(() => {
|
|
45
74
|
let cancelled = false;
|
|
46
75
|
|
|
47
76
|
async function load() {
|
|
48
77
|
try {
|
|
49
|
-
|
|
50
|
-
buildReadOnlyDiagnostics({ homeDir, workspaceRoot, packageName, packageRoot, cliVersion }),
|
|
51
|
-
resolveProfile({ homeDir, workspaceRoot })
|
|
52
|
-
]);
|
|
53
|
-
|
|
78
|
+
await reload();
|
|
54
79
|
if (cancelled) return;
|
|
55
|
-
setDiagnostics(diag);
|
|
56
|
-
setProfileJson(buildProfileJson(profileResolved));
|
|
57
80
|
setLoading(false);
|
|
58
81
|
} catch (loadError) {
|
|
59
82
|
if (cancelled) return;
|
|
@@ -73,6 +96,81 @@ export function OrchestratorApp({
|
|
|
73
96
|
exit();
|
|
74
97
|
};
|
|
75
98
|
|
|
99
|
+
const openRunDetail = async (run) => {
|
|
100
|
+
if (!run) return;
|
|
101
|
+
const events = await readRunEvents(homeDir, run.runId, { limit: 20 });
|
|
102
|
+
setSelectedRun(run);
|
|
103
|
+
setSelectedEvents(events);
|
|
104
|
+
setView(ORCHESTRATOR_VIEWS.RUN_DETAIL);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const launchableAgents = resolveLaunchableAgents(dashboard?.providers ?? []);
|
|
108
|
+
|
|
109
|
+
const resetLaunchWizard = () => {
|
|
110
|
+
setLaunchStep(LAUNCH_WIZARD_STEPS.AGENT);
|
|
111
|
+
setLaunchDraft(createLaunchDraft());
|
|
112
|
+
setLaunchAgentIndex(0);
|
|
113
|
+
setLaunchPermissionIndex(0);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const handleLaunch = async (draft) => {
|
|
117
|
+
if (!draft.agentId || !draft.task.trim()) {
|
|
118
|
+
setError("Agent and task are required.");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
setBusy(true);
|
|
123
|
+
setStatusMessage(`Launching ${draft.agentId}…`);
|
|
124
|
+
try {
|
|
125
|
+
const permissions = resolveLaunchPermissions({
|
|
126
|
+
...draft,
|
|
127
|
+
permissionIndex: launchPermissionIndex
|
|
128
|
+
});
|
|
129
|
+
const { runId } = await startRun({
|
|
130
|
+
homeDir,
|
|
131
|
+
agentId: draft.agentId,
|
|
132
|
+
task: draft.task.trim(),
|
|
133
|
+
cwd: workspaceRoot,
|
|
134
|
+
model: draft.model.trim() || null,
|
|
135
|
+
permissions,
|
|
136
|
+
cliVersion,
|
|
137
|
+
profile: dashboard?.profile ?? null,
|
|
138
|
+
follow: false,
|
|
139
|
+
wait: false
|
|
140
|
+
});
|
|
141
|
+
await reload();
|
|
142
|
+
const run = (await buildRuntimeDashboardData({ homeDir, workspaceRoot, cliVersion }))
|
|
143
|
+
.runs.find((entry) => entry.runId === runId);
|
|
144
|
+
setStatusMessage(`Run started: ${runId}`);
|
|
145
|
+
resetLaunchWizard();
|
|
146
|
+
setView(ORCHESTRATOR_VIEWS.HOME);
|
|
147
|
+
if (run) await openRunDetail(run);
|
|
148
|
+
} catch (launchError) {
|
|
149
|
+
setError(launchError instanceof Error ? launchError.message : String(launchError));
|
|
150
|
+
} finally {
|
|
151
|
+
setBusy(false);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const handleCancelRun = async () => {
|
|
156
|
+
if (!selectedRun || !isRunCancellable(selectedRun)) return;
|
|
157
|
+
setBusy(true);
|
|
158
|
+
try {
|
|
159
|
+
await stopRun(homeDir, selectedRun.runId);
|
|
160
|
+
await reload();
|
|
161
|
+
const refreshed = await buildRuntimeDashboardData({ homeDir, workspaceRoot, cliVersion });
|
|
162
|
+
const run = refreshed.runs.find((entry) => entry.runId === selectedRun.runId);
|
|
163
|
+
const events = await readRunEvents(homeDir, selectedRun.runId, { limit: 20 });
|
|
164
|
+
setSelectedRun(run ?? selectedRun);
|
|
165
|
+
setSelectedEvents(events);
|
|
166
|
+
setStatusMessage(`Cancelled ${selectedRun.runId}`);
|
|
167
|
+
} catch (cancelError) {
|
|
168
|
+
setError(cancelError instanceof Error ? cancelError.message : String(cancelError));
|
|
169
|
+
} finally {
|
|
170
|
+
setBusy(false);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
76
174
|
useInput((inputKey, key) => {
|
|
77
175
|
if (key.escape) {
|
|
78
176
|
if (view === ORCHESTRATOR_VIEWS.HOME) {
|
|
@@ -80,24 +178,148 @@ export function OrchestratorApp({
|
|
|
80
178
|
return;
|
|
81
179
|
}
|
|
82
180
|
setView(ORCHESTRATOR_VIEWS.HOME);
|
|
83
|
-
|
|
181
|
+
setSelectedRun(null);
|
|
182
|
+
setListIndex(0);
|
|
84
183
|
return;
|
|
85
184
|
}
|
|
86
185
|
|
|
87
|
-
if (loading || error) return;
|
|
186
|
+
if (loading || error || busy) return;
|
|
187
|
+
|
|
188
|
+
if (view === ORCHESTRATOR_VIEWS.LAUNCH) {
|
|
189
|
+
if (launchableAgents.length === 0) {
|
|
190
|
+
if (key.escape) {
|
|
191
|
+
resetLaunchWizard();
|
|
192
|
+
setView(ORCHESTRATOR_VIEWS.HOME);
|
|
193
|
+
}
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (launchStep === LAUNCH_WIZARD_STEPS.AGENT) {
|
|
198
|
+
if (key.upArrow) {
|
|
199
|
+
setLaunchAgentIndex((index) => Math.max(0, index - 1));
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (key.downArrow) {
|
|
203
|
+
setLaunchAgentIndex((index) => Math.min(launchableAgents.length - 1, index + 1));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (key.return) {
|
|
207
|
+
const agentId = launchableAgents[launchAgentIndex];
|
|
208
|
+
setLaunchDraft((draft) => ({ ...draft, agentId }));
|
|
209
|
+
setLaunchStep(LAUNCH_WIZARD_STEPS.TASK);
|
|
210
|
+
}
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
88
213
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
214
|
+
if (launchStep === LAUNCH_WIZARD_STEPS.TASK) {
|
|
215
|
+
if (key.return) {
|
|
216
|
+
if (!launchDraft.task.trim()) {
|
|
217
|
+
setError("Task cannot be empty.");
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
setLaunchStep(LAUNCH_WIZARD_STEPS.MODEL);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (key.backspace || key.delete) {
|
|
224
|
+
setLaunchDraft((draft) => ({ ...draft, task: draft.task.slice(0, -1) }));
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (inputKey && inputKey.length === 1 && !key.ctrl && !key.meta) {
|
|
228
|
+
setLaunchDraft((draft) => ({ ...draft, task: `${draft.task}${inputKey}` }));
|
|
229
|
+
}
|
|
230
|
+
return;
|
|
92
231
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
232
|
+
|
|
233
|
+
if (launchStep === LAUNCH_WIZARD_STEPS.MODEL) {
|
|
234
|
+
if (key.return) {
|
|
235
|
+
setLaunchStep(LAUNCH_WIZARD_STEPS.PERMISSIONS);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (key.backspace || key.delete) {
|
|
239
|
+
setLaunchDraft((draft) => ({ ...draft, model: draft.model.slice(0, -1) }));
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (inputKey && inputKey.length === 1 && !key.ctrl && !key.meta) {
|
|
243
|
+
setLaunchDraft((draft) => ({ ...draft, model: `${draft.model}${inputKey}` }));
|
|
244
|
+
}
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (launchStep === LAUNCH_WIZARD_STEPS.PERMISSIONS) {
|
|
249
|
+
if (key.upArrow) {
|
|
250
|
+
setLaunchPermissionIndex((index) => Math.max(0, index - 1));
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
if (key.downArrow) {
|
|
254
|
+
setLaunchPermissionIndex((index) => Math.min(LAUNCH_PERMISSION_OPTIONS.length - 1, index + 1));
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (key.return) {
|
|
258
|
+
setLaunchStep(LAUNCH_WIZARD_STEPS.CONFIRM);
|
|
259
|
+
}
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (launchStep === LAUNCH_WIZARD_STEPS.CONFIRM) {
|
|
264
|
+
if (key.return) {
|
|
265
|
+
handleLaunch({ ...launchDraft, permissionIndex: launchPermissionIndex });
|
|
266
|
+
}
|
|
267
|
+
if (key.escape) {
|
|
268
|
+
setLaunchStep(retreatLaunchWizardStep(launchStep));
|
|
269
|
+
}
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (inputKey.toLowerCase() === "r") {
|
|
274
|
+
reload().catch((reloadError) => {
|
|
275
|
+
setError(reloadError instanceof Error ? reloadError.message : String(reloadError));
|
|
276
|
+
});
|
|
96
277
|
}
|
|
97
278
|
return;
|
|
98
279
|
}
|
|
99
280
|
|
|
100
|
-
if (view
|
|
281
|
+
if (view === ORCHESTRATOR_VIEWS.ACTIVE_RUNS || view === ORCHESTRATOR_VIEWS.RECENT_RUNS) {
|
|
282
|
+
const runs = view === ORCHESTRATOR_VIEWS.ACTIVE_RUNS
|
|
283
|
+
? dashboard?.activeRuns ?? []
|
|
284
|
+
: dashboard?.recentRuns ?? [];
|
|
285
|
+
|
|
286
|
+
if (key.upArrow) {
|
|
287
|
+
setListIndex((index) => Math.max(0, index - 1));
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
if (key.downArrow) {
|
|
291
|
+
setListIndex((index) => Math.min(Math.max(runs.length - 1, 0), index + 1));
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
if (key.return) {
|
|
295
|
+
openRunDetail(selectRunFromList(runs, listIndex));
|
|
296
|
+
}
|
|
297
|
+
if (inputKey.toLowerCase() === "r") {
|
|
298
|
+
reload().catch((reloadError) => {
|
|
299
|
+
setError(reloadError instanceof Error ? reloadError.message : String(reloadError));
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (view === ORCHESTRATOR_VIEWS.RUN_DETAIL) {
|
|
306
|
+
if (inputKey.toLowerCase() === "c" && isRunCancellable(selectedRun)) {
|
|
307
|
+
handleCancelRun();
|
|
308
|
+
}
|
|
309
|
+
if (inputKey.toLowerCase() === "r") {
|
|
310
|
+
openRunDetail(selectedRun);
|
|
311
|
+
}
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (view !== ORCHESTRATOR_VIEWS.HOME) {
|
|
316
|
+
if (inputKey.toLowerCase() === "r") {
|
|
317
|
+
reload().catch((reloadError) => {
|
|
318
|
+
setError(reloadError instanceof Error ? reloadError.message : String(reloadError));
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
101
323
|
|
|
102
324
|
if (key.upArrow) {
|
|
103
325
|
setMenuIndex((index) => shiftMenuIndex(index, "up"));
|
|
@@ -112,55 +334,73 @@ export function OrchestratorApp({
|
|
|
112
334
|
if (!key.return) return;
|
|
113
335
|
|
|
114
336
|
const item = resolveMenuItem(menuIndex);
|
|
115
|
-
if (item?.action === "
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
homeDir,
|
|
119
|
-
workspaceRoot,
|
|
120
|
-
packageName,
|
|
121
|
-
options: { packageRoot, cliVersion }
|
|
122
|
-
}).then((builtPlan) => {
|
|
123
|
-
setPlan(builtPlan);
|
|
124
|
-
setView(ORCHESTRATOR_VIEWS.CONFIRM);
|
|
125
|
-
}).catch((planError) => {
|
|
126
|
-
setError(planError instanceof Error ? planError.message : String(planError));
|
|
127
|
-
});
|
|
337
|
+
if (item?.action === "launch") {
|
|
338
|
+
resetLaunchWizard();
|
|
339
|
+
setView(ORCHESTRATOR_VIEWS.LAUNCH);
|
|
128
340
|
return;
|
|
129
341
|
}
|
|
130
342
|
|
|
131
343
|
setView(resolveMenuItemView(menuIndex));
|
|
344
|
+
setListIndex(0);
|
|
132
345
|
});
|
|
133
346
|
|
|
134
347
|
if (loading) {
|
|
135
348
|
return React.createElement(Box, { flexDirection: "column" },
|
|
136
349
|
React.createElement(Text, { bold: true, color: COLORS.accent }, BRAND.displayName),
|
|
137
|
-
React.createElement(Text, { color: COLORS.muted }, "Loading
|
|
350
|
+
React.createElement(Text, { color: COLORS.muted }, "Loading runtime dashboard…")
|
|
138
351
|
);
|
|
139
352
|
}
|
|
140
353
|
|
|
141
354
|
if (error) {
|
|
142
355
|
return React.createElement(Box, { flexDirection: "column" },
|
|
143
|
-
React.createElement(Text, { bold: true, color: COLORS.danger }, "
|
|
356
|
+
React.createElement(Text, { bold: true, color: COLORS.danger }, "Runtime error"),
|
|
144
357
|
React.createElement(Text, null, error),
|
|
145
358
|
React.createElement(Text, { dimColor: true }, "Esc to exit")
|
|
146
359
|
);
|
|
147
360
|
}
|
|
148
361
|
|
|
149
362
|
return React.createElement(Box, { flexDirection: "column" },
|
|
150
|
-
React.createElement(Text, { bold: true, color: COLORS.accent }, `${BRAND.displayName}
|
|
151
|
-
React.createElement(Text, { color: COLORS.muted }, "
|
|
363
|
+
React.createElement(Text, { bold: true, color: COLORS.accent }, `${BRAND.displayName} runtime`),
|
|
364
|
+
React.createElement(Text, { color: COLORS.muted }, "Launch · supervise · audit agent runs"),
|
|
365
|
+
statusMessage && React.createElement(Text, { color: COLORS.success }, statusMessage),
|
|
152
366
|
React.createElement(Text, null, ""),
|
|
153
|
-
renderView({
|
|
367
|
+
renderView({
|
|
368
|
+
view,
|
|
369
|
+
dashboard,
|
|
370
|
+
diagnostics,
|
|
371
|
+
menuIndex,
|
|
372
|
+
listIndex,
|
|
373
|
+
launchStep,
|
|
374
|
+
launchDraft,
|
|
375
|
+
launchAgentIndex,
|
|
376
|
+
launchPermissionIndex,
|
|
377
|
+
launchableAgents,
|
|
378
|
+
selectedRun,
|
|
379
|
+
selectedEvents
|
|
380
|
+
}),
|
|
154
381
|
React.createElement(Text, null, ""),
|
|
155
|
-
React.createElement(Text, { dimColor: true }, footerHint(view))
|
|
382
|
+
React.createElement(Text, { dimColor: true }, footerHint(view, selectedRun, launchStep))
|
|
156
383
|
);
|
|
157
384
|
}
|
|
158
385
|
|
|
159
|
-
function renderView({
|
|
386
|
+
function renderView({
|
|
387
|
+
view,
|
|
388
|
+
dashboard,
|
|
389
|
+
diagnostics,
|
|
390
|
+
menuIndex,
|
|
391
|
+
listIndex,
|
|
392
|
+
launchStep,
|
|
393
|
+
launchDraft,
|
|
394
|
+
launchAgentIndex,
|
|
395
|
+
launchPermissionIndex,
|
|
396
|
+
launchableAgents,
|
|
397
|
+
selectedRun,
|
|
398
|
+
selectedEvents
|
|
399
|
+
}) {
|
|
160
400
|
switch (view) {
|
|
161
401
|
case ORCHESTRATOR_VIEWS.HOME:
|
|
162
402
|
return React.createElement(Box, { flexDirection: "column" },
|
|
163
|
-
React.createElement(Text, { bold: true }, "
|
|
403
|
+
React.createElement(Text, { bold: true }, "Operations"),
|
|
164
404
|
ORCHESTRATOR_MENU.map((item, index) =>
|
|
165
405
|
React.createElement(Text, {
|
|
166
406
|
key: item.id,
|
|
@@ -170,55 +410,74 @@ function renderView({ view, diagnostics, profileJson, plan, menuIndex }) {
|
|
|
170
410
|
),
|
|
171
411
|
React.createElement(Text, null, ""),
|
|
172
412
|
React.createElement(Text, { bold: true }, "Snapshot"),
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
diagnostics.intelligence && React.createElement(
|
|
176
|
-
Text,
|
|
177
|
-
null,
|
|
178
|
-
`Intelligence: local=${diagnostics.intelligence.summary.localAvailable ? "yes" : "no"} cloud=${diagnostics.intelligence.summary.cloudAuthenticated ? "yes" : "no"}`
|
|
179
|
-
)
|
|
413
|
+
formatDashboardSnapshot(dashboard)
|
|
414
|
+
.map((line) => React.createElement(Text, { key: line }, line))
|
|
180
415
|
);
|
|
181
|
-
case ORCHESTRATOR_VIEWS.
|
|
416
|
+
case ORCHESTRATOR_VIEWS.ACTIVE_RUNS:
|
|
182
417
|
return React.createElement(Box, { flexDirection: "column" },
|
|
183
|
-
React.createElement(Text, { bold: true }, "
|
|
184
|
-
|
|
185
|
-
.map((line) => React.createElement(Text, {
|
|
418
|
+
React.createElement(Text, { bold: true }, "Active runs"),
|
|
419
|
+
formatRunLines(dashboard?.activeRuns ?? [], { emptyMessage: "No active runs." })
|
|
420
|
+
.map((line, index) => React.createElement(Text, {
|
|
421
|
+
key: line,
|
|
422
|
+
color: index === listIndex ? COLORS.accent : undefined,
|
|
423
|
+
bold: index === listIndex
|
|
424
|
+
}, `${index === listIndex ? "› " : " "}${line}`))
|
|
425
|
+
);
|
|
426
|
+
case ORCHESTRATOR_VIEWS.RECENT_RUNS:
|
|
427
|
+
return React.createElement(Box, { flexDirection: "column" },
|
|
428
|
+
React.createElement(Text, { bold: true }, "Recent runs"),
|
|
429
|
+
formatRunLines(dashboard?.recentRuns ?? [], { emptyMessage: "No completed runs yet." })
|
|
430
|
+
.map((line, index) => React.createElement(Text, {
|
|
431
|
+
key: line,
|
|
432
|
+
color: index === listIndex ? COLORS.accent : undefined,
|
|
433
|
+
bold: index === listIndex
|
|
434
|
+
}, `${index === listIndex ? "› " : " "}${line}`))
|
|
186
435
|
);
|
|
187
|
-
case ORCHESTRATOR_VIEWS.
|
|
436
|
+
case ORCHESTRATOR_VIEWS.PROVIDERS:
|
|
188
437
|
return React.createElement(Box, { flexDirection: "column" },
|
|
189
|
-
React.createElement(Text, { bold: true }, "
|
|
190
|
-
|
|
438
|
+
React.createElement(Text, { bold: true }, "Providers"),
|
|
439
|
+
formatProviderLines(dashboard?.providers ?? [])
|
|
191
440
|
.map((line) => React.createElement(Text, { key: line }, line))
|
|
192
441
|
);
|
|
193
|
-
case ORCHESTRATOR_VIEWS.
|
|
442
|
+
case ORCHESTRATOR_VIEWS.LAUNCH:
|
|
443
|
+
if (launchableAgents.length === 0) {
|
|
444
|
+
return React.createElement(Box, { flexDirection: "column" },
|
|
445
|
+
React.createElement(Text, { bold: true }, "Launch run"),
|
|
446
|
+
React.createElement(Text, { color: COLORS.warning }, "No launchable agents detected."),
|
|
447
|
+
React.createElement(Text, { dimColor: true }, "Esc to return")
|
|
448
|
+
);
|
|
449
|
+
}
|
|
194
450
|
return React.createElement(Box, { flexDirection: "column" },
|
|
195
|
-
React.createElement(Text, { bold: true }, "
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
451
|
+
React.createElement(Text, { bold: true }, "Launch run"),
|
|
452
|
+
formatLaunchWizardLines({
|
|
453
|
+
step: launchStep,
|
|
454
|
+
draft: launchDraft,
|
|
455
|
+
launchableAgents,
|
|
456
|
+
agentIndex: launchAgentIndex,
|
|
457
|
+
permissionIndex: launchPermissionIndex
|
|
458
|
+
}).map((line) => React.createElement(Text, { key: line, color: line.startsWith("›") ? COLORS.accent : undefined }, line))
|
|
200
459
|
);
|
|
201
|
-
case ORCHESTRATOR_VIEWS.
|
|
460
|
+
case ORCHESTRATOR_VIEWS.RUN_DETAIL:
|
|
202
461
|
return React.createElement(Box, { flexDirection: "column" },
|
|
203
|
-
React.createElement(Text, { bold: true }, "
|
|
204
|
-
|
|
462
|
+
React.createElement(Text, { bold: true }, "Run detail"),
|
|
463
|
+
formatRunDetailLines(selectedRun, selectedEvents)
|
|
205
464
|
.map((line) => React.createElement(Text, { key: line }, line))
|
|
206
465
|
);
|
|
207
|
-
case ORCHESTRATOR_VIEWS.
|
|
208
|
-
case ORCHESTRATOR_VIEWS.CONFIRM:
|
|
466
|
+
case ORCHESTRATOR_VIEWS.DIAGNOSTICS:
|
|
209
467
|
return React.createElement(Box, { flexDirection: "column" },
|
|
210
|
-
React.createElement(Text, { bold: true },
|
|
211
|
-
|
|
212
|
-
|
|
468
|
+
React.createElement(Text, { bold: true }, "Diagnostics"),
|
|
469
|
+
formatDiagnosticsLines(diagnostics)
|
|
470
|
+
.map((line) => React.createElement(Text, { key: line }, line))
|
|
213
471
|
);
|
|
214
472
|
case ORCHESTRATOR_VIEWS.HELP:
|
|
215
473
|
return React.createElement(Box, { flexDirection: "column" },
|
|
216
474
|
React.createElement(Text, { bold: true }, "Help"),
|
|
217
|
-
React.createElement(Text, null, "Kairo
|
|
218
|
-
React.createElement(Text, null, "
|
|
219
|
-
React.createElement(Text, null, "
|
|
220
|
-
React.createElement(Text, null, "
|
|
221
|
-
React.createElement(Text, null, "
|
|
475
|
+
React.createElement(Text, null, "Kairo runtime launches and audits agent CLIs you manage."),
|
|
476
|
+
React.createElement(Text, null, "CLI: kairo run --agent <id> --task \"...\""),
|
|
477
|
+
React.createElement(Text, null, "CLI: kairo runs list|show|stop"),
|
|
478
|
+
React.createElement(Text, null, "Audit trail: ~/.harness/runs/<runId>/"),
|
|
479
|
+
React.createElement(Text, null, "Transcripts are opt-in via --capture-transcript."),
|
|
480
|
+
React.createElement(Text, null, "Credentials stay in environment variables — never in profiles.")
|
|
222
481
|
);
|
|
223
482
|
default: {
|
|
224
483
|
const _exhaustive = view;
|
|
@@ -227,8 +486,23 @@ function renderView({ view, diagnostics, profileJson, plan, menuIndex }) {
|
|
|
227
486
|
}
|
|
228
487
|
}
|
|
229
488
|
|
|
230
|
-
function footerHint(view) {
|
|
489
|
+
function footerHint(view, selectedRun, launchStep) {
|
|
231
490
|
if (view === ORCHESTRATOR_VIEWS.HOME) return "↑↓ navigate · Enter select · Esc quit";
|
|
232
|
-
if (view === ORCHESTRATOR_VIEWS.
|
|
233
|
-
|
|
491
|
+
if (view === ORCHESTRATOR_VIEWS.ACTIVE_RUNS || view === ORCHESTRATOR_VIEWS.RECENT_RUNS) {
|
|
492
|
+
return "↑↓ select run · Enter inspect · R refresh · Esc menu";
|
|
493
|
+
}
|
|
494
|
+
if (view === ORCHESTRATOR_VIEWS.LAUNCH) {
|
|
495
|
+
if (launchStep === LAUNCH_WIZARD_STEPS.TASK || launchStep === LAUNCH_WIZARD_STEPS.MODEL) {
|
|
496
|
+
return "Type · Enter next · Esc menu";
|
|
497
|
+
}
|
|
498
|
+
if (launchStep === LAUNCH_WIZARD_STEPS.CONFIRM) {
|
|
499
|
+
return "Enter launch · Esc back · R refresh";
|
|
500
|
+
}
|
|
501
|
+
return "↑↓ navigate · Enter select · Esc menu";
|
|
502
|
+
}
|
|
503
|
+
if (view === ORCHESTRATOR_VIEWS.RUN_DETAIL) {
|
|
504
|
+
if (isRunCancellable(selectedRun)) return "C cancel · R refresh · Esc menu";
|
|
505
|
+
return "R refresh · Esc menu";
|
|
506
|
+
}
|
|
507
|
+
return "R refresh · Esc menu";
|
|
234
508
|
}
|