@kurtel/cli 0.1.6 → 0.1.8
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/dist/commands/run.js +7 -2
- package/dist/session/repl.js +55 -9
- package/package.json +1 -1
package/dist/commands/run.js
CHANGED
|
@@ -5,12 +5,12 @@ export async function runCommand(task, opts) {
|
|
|
5
5
|
if (!task || task.trim() === "") {
|
|
6
6
|
console.log(`${c.red(symbols.cross)} Provide a task, e.g. ${c.indigo('kurtel run "fix the flaky auth test"')}`);
|
|
7
7
|
process.exitCode = 1;
|
|
8
|
-
return;
|
|
8
|
+
return undefined;
|
|
9
9
|
}
|
|
10
10
|
if (opts.engine && !isEngineName(opts.engine)) {
|
|
11
11
|
console.log(`${c.red(symbols.cross)} Unknown engine ${c.white(opts.engine)}. Use ${c.indigo("claude-code")} or ${c.indigo("codex")}.`);
|
|
12
12
|
process.exitCode = 1;
|
|
13
|
-
return;
|
|
13
|
+
return undefined;
|
|
14
14
|
}
|
|
15
15
|
try {
|
|
16
16
|
const run = await createRun({
|
|
@@ -18,16 +18,20 @@ export async function runCommand(task, opts) {
|
|
|
18
18
|
repo: opts.repo,
|
|
19
19
|
branch: opts.branch,
|
|
20
20
|
engine: opts.engine,
|
|
21
|
+
model: opts.model,
|
|
21
22
|
});
|
|
22
23
|
console.log("");
|
|
23
24
|
console.log(`${symbols.check} Launched ${c.indigo(run.id)}`);
|
|
24
25
|
console.log(`${c.gray("task")} ${c.white(run.task)}`);
|
|
25
26
|
console.log(`${c.gray("engine")} ${c.white(run.engine)}`);
|
|
27
|
+
if (run.model)
|
|
28
|
+
console.log(`${c.gray("model")} ${c.white(run.model)}`);
|
|
26
29
|
if (run.repo)
|
|
27
30
|
console.log(`${c.gray("repo")} ${c.white(run.repo)}`);
|
|
28
31
|
console.log(`${c.gray("status")} ${c.indigo(run.status)}`);
|
|
29
32
|
console.log("");
|
|
30
33
|
console.log(`${c.dim("Follow it with")} ${c.indigo(`kurtel logs ${run.id} --follow`)}`);
|
|
34
|
+
return run.id;
|
|
31
35
|
}
|
|
32
36
|
catch (e) {
|
|
33
37
|
if (e instanceof AuthError) {
|
|
@@ -37,5 +41,6 @@ export async function runCommand(task, opts) {
|
|
|
37
41
|
console.log(`${c.red(symbols.cross)} Failed to launch: ${e instanceof Error ? e.message : String(e)}`);
|
|
38
42
|
}
|
|
39
43
|
process.exitCode = 1;
|
|
44
|
+
return undefined;
|
|
40
45
|
}
|
|
41
46
|
}
|
package/dist/session/repl.js
CHANGED
|
@@ -6,15 +6,24 @@ import { agentsCommand } from "../commands/agents.js";
|
|
|
6
6
|
import { loginCommand } from "../commands/auth.js";
|
|
7
7
|
import { configCommand } from "../commands/config.js";
|
|
8
8
|
import { runCommand } from "../commands/run.js";
|
|
9
|
+
import { runsCommand } from "../commands/runs.js";
|
|
10
|
+
import { logsCommand, statusCommand, stopCommand } from "../commands/runtime.js";
|
|
9
11
|
const SLASH_COMMANDS = [
|
|
10
12
|
["/help", "Show this help"],
|
|
11
13
|
["/run <task>", "Launch a cloud agent on a task"],
|
|
14
|
+
["/runs", "List your recent runs"],
|
|
15
|
+
["/logs [id]", "Stream a run's logs (defaults to the last one)"],
|
|
16
|
+
["/status [id]", "Show a run's status & result"],
|
|
17
|
+
["/stop [id]", "Cancel a run and tear down its sandbox"],
|
|
12
18
|
["/agents", "List active agents"],
|
|
13
19
|
["/login", "Sign in to Kurtel"],
|
|
14
20
|
["/config", "Show local configuration"],
|
|
15
21
|
["/clear", "Clear the screen"],
|
|
16
22
|
["/exit", "Quit the session"],
|
|
17
23
|
];
|
|
24
|
+
// Remember the most recently launched run so `/logs` and `/status` can default
|
|
25
|
+
// to it without making the user paste an id.
|
|
26
|
+
let lastRunId = null;
|
|
18
27
|
function prompt() {
|
|
19
28
|
return `${c.indigo("kurtel")} ${c.indigo(symbols.arrow)} `;
|
|
20
29
|
}
|
|
@@ -28,16 +37,12 @@ function printHelp() {
|
|
|
28
37
|
console.log(c.dim("Anything else you type is treated as a task and launches an agent."));
|
|
29
38
|
console.log("");
|
|
30
39
|
}
|
|
31
|
-
// While we're collecting answers via rl.question, the main "line" handler must
|
|
32
|
-
// stand down so it doesn't re-interpret the answers as new commands.
|
|
33
40
|
let asking = false;
|
|
34
41
|
function ask(rl, query) {
|
|
35
42
|
return new Promise((resolve) => {
|
|
36
43
|
rl.question(query, (answer) => resolve(answer.trim()));
|
|
37
44
|
});
|
|
38
45
|
}
|
|
39
|
-
// Interactive launch: ask for repo / branch / engine / model (with sensible
|
|
40
|
-
// defaults from local config), then hand off to the real run command.
|
|
41
46
|
async function launchFromPrompt(rl, task) {
|
|
42
47
|
const cfg = loadConfig();
|
|
43
48
|
const defBranch = cfg.defaultBranch || "main";
|
|
@@ -59,12 +64,24 @@ async function launchFromPrompt(rl, task) {
|
|
|
59
64
|
finally {
|
|
60
65
|
asking = false;
|
|
61
66
|
}
|
|
62
|
-
await runCommand(task, {
|
|
67
|
+
const id = await runCommand(task, {
|
|
63
68
|
repo: repo || undefined,
|
|
64
69
|
branch,
|
|
65
70
|
engine,
|
|
66
71
|
model: model || undefined,
|
|
67
72
|
});
|
|
73
|
+
if (id) {
|
|
74
|
+
lastRunId = id;
|
|
75
|
+
console.log(`${c.dim("In here:")} ${c.indigo("/logs")} ${c.dim("to watch ·")} ${c.indigo("/runs")} ${c.dim("to list")}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function resolveId(arg) {
|
|
79
|
+
if (arg)
|
|
80
|
+
return arg;
|
|
81
|
+
if (lastRunId)
|
|
82
|
+
return lastRunId;
|
|
83
|
+
console.log(`${c.red(symbols.cross)} No run id given and no recent run. Try ${c.indigo("/runs")}.`);
|
|
84
|
+
return null;
|
|
68
85
|
}
|
|
69
86
|
export async function startSession(model) {
|
|
70
87
|
console.log(banner());
|
|
@@ -81,7 +98,6 @@ export async function startSession(model) {
|
|
|
81
98
|
});
|
|
82
99
|
rl.prompt();
|
|
83
100
|
rl.on("line", async (input) => {
|
|
84
|
-
// Standing down while collecting answers to /run questions.
|
|
85
101
|
if (asking)
|
|
86
102
|
return;
|
|
87
103
|
const line = input.trim();
|
|
@@ -106,6 +122,39 @@ export async function startSession(model) {
|
|
|
106
122
|
console.clear();
|
|
107
123
|
console.log(banner());
|
|
108
124
|
break;
|
|
125
|
+
case "runs":
|
|
126
|
+
case "ls":
|
|
127
|
+
rl.pause();
|
|
128
|
+
await runsCommand();
|
|
129
|
+
rl.resume();
|
|
130
|
+
break;
|
|
131
|
+
case "logs": {
|
|
132
|
+
const id = resolveId(arg);
|
|
133
|
+
if (id) {
|
|
134
|
+
rl.pause();
|
|
135
|
+
await logsCommand(id, { follow: true });
|
|
136
|
+
rl.resume();
|
|
137
|
+
}
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
case "status": {
|
|
141
|
+
const id = resolveId(arg);
|
|
142
|
+
if (id) {
|
|
143
|
+
rl.pause();
|
|
144
|
+
await statusCommand(id);
|
|
145
|
+
rl.resume();
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
case "stop": {
|
|
150
|
+
const id = resolveId(arg);
|
|
151
|
+
if (id) {
|
|
152
|
+
rl.pause();
|
|
153
|
+
await stopCommand(id);
|
|
154
|
+
rl.resume();
|
|
155
|
+
}
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
109
158
|
case "agents":
|
|
110
159
|
case "ps":
|
|
111
160
|
rl.pause();
|
|
@@ -136,7 +185,6 @@ export async function startSession(model) {
|
|
|
136
185
|
rl.prompt();
|
|
137
186
|
return;
|
|
138
187
|
}
|
|
139
|
-
// Free text -> treat as a task (interactive launch).
|
|
140
188
|
await launchFromPrompt(rl, line);
|
|
141
189
|
rl.prompt();
|
|
142
190
|
});
|
|
@@ -144,11 +192,9 @@ export async function startSession(model) {
|
|
|
144
192
|
console.log(`\n${c.dim("See you soon. ")}${c.indigo("›")}\n`);
|
|
145
193
|
process.exit(0);
|
|
146
194
|
});
|
|
147
|
-
// Ctrl+C: confirm-style behavior — first clears line, prompt again.
|
|
148
195
|
rl.on("SIGINT", () => {
|
|
149
196
|
console.log(`\n${c.dim("(use /exit or Ctrl+D to quit)")}`);
|
|
150
197
|
rl.prompt();
|
|
151
198
|
});
|
|
152
|
-
// Touch config so a fresh user has it.
|
|
153
199
|
loadConfig();
|
|
154
200
|
}
|