-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.ts
More file actions
executable file
·82 lines (67 loc) · 2.73 KB
/
Copy pathindex.ts
File metadata and controls
executable file
·82 lines (67 loc) · 2.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/env bun
import { createShell } from "./src/ui/shell.ts";
import { runOrchestrator } from "./src/orchestrator.ts";
import { showWelcomeScreen } from "./src/ui/welcome.ts";
import { createLog } from "./src/ui/log.ts";
import { createSession, findIncompleteSessionById, findIncompleteSessionByPrompt, listIncompleteSessions, type SessionSummary } from "./src/session.ts";
const cwd = process.cwd();
const args = process.argv.slice(2);
let prompt = "";
let existingSession: SessionSummary | null = null;
if (args[0] === "resume") {
existingSession = args[1]
? await findIncompleteSessionById(cwd, args[1])
: await selectIncompleteSession(cwd);
if (!existingSession) {
process.stderr.write("fatal: no matching incomplete order\n");
process.exit(1);
}
prompt = existingSession.state.prompt;
} else {
prompt = args.join(" ").trim();
if (!prompt) prompt = await showWelcomeScreen(cwd);
existingSession = await confirmMatchingResume(cwd, prompt);
}
const shell = await createShell();
const session = await createSession(prompt, cwd, existingSession ?? undefined);
try {
await runOrchestrator(prompt, cwd, shell, session);
} catch (err) {
shell.destroy();
process.stderr.write(`fatal: ${err instanceof Error ? err.message : String(err)}\n`);
process.exit(1);
}
async function confirmMatchingResume(cwd: string, prompt: string): Promise<SessionSummary | null> {
const session = await findIncompleteSessionByPrompt(cwd, prompt);
if (!session) return null;
const shell = await createShell();
const log = createLog(shell);
shell.setHeader("resume order", "order");
const [answer] = await log.promptSelect(
`resume ${session.orderId}?`,
[
{ label: "resume", description: previewPrompt(session.state.prompt) },
{ label: "start new", description: "leave the existing order untouched" },
],
false,
);
shell.destroy();
return answer === "resume" ? session : null;
}
async function selectIncompleteSession(cwd: string): Promise<SessionSummary | null> {
const sessions = await listIncompleteSessions(cwd);
if (sessions.length === 0) return null;
const shell = await createShell();
const log = createLog(shell);
shell.setHeader("resume order", "order");
const options = sessions.map((session) => ({
label: session.orderId,
description: `${session.state.completedTaskIds.length}/${session.state.planner?.tasks.length ?? 0} tasks · ${previewPrompt(session.state.prompt)}`,
}));
const [selected] = await log.promptSelect("choose an incomplete order", options, false);
shell.destroy();
return sessions.find((session) => session.orderId === selected) ?? null;
}
function previewPrompt(prompt: string): string {
return prompt.length <= 80 ? prompt : `${prompt.slice(0, 79)}…`;
}