@vm0/cli 9.0.0 → 9.2.0

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.
Files changed (2) hide show
  1. package/index.js +624 -393
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { Command as Command45 } from "commander";
5
- import chalk46 from "chalk";
4
+ import { Command as Command48 } from "commander";
5
+ import chalk48 from "chalk";
6
6
 
7
7
  // src/lib/api/auth.ts
8
8
  import chalk from "chalk";
@@ -12,20 +12,27 @@ import { homedir } from "os";
12
12
  import { join } from "path";
13
13
  import { readFile, writeFile, mkdir, unlink } from "fs/promises";
14
14
  import { existsSync } from "fs";
15
- var CONFIG_DIR = join(homedir(), ".vm0");
16
- var CONFIG_FILE = join(CONFIG_DIR, "config.json");
15
+ function getConfigDir() {
16
+ return join(homedir(), ".vm0");
17
+ }
18
+ function getConfigFile() {
19
+ return join(getConfigDir(), "config.json");
20
+ }
17
21
  async function loadConfig() {
18
- if (!existsSync(CONFIG_FILE)) {
22
+ const configFile = getConfigFile();
23
+ if (!existsSync(configFile)) {
19
24
  return {};
20
25
  }
21
- const content = await readFile(CONFIG_FILE, "utf8");
26
+ const content = await readFile(configFile, "utf8");
22
27
  return JSON.parse(content);
23
28
  }
24
29
  async function saveConfig(config) {
25
- await mkdir(CONFIG_DIR, { recursive: true });
30
+ const configDir = getConfigDir();
31
+ const configFile = getConfigFile();
32
+ await mkdir(configDir, { recursive: true });
26
33
  const existing = await loadConfig();
27
34
  const merged = { ...existing, ...config };
28
- await writeFile(CONFIG_FILE, JSON.stringify(merged, null, 2), "utf8");
35
+ await writeFile(configFile, JSON.stringify(merged, null, 2), "utf8");
29
36
  }
30
37
  async function getToken() {
31
38
  if (process.env.VM0_TOKEN) {
@@ -43,8 +50,9 @@ async function getApiUrl() {
43
50
  return config.apiUrl ?? "https://www.vm0.ai";
44
51
  }
45
52
  async function clearConfig() {
46
- if (existsSync(CONFIG_FILE)) {
47
- await unlink(CONFIG_FILE);
53
+ const configFile = getConfigFile();
54
+ if (existsSync(configFile)) {
55
+ await unlink(configFile);
48
56
  }
49
57
  }
50
58
 
@@ -86,7 +94,7 @@ async function authenticate(apiUrl) {
86
94
  console.log("Initiating authentication...");
87
95
  const deviceAuth = await requestDeviceCode(targetApiUrl);
88
96
  console.log(chalk.green("\nDevice code generated"));
89
- const verificationUrl = `${targetApiUrl}/cli-auth`;
97
+ const verificationUrl = `${targetApiUrl}${deviceAuth.verification_path}`;
90
98
  console.log(chalk.cyan(`
91
99
  To authenticate, visit: ${verificationUrl}`));
92
100
  console.log(`And enter this code: ${chalk.bold(deviceAuth.user_code)}`);
@@ -182,8 +190,14 @@ async function setupToken() {
182
190
  );
183
191
  }
184
192
 
185
- // src/commands/compose.ts
193
+ // src/commands/auth/login.ts
186
194
  import { Command } from "commander";
195
+ var loginCommand = new Command().name("login").description("Log in to VM0 (use VM0_API_URL env var to set API URL)").action(async () => {
196
+ await authenticate();
197
+ });
198
+
199
+ // src/commands/compose.ts
200
+ import { Command as Command2 } from "commander";
187
201
  import chalk2 from "chalk";
188
202
  import { readFile as readFile4 } from "fs/promises";
189
203
  import { existsSync as existsSync3 } from "fs";
@@ -711,7 +725,8 @@ var runsMainContract = c3.router({
711
725
  201: createRunResponseSchema,
712
726
  400: apiErrorSchema,
713
727
  401: apiErrorSchema,
714
- 404: apiErrorSchema
728
+ 404: apiErrorSchema,
729
+ 429: apiErrorSchema
715
730
  },
716
731
  summary: "Create and execute agent run"
717
732
  }
@@ -1483,7 +1498,7 @@ var cliAuthDeviceContract = c6.router({
1483
1498
  200: z8.object({
1484
1499
  device_code: z8.string(),
1485
1500
  user_code: z8.string(),
1486
- verification_url: z8.string(),
1501
+ verification_path: z8.string(),
1487
1502
  expires_in: z8.number(),
1488
1503
  interval: z8.number()
1489
1504
  }),
@@ -2296,8 +2311,10 @@ var publicApiErrorTypeSchema = z18.enum([
2296
2311
  // Auth failure (401)
2297
2312
  "not_found_error",
2298
2313
  // Resource missing (404)
2299
- "conflict_error"
2314
+ "conflict_error",
2300
2315
  // Resource conflict (409)
2316
+ "rate_limit_error"
2317
+ // Rate limit exceeded (429)
2301
2318
  ]);
2302
2319
  var publicApiErrorSchema = z18.object({
2303
2320
  error: z18.object({
@@ -2327,6 +2344,11 @@ var timestampSchema = z18.string().datetime();
2327
2344
 
2328
2345
  // ../../packages/core/src/contracts/platform.ts
2329
2346
  var c15 = initContract();
2347
+ var platformPaginationSchema = z19.object({
2348
+ hasMore: z19.boolean(),
2349
+ nextCursor: z19.string().nullable(),
2350
+ totalPages: z19.number()
2351
+ });
2330
2352
  var platformLogStatusSchema = z19.enum([
2331
2353
  "pending",
2332
2354
  "running",
@@ -2338,9 +2360,10 @@ var platformLogStatusSchema = z19.enum([
2338
2360
  var platformLogEntrySchema = z19.object({
2339
2361
  id: z19.string().uuid()
2340
2362
  });
2341
- var platformLogsListResponseSchema = createPaginatedResponseSchema(
2342
- platformLogEntrySchema
2343
- );
2363
+ var platformLogsListResponseSchema = z19.object({
2364
+ data: z19.array(platformLogEntrySchema),
2365
+ pagination: platformPaginationSchema
2366
+ });
2344
2367
  var artifactSchema = z19.object({
2345
2368
  name: z19.string().nullable(),
2346
2369
  version: z19.string().nullable()
@@ -2349,7 +2372,7 @@ var platformLogDetailSchema = z19.object({
2349
2372
  id: z19.string().uuid(),
2350
2373
  sessionId: z19.string().nullable(),
2351
2374
  agentName: z19.string(),
2352
- provider: z19.string(),
2375
+ framework: z19.string().nullable(),
2353
2376
  status: platformLogStatusSchema,
2354
2377
  prompt: z19.string(),
2355
2378
  error: z19.string().nullable(),
@@ -2387,6 +2410,26 @@ var platformLogsByIdContract = c15.router({
2387
2410
  summary: "Get agent run log details by ID"
2388
2411
  }
2389
2412
  });
2413
+ var artifactDownloadResponseSchema = z19.object({
2414
+ url: z19.string().url(),
2415
+ expiresAt: z19.string()
2416
+ });
2417
+ var platformArtifactDownloadContract = c15.router({
2418
+ getDownloadUrl: {
2419
+ method: "GET",
2420
+ path: "/api/platform/artifacts/download",
2421
+ query: z19.object({
2422
+ name: z19.string().min(1, "Artifact name is required"),
2423
+ version: z19.string().optional()
2424
+ }),
2425
+ responses: {
2426
+ 200: artifactDownloadResponseSchema,
2427
+ 401: apiErrorSchema,
2428
+ 404: apiErrorSchema
2429
+ },
2430
+ summary: "Get presigned URL for artifact download"
2431
+ }
2432
+ });
2390
2433
 
2391
2434
  // ../../packages/core/src/contracts/public/agents.ts
2392
2435
  import { z as z20 } from "zod";
@@ -2519,9 +2562,7 @@ var createRunRequestSchema = z21.object({
2519
2562
  // volume_name -> version
2520
2563
  });
2521
2564
  var runListQuerySchema = listQuerySchema.extend({
2522
- agentId: z21.string().optional(),
2523
- status: publicRunStatusSchema.optional(),
2524
- since: timestampSchema.optional()
2565
+ status: publicRunStatusSchema.optional()
2525
2566
  });
2526
2567
  var publicRunsListContract = c17.router({
2527
2568
  list: {
@@ -2535,7 +2576,7 @@ var publicRunsListContract = c17.router({
2535
2576
  500: publicApiErrorSchema
2536
2577
  },
2537
2578
  summary: "List runs",
2538
- description: "List runs with optional filtering by agent, status, and time"
2579
+ description: "List runs with optional filtering by status"
2539
2580
  },
2540
2581
  create: {
2541
2582
  method: "POST",
@@ -2548,6 +2589,7 @@ var publicRunsListContract = c17.router({
2548
2589
  400: publicApiErrorSchema,
2549
2590
  401: publicApiErrorSchema,
2550
2591
  404: publicApiErrorSchema,
2592
+ 429: publicApiErrorSchema,
2551
2593
  500: publicApiErrorSchema
2552
2594
  },
2553
2595
  summary: "Create run",
@@ -3094,10 +3136,10 @@ async function getRawHeaders() {
3094
3136
  }
3095
3137
  return headers;
3096
3138
  }
3097
- async function httpGet(path14) {
3139
+ async function httpGet(path15) {
3098
3140
  const baseUrl = await getBaseUrl();
3099
3141
  const headers = await getRawHeaders();
3100
- return fetch(`${baseUrl}${path14}`, {
3142
+ return fetch(`${baseUrl}${path15}`, {
3101
3143
  method: "GET",
3102
3144
  headers
3103
3145
  });
@@ -3577,49 +3619,49 @@ var cliComposeSchema = z24.object({
3577
3619
  function formatZodError(error) {
3578
3620
  const issue = error.issues[0];
3579
3621
  if (!issue) return "Validation failed";
3580
- const path14 = issue.path.join(".");
3622
+ const path15 = issue.path.join(".");
3581
3623
  const message = issue.message;
3582
- if (!path14) return message;
3624
+ if (!path15) return message;
3583
3625
  if (issue.code === "invalid_type") {
3584
3626
  const received = issue.received;
3585
3627
  const isMissing = received === "undefined" || message.includes("received undefined") || message === "Required";
3586
- if (path14 === "version" && isMissing) {
3628
+ if (path15 === "version" && isMissing) {
3587
3629
  return "Missing config.version";
3588
3630
  }
3589
- if (path14 === "agents" && isMissing) {
3631
+ if (path15 === "agents" && isMissing) {
3590
3632
  return "Missing agents object in config";
3591
3633
  }
3592
- if (path14.startsWith("volumes.") && path14.endsWith(".name")) {
3593
- const volumeKey = path14.split(".")[1];
3634
+ if (path15.startsWith("volumes.") && path15.endsWith(".name")) {
3635
+ const volumeKey = path15.split(".")[1];
3594
3636
  return `Volume "${volumeKey}" must have a 'name' field (string)`;
3595
3637
  }
3596
- if (path14.startsWith("volumes.") && path14.endsWith(".version")) {
3597
- const volumeKey = path14.split(".")[1];
3638
+ if (path15.startsWith("volumes.") && path15.endsWith(".version")) {
3639
+ const volumeKey = path15.split(".")[1];
3598
3640
  return `Volume "${volumeKey}" must have a 'version' field (string)`;
3599
3641
  }
3600
3642
  if (issue.expected === "array") {
3601
- const fieldName = path14.replace(/^agents\.[^.]+\./, "agent.");
3643
+ const fieldName = path15.replace(/^agents\.[^.]+\./, "agent.");
3602
3644
  return `${fieldName} must be an array`;
3603
3645
  }
3604
3646
  if (issue.expected === "string" && received === "number") {
3605
- const fieldName = path14.replace(/^agents\.[^.]+\./, "agent.");
3647
+ const fieldName = path15.replace(/^agents\.[^.]+\./, "agent.");
3606
3648
  const match = fieldName.match(/^(agent\.[^.]+)\.\d+$/);
3607
3649
  if (match) {
3608
3650
  return `Each entry in ${match[1]?.replace("agent.", "")} must be a string`;
3609
3651
  }
3610
3652
  }
3611
3653
  }
3612
- if (issue.code === "invalid_key" && path14.startsWith("agents.")) {
3654
+ if (issue.code === "invalid_key" && path15.startsWith("agents.")) {
3613
3655
  return "Invalid agent name format. Must be 3-64 characters, letters, numbers, and hyphens only. Must start and end with letter or number.";
3614
3656
  }
3615
- if (message === "Invalid key in record" && path14.startsWith("agents.")) {
3657
+ if (message === "Invalid key in record" && path15.startsWith("agents.")) {
3616
3658
  return "Invalid agent name format. Must be 3-64 characters, letters, numbers, and hyphens only. Must start and end with letter or number.";
3617
3659
  }
3618
3660
  if (issue.code === "custom") {
3619
3661
  return message;
3620
3662
  }
3621
- if (path14.startsWith("agents.")) {
3622
- const cleanPath = path14.replace(/^agents\.[^.]+\./, "agent.");
3663
+ if (path15.startsWith("agents.")) {
3664
+ const cleanPath = path15.replace(/^agents\.[^.]+\./, "agent.");
3623
3665
  if (message.startsWith("Invalid input:")) {
3624
3666
  const match = message.match(/expected (\w+), received (\w+)/);
3625
3667
  if (match && match[1] === "string" && match[2] === "number") {
@@ -3631,7 +3673,7 @@ function formatZodError(error) {
3631
3673
  }
3632
3674
  return `${cleanPath}: ${message}`;
3633
3675
  }
3634
- return `${path14}: ${message}`;
3676
+ return `${path15}: ${message}`;
3635
3677
  }
3636
3678
  function validateAgentName(name) {
3637
3679
  return cliAgentNameSchema.safeParse(name).success;
@@ -4205,7 +4247,7 @@ function getSecretsFromComposeContent(content) {
4205
4247
  const grouped = groupVariablesBySource(refs);
4206
4248
  return new Set(grouped.secrets.map((r) => r.name));
4207
4249
  }
4208
- var composeCommand = new Command().name("compose").description("Create or update agent compose (e.g., vm0.yaml)").argument("<agent-yaml>", "Path to agent YAML file").option("-y, --yes", "Skip confirmation prompts for skill requirements").action(async (configFile, options) => {
4250
+ var composeCommand = new Command2().name("compose").description("Create or update agent compose (e.g., vm0.yaml)").argument("<agent-yaml>", "Path to agent YAML file").option("-y, --yes", "Skip confirmation prompts for skill requirements").action(async (configFile, options) => {
4209
4251
  try {
4210
4252
  if (!existsSync3(configFile)) {
4211
4253
  console.error(chalk2.red(`\u2717 Config file not found: ${configFile}`));
@@ -4409,7 +4451,7 @@ var composeCommand = new Command().name("compose").description("Create or update
4409
4451
  });
4410
4452
 
4411
4453
  // src/commands/run/run.ts
4412
- import { Command as Command2, Option } from "commander";
4454
+ import { Command as Command3, Option } from "commander";
4413
4455
  import chalk6 from "chalk";
4414
4456
 
4415
4457
  // src/lib/events/event-renderer.ts
@@ -4428,25 +4470,6 @@ var EventRenderer = class {
4428
4470
  console.log(chalk3.dim(` (use "vm0 logs ${info.runId}" to view logs)`));
4429
4471
  console.log();
4430
4472
  }
4431
- /**
4432
- * Format elapsed time between two timestamps
4433
- * Returns [+Nms] for < 1000ms, [+N.Ns] for >= 1000ms
4434
- */
4435
- static formatElapsed(previous, current) {
4436
- const elapsedMs = current.getTime() - previous.getTime();
4437
- if (elapsedMs < 1e3) {
4438
- return `[+${elapsedMs}ms]`;
4439
- }
4440
- return `[+${(elapsedMs / 1e3).toFixed(1)}s]`;
4441
- }
4442
- /**
4443
- * Format total elapsed time
4444
- * Returns N.Ns format
4445
- */
4446
- static formatTotalTime(start, end) {
4447
- const elapsedMs = end.getTime() - start.getTime();
4448
- return `${(elapsedMs / 1e3).toFixed(1)}s`;
4449
- }
4450
4473
  /**
4451
4474
  * Format timestamp for display (without milliseconds, matching metrics format)
4452
4475
  */
@@ -4458,24 +4481,21 @@ var EventRenderer = class {
4458
4481
  */
4459
4482
  static render(event, options) {
4460
4483
  const timestampPrefix = options?.showTimestamp ? `[${this.formatTimestamp(event.timestamp)}] ` : "";
4461
- const elapsedSuffix = options?.verbose && options?.previousTimestamp ? " " + chalk3.dim(
4462
- this.formatElapsed(options.previousTimestamp, event.timestamp)
4463
- ) : "";
4464
4484
  switch (event.type) {
4465
4485
  case "init":
4466
- this.renderInit(event, timestampPrefix, elapsedSuffix);
4486
+ this.renderInit(event, timestampPrefix);
4467
4487
  break;
4468
4488
  case "text":
4469
- this.renderText(event, timestampPrefix, elapsedSuffix);
4489
+ this.renderText(event, timestampPrefix);
4470
4490
  break;
4471
4491
  case "tool_use":
4472
- this.renderToolUse(event, timestampPrefix, elapsedSuffix);
4492
+ this.renderToolUse(event, timestampPrefix);
4473
4493
  break;
4474
4494
  case "tool_result":
4475
- this.renderToolResult(event, timestampPrefix, elapsedSuffix);
4495
+ this.renderToolResult(event, timestampPrefix);
4476
4496
  break;
4477
4497
  case "result":
4478
- this.renderResult(event, timestampPrefix, elapsedSuffix);
4498
+ this.renderResult(event, timestampPrefix);
4479
4499
  break;
4480
4500
  }
4481
4501
  }
@@ -4483,8 +4503,7 @@ var EventRenderer = class {
4483
4503
  * Render run completed state
4484
4504
  * Note: This is run lifecycle status, not an event
4485
4505
  */
4486
- static renderRunCompleted(result, options) {
4487
- const now = /* @__PURE__ */ new Date();
4506
+ static renderRunCompleted(result) {
4488
4507
  console.log("");
4489
4508
  console.log(chalk3.green("\u2713 Run completed successfully"));
4490
4509
  if (result) {
@@ -4504,10 +4523,6 @@ var EventRenderer = class {
4504
4523
  }
4505
4524
  }
4506
4525
  }
4507
- if (options?.verbose && options?.startTimestamp) {
4508
- const totalTime = this.formatTotalTime(options.startTimestamp, now);
4509
- console.log(` Total time: ${chalk3.dim(totalTime)}`);
4510
- }
4511
4526
  }
4512
4527
  /**
4513
4528
  * Render run failed state
@@ -4521,10 +4536,10 @@ var EventRenderer = class {
4521
4536
  chalk3.dim(` (use "vm0 logs ${runId} --system" to view system logs)`)
4522
4537
  );
4523
4538
  }
4524
- static renderInit(event, prefix, suffix) {
4539
+ static renderInit(event, prefix) {
4525
4540
  const frameworkStr = String(event.data.framework || "claude-code");
4526
4541
  const displayName = isSupportedFramework(frameworkStr) ? getFrameworkDisplayName(frameworkStr) : frameworkStr;
4527
- console.log(prefix + "[init]" + suffix + ` Starting ${displayName} agent`);
4542
+ console.log(prefix + `[init] Starting ${displayName} agent`);
4528
4543
  console.log(` Session: ${chalk3.dim(String(event.data.sessionId || ""))}`);
4529
4544
  if (event.data.model) {
4530
4545
  console.log(` Model: ${chalk3.dim(String(event.data.model))}`);
@@ -4535,13 +4550,13 @@ var EventRenderer = class {
4535
4550
  )}`
4536
4551
  );
4537
4552
  }
4538
- static renderText(event, prefix, suffix) {
4553
+ static renderText(event, prefix) {
4539
4554
  const text = String(event.data.text || "");
4540
- console.log(prefix + "[text]" + suffix + " " + text);
4555
+ console.log(prefix + "[text] " + text);
4541
4556
  }
4542
- static renderToolUse(event, prefix, suffix) {
4557
+ static renderToolUse(event, prefix) {
4543
4558
  const tool = String(event.data.tool || "");
4544
- console.log(prefix + "[tool_use]" + suffix + " " + tool);
4559
+ console.log(prefix + "[tool_use] " + tool);
4545
4560
  const input = event.data.input;
4546
4561
  if (input && typeof input === "object") {
4547
4562
  for (const [key, value] of Object.entries(input)) {
@@ -4552,17 +4567,17 @@ var EventRenderer = class {
4552
4567
  }
4553
4568
  }
4554
4569
  }
4555
- static renderToolResult(event, prefix, suffix) {
4570
+ static renderToolResult(event, prefix) {
4556
4571
  const isError = Boolean(event.data.isError);
4557
4572
  const status = isError ? "Error" : "Completed";
4558
- console.log(prefix + "[tool_result]" + suffix + " " + status);
4573
+ console.log(prefix + "[tool_result] " + status);
4559
4574
  const result = String(event.data.result || "");
4560
4575
  console.log(` ${chalk3.dim(result)}`);
4561
4576
  }
4562
- static renderResult(event, prefix, suffix) {
4577
+ static renderResult(event, prefix) {
4563
4578
  const success = Boolean(event.data.success);
4564
4579
  const status = success ? "\u2713 completed successfully" : "\u2717 failed";
4565
- console.log(prefix + "[result]" + suffix + " " + status);
4580
+ console.log(prefix + "[result] " + status);
4566
4581
  const durationMs = Number(event.data.durationMs || 0);
4567
4582
  const durationSec = (durationMs / 1e3).toFixed(1);
4568
4583
  console.log(` Duration: ${chalk3.dim(durationSec + "s")}`);
@@ -5834,7 +5849,7 @@ var ApiClient = class {
5834
5849
  /**
5835
5850
  * Generic GET request
5836
5851
  */
5837
- async get(path14) {
5852
+ async get(path15) {
5838
5853
  const baseUrl = await this.getBaseUrl();
5839
5854
  const token = await getToken();
5840
5855
  if (!token) {
@@ -5847,7 +5862,7 @@ var ApiClient = class {
5847
5862
  if (bypassSecret) {
5848
5863
  headers["x-vercel-protection-bypass"] = bypassSecret;
5849
5864
  }
5850
- return fetch(`${baseUrl}${path14}`, {
5865
+ return fetch(`${baseUrl}${path15}`, {
5851
5866
  method: "GET",
5852
5867
  headers
5853
5868
  });
@@ -5855,7 +5870,7 @@ var ApiClient = class {
5855
5870
  /**
5856
5871
  * Generic POST request
5857
5872
  */
5858
- async post(path14, options) {
5873
+ async post(path15, options) {
5859
5874
  const baseUrl = await this.getBaseUrl();
5860
5875
  const token = await getToken();
5861
5876
  if (!token) {
@@ -5871,7 +5886,7 @@ var ApiClient = class {
5871
5886
  if (bypassSecret) {
5872
5887
  headers["x-vercel-protection-bypass"] = bypassSecret;
5873
5888
  }
5874
- return fetch(`${baseUrl}${path14}`, {
5889
+ return fetch(`${baseUrl}${path15}`, {
5875
5890
  method: "POST",
5876
5891
  headers,
5877
5892
  body: options?.body
@@ -5880,7 +5895,7 @@ var ApiClient = class {
5880
5895
  /**
5881
5896
  * Generic DELETE request
5882
5897
  */
5883
- async delete(path14) {
5898
+ async delete(path15) {
5884
5899
  const baseUrl = await this.getBaseUrl();
5885
5900
  const token = await getToken();
5886
5901
  if (!token) {
@@ -5893,7 +5908,7 @@ var ApiClient = class {
5893
5908
  if (bypassSecret) {
5894
5909
  headers["x-vercel-protection-bypass"] = bypassSecret;
5895
5910
  }
5896
- return fetch(`${baseUrl}${path14}`, {
5911
+ return fetch(`${baseUrl}${path15}`, {
5897
5912
  method: "DELETE",
5898
5913
  headers
5899
5914
  });
@@ -5926,15 +5941,7 @@ function getRunChannelName(runId) {
5926
5941
 
5927
5942
  // src/lib/realtime/stream-events.ts
5928
5943
  async function streamEvents(runId, options) {
5929
- const {
5930
- verbose,
5931
- startTimestamp,
5932
- onEvent,
5933
- onRunCompleted,
5934
- onRunFailed,
5935
- onTimeout
5936
- } = options;
5937
- let previousTimestamp = startTimestamp;
5944
+ const { onEvent, onRunCompleted, onRunFailed, onTimeout } = options;
5938
5945
  const ablyClient = createRealtimeClient(async () => {
5939
5946
  return apiClient.getRealtimeToken(runId);
5940
5947
  });
@@ -5971,20 +5978,12 @@ async function streamEvents(runId, options) {
5971
5978
  }
5972
5979
  nextExpectedSequence = Math.max(nextExpectedSequence, seq + 1);
5973
5980
  }
5974
- previousTimestamp = onEvent(event, {
5975
- verbose,
5976
- previousTimestamp,
5977
- startTimestamp
5978
- });
5981
+ onEvent(event);
5979
5982
  }
5980
5983
  } else if (message.name === "status") {
5981
5984
  const data = message.data;
5982
5985
  if (data.status === "completed") {
5983
- onRunCompleted(data.result, {
5984
- verbose,
5985
- previousTimestamp,
5986
- startTimestamp
5987
- });
5986
+ onRunCompleted(data.result);
5988
5987
  result = {
5989
5988
  succeeded: true,
5990
5989
  runId,
@@ -6093,28 +6092,18 @@ function parseIdentifier(identifier) {
6093
6092
  }
6094
6093
  return { scope, name: rest };
6095
6094
  }
6096
- function renderEvent(event, options) {
6095
+ function renderEvent(event) {
6097
6096
  const eventData = event;
6098
6097
  const parsed = parseEvent(eventData);
6099
6098
  if (parsed) {
6100
- EventRenderer.render(parsed, {
6101
- verbose: options.verbose,
6102
- previousTimestamp: options.previousTimestamp,
6103
- startTimestamp: options.startTimestamp
6104
- });
6105
- return parsed.timestamp;
6099
+ EventRenderer.render(parsed);
6106
6100
  }
6107
- return options.previousTimestamp;
6108
6101
  }
6109
- async function streamRealtimeEvents(runId, options) {
6110
- const startTimestamp = options.startTimestamp;
6111
- const verbose = options.verbose;
6102
+ async function streamRealtimeEvents(runId) {
6112
6103
  return streamEvents(runId, {
6113
- verbose,
6114
- startTimestamp,
6115
6104
  onEvent: renderEvent,
6116
- onRunCompleted: (result, opts) => {
6117
- EventRenderer.renderRunCompleted(result, opts);
6105
+ onRunCompleted: (result) => {
6106
+ EventRenderer.renderRunCompleted(result);
6118
6107
  },
6119
6108
  onRunFailed: (error, rid) => {
6120
6109
  EventRenderer.renderRunFailed(error, rid);
@@ -6127,14 +6116,11 @@ async function streamRealtimeEvents(runId, options) {
6127
6116
  }
6128
6117
  });
6129
6118
  }
6130
- async function pollEvents(runId, options) {
6119
+ async function pollEvents(runId) {
6131
6120
  let nextSequence = -1;
6132
6121
  let complete = false;
6133
6122
  let result = { succeeded: true, runId };
6134
6123
  const pollIntervalMs = 1e3;
6135
- const startTimestamp = options.startTimestamp;
6136
- let previousTimestamp = startTimestamp;
6137
- const verbose = options.verbose;
6138
6124
  while (!complete) {
6139
6125
  const response = await getEvents(runId, {
6140
6126
  since: nextSequence
@@ -6146,12 +6132,7 @@ async function pollEvents(runId, options) {
6146
6132
  } else {
6147
6133
  const parsed = parseEvent(eventData);
6148
6134
  if (parsed) {
6149
- EventRenderer.render(parsed, {
6150
- verbose,
6151
- previousTimestamp,
6152
- startTimestamp
6153
- });
6154
- previousTimestamp = parsed.timestamp;
6135
+ EventRenderer.render(parsed);
6155
6136
  }
6156
6137
  }
6157
6138
  }
@@ -6159,11 +6140,7 @@ async function pollEvents(runId, options) {
6159
6140
  const runStatus = response.run.status;
6160
6141
  if (runStatus === "completed") {
6161
6142
  complete = true;
6162
- EventRenderer.renderRunCompleted(response.run.result, {
6163
- verbose,
6164
- previousTimestamp,
6165
- startTimestamp
6166
- });
6143
+ EventRenderer.renderRunCompleted(response.run.result);
6167
6144
  result = {
6168
6145
  succeeded: true,
6169
6146
  runId,
@@ -6188,18 +6165,6 @@ async function pollEvents(runId, options) {
6188
6165
  }
6189
6166
  return result;
6190
6167
  }
6191
- function logVerbosePreFlight(action, details) {
6192
- console.log(`
6193
- ${action}...`);
6194
- for (const { label, value } of details) {
6195
- if (value !== void 0) {
6196
- console.log(chalk5.dim(` ${label}: ${value}`));
6197
- }
6198
- }
6199
- console.log();
6200
- console.log("Executing in sandbox...");
6201
- console.log();
6202
- }
6203
6168
  function showNextSteps(result) {
6204
6169
  const { runId, sessionId, checkpointId } = result;
6205
6170
  console.log();
@@ -6222,7 +6187,7 @@ function showNextSteps(result) {
6222
6187
  }
6223
6188
 
6224
6189
  // src/commands/run/run.ts
6225
- var mainRunCommand = new Command2().name("run").description("Run an agent").argument(
6190
+ var mainRunCommand = new Command3().name("run").description("Run an agent").argument(
6226
6191
  "<agent-name>",
6227
6192
  "Agent reference: [scope/]name[:version] (e.g., 'my-agent', 'lancy/my-agent:abc123', 'my-agent:latest')"
6228
6193
  ).argument("<prompt>", "Prompt for the agent").option(
@@ -6249,33 +6214,23 @@ var mainRunCommand = new Command2().name("run").description("Run an agent").argu
6249
6214
  ).option(
6250
6215
  "--conversation <id>",
6251
6216
  "Resume from conversation ID (for fine-grained control)"
6252
- ).option("-v, --verbose", "Show verbose output with timing information").option(
6217
+ ).option(
6253
6218
  "--experimental-realtime",
6254
6219
  "Use realtime event streaming instead of polling (experimental)"
6255
6220
  ).option(
6256
6221
  "--model-provider <type>",
6257
6222
  "Override model provider (e.g., anthropic-api-key)"
6258
6223
  ).addOption(new Option("--debug-no-mock-claude").hideHelp()).action(
6259
- // eslint-disable-next-line complexity -- TODO: refactor complex function
6260
6224
  async (identifier, prompt, options) => {
6261
- const startTimestamp = /* @__PURE__ */ new Date();
6262
- const verbose = options.verbose;
6263
6225
  try {
6264
6226
  const { scope, name, version } = parseIdentifier(identifier);
6265
6227
  let composeId;
6266
6228
  let composeContent;
6267
6229
  if (isUUID(name)) {
6268
- if (verbose) {
6269
- console.log(chalk6.dim(` Using compose ID: ${identifier}`));
6270
- }
6271
6230
  const compose = await getComposeById(name);
6272
6231
  composeId = compose.id;
6273
6232
  composeContent = compose.content;
6274
6233
  } else {
6275
- if (verbose) {
6276
- const displayRef = scope ? `${scope}/${name}` : name;
6277
- console.log(chalk6.dim(` Resolving agent: ${displayRef}`));
6278
- }
6279
6234
  const compose = await getComposeByName(name, scope);
6280
6235
  if (!compose) {
6281
6236
  console.error(chalk6.red(`\u2717 Agent not found: ${identifier}`));
@@ -6288,25 +6243,12 @@ var mainRunCommand = new Command2().name("run").description("Run an agent").argu
6288
6243
  }
6289
6244
  composeId = compose.id;
6290
6245
  composeContent = compose.content;
6291
- if (verbose) {
6292
- console.log(chalk6.dim(` Resolved to compose ID: ${composeId}`));
6293
- }
6294
6246
  }
6295
6247
  let agentComposeVersionId;
6296
6248
  if (version && version !== "latest") {
6297
- if (verbose) {
6298
- console.log(chalk6.dim(` Resolving version: ${version}`));
6299
- }
6300
6249
  try {
6301
6250
  const versionInfo = await getComposeVersion(composeId, version);
6302
6251
  agentComposeVersionId = versionInfo.versionId;
6303
- if (verbose) {
6304
- console.log(
6305
- chalk6.dim(
6306
- ` Resolved to version ID: ${agentComposeVersionId.slice(0, 8)}...`
6307
- )
6308
- );
6309
- }
6310
6252
  } catch {
6311
6253
  throw new Error(`Version not found: ${version}`);
6312
6254
  }
@@ -6319,45 +6261,6 @@ var mainRunCommand = new Command2().name("run").description("Run an agent").argu
6319
6261
  secretNames,
6320
6262
  options.envFile
6321
6263
  );
6322
- if (verbose && varNames.length > 0) {
6323
- console.log(chalk6.dim(` Required vars: ${varNames.join(", ")}`));
6324
- if (vars) {
6325
- console.log(
6326
- chalk6.dim(` Loaded vars: ${Object.keys(vars).join(", ")}`)
6327
- );
6328
- }
6329
- }
6330
- if (verbose && secretNames.length > 0) {
6331
- console.log(
6332
- chalk6.dim(` Required secrets: ${secretNames.join(", ")}`)
6333
- );
6334
- if (secrets) {
6335
- console.log(
6336
- chalk6.dim(` Loaded secrets: ${Object.keys(secrets).join(", ")}`)
6337
- );
6338
- }
6339
- }
6340
- if (verbose) {
6341
- logVerbosePreFlight("Creating agent run", [
6342
- { label: "Prompt", value: prompt },
6343
- { label: "Version", value: version || "latest (HEAD)" },
6344
- {
6345
- label: "Variables",
6346
- value: vars && Object.keys(vars).length > 0 ? JSON.stringify(vars) : void 0
6347
- },
6348
- {
6349
- label: "Secrets",
6350
- value: secrets && Object.keys(secrets).length > 0 ? `${Object.keys(secrets).length} loaded` : void 0
6351
- },
6352
- { label: "Artifact", value: options.artifactName },
6353
- { label: "Artifact version", value: options.artifactVersion },
6354
- {
6355
- label: "Volume versions",
6356
- value: Object.keys(options.volumeVersion).length > 0 ? JSON.stringify(options.volumeVersion) : void 0
6357
- },
6358
- { label: "Conversation", value: options.conversation }
6359
- ]);
6360
- }
6361
6264
  const response = await createRun({
6362
6265
  // Use agentComposeVersionId if resolved, otherwise use agentComposeId (resolves to HEAD)
6363
6266
  ...agentComposeVersionId ? { agentComposeVersionId } : { agentComposeId: composeId },
@@ -6382,13 +6285,7 @@ var mainRunCommand = new Command2().name("run").description("Run an agent").argu
6382
6285
  runId: response.runId,
6383
6286
  sandboxId: response.sandboxId
6384
6287
  });
6385
- const result = options.experimentalRealtime ? await streamRealtimeEvents(response.runId, {
6386
- verbose,
6387
- startTimestamp
6388
- }) : await pollEvents(response.runId, {
6389
- verbose,
6390
- startTimestamp
6391
- });
6288
+ const result = options.experimentalRealtime ? await streamRealtimeEvents(response.runId) : await pollEvents(response.runId);
6392
6289
  if (!result.succeeded) {
6393
6290
  process.exit(1);
6394
6291
  }
@@ -6430,9 +6327,9 @@ var mainRunCommand = new Command2().name("run").description("Run an agent").argu
6430
6327
  );
6431
6328
 
6432
6329
  // src/commands/run/resume.ts
6433
- import { Command as Command3, Option as Option2 } from "commander";
6330
+ import { Command as Command4, Option as Option2 } from "commander";
6434
6331
  import chalk7 from "chalk";
6435
- var resumeCommand = new Command3().name("resume").description("Resume an agent run from a checkpoint (uses all snapshot data)").argument("<checkpointId>", "Checkpoint ID to resume from").argument("<prompt>", "Prompt for the resumed agent").option(
6332
+ var resumeCommand = new Command4().name("resume").description("Resume an agent run from a checkpoint (uses all snapshot data)").argument("<checkpointId>", "Checkpoint ID to resume from").argument("<prompt>", "Prompt for the resumed agent").option(
6436
6333
  "--env-file <path>",
6437
6334
  "Load environment variables from file (priority: CLI flags > file > env vars)"
6438
6335
  ).option(
@@ -6450,18 +6347,15 @@ var resumeCommand = new Command3().name("resume").description("Resume an agent r
6450
6347
  "Volume version override (repeatable)",
6451
6348
  collectVolumeVersions,
6452
6349
  {}
6453
- ).option("-v, --verbose", "Show verbose output with timing information").option(
6350
+ ).option(
6454
6351
  "--experimental-realtime",
6455
6352
  "Use realtime event streaming instead of polling (experimental)"
6456
6353
  ).option(
6457
6354
  "--model-provider <type>",
6458
6355
  "Override model provider (e.g., anthropic-api-key)"
6459
6356
  ).addOption(new Option2("--debug-no-mock-claude").hideHelp()).action(
6460
- // eslint-disable-next-line complexity -- TODO: refactor complex function
6461
6357
  async (checkpointId, prompt, options, command) => {
6462
- const startTimestamp = /* @__PURE__ */ new Date();
6463
6358
  const allOpts = command.optsWithGlobals();
6464
- const verbose = options.verbose || allOpts.verbose;
6465
6359
  const vars = { ...allOpts.vars, ...options.vars };
6466
6360
  const secrets = { ...allOpts.secrets, ...options.secrets };
6467
6361
  try {
@@ -6476,24 +6370,6 @@ var resumeCommand = new Command3().name("resume").description("Resume an agent r
6476
6370
  const requiredSecretNames = checkpointInfo.agentComposeSnapshot.secretNames || [];
6477
6371
  const envFile = options.envFile || allOpts.envFile;
6478
6372
  const loadedSecrets = loadValues(secrets, requiredSecretNames, envFile);
6479
- if (verbose) {
6480
- logVerbosePreFlight("Resuming agent run from checkpoint", [
6481
- { label: "Checkpoint ID", value: checkpointId },
6482
- { label: "Prompt", value: prompt },
6483
- {
6484
- label: "Variables",
6485
- value: Object.keys(vars).length > 0 ? JSON.stringify(vars) : void 0
6486
- },
6487
- {
6488
- label: "Secrets",
6489
- value: loadedSecrets && Object.keys(loadedSecrets).length > 0 ? `${Object.keys(loadedSecrets).length} loaded` : void 0
6490
- },
6491
- {
6492
- label: "Volume overrides",
6493
- value: Object.keys(allOpts.volumeVersion).length > 0 ? JSON.stringify(allOpts.volumeVersion) : void 0
6494
- }
6495
- ]);
6496
- }
6497
6373
  const response = await createRun({
6498
6374
  checkpointId,
6499
6375
  prompt,
@@ -6515,13 +6391,7 @@ var resumeCommand = new Command3().name("resume").description("Resume an agent r
6515
6391
  sandboxId: response.sandboxId
6516
6392
  });
6517
6393
  const experimentalRealtime = options.experimentalRealtime || allOpts.experimentalRealtime;
6518
- const result = experimentalRealtime ? await streamRealtimeEvents(response.runId, {
6519
- verbose,
6520
- startTimestamp
6521
- }) : await pollEvents(response.runId, {
6522
- verbose,
6523
- startTimestamp
6524
- });
6394
+ const result = experimentalRealtime ? await streamRealtimeEvents(response.runId) : await pollEvents(response.runId);
6525
6395
  if (!result.succeeded) {
6526
6396
  process.exit(1);
6527
6397
  }
@@ -6555,9 +6425,9 @@ var resumeCommand = new Command3().name("resume").description("Resume an agent r
6555
6425
  );
6556
6426
 
6557
6427
  // src/commands/run/continue.ts
6558
- import { Command as Command4, Option as Option3 } from "commander";
6428
+ import { Command as Command5, Option as Option3 } from "commander";
6559
6429
  import chalk8 from "chalk";
6560
- var continueCommand = new Command4().name("continue").description(
6430
+ var continueCommand = new Command5().name("continue").description(
6561
6431
  "Continue an agent run from a session (uses latest artifact version)"
6562
6432
  ).argument("<agentSessionId>", "Agent session ID to continue from").argument("<prompt>", "Prompt for the continued agent").option(
6563
6433
  "--env-file <path>",
@@ -6577,18 +6447,15 @@ var continueCommand = new Command4().name("continue").description(
6577
6447
  "Volume version override (repeatable)",
6578
6448
  collectVolumeVersions,
6579
6449
  {}
6580
- ).option("-v, --verbose", "Show verbose output with timing information").option(
6450
+ ).option(
6581
6451
  "--experimental-realtime",
6582
6452
  "Use realtime event streaming instead of polling (experimental)"
6583
6453
  ).option(
6584
6454
  "--model-provider <type>",
6585
6455
  "Override model provider (e.g., anthropic-api-key)"
6586
6456
  ).addOption(new Option3("--debug-no-mock-claude").hideHelp()).action(
6587
- // eslint-disable-next-line complexity -- TODO: refactor complex function
6588
6457
  async (agentSessionId, prompt, options, command) => {
6589
- const startTimestamp = /* @__PURE__ */ new Date();
6590
6458
  const allOpts = command.optsWithGlobals();
6591
- const verbose = options.verbose || allOpts.verbose;
6592
6459
  const vars = { ...allOpts.vars, ...options.vars };
6593
6460
  const secrets = { ...allOpts.secrets, ...options.secrets };
6594
6461
  try {
@@ -6603,25 +6470,6 @@ var continueCommand = new Command4().name("continue").description(
6603
6470
  const requiredSecretNames = sessionInfo.secretNames || [];
6604
6471
  const envFile = options.envFile || allOpts.envFile;
6605
6472
  const loadedSecrets = loadValues(secrets, requiredSecretNames, envFile);
6606
- if (verbose) {
6607
- logVerbosePreFlight("Continuing agent run from session", [
6608
- { label: "Session ID", value: agentSessionId },
6609
- { label: "Prompt", value: prompt },
6610
- { label: "Note", value: "Using latest artifact version" },
6611
- {
6612
- label: "Variables",
6613
- value: Object.keys(vars).length > 0 ? JSON.stringify(vars) : void 0
6614
- },
6615
- {
6616
- label: "Secrets",
6617
- value: loadedSecrets && Object.keys(loadedSecrets).length > 0 ? `${Object.keys(loadedSecrets).length} loaded` : void 0
6618
- },
6619
- {
6620
- label: "Volume overrides",
6621
- value: Object.keys(allOpts.volumeVersion).length > 0 ? JSON.stringify(allOpts.volumeVersion) : void 0
6622
- }
6623
- ]);
6624
- }
6625
6473
  const response = await createRun({
6626
6474
  sessionId: agentSessionId,
6627
6475
  prompt,
@@ -6643,13 +6491,7 @@ var continueCommand = new Command4().name("continue").description(
6643
6491
  sandboxId: response.sandboxId
6644
6492
  });
6645
6493
  const experimentalRealtime = options.experimentalRealtime || allOpts.experimentalRealtime;
6646
- const result = experimentalRealtime ? await streamRealtimeEvents(response.runId, {
6647
- verbose,
6648
- startTimestamp
6649
- }) : await pollEvents(response.runId, {
6650
- verbose,
6651
- startTimestamp
6652
- });
6494
+ const result = experimentalRealtime ? await streamRealtimeEvents(response.runId) : await pollEvents(response.runId);
6653
6495
  if (!result.succeeded) {
6654
6496
  process.exit(1);
6655
6497
  }
@@ -6690,10 +6532,10 @@ mainRunCommand.addCommand(continueCommand);
6690
6532
  var runCommand = mainRunCommand;
6691
6533
 
6692
6534
  // src/commands/volume/index.ts
6693
- import { Command as Command11 } from "commander";
6535
+ import { Command as Command12 } from "commander";
6694
6536
 
6695
6537
  // src/commands/volume/init.ts
6696
- import { Command as Command5 } from "commander";
6538
+ import { Command as Command6 } from "commander";
6697
6539
  import chalk9 from "chalk";
6698
6540
  import path6 from "path";
6699
6541
 
@@ -6702,8 +6544,8 @@ import { readFile as readFile5, writeFile as writeFile4, mkdir as mkdir4 } from
6702
6544
  import { existsSync as existsSync5 } from "fs";
6703
6545
  import { parse as parseYaml3, stringify as stringifyYaml } from "yaml";
6704
6546
  import path5 from "path";
6705
- var CONFIG_DIR2 = ".vm0";
6706
- var CONFIG_FILE2 = "storage.yaml";
6547
+ var CONFIG_DIR = ".vm0";
6548
+ var CONFIG_FILE = "storage.yaml";
6707
6549
  function isValidStorageName(name) {
6708
6550
  if (name.length < 3 || name.length > 64) {
6709
6551
  return false;
@@ -6712,8 +6554,8 @@ function isValidStorageName(name) {
6712
6554
  return pattern.test(name) && !name.includes("--");
6713
6555
  }
6714
6556
  async function readStorageConfig(basePath = process.cwd()) {
6715
- const configPath = path5.join(basePath, CONFIG_DIR2, CONFIG_FILE2);
6716
- const legacyConfigPath = path5.join(basePath, CONFIG_DIR2, "volume.yaml");
6557
+ const configPath = path5.join(basePath, CONFIG_DIR, CONFIG_FILE);
6558
+ const legacyConfigPath = path5.join(basePath, CONFIG_DIR, "volume.yaml");
6717
6559
  let actualPath = null;
6718
6560
  if (existsSync5(configPath)) {
6719
6561
  actualPath = configPath;
@@ -6731,8 +6573,8 @@ async function readStorageConfig(basePath = process.cwd()) {
6731
6573
  return config;
6732
6574
  }
6733
6575
  async function writeStorageConfig(storageName, basePath = process.cwd(), type = "volume") {
6734
- const configDir = path5.join(basePath, CONFIG_DIR2);
6735
- const configPath = path5.join(configDir, CONFIG_FILE2);
6576
+ const configDir = path5.join(basePath, CONFIG_DIR);
6577
+ const configPath = path5.join(configDir, CONFIG_FILE);
6736
6578
  if (!existsSync5(configDir)) {
6737
6579
  await mkdir4(configDir, { recursive: true });
6738
6580
  }
@@ -6745,7 +6587,7 @@ async function writeStorageConfig(storageName, basePath = process.cwd(), type =
6745
6587
  }
6746
6588
 
6747
6589
  // src/commands/volume/init.ts
6748
- var initCommand = new Command5().name("init").description("Initialize a volume in the current directory").option("-n, --name <name>", "Volume name (required in non-interactive mode)").action(async (options) => {
6590
+ var initCommand = new Command6().name("init").description("Initialize a volume in the current directory").option("-n, --name <name>", "Volume name (required in non-interactive mode)").action(async (options) => {
6749
6591
  try {
6750
6592
  const cwd = process.cwd();
6751
6593
  const dirName = path6.basename(cwd);
@@ -6817,9 +6659,9 @@ var initCommand = new Command5().name("init").description("Initialize a volume i
6817
6659
  });
6818
6660
 
6819
6661
  // src/commands/volume/push.ts
6820
- import { Command as Command6 } from "commander";
6662
+ import { Command as Command7 } from "commander";
6821
6663
  import chalk10 from "chalk";
6822
- var pushCommand = new Command6().name("push").description("Push local files to cloud volume").option(
6664
+ var pushCommand = new Command7().name("push").description("Push local files to cloud volume").option(
6823
6665
  "-f, --force",
6824
6666
  "Force upload even if content unchanged (recreate archive)"
6825
6667
  ).action(async (options) => {
@@ -6863,7 +6705,7 @@ var pushCommand = new Command6().name("push").description("Push local files to c
6863
6705
  });
6864
6706
 
6865
6707
  // src/commands/volume/pull.ts
6866
- import { Command as Command7 } from "commander";
6708
+ import { Command as Command8 } from "commander";
6867
6709
  import chalk12 from "chalk";
6868
6710
  import path7 from "path";
6869
6711
  import * as fs6 from "fs";
@@ -6883,7 +6725,7 @@ async function handleEmptyStorageResponse(cwd) {
6883
6725
  }
6884
6726
 
6885
6727
  // src/commands/volume/pull.ts
6886
- var pullCommand = new Command7().name("pull").description("Pull cloud files to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(async (versionId) => {
6728
+ var pullCommand = new Command8().name("pull").description("Pull cloud files to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(async (versionId) => {
6887
6729
  try {
6888
6730
  const cwd = process.cwd();
6889
6731
  const config = await readStorageConfig(cwd);
@@ -6956,9 +6798,9 @@ var pullCommand = new Command7().name("pull").description("Pull cloud files to l
6956
6798
  });
6957
6799
 
6958
6800
  // src/commands/volume/status.ts
6959
- import { Command as Command8 } from "commander";
6801
+ import { Command as Command9 } from "commander";
6960
6802
  import chalk13 from "chalk";
6961
- var statusCommand = new Command8().name("status").description("Show status of cloud volume").action(async () => {
6803
+ var statusCommand = new Command9().name("status").description("Show status of cloud volume").action(async () => {
6962
6804
  try {
6963
6805
  const cwd = process.cwd();
6964
6806
  const config = await readStorageConfig(cwd);
@@ -7010,9 +6852,9 @@ var statusCommand = new Command8().name("status").description("Show status of cl
7010
6852
  });
7011
6853
 
7012
6854
  // src/commands/volume/list.ts
7013
- import { Command as Command9 } from "commander";
6855
+ import { Command as Command10 } from "commander";
7014
6856
  import chalk14 from "chalk";
7015
- var listCommand = new Command9().name("list").alias("ls").description("List all remote volumes").action(async () => {
6857
+ var listCommand = new Command10().name("list").alias("ls").description("List all remote volumes").action(async () => {
7016
6858
  try {
7017
6859
  const items = await listStorages({ type: "volume" });
7018
6860
  if (items.length === 0) {
@@ -7061,7 +6903,7 @@ var listCommand = new Command9().name("list").alias("ls").description("List all
7061
6903
  });
7062
6904
 
7063
6905
  // src/commands/volume/clone.ts
7064
- import { Command as Command10 } from "commander";
6906
+ import { Command as Command11 } from "commander";
7065
6907
  import chalk16 from "chalk";
7066
6908
 
7067
6909
  // src/lib/storage/clone-utils.ts
@@ -7131,7 +6973,7 @@ async function cloneStorage(name, type, destination, options = {}) {
7131
6973
  }
7132
6974
 
7133
6975
  // src/commands/volume/clone.ts
7134
- var cloneCommand = new Command10().name("clone").description("Clone a remote volume to local directory (latest version)").argument("<name>", "Volume name to clone").argument("[destination]", "Destination directory (default: volume name)").action(async (name, destination) => {
6976
+ var cloneCommand = new Command11().name("clone").description("Clone a remote volume to local directory (latest version)").argument("<name>", "Volume name to clone").argument("[destination]", "Destination directory (default: volume name)").action(async (name, destination) => {
7135
6977
  try {
7136
6978
  const targetDir = destination || name;
7137
6979
  console.log(`Cloning volume: ${name}`);
@@ -7154,16 +6996,16 @@ var cloneCommand = new Command10().name("clone").description("Clone a remote vol
7154
6996
  });
7155
6997
 
7156
6998
  // src/commands/volume/index.ts
7157
- var volumeCommand = new Command11().name("volume").description("Manage volumes (defined in compose, not versioned after run)").addCommand(initCommand).addCommand(pushCommand).addCommand(pullCommand).addCommand(statusCommand).addCommand(listCommand).addCommand(cloneCommand);
6999
+ var volumeCommand = new Command12().name("volume").description("Manage volumes (defined in compose, not versioned after run)").addCommand(initCommand).addCommand(pushCommand).addCommand(pullCommand).addCommand(statusCommand).addCommand(listCommand).addCommand(cloneCommand);
7158
7000
 
7159
7001
  // src/commands/artifact/index.ts
7160
- import { Command as Command18 } from "commander";
7002
+ import { Command as Command19 } from "commander";
7161
7003
 
7162
7004
  // src/commands/artifact/init.ts
7163
- import { Command as Command12 } from "commander";
7005
+ import { Command as Command13 } from "commander";
7164
7006
  import chalk17 from "chalk";
7165
7007
  import path9 from "path";
7166
- var initCommand2 = new Command12().name("init").description("Initialize an artifact in the current directory").option(
7008
+ var initCommand2 = new Command13().name("init").description("Initialize an artifact in the current directory").option(
7167
7009
  "-n, --name <name>",
7168
7010
  "Artifact name (required in non-interactive mode)"
7169
7011
  ).action(async (options) => {
@@ -7253,9 +7095,9 @@ var initCommand2 = new Command12().name("init").description("Initialize an artif
7253
7095
  });
7254
7096
 
7255
7097
  // src/commands/artifact/push.ts
7256
- import { Command as Command13 } from "commander";
7098
+ import { Command as Command14 } from "commander";
7257
7099
  import chalk18 from "chalk";
7258
- var pushCommand2 = new Command13().name("push").description("Push local files to cloud artifact").option(
7100
+ var pushCommand2 = new Command14().name("push").description("Push local files to cloud artifact").option(
7259
7101
  "-f, --force",
7260
7102
  "Force upload even if content unchanged (recreate archive)"
7261
7103
  ).action(async (options) => {
@@ -7304,13 +7146,13 @@ var pushCommand2 = new Command13().name("push").description("Push local files to
7304
7146
  });
7305
7147
 
7306
7148
  // src/commands/artifact/pull.ts
7307
- import { Command as Command14 } from "commander";
7149
+ import { Command as Command15 } from "commander";
7308
7150
  import chalk19 from "chalk";
7309
7151
  import path10 from "path";
7310
7152
  import * as fs8 from "fs";
7311
7153
  import * as os6 from "os";
7312
7154
  import * as tar5 from "tar";
7313
- var pullCommand2 = new Command14().name("pull").description("Pull cloud artifact to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(async (versionId) => {
7155
+ var pullCommand2 = new Command15().name("pull").description("Pull cloud artifact to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(async (versionId) => {
7314
7156
  try {
7315
7157
  const cwd = process.cwd();
7316
7158
  const config = await readStorageConfig(cwd);
@@ -7388,9 +7230,9 @@ var pullCommand2 = new Command14().name("pull").description("Pull cloud artifact
7388
7230
  });
7389
7231
 
7390
7232
  // src/commands/artifact/status.ts
7391
- import { Command as Command15 } from "commander";
7233
+ import { Command as Command16 } from "commander";
7392
7234
  import chalk20 from "chalk";
7393
- var statusCommand2 = new Command15().name("status").description("Show status of cloud artifact").action(async () => {
7235
+ var statusCommand2 = new Command16().name("status").description("Show status of cloud artifact").action(async () => {
7394
7236
  try {
7395
7237
  const cwd = process.cwd();
7396
7238
  const config = await readStorageConfig(cwd);
@@ -7438,9 +7280,9 @@ var statusCommand2 = new Command15().name("status").description("Show status of
7438
7280
  });
7439
7281
 
7440
7282
  // src/commands/artifact/list.ts
7441
- import { Command as Command16 } from "commander";
7283
+ import { Command as Command17 } from "commander";
7442
7284
  import chalk21 from "chalk";
7443
- var listCommand2 = new Command16().name("list").alias("ls").description("List all remote artifacts").action(async () => {
7285
+ var listCommand2 = new Command17().name("list").alias("ls").description("List all remote artifacts").action(async () => {
7444
7286
  try {
7445
7287
  const items = await listStorages({ type: "artifact" });
7446
7288
  if (items.length === 0) {
@@ -7491,9 +7333,9 @@ var listCommand2 = new Command16().name("list").alias("ls").description("List al
7491
7333
  });
7492
7334
 
7493
7335
  // src/commands/artifact/clone.ts
7494
- import { Command as Command17 } from "commander";
7336
+ import { Command as Command18 } from "commander";
7495
7337
  import chalk22 from "chalk";
7496
- var cloneCommand2 = new Command17().name("clone").description("Clone a remote artifact to local directory (latest version)").argument("<name>", "Artifact name to clone").argument("[destination]", "Destination directory (default: artifact name)").action(async (name, destination) => {
7338
+ var cloneCommand2 = new Command18().name("clone").description("Clone a remote artifact to local directory (latest version)").argument("<name>", "Artifact name to clone").argument("[destination]", "Destination directory (default: artifact name)").action(async (name, destination) => {
7497
7339
  try {
7498
7340
  const targetDir = destination || name;
7499
7341
  console.log(`Cloning artifact: ${name}`);
@@ -7516,10 +7358,10 @@ var cloneCommand2 = new Command17().name("clone").description("Clone a remote ar
7516
7358
  });
7517
7359
 
7518
7360
  // src/commands/artifact/index.ts
7519
- var artifactCommand = new Command18().name("artifact").description("Manage artifacts (specified at run, versioned after run)").addCommand(initCommand2).addCommand(pushCommand2).addCommand(pullCommand2).addCommand(statusCommand2).addCommand(listCommand2).addCommand(cloneCommand2);
7361
+ var artifactCommand = new Command19().name("artifact").description("Manage artifacts (specified at run, versioned after run)").addCommand(initCommand2).addCommand(pushCommand2).addCommand(pullCommand2).addCommand(statusCommand2).addCommand(listCommand2).addCommand(cloneCommand2);
7520
7362
 
7521
7363
  // src/commands/cook.ts
7522
- import { Command as Command19, Option as Option4 } from "commander";
7364
+ import { Command as Command20, Option as Option4 } from "commander";
7523
7365
  import chalk24 from "chalk";
7524
7366
  import { readFile as readFile7, mkdir as mkdir6 } from "fs/promises";
7525
7367
  import { existsSync as existsSync8 } from "fs";
@@ -7672,8 +7514,8 @@ import { homedir as homedir2 } from "os";
7672
7514
  import { join as join6 } from "path";
7673
7515
  import { readFile as readFile6, writeFile as writeFile5, mkdir as mkdir5 } from "fs/promises";
7674
7516
  import { existsSync as existsSync7 } from "fs";
7675
- var CONFIG_DIR3 = join6(homedir2(), ".vm0");
7676
- var COOK_STATE_FILE = join6(CONFIG_DIR3, "cook.json");
7517
+ var CONFIG_DIR2 = join6(homedir2(), ".vm0");
7518
+ var COOK_STATE_FILE = join6(CONFIG_DIR2, "cook.json");
7677
7519
  var STALE_THRESHOLD_MS = 48 * 60 * 60 * 1e3;
7678
7520
  async function loadCookStateFile() {
7679
7521
  if (!existsSync7(COOK_STATE_FILE)) {
@@ -7712,7 +7554,7 @@ async function loadCookState() {
7712
7554
  };
7713
7555
  }
7714
7556
  async function saveCookState(state) {
7715
- await mkdir5(CONFIG_DIR3, { recursive: true });
7557
+ await mkdir5(CONFIG_DIR2, { recursive: true });
7716
7558
  const file = await loadCookStateFile();
7717
7559
  const ppid = String(process.ppid);
7718
7560
  const now = Date.now();
@@ -7733,7 +7575,7 @@ async function saveCookState(state) {
7733
7575
  }
7734
7576
 
7735
7577
  // src/commands/cook.ts
7736
- var CONFIG_FILE3 = "vm0.yaml";
7578
+ var CONFIG_FILE2 = "vm0.yaml";
7737
7579
  var ARTIFACT_DIR = "artifact";
7738
7580
  function printCommand(cmd) {
7739
7581
  console.log(chalk24.dim(`> ${cmd}`));
@@ -7880,7 +7722,7 @@ async function autoPullArtifact(runOutput, artifactDir) {
7880
7722
  }
7881
7723
  }
7882
7724
  }
7883
- var cookCmd = new Command19().name("cook").description("Quick start: prepare, compose and run agent from vm0.yaml");
7725
+ var cookCmd = new Command20().name("cook").description("Quick start: prepare, compose and run agent from vm0.yaml");
7884
7726
  cookCmd.argument("[prompt]", "Prompt for the agent").option(
7885
7727
  "--env-file <path>",
7886
7728
  "Load environment variables from file (priority: CLI flags > file > env vars)"
@@ -7888,20 +7730,20 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
7888
7730
  // eslint-disable-next-line complexity -- TODO: refactor complex function
7889
7731
  async (prompt, options) => {
7890
7732
  if (!options.noAutoUpdate) {
7891
- const shouldExit = await checkAndUpgrade("9.0.0", prompt);
7733
+ const shouldExit = await checkAndUpgrade("9.2.0", prompt);
7892
7734
  if (shouldExit) {
7893
7735
  process.exit(0);
7894
7736
  }
7895
7737
  }
7896
7738
  const cwd = process.cwd();
7897
- console.log(chalk24.bold(`Reading config: ${CONFIG_FILE3}`));
7898
- if (!existsSync8(CONFIG_FILE3)) {
7899
- console.error(chalk24.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
7739
+ console.log(chalk24.bold(`Reading config: ${CONFIG_FILE2}`));
7740
+ if (!existsSync8(CONFIG_FILE2)) {
7741
+ console.error(chalk24.red(`\u2717 Config file not found: ${CONFIG_FILE2}`));
7900
7742
  process.exit(1);
7901
7743
  }
7902
7744
  let config;
7903
7745
  try {
7904
- const content = await readFile7(CONFIG_FILE3, "utf8");
7746
+ const content = await readFile7(CONFIG_FILE2, "utf8");
7905
7747
  config = parseYaml4(content);
7906
7748
  } catch (error) {
7907
7749
  console.error(chalk24.red("\u2717 Invalid YAML format"));
@@ -8022,7 +7864,7 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
8022
7864
  }
8023
7865
  console.log();
8024
7866
  console.log(chalk24.bold("Composing agent:"));
8025
- const composeArgs = options.yes ? ["compose", "--yes", CONFIG_FILE3] : ["compose", CONFIG_FILE3];
7867
+ const composeArgs = options.yes ? ["compose", "--yes", CONFIG_FILE2] : ["compose", CONFIG_FILE2];
8026
7868
  printCommand(`vm0 ${composeArgs.join(" ")}`);
8027
7869
  try {
8028
7870
  await execVm0Command(composeArgs, {
@@ -8216,7 +8058,7 @@ cookCmd.command("resume").description(
8216
8058
  var cookCommand = cookCmd;
8217
8059
 
8218
8060
  // src/commands/logs/index.ts
8219
- import { Command as Command20 } from "commander";
8061
+ import { Command as Command21 } from "commander";
8220
8062
  import chalk25 from "chalk";
8221
8063
 
8222
8064
  // src/lib/utils/time-parser.ts
@@ -8334,7 +8176,7 @@ function getLogType(options) {
8334
8176
  if (options.network) return "network";
8335
8177
  return "agent";
8336
8178
  }
8337
- var logsCommand = new Command20().name("logs").description("View logs for an agent run").argument("<runId>", "Run ID to fetch logs for").option("-a, --agent", "Show agent events (default)").option("-s, --system", "Show system log").option("-m, --metrics", "Show metrics").option("-n, --network", "Show network logs (proxy traffic)").option(
8179
+ var logsCommand = new Command21().name("logs").description("View logs for an agent run").argument("<runId>", "Run ID to fetch logs for").option("-a, --agent", "Show agent events (default)").option("-s, --system", "Show system log").option("-m, --metrics", "Show metrics").option("-n, --network", "Show network logs (proxy traffic)").option(
8338
8180
  "--since <time>",
8339
8181
  "Show logs since timestamp (e.g., 5m, 2h, 1d, 2024-01-15T10:30:00Z, 1705312200)"
8340
8182
  ).option("--tail <n>", "Show last N entries (default: 5, max: 100)").option("--head <n>", "Show first N entries (max: 100)").action(
@@ -8470,12 +8312,12 @@ function handleError2(error, runId) {
8470
8312
  }
8471
8313
 
8472
8314
  // src/commands/scope/index.ts
8473
- import { Command as Command23 } from "commander";
8315
+ import { Command as Command24 } from "commander";
8474
8316
 
8475
8317
  // src/commands/scope/status.ts
8476
- import { Command as Command21 } from "commander";
8318
+ import { Command as Command22 } from "commander";
8477
8319
  import chalk26 from "chalk";
8478
- var statusCommand3 = new Command21().name("status").description("View current scope status").action(async () => {
8320
+ var statusCommand3 = new Command22().name("status").description("View current scope status").action(async () => {
8479
8321
  try {
8480
8322
  const scope = await getScope();
8481
8323
  console.log(chalk26.bold("Scope Information:"));
@@ -8507,9 +8349,9 @@ var statusCommand3 = new Command21().name("status").description("View current sc
8507
8349
  });
8508
8350
 
8509
8351
  // src/commands/scope/set.ts
8510
- import { Command as Command22 } from "commander";
8352
+ import { Command as Command23 } from "commander";
8511
8353
  import chalk27 from "chalk";
8512
- var setCommand = new Command22().name("set").description("Set your scope slug").argument("<slug>", "The scope slug (e.g., your username)").option("--force", "Force change existing scope (may break references)").action(async (slug, options) => {
8354
+ var setCommand = new Command23().name("set").description("Set your scope slug").argument("<slug>", "The scope slug (e.g., your username)").option("--force", "Force change existing scope (may break references)").action(async (slug, options) => {
8513
8355
  try {
8514
8356
  let existingScope;
8515
8357
  try {
@@ -8574,15 +8416,15 @@ var setCommand = new Command22().name("set").description("Set your scope slug").
8574
8416
  });
8575
8417
 
8576
8418
  // src/commands/scope/index.ts
8577
- var scopeCommand = new Command23().name("scope").description("Manage your scope (namespace for agents)").addCommand(statusCommand3).addCommand(setCommand);
8419
+ var scopeCommand = new Command24().name("scope").description("Manage your scope (namespace for agents)").addCommand(statusCommand3).addCommand(setCommand);
8578
8420
 
8579
8421
  // src/commands/agent/index.ts
8580
- import { Command as Command26 } from "commander";
8422
+ import { Command as Command27 } from "commander";
8581
8423
 
8582
8424
  // src/commands/agent/list.ts
8583
- import { Command as Command24 } from "commander";
8425
+ import { Command as Command25 } from "commander";
8584
8426
  import chalk28 from "chalk";
8585
- var listCommand3 = new Command24().name("list").alias("ls").description("List all agent composes").action(async () => {
8427
+ var listCommand3 = new Command25().name("list").alias("ls").description("List all agent composes").action(async () => {
8586
8428
  try {
8587
8429
  const response = await httpGet("/api/agent/composes/list");
8588
8430
  if (!response.ok) {
@@ -8625,7 +8467,7 @@ var listCommand3 = new Command24().name("list").alias("ls").description("List al
8625
8467
  });
8626
8468
 
8627
8469
  // src/commands/agent/status.ts
8628
- import { Command as Command25 } from "commander";
8470
+ import { Command as Command26 } from "commander";
8629
8471
  import chalk29 from "chalk";
8630
8472
 
8631
8473
  // src/lib/domain/source-derivation.ts
@@ -8798,7 +8640,7 @@ function formatComposeOutput(name, versionId, content, variableSources) {
8798
8640
  formatAgentDetails(agentName, agent, agentSources, content.volumes);
8799
8641
  }
8800
8642
  }
8801
- var statusCommand4 = new Command25().name("status").description("Show status of agent compose").argument(
8643
+ var statusCommand4 = new Command26().name("status").description("Show status of agent compose").argument(
8802
8644
  "<name[:version]>",
8803
8645
  "Agent name with optional version (e.g., my-agent:latest or my-agent:a1b2c3d4)"
8804
8646
  ).option("--no-sources", "Skip fetching skills to determine variable sources").action(async (argument, options) => {
@@ -8878,10 +8720,10 @@ var statusCommand4 = new Command25().name("status").description("Show status of
8878
8720
  });
8879
8721
 
8880
8722
  // src/commands/agent/index.ts
8881
- var agentCommand = new Command26().name("agent").description("Manage agent composes").addCommand(listCommand3).addCommand(statusCommand4);
8723
+ var agentCommand = new Command27().name("agent").description("Manage agent composes").addCommand(listCommand3).addCommand(statusCommand4);
8882
8724
 
8883
8725
  // src/commands/init.ts
8884
- import { Command as Command27 } from "commander";
8726
+ import { Command as Command28 } from "commander";
8885
8727
  import chalk30 from "chalk";
8886
8728
  import path13 from "path";
8887
8729
  import { existsSync as existsSync9 } from "fs";
@@ -8920,7 +8762,7 @@ function checkExistingFiles() {
8920
8762
  if (existsSync9(AGENTS_MD_FILE)) existingFiles.push(AGENTS_MD_FILE);
8921
8763
  return existingFiles;
8922
8764
  }
8923
- var initCommand3 = new Command27().name("init").description("Initialize a new VM0 project in the current directory").option("-f, --force", "Overwrite existing files").option("-n, --name <name>", "Agent name (required in non-interactive mode)").action(async (options) => {
8765
+ var initCommand3 = new Command28().name("init").description("Initialize a new VM0 project in the current directory").option("-f, --force", "Overwrite existing files").option("-n, --name <name>", "Agent name (required in non-interactive mode)").action(async (options) => {
8924
8766
  const existingFiles = checkExistingFiles();
8925
8767
  if (existingFiles.length > 0 && !options.force) {
8926
8768
  for (const file of existingFiles) {
@@ -8986,10 +8828,10 @@ var initCommand3 = new Command27().name("init").description("Initialize a new VM
8986
8828
  });
8987
8829
 
8988
8830
  // src/commands/schedule/index.ts
8989
- import { Command as Command34 } from "commander";
8831
+ import { Command as Command35 } from "commander";
8990
8832
 
8991
8833
  // src/commands/schedule/setup.ts
8992
- import { Command as Command28 } from "commander";
8834
+ import { Command as Command29 } from "commander";
8993
8835
  import chalk32 from "chalk";
8994
8836
 
8995
8837
  // src/lib/domain/schedule-utils.ts
@@ -9568,7 +9410,7 @@ Deploying schedule for agent ${chalk32.cyan(params.agentName)}...`
9568
9410
  secrets: expandedSecrets,
9569
9411
  artifactName: params.artifactName
9570
9412
  });
9571
- displayDeployResult(params.agentName, deployResult);
9413
+ return deployResult;
9572
9414
  }
9573
9415
  function handleSetupError(error) {
9574
9416
  console.error(chalk32.red("\u2717 Failed to setup schedule"));
@@ -9608,14 +9450,53 @@ function displayDeployResult(agentName, deployResult) {
9608
9450
  );
9609
9451
  console.log(chalk32.dim(` At: ${atTimeFormatted}`));
9610
9452
  }
9611
- if (deployResult.created) {
9612
- console.log();
9453
+ }
9454
+ async function tryEnableSchedule(scheduleName, composeId, agentName) {
9455
+ try {
9456
+ await enableSchedule({ name: scheduleName, composeId });
9613
9457
  console.log(
9614
- ` To activate: ${chalk32.cyan(`vm0 schedule enable ${agentName}`)}`
9458
+ chalk32.green(`\u2713 Enabled schedule for agent ${chalk32.cyan(agentName)}`)
9615
9459
  );
9460
+ } catch (error) {
9461
+ console.error(chalk32.yellow("\u26A0 Failed to enable schedule"));
9462
+ if (error instanceof ApiRequestError) {
9463
+ if (error.code === "SCHEDULE_PAST") {
9464
+ console.error(chalk32.dim(" Scheduled time has already passed"));
9465
+ } else {
9466
+ console.error(chalk32.dim(` ${error.message}`));
9467
+ }
9468
+ } else if (error instanceof Error) {
9469
+ console.error(chalk32.dim(` ${error.message}`));
9470
+ }
9471
+ console.log(
9472
+ ` To enable manually: ${chalk32.cyan(`vm0 schedule enable ${agentName}`)}`
9473
+ );
9474
+ }
9475
+ }
9476
+ function showEnableHint(agentName) {
9477
+ console.log();
9478
+ console.log(` To enable: ${chalk32.cyan(`vm0 schedule enable ${agentName}`)}`);
9479
+ }
9480
+ async function handleScheduleEnabling(params) {
9481
+ const { scheduleName, composeId, agentName, enableFlag, shouldPromptEnable } = params;
9482
+ if (enableFlag) {
9483
+ await tryEnableSchedule(scheduleName, composeId, agentName);
9484
+ return;
9485
+ }
9486
+ if (shouldPromptEnable && isInteractive()) {
9487
+ const enableNow = await promptConfirm("Enable this schedule?", true);
9488
+ if (enableNow) {
9489
+ await tryEnableSchedule(scheduleName, composeId, agentName);
9490
+ } else {
9491
+ showEnableHint(agentName);
9492
+ }
9493
+ return;
9494
+ }
9495
+ if (shouldPromptEnable) {
9496
+ showEnableHint(agentName);
9616
9497
  }
9617
9498
  }
9618
- var setupCommand = new Command28().name("setup").description("Create or edit a schedule for an agent").argument("<agent-name>", "Agent name to configure schedule for").option("-f, --frequency <type>", "Frequency: daily|weekly|monthly|once").option("-t, --time <HH:MM>", "Time to run (24-hour format)").option("-d, --day <day>", "Day of week (mon-sun) or day of month (1-31)").option("-z, --timezone <tz>", "IANA timezone").option("-p, --prompt <text>", "Prompt to run").option("--var <name=value>", "Variable (can be repeated)", collect, []).option("--secret <name=value>", "Secret (can be repeated)", collect, []).option("--artifact-name <name>", "Artifact name", "artifact").action(async (agentName, options) => {
9499
+ var setupCommand = new Command29().name("setup").description("Create or edit a schedule for an agent").argument("<agent-name>", "Agent name to configure schedule for").option("-f, --frequency <type>", "Frequency: daily|weekly|monthly|once").option("-t, --time <HH:MM>", "Time to run (24-hour format)").option("-d, --day <day>", "Day of week (mon-sun) or day of month (1-31)").option("-z, --timezone <tz>", "IANA timezone").option("-p, --prompt <text>", "Prompt to run").option("--var <name=value>", "Variable (can be repeated)", collect, []).option("--secret <name=value>", "Secret (can be repeated)", collect, []).option("--artifact-name <name>", "Artifact name", "artifact").option("-e, --enable", "Enable schedule immediately after creation").action(async (agentName, options) => {
9619
9500
  try {
9620
9501
  const { composeId, scheduleName, composeContent } = await resolveAgent(agentName);
9621
9502
  const requiredConfig = extractRequiredConfiguration(composeContent);
@@ -9662,7 +9543,7 @@ var setupCommand = new Command28().name("setup").description("Create or edit a s
9662
9543
  optionVars: options.var || [],
9663
9544
  existingSchedule
9664
9545
  });
9665
- await buildAndDeploy({
9546
+ const deployResult = await buildAndDeploy({
9666
9547
  scheduleName,
9667
9548
  composeId,
9668
9549
  agentName,
@@ -9676,15 +9557,24 @@ var setupCommand = new Command28().name("setup").description("Create or edit a s
9676
9557
  secrets: config.preserveExistingSecrets ? void 0 : Object.keys(config.secrets).length > 0 ? config.secrets : void 0,
9677
9558
  artifactName: options.artifactName
9678
9559
  });
9560
+ displayDeployResult(agentName, deployResult);
9561
+ const shouldPromptEnable = deployResult.created || existingSchedule !== void 0 && !existingSchedule.enabled;
9562
+ await handleScheduleEnabling({
9563
+ scheduleName,
9564
+ composeId,
9565
+ agentName,
9566
+ enableFlag: options.enable ?? false,
9567
+ shouldPromptEnable
9568
+ });
9679
9569
  } catch (error) {
9680
9570
  handleSetupError(error);
9681
9571
  }
9682
9572
  });
9683
9573
 
9684
9574
  // src/commands/schedule/list.ts
9685
- import { Command as Command29 } from "commander";
9575
+ import { Command as Command30 } from "commander";
9686
9576
  import chalk33 from "chalk";
9687
- var listCommand4 = new Command29().name("list").alias("ls").description("List all schedules").action(async () => {
9577
+ var listCommand4 = new Command30().name("list").alias("ls").description("List all schedules").action(async () => {
9688
9578
  try {
9689
9579
  const result = await listSchedules();
9690
9580
  if (result.schedules.length === 0) {
@@ -9738,7 +9628,7 @@ var listCommand4 = new Command29().name("list").alias("ls").description("List al
9738
9628
  });
9739
9629
 
9740
9630
  // src/commands/schedule/status.ts
9741
- import { Command as Command30 } from "commander";
9631
+ import { Command as Command31 } from "commander";
9742
9632
  import chalk34 from "chalk";
9743
9633
  function formatDateTimeStyled(dateStr) {
9744
9634
  if (!dateStr) return chalk34.dim("-");
@@ -9841,7 +9731,7 @@ function handleStatusError(error, agentName) {
9841
9731
  }
9842
9732
  process.exit(1);
9843
9733
  }
9844
- var statusCommand5 = new Command30().name("status").description("Show detailed status of a schedule").argument("<agent-name>", "Agent name").option(
9734
+ var statusCommand5 = new Command31().name("status").description("Show detailed status of a schedule").argument("<agent-name>", "Agent name").option(
9845
9735
  "-l, --limit <number>",
9846
9736
  "Number of recent runs to show (0 to hide)",
9847
9737
  "5"
@@ -9867,9 +9757,9 @@ var statusCommand5 = new Command30().name("status").description("Show detailed s
9867
9757
  });
9868
9758
 
9869
9759
  // src/commands/schedule/delete.ts
9870
- import { Command as Command31 } from "commander";
9760
+ import { Command as Command32 } from "commander";
9871
9761
  import chalk35 from "chalk";
9872
- var deleteCommand = new Command31().name("delete").alias("rm").description("Delete a schedule").argument("<agent-name>", "Agent name").option("-f, --force", "Skip confirmation prompt").action(async (agentName, options) => {
9762
+ var deleteCommand = new Command32().name("delete").alias("rm").description("Delete a schedule").argument("<agent-name>", "Agent name").option("-f, --force", "Skip confirmation prompt").action(async (agentName, options) => {
9873
9763
  try {
9874
9764
  const resolved = await resolveScheduleByAgent(agentName);
9875
9765
  if (!options.force) {
@@ -9914,9 +9804,9 @@ var deleteCommand = new Command31().name("delete").alias("rm").description("Dele
9914
9804
  });
9915
9805
 
9916
9806
  // src/commands/schedule/enable.ts
9917
- import { Command as Command32 } from "commander";
9807
+ import { Command as Command33 } from "commander";
9918
9808
  import chalk36 from "chalk";
9919
- var enableCommand = new Command32().name("enable").description("Enable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
9809
+ var enableCommand = new Command33().name("enable").description("Enable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
9920
9810
  try {
9921
9811
  const resolved = await resolveScheduleByAgent(agentName);
9922
9812
  await enableSchedule({
@@ -9959,9 +9849,9 @@ var enableCommand = new Command32().name("enable").description("Enable a schedul
9959
9849
  });
9960
9850
 
9961
9851
  // src/commands/schedule/disable.ts
9962
- import { Command as Command33 } from "commander";
9852
+ import { Command as Command34 } from "commander";
9963
9853
  import chalk37 from "chalk";
9964
- var disableCommand = new Command33().name("disable").description("Disable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
9854
+ var disableCommand = new Command34().name("disable").description("Disable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
9965
9855
  try {
9966
9856
  const resolved = await resolveScheduleByAgent(agentName);
9967
9857
  await disableSchedule({
@@ -9990,10 +9880,10 @@ var disableCommand = new Command33().name("disable").description("Disable a sche
9990
9880
  });
9991
9881
 
9992
9882
  // src/commands/schedule/index.ts
9993
- var scheduleCommand = new Command34().name("schedule").description("Manage agent schedules").addCommand(setupCommand).addCommand(listCommand4).addCommand(statusCommand5).addCommand(deleteCommand).addCommand(enableCommand).addCommand(disableCommand);
9883
+ var scheduleCommand = new Command35().name("schedule").description("Manage agent schedules").addCommand(setupCommand).addCommand(listCommand4).addCommand(statusCommand5).addCommand(deleteCommand).addCommand(enableCommand).addCommand(disableCommand);
9994
9884
 
9995
9885
  // src/commands/usage.ts
9996
- import { Command as Command35 } from "commander";
9886
+ import { Command as Command36 } from "commander";
9997
9887
  import chalk38 from "chalk";
9998
9888
 
9999
9889
  // src/lib/utils/duration-formatter.ts
@@ -10067,7 +9957,7 @@ function fillMissingDates(daily, startDate, endDate) {
10067
9957
  result.sort((a, b) => b.date.localeCompare(a.date));
10068
9958
  return result;
10069
9959
  }
10070
- var usageCommand = new Command35().name("usage").description("View usage statistics").option("--since <date>", "Start date (ISO format or relative: 7d, 30d)").option(
9960
+ var usageCommand = new Command36().name("usage").description("View usage statistics").option("--since <date>", "Start date (ISO format or relative: 7d, 30d)").option(
10071
9961
  "--until <date>",
10072
9962
  "End date (ISO format or relative, defaults to now)"
10073
9963
  ).action(async (options) => {
@@ -10164,12 +10054,12 @@ var usageCommand = new Command35().name("usage").description("View usage statist
10164
10054
  });
10165
10055
 
10166
10056
  // src/commands/credential/index.ts
10167
- import { Command as Command39 } from "commander";
10057
+ import { Command as Command40 } from "commander";
10168
10058
 
10169
10059
  // src/commands/credential/list.ts
10170
- import { Command as Command36 } from "commander";
10060
+ import { Command as Command37 } from "commander";
10171
10061
  import chalk39 from "chalk";
10172
- var listCommand5 = new Command36().name("list").alias("ls").description("List all credentials").action(async () => {
10062
+ var listCommand5 = new Command37().name("list").alias("ls").description("List all credentials").action(async () => {
10173
10063
  try {
10174
10064
  const result = await listCredentials();
10175
10065
  if (result.credentials.length === 0) {
@@ -10210,9 +10100,9 @@ var listCommand5 = new Command36().name("list").alias("ls").description("List al
10210
10100
  });
10211
10101
 
10212
10102
  // src/commands/credential/set.ts
10213
- import { Command as Command37 } from "commander";
10103
+ import { Command as Command38 } from "commander";
10214
10104
  import chalk40 from "chalk";
10215
- var setCommand2 = new Command37().name("set").description("Create or update a credential").argument("<name>", "Credential name (uppercase, e.g., MY_API_KEY)").argument("<value>", "Credential value").option("-d, --description <description>", "Optional description").action(
10105
+ var setCommand2 = new Command38().name("set").description("Create or update a credential").argument("<name>", "Credential name (uppercase, e.g., MY_API_KEY)").argument("<value>", "Credential value").option("-d, --description <description>", "Optional description").action(
10216
10106
  async (name, value, options) => {
10217
10107
  try {
10218
10108
  const credential = await setCredential({
@@ -10250,9 +10140,9 @@ var setCommand2 = new Command37().name("set").description("Create or update a cr
10250
10140
  );
10251
10141
 
10252
10142
  // src/commands/credential/delete.ts
10253
- import { Command as Command38 } from "commander";
10143
+ import { Command as Command39 } from "commander";
10254
10144
  import chalk41 from "chalk";
10255
- var deleteCommand2 = new Command38().name("delete").description("Delete a credential").argument("<name>", "Credential name to delete").option("-y, --yes", "Skip confirmation prompt").action(async (name, options) => {
10145
+ var deleteCommand2 = new Command39().name("delete").description("Delete a credential").argument("<name>", "Credential name to delete").option("-y, --yes", "Skip confirmation prompt").action(async (name, options) => {
10256
10146
  try {
10257
10147
  try {
10258
10148
  await getCredential(name);
@@ -10293,15 +10183,15 @@ var deleteCommand2 = new Command38().name("delete").description("Delete a creden
10293
10183
  });
10294
10184
 
10295
10185
  // src/commands/credential/index.ts
10296
- var credentialCommand = new Command39().name("credential").description("Manage stored credentials for agent runs").addCommand(listCommand5).addCommand(setCommand2).addCommand(deleteCommand2);
10186
+ var credentialCommand = new Command40().name("credential").description("Manage stored credentials for agent runs").addCommand(listCommand5).addCommand(setCommand2).addCommand(deleteCommand2);
10297
10187
 
10298
10188
  // src/commands/model-provider/index.ts
10299
- import { Command as Command44 } from "commander";
10189
+ import { Command as Command45 } from "commander";
10300
10190
 
10301
10191
  // src/commands/model-provider/list.ts
10302
- import { Command as Command40 } from "commander";
10192
+ import { Command as Command41 } from "commander";
10303
10193
  import chalk42 from "chalk";
10304
- var listCommand6 = new Command40().name("list").alias("ls").description("List all model providers").action(async () => {
10194
+ var listCommand6 = new Command41().name("list").alias("ls").description("List all model providers").action(async () => {
10305
10195
  try {
10306
10196
  const result = await listModelProviders();
10307
10197
  if (result.modelProviders.length === 0) {
@@ -10355,7 +10245,7 @@ var listCommand6 = new Command40().name("list").alias("ls").description("List al
10355
10245
  });
10356
10246
 
10357
10247
  // src/commands/model-provider/setup.ts
10358
- import { Command as Command41 } from "commander";
10248
+ import { Command as Command42 } from "commander";
10359
10249
  import chalk43 from "chalk";
10360
10250
  import prompts2 from "prompts";
10361
10251
  var providerChoices = Object.entries(MODEL_PROVIDER_TYPES).map(
@@ -10364,7 +10254,7 @@ var providerChoices = Object.entries(MODEL_PROVIDER_TYPES).map(
10364
10254
  value: type
10365
10255
  })
10366
10256
  );
10367
- var setupCommand2 = new Command41().name("setup").description("Configure a model provider").option("-t, --type <type>", "Provider type (for non-interactive mode)").option(
10257
+ var setupCommand2 = new Command42().name("setup").description("Configure a model provider").option("-t, --type <type>", "Provider type (for non-interactive mode)").option(
10368
10258
  "-c, --credential <credential>",
10369
10259
  "Credential value (for non-interactive mode)"
10370
10260
  ).option("--convert", "Convert existing user credential to model provider").action(
@@ -10485,9 +10375,9 @@ var setupCommand2 = new Command41().name("setup").description("Configure a model
10485
10375
  );
10486
10376
 
10487
10377
  // src/commands/model-provider/delete.ts
10488
- import { Command as Command42 } from "commander";
10378
+ import { Command as Command43 } from "commander";
10489
10379
  import chalk44 from "chalk";
10490
- var deleteCommand3 = new Command42().name("delete").description("Delete a model provider").argument("<type>", "Model provider type to delete").action(async (type) => {
10380
+ var deleteCommand3 = new Command43().name("delete").description("Delete a model provider").argument("<type>", "Model provider type to delete").action(async (type) => {
10491
10381
  try {
10492
10382
  if (!Object.keys(MODEL_PROVIDER_TYPES).includes(type)) {
10493
10383
  console.error(chalk44.red(`\u2717 Invalid type "${type}"`));
@@ -10517,9 +10407,9 @@ var deleteCommand3 = new Command42().name("delete").description("Delete a model
10517
10407
  });
10518
10408
 
10519
10409
  // src/commands/model-provider/set-default.ts
10520
- import { Command as Command43 } from "commander";
10410
+ import { Command as Command44 } from "commander";
10521
10411
  import chalk45 from "chalk";
10522
- var setDefaultCommand = new Command43().name("set-default").description("Set a model provider as default for its framework").argument("<type>", "Model provider type to set as default").action(async (type) => {
10412
+ var setDefaultCommand = new Command44().name("set-default").description("Set a model provider as default for its framework").argument("<type>", "Model provider type to set as default").action(async (type) => {
10523
10413
  try {
10524
10414
  if (!Object.keys(MODEL_PROVIDER_TYPES).includes(type)) {
10525
10415
  console.error(chalk45.red(`\u2717 Invalid type "${type}"`));
@@ -10553,13 +10443,354 @@ var setDefaultCommand = new Command43().name("set-default").description("Set a m
10553
10443
  });
10554
10444
 
10555
10445
  // src/commands/model-provider/index.ts
10556
- var modelProviderCommand = new Command44().name("model-provider").description("Manage model providers for agent runs").addCommand(listCommand6).addCommand(setupCommand2).addCommand(deleteCommand3).addCommand(setDefaultCommand);
10446
+ var modelProviderCommand = new Command45().name("model-provider").description("Manage model providers for agent runs").addCommand(listCommand6).addCommand(setupCommand2).addCommand(deleteCommand3).addCommand(setDefaultCommand);
10447
+
10448
+ // src/commands/onboard.ts
10449
+ import { Command as Command47 } from "commander";
10450
+ import chalk47 from "chalk";
10451
+ import prompts3 from "prompts";
10452
+ import { mkdir as mkdir8 } from "fs/promises";
10453
+ import { existsSync as existsSync10 } from "fs";
10454
+
10455
+ // src/commands/setup-claude.ts
10456
+ import { Command as Command46 } from "commander";
10457
+ import chalk46 from "chalk";
10458
+ import { mkdir as mkdir7, writeFile as writeFile7 } from "fs/promises";
10459
+ import path14 from "path";
10460
+ var SKILL_DIR = ".claude/skills/vm0-agent-builder";
10461
+ var SKILL_CONTENT = `---
10462
+ name: vm0-agent-builder
10463
+ description: Guide for building VM0 agents with Claude's help. Use this skill when users want to create or improve their agent's AGENTS.md and vm0.yaml configuration.
10464
+ ---
10465
+
10466
+ # VM0 Agent Builder
10467
+
10468
+ Help users create effective AI agents using the VM0 platform. This skill guides the process of designing agent workflows, writing AGENTS.md instructions, and configuring vm0.yaml.
10469
+
10470
+ ## When to Use
10471
+
10472
+ - User wants to create a new VM0 agent from scratch
10473
+ - User wants to improve an existing agent's instructions
10474
+ - User needs help configuring vm0.yaml with skills
10475
+ - User is unsure how to structure their agent's workflow
10476
+
10477
+ ## Workflow
10478
+
10479
+ ### Step 1: Understand the Goal
10480
+
10481
+ Ask the user what they want their agent to accomplish:
10482
+ - What is the main task or problem to solve?
10483
+ - What inputs will the agent receive?
10484
+ - What outputs should the agent produce?
10485
+ - Are there any constraints or requirements?
10486
+
10487
+ ### Step 2: Design the Workflow
10488
+
10489
+ Break down the task into clear, sequential steps:
10490
+ 1. Each step should be a single, focused action
10491
+ 2. Steps should build on each other logically
10492
+ 3. Include error handling and edge cases
10493
+ 4. Consider what tools/skills the agent will need
10494
+
10495
+ ### Step 3: Write AGENTS.md
10496
+
10497
+ Create the agent instructions file with:
10498
+
10499
+ \`\`\`markdown
10500
+ # Agent Instructions
10501
+
10502
+ You are a [role description].
10503
+
10504
+ ## Goal
10505
+
10506
+ [Clear statement of what the agent should accomplish]
10507
+
10508
+ ## Workflow
10509
+
10510
+ 1. [First step with specific instructions]
10511
+ 2. [Second step with specific instructions]
10512
+ 3. [Continue with remaining steps...]
10513
+
10514
+ ## Output
10515
+
10516
+ [Describe the expected output format and location]
10517
+
10518
+ ## Constraints
10519
+
10520
+ [Any limitations or rules the agent should follow]
10521
+ \`\`\`
10522
+
10523
+ ### Step 4: Configure vm0.yaml
10524
+
10525
+ Update the vm0.yaml to include necessary skills:
10526
+
10527
+ \`\`\`yaml
10528
+ version: "1.0"
10529
+
10530
+ agents:
10531
+ agent-name:
10532
+ framework: claude-code
10533
+ instructions: AGENTS.md
10534
+ skills:
10535
+ - https://github.com/vm0-ai/vm0-skills/tree/main/skill-name
10536
+ environment:
10537
+ # Add any required environment variables
10538
+ API_KEY: "\${{ secrets.API_KEY }}"
10539
+ \`\`\`
10540
+
10541
+ ### Step 5: Test the Agent
10542
+
10543
+ Guide the user to test their agent:
10544
+
10545
+ \`\`\`bash
10546
+ # Deploy the agent configuration
10547
+ vm0 compose vm0.yaml
10548
+
10549
+ # Run the agent with a test prompt
10550
+ vm0 cook "start working on the task"
10551
+
10552
+ # Check the logs if needed
10553
+ vm0 logs <run-id>
10554
+ \`\`\`
10555
+
10556
+ ## Available Skills
10557
+
10558
+ Common skills from vm0-skills repository:
10559
+
10560
+ | Skill | Purpose |
10561
+ |-------|---------|
10562
+ | \`github\` | GitHub API operations (issues, PRs, repos) |
10563
+ | \`slack\` | Send messages to Slack channels |
10564
+ | \`notion\` | Read/write Notion pages and databases |
10565
+ | \`firecrawl\` | Web scraping and content extraction |
10566
+ | \`browserbase\` | Browser automation |
10567
+ | \`openai\` | OpenAI API for embeddings, completions |
10568
+ | \`supabase\` | Database operations with Supabase |
10569
+
10570
+ Browse all skills: https://github.com/vm0-ai/vm0-skills
10571
+
10572
+ ## Example Agents
10573
+
10574
+ ### Content Curator Agent
10575
+
10576
+ \`\`\`markdown
10577
+ # Agent Instructions
10578
+
10579
+ You are a content curator that monitors HackerNews for AI-related articles.
10580
+
10581
+ ## Workflow
10582
+
10583
+ 1. Go to HackerNews and read the top 30 stories
10584
+ 2. Filter for AI, ML, and LLM related content
10585
+ 3. For each relevant article, extract:
10586
+ - Title and URL
10587
+ - Key points (2-3 sentences)
10588
+ - Why it's interesting
10589
+ 4. Write a summary to \`daily-digest.md\`
10590
+
10591
+ ## Output
10592
+
10593
+ Create \`daily-digest.md\` with today's date as the header.
10594
+ \`\`\`
10595
+
10596
+ ### GitHub Issue Tracker Agent
10597
+
10598
+ \`\`\`markdown
10599
+ # Agent Instructions
10600
+
10601
+ You are a GitHub issue tracker that summarizes open issues.
10602
+
10603
+ ## Workflow
10604
+
10605
+ 1. List all open issues in the repository
10606
+ 2. Group issues by labels (bug, feature, docs)
10607
+ 3. For each group, summarize:
10608
+ - Number of issues
10609
+ - Oldest issue age
10610
+ - Most discussed issues
10611
+ 4. Create a report in \`issue-report.md\`
10612
+
10613
+ ## Skills Required
10614
+
10615
+ - github (for API access)
10616
+ \`\`\`
10617
+
10618
+ ### Data Pipeline Agent
10619
+
10620
+ \`\`\`markdown
10621
+ # Agent Instructions
10622
+
10623
+ You are a data pipeline agent that processes CSV files.
10624
+
10625
+ ## Workflow
10626
+
10627
+ 1. Read all CSV files from the input volume
10628
+ 2. For each file:
10629
+ - Validate the schema
10630
+ - Clean missing values
10631
+ - Transform dates to ISO format
10632
+ 3. Merge all files into \`combined.csv\`
10633
+ 4. Generate a summary report
10634
+
10635
+ ## Input
10636
+
10637
+ Files are provided via volume mount.
10638
+
10639
+ ## Output
10640
+
10641
+ Write results to the artifact directory.
10642
+ \`\`\`
10643
+
10644
+ ## Best Practices
10645
+
10646
+ 1. **Be Specific**: Vague instructions lead to unpredictable results
10647
+ 2. **One Task Per Step**: Keep workflow steps focused and atomic
10648
+ 3. **Define Output Clearly**: Specify exact file names and formats
10649
+ 4. **Handle Errors**: Include what to do when things go wrong
10650
+ 5. **Test Incrementally**: Start with simple workflows, add complexity
10651
+ 6. **Use Skills Wisely**: Only include skills the agent actually needs
10652
+
10653
+ ## Troubleshooting
10654
+
10655
+ ### Agent doesn't follow instructions
10656
+ - Make instructions more specific and explicit
10657
+ - Add examples of expected behavior
10658
+ - Break complex steps into smaller sub-steps
10659
+
10660
+ ### Agent uses wrong tools
10661
+ - Specify which tools/skills to use for each step
10662
+ - Add constraints about what NOT to do
10663
+
10664
+ ### Output format is wrong
10665
+ - Provide exact templates for output files
10666
+ - Include example output in the instructions
10667
+ `;
10668
+ var setupClaudeCommand = new Command46().name("setup-claude").description("Add/update Claude skill for agent building").action(async () => {
10669
+ console.log(chalk46.dim("Installing vm0-agent-builder skill..."));
10670
+ await mkdir7(SKILL_DIR, { recursive: true });
10671
+ await writeFile7(path14.join(SKILL_DIR, "SKILL.md"), SKILL_CONTENT);
10672
+ console.log(
10673
+ chalk46.green(`Done Installed vm0-agent-builder skill to ${SKILL_DIR}`)
10674
+ );
10675
+ console.log();
10676
+ console.log("Next step:");
10677
+ console.log(
10678
+ chalk46.cyan(
10679
+ ' claude /vm0-agent-builder "I want to build an agent that..."'
10680
+ )
10681
+ );
10682
+ });
10683
+
10684
+ // src/commands/onboard.ts
10685
+ var DEMO_AGENT_DIR = "vm0-demo-agent";
10686
+ var DEMO_AGENT_NAME = "vm0-demo-agent";
10687
+ var onboardCommand = new Command47().name("onboard").description("Guided setup for new VM0 users").option("-y, --yes", "Skip confirmation prompts").option(
10688
+ "--method <method>",
10689
+ "Agent building method: claude or manual",
10690
+ void 0
10691
+ ).action(async (options) => {
10692
+ const token = await getToken();
10693
+ if (token) {
10694
+ console.log(chalk47.green("Done Authenticated"));
10695
+ } else {
10696
+ console.log(chalk47.dim("Authentication required..."));
10697
+ console.log();
10698
+ await loginCommand.parseAsync([], { from: "user" });
10699
+ }
10700
+ try {
10701
+ const result = await listModelProviders();
10702
+ if (result.modelProviders.length > 0) {
10703
+ console.log(chalk47.green("Done Model provider configured"));
10704
+ } else {
10705
+ console.log(chalk47.dim("Model provider setup required..."));
10706
+ console.log();
10707
+ await setupCommand2.parseAsync([], { from: "user" });
10708
+ }
10709
+ } catch {
10710
+ console.log(chalk47.dim("Setting up model provider..."));
10711
+ console.log();
10712
+ await setupCommand2.parseAsync([], { from: "user" });
10713
+ }
10714
+ let createAgent = options.yes;
10715
+ if (!createAgent && isInteractive()) {
10716
+ const response = await prompts3(
10717
+ {
10718
+ type: "confirm",
10719
+ name: "create",
10720
+ message: `Create ${DEMO_AGENT_DIR}?`,
10721
+ initial: true
10722
+ },
10723
+ { onCancel: () => process.exit(0) }
10724
+ );
10725
+ createAgent = response.create;
10726
+ }
10727
+ if (!createAgent) {
10728
+ console.log(chalk47.dim("Skipped agent creation"));
10729
+ return;
10730
+ }
10731
+ if (existsSync10(DEMO_AGENT_DIR)) {
10732
+ console.log(chalk47.red(`x ${DEMO_AGENT_DIR}/ already exists`));
10733
+ console.log();
10734
+ console.log("Remove it first or use a different directory:");
10735
+ console.log(chalk47.cyan(` rm -rf ${DEMO_AGENT_DIR}`));
10736
+ process.exit(1);
10737
+ }
10738
+ await mkdir8(DEMO_AGENT_DIR, { recursive: true });
10739
+ const originalDir = process.cwd();
10740
+ process.chdir(DEMO_AGENT_DIR);
10741
+ try {
10742
+ await initCommand3.parseAsync(["--name", DEMO_AGENT_NAME], {
10743
+ from: "user"
10744
+ });
10745
+ } finally {
10746
+ process.chdir(originalDir);
10747
+ }
10748
+ console.log();
10749
+ let method = options.method;
10750
+ if (!method && isInteractive()) {
10751
+ const response = await prompts3(
10752
+ {
10753
+ type: "select",
10754
+ name: "method",
10755
+ message: "How would you like to build your agent?",
10756
+ choices: [
10757
+ {
10758
+ title: "Use `vm0 setup-claude` to let Claude help (Recommended)",
10759
+ value: "claude"
10760
+ },
10761
+ {
10762
+ title: "I will do it myself (Edit `AGENTS.md` and `vm0.yaml`)",
10763
+ value: "manual"
10764
+ }
10765
+ ]
10766
+ },
10767
+ { onCancel: () => process.exit(0) }
10768
+ );
10769
+ method = response.method;
10770
+ }
10771
+ if (method === "claude") {
10772
+ process.chdir(DEMO_AGENT_DIR);
10773
+ try {
10774
+ await setupClaudeCommand.parseAsync([], { from: "user" });
10775
+ } finally {
10776
+ process.chdir(originalDir);
10777
+ }
10778
+ } else {
10779
+ console.log("Next steps:");
10780
+ console.log(` 1. ${chalk47.cyan(`cd ${DEMO_AGENT_DIR}`)}`);
10781
+ console.log(
10782
+ ` 2. Edit ${chalk47.cyan("AGENTS.md")} to define your agent's workflow`
10783
+ );
10784
+ console.log(` 3. Edit ${chalk47.cyan("vm0.yaml")} to configure skills`);
10785
+ console.log(` 4. Run ${chalk47.cyan('vm0 cook "start working"')} to test`);
10786
+ }
10787
+ });
10557
10788
 
10558
10789
  // src/index.ts
10559
- var program = new Command45();
10560
- program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.0.0");
10790
+ var program = new Command48();
10791
+ program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.2.0");
10561
10792
  program.command("info").description("Display environment information").action(async () => {
10562
- console.log(chalk46.bold("System Information:"));
10793
+ console.log(chalk48.bold("System Information:"));
10563
10794
  console.log(`Node Version: ${process.version}`);
10564
10795
  console.log(`Platform: ${process.platform}`);
10565
10796
  console.log(`Architecture: ${process.arch}`);
@@ -10567,9 +10798,7 @@ program.command("info").description("Display environment information").action(as
10567
10798
  console.log(`API Host: ${apiUrl}`);
10568
10799
  });
10569
10800
  var authCommand = program.command("auth").description("Authenticate vm0");
10570
- authCommand.command("login").description("Log in to VM0 (use VM0_API_URL env var to set API URL)").action(async () => {
10571
- await authenticate();
10572
- });
10801
+ authCommand.addCommand(loginCommand);
10573
10802
  authCommand.command("logout").description("Log out of VM0").action(async () => {
10574
10803
  await logout();
10575
10804
  });
@@ -10592,6 +10821,8 @@ program.addCommand(scheduleCommand);
10592
10821
  program.addCommand(usageCommand);
10593
10822
  program.addCommand(credentialCommand);
10594
10823
  program.addCommand(modelProviderCommand);
10824
+ program.addCommand(onboardCommand);
10825
+ program.addCommand(setupClaudeCommand);
10595
10826
  if (process.argv[1]?.endsWith("index.js") || process.argv[1]?.endsWith("index.ts") || process.argv[1]?.endsWith("vm0")) {
10596
10827
  program.parse();
10597
10828
  }