@kurtel/cli 0.1.6 → 0.1.11

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.
@@ -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
  }
package/dist/ui/banner.js CHANGED
@@ -2,10 +2,11 @@ import { c, symbols } from "./colors.js";
2
2
  import { box } from "./box.js";
3
3
  import { getVersion } from "../lib/version.js";
4
4
  const wordmark = [
5
- " _ __ _ _ ",
6
- " | |/ / _ _ _ | |_ ___| |",
7
- " | ' < | '_| || | _/ -_) |",
8
- " |_|\\_\\ |_| \\_,_|\\__\\___|_|",
5
+ " _ __ _ _ ",
6
+ "| |/ / _ _ __| |_ ___| |",
7
+ "| ' / | | | '__| __/ _ \\ |",
8
+ "| . \\ |_| | | | || __/ |",
9
+ "|_|\\_\\__,_|_| \\__\\___|_|",
9
10
  ];
10
11
  export function banner() {
11
12
  const art = wordmark.map((l) => c.indigoBold(l)).join("\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kurtel/cli",
3
- "version": "0.1.6",
3
+ "version": "0.1.11",
4
4
  "description": "Launch self-improving coding agents in the cloud — the Kurtel CLI.",
5
5
  "type": "module",
6
6
  "bin": {