@kal-elsam/kairo-runtime 0.2.0 → 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 +365 -81
- package/src/global/ink/orchestrator-state.js +233 -60
- 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,15 +1,31 @@
|
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
LAUNCH_WIZARD_STEPS,
|
|
13
|
+
LAUNCH_PERMISSION_OPTIONS,
|
|
14
|
+
createLaunchDraft,
|
|
15
|
+
formatDashboardSnapshot,
|
|
16
|
+
formatDiagnosticsLines,
|
|
17
|
+
formatLaunchWizardLines,
|
|
18
|
+
formatProviderLines,
|
|
19
|
+
formatRunDetailLines,
|
|
20
|
+
formatRunLines,
|
|
21
|
+
isRunCancellable,
|
|
22
|
+
resolveLaunchPermissions,
|
|
23
|
+
resolveLaunchableAgents,
|
|
24
|
+
resolveMenuItem,
|
|
25
|
+
resolveMenuItemView,
|
|
26
|
+
retreatLaunchWizardStep,
|
|
27
|
+
selectRunFromList,
|
|
28
|
+
shiftMenuIndex
|
|
13
29
|
} from "./orchestrator-state.js";
|
|
14
30
|
|
|
15
31
|
const COLORS = {
|
|
@@ -31,25 +47,36 @@ export function OrchestratorApp({
|
|
|
31
47
|
const { exit } = useApp();
|
|
32
48
|
const [view, setView] = useState(ORCHESTRATOR_VIEWS.HOME);
|
|
33
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);
|
|
34
55
|
const [loading, setLoading] = useState(true);
|
|
56
|
+
const [busy, setBusy] = useState(false);
|
|
35
57
|
const [error, setError] = useState(null);
|
|
58
|
+
const [dashboard, setDashboard] = useState(null);
|
|
36
59
|
const [diagnostics, setDiagnostics] = useState(null);
|
|
37
|
-
const [
|
|
38
|
-
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
|
+
};
|
|
39
72
|
|
|
40
73
|
useEffect(() => {
|
|
41
74
|
let cancelled = false;
|
|
42
75
|
|
|
43
76
|
async function load() {
|
|
44
77
|
try {
|
|
45
|
-
|
|
46
|
-
buildReadOnlyDiagnostics({ homeDir, workspaceRoot, packageName, packageRoot, cliVersion }),
|
|
47
|
-
resolveProfile({ homeDir, workspaceRoot })
|
|
48
|
-
]);
|
|
49
|
-
|
|
78
|
+
await reload();
|
|
50
79
|
if (cancelled) return;
|
|
51
|
-
setDiagnostics(diag);
|
|
52
|
-
setProfileJson(buildProfileJson(profileResolved));
|
|
53
80
|
setLoading(false);
|
|
54
81
|
} catch (loadError) {
|
|
55
82
|
if (cancelled) return;
|
|
@@ -69,6 +96,81 @@ export function OrchestratorApp({
|
|
|
69
96
|
exit();
|
|
70
97
|
};
|
|
71
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
|
+
|
|
72
174
|
useInput((inputKey, key) => {
|
|
73
175
|
if (key.escape) {
|
|
74
176
|
if (view === ORCHESTRATOR_VIEWS.HOME) {
|
|
@@ -76,87 +178,229 @@ export function OrchestratorApp({
|
|
|
76
178
|
return;
|
|
77
179
|
}
|
|
78
180
|
setView(ORCHESTRATOR_VIEWS.HOME);
|
|
79
|
-
|
|
181
|
+
setSelectedRun(null);
|
|
182
|
+
setListIndex(0);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
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
|
+
}
|
|
213
|
+
|
|
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;
|
|
231
|
+
}
|
|
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
|
+
});
|
|
277
|
+
}
|
|
80
278
|
return;
|
|
81
279
|
}
|
|
82
280
|
|
|
83
|
-
if (
|
|
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
|
+
}
|
|
84
304
|
|
|
85
|
-
if (view === ORCHESTRATOR_VIEWS.
|
|
86
|
-
if (inputKey.toLowerCase() === "
|
|
87
|
-
|
|
305
|
+
if (view === ORCHESTRATOR_VIEWS.RUN_DETAIL) {
|
|
306
|
+
if (inputKey.toLowerCase() === "c" && isRunCancellable(selectedRun)) {
|
|
307
|
+
handleCancelRun();
|
|
88
308
|
}
|
|
89
|
-
if (inputKey.toLowerCase() === "
|
|
90
|
-
|
|
91
|
-
setPlan(null);
|
|
309
|
+
if (inputKey.toLowerCase() === "r") {
|
|
310
|
+
openRunDetail(selectedRun);
|
|
92
311
|
}
|
|
93
312
|
return;
|
|
94
313
|
}
|
|
95
314
|
|
|
96
|
-
if (view !== ORCHESTRATOR_VIEWS.HOME)
|
|
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
|
+
}
|
|
97
323
|
|
|
98
324
|
if (key.upArrow) {
|
|
99
|
-
setMenuIndex((index) =>
|
|
325
|
+
setMenuIndex((index) => shiftMenuIndex(index, "up"));
|
|
100
326
|
return;
|
|
101
327
|
}
|
|
102
328
|
|
|
103
329
|
if (key.downArrow) {
|
|
104
|
-
setMenuIndex((index) =>
|
|
330
|
+
setMenuIndex((index) => shiftMenuIndex(index, "down"));
|
|
105
331
|
return;
|
|
106
332
|
}
|
|
107
333
|
|
|
108
334
|
if (!key.return) return;
|
|
109
335
|
|
|
110
|
-
const item =
|
|
111
|
-
if (item
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
homeDir,
|
|
115
|
-
workspaceRoot,
|
|
116
|
-
packageName,
|
|
117
|
-
options: { packageRoot, cliVersion }
|
|
118
|
-
}).then((builtPlan) => {
|
|
119
|
-
setPlan(builtPlan);
|
|
120
|
-
setView(ORCHESTRATOR_VIEWS.CONFIRM);
|
|
121
|
-
}).catch((planError) => {
|
|
122
|
-
setError(planError instanceof Error ? planError.message : String(planError));
|
|
123
|
-
});
|
|
336
|
+
const item = resolveMenuItem(menuIndex);
|
|
337
|
+
if (item?.action === "launch") {
|
|
338
|
+
resetLaunchWizard();
|
|
339
|
+
setView(ORCHESTRATOR_VIEWS.LAUNCH);
|
|
124
340
|
return;
|
|
125
341
|
}
|
|
126
342
|
|
|
127
|
-
setView(
|
|
343
|
+
setView(resolveMenuItemView(menuIndex));
|
|
344
|
+
setListIndex(0);
|
|
128
345
|
});
|
|
129
346
|
|
|
130
347
|
if (loading) {
|
|
131
348
|
return React.createElement(Box, { flexDirection: "column" },
|
|
132
349
|
React.createElement(Text, { bold: true, color: COLORS.accent }, BRAND.displayName),
|
|
133
|
-
React.createElement(Text, { color: COLORS.muted }, "Loading
|
|
350
|
+
React.createElement(Text, { color: COLORS.muted }, "Loading runtime dashboard…")
|
|
134
351
|
);
|
|
135
352
|
}
|
|
136
353
|
|
|
137
354
|
if (error) {
|
|
138
355
|
return React.createElement(Box, { flexDirection: "column" },
|
|
139
|
-
React.createElement(Text, { bold: true, color: COLORS.danger }, "
|
|
356
|
+
React.createElement(Text, { bold: true, color: COLORS.danger }, "Runtime error"),
|
|
140
357
|
React.createElement(Text, null, error),
|
|
141
358
|
React.createElement(Text, { dimColor: true }, "Esc to exit")
|
|
142
359
|
);
|
|
143
360
|
}
|
|
144
361
|
|
|
145
362
|
return React.createElement(Box, { flexDirection: "column" },
|
|
146
|
-
React.createElement(Text, { bold: true, color: COLORS.accent }, `${BRAND.displayName}
|
|
147
|
-
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),
|
|
148
366
|
React.createElement(Text, null, ""),
|
|
149
|
-
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
|
+
}),
|
|
150
381
|
React.createElement(Text, null, ""),
|
|
151
|
-
React.createElement(Text, { dimColor: true }, footerHint(view))
|
|
382
|
+
React.createElement(Text, { dimColor: true }, footerHint(view, selectedRun, launchStep))
|
|
152
383
|
);
|
|
153
384
|
}
|
|
154
385
|
|
|
155
|
-
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
|
+
}) {
|
|
156
400
|
switch (view) {
|
|
157
401
|
case ORCHESTRATOR_VIEWS.HOME:
|
|
158
402
|
return React.createElement(Box, { flexDirection: "column" },
|
|
159
|
-
React.createElement(Text, { bold: true }, "
|
|
403
|
+
React.createElement(Text, { bold: true }, "Operations"),
|
|
160
404
|
ORCHESTRATOR_MENU.map((item, index) =>
|
|
161
405
|
React.createElement(Text, {
|
|
162
406
|
key: item.id,
|
|
@@ -166,49 +410,74 @@ function renderView({ view, diagnostics, profileJson, plan, menuIndex }) {
|
|
|
166
410
|
),
|
|
167
411
|
React.createElement(Text, null, ""),
|
|
168
412
|
React.createElement(Text, { bold: true }, "Snapshot"),
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
)
|
|
413
|
+
formatDashboardSnapshot(dashboard)
|
|
414
|
+
.map((line) => React.createElement(Text, { key: line }, line))
|
|
415
|
+
);
|
|
416
|
+
case ORCHESTRATOR_VIEWS.ACTIVE_RUNS:
|
|
417
|
+
return React.createElement(Box, { flexDirection: "column" },
|
|
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}`))
|
|
176
435
|
);
|
|
177
|
-
case ORCHESTRATOR_VIEWS.
|
|
436
|
+
case ORCHESTRATOR_VIEWS.PROVIDERS:
|
|
178
437
|
return React.createElement(Box, { flexDirection: "column" },
|
|
179
|
-
React.createElement(Text, { bold: true }, "
|
|
180
|
-
|
|
438
|
+
React.createElement(Text, { bold: true }, "Providers"),
|
|
439
|
+
formatProviderLines(dashboard?.providers ?? [])
|
|
181
440
|
.map((line) => React.createElement(Text, { key: line }, line))
|
|
182
441
|
);
|
|
183
|
-
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
|
+
}
|
|
184
450
|
return React.createElement(Box, { flexDirection: "column" },
|
|
185
|
-
React.createElement(Text, { bold: true }, "
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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))
|
|
190
459
|
);
|
|
191
|
-
case ORCHESTRATOR_VIEWS.
|
|
460
|
+
case ORCHESTRATOR_VIEWS.RUN_DETAIL:
|
|
192
461
|
return React.createElement(Box, { flexDirection: "column" },
|
|
193
|
-
React.createElement(Text, { bold: true }, "
|
|
194
|
-
|
|
462
|
+
React.createElement(Text, { bold: true }, "Run detail"),
|
|
463
|
+
formatRunDetailLines(selectedRun, selectedEvents)
|
|
195
464
|
.map((line) => React.createElement(Text, { key: line }, line))
|
|
196
465
|
);
|
|
197
|
-
case ORCHESTRATOR_VIEWS.
|
|
198
|
-
case ORCHESTRATOR_VIEWS.CONFIRM:
|
|
466
|
+
case ORCHESTRATOR_VIEWS.DIAGNOSTICS:
|
|
199
467
|
return React.createElement(Box, { flexDirection: "column" },
|
|
200
|
-
React.createElement(Text, { bold: true },
|
|
201
|
-
|
|
202
|
-
|
|
468
|
+
React.createElement(Text, { bold: true }, "Diagnostics"),
|
|
469
|
+
formatDiagnosticsLines(diagnostics)
|
|
470
|
+
.map((line) => React.createElement(Text, { key: line }, line))
|
|
203
471
|
);
|
|
204
472
|
case ORCHESTRATOR_VIEWS.HELP:
|
|
205
473
|
return React.createElement(Box, { flexDirection: "column" },
|
|
206
474
|
React.createElement(Text, { bold: true }, "Help"),
|
|
207
|
-
React.createElement(Text, null, "Kairo
|
|
208
|
-
React.createElement(Text, null, "
|
|
209
|
-
React.createElement(Text, null, "
|
|
210
|
-
React.createElement(Text, null, "
|
|
211
|
-
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.")
|
|
212
481
|
);
|
|
213
482
|
default: {
|
|
214
483
|
const _exhaustive = view;
|
|
@@ -217,8 +486,23 @@ function renderView({ view, diagnostics, profileJson, plan, menuIndex }) {
|
|
|
217
486
|
}
|
|
218
487
|
}
|
|
219
488
|
|
|
220
|
-
function footerHint(view) {
|
|
489
|
+
function footerHint(view, selectedRun, launchStep) {
|
|
221
490
|
if (view === ORCHESTRATOR_VIEWS.HOME) return "↑↓ navigate · Enter select · Esc quit";
|
|
222
|
-
if (view === ORCHESTRATOR_VIEWS.
|
|
223
|
-
|
|
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";
|
|
224
508
|
}
|