@vm0/cli 0.2.0 → 0.3.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 +674 -8
  2. package/package.json +3 -2
package/index.js CHANGED
@@ -12147,19 +12147,685 @@ var helloContract = c.router({
12147
12147
  var FOO = "hello";
12148
12148
 
12149
12149
  // src/index.ts
12150
- import { Command } from "commander";
12150
+ import { Command as Command3 } from "commander";
12151
+ import chalk5 from "chalk";
12152
+
12153
+ // src/lib/auth.ts
12151
12154
  import chalk from "chalk";
12152
- var program = new Command();
12153
- program.name("vm0-cli").description("Vm0 CLI - A modern build tool").version("0.1.0");
12155
+
12156
+ // src/lib/config.ts
12157
+ import { homedir } from "os";
12158
+ import { join } from "path";
12159
+ import { readFile, writeFile, mkdir, unlink } from "fs/promises";
12160
+ import { existsSync } from "fs";
12161
+ var CONFIG_DIR = join(homedir(), ".vm0");
12162
+ var CONFIG_FILE = join(CONFIG_DIR, "config.json");
12163
+ async function loadConfig() {
12164
+ if (!existsSync(CONFIG_FILE)) {
12165
+ return {};
12166
+ }
12167
+ const content = await readFile(CONFIG_FILE, "utf8");
12168
+ return JSON.parse(content);
12169
+ }
12170
+ async function saveConfig(config2) {
12171
+ await mkdir(CONFIG_DIR, { recursive: true });
12172
+ const existing = await loadConfig();
12173
+ const merged = { ...existing, ...config2 };
12174
+ await writeFile(CONFIG_FILE, JSON.stringify(merged, null, 2), "utf8");
12175
+ }
12176
+ async function getToken() {
12177
+ if (process.env.VM0_TOKEN) {
12178
+ return process.env.VM0_TOKEN;
12179
+ }
12180
+ const config2 = await loadConfig();
12181
+ return config2.token;
12182
+ }
12183
+ async function getApiUrl() {
12184
+ const config2 = await loadConfig();
12185
+ const apiHost = process.env.API_HOST;
12186
+ if (apiHost) {
12187
+ return apiHost.startsWith("http") ? apiHost : `https://${apiHost}`;
12188
+ }
12189
+ return config2.apiUrl ?? "https://www.vm0.ai";
12190
+ }
12191
+ async function clearConfig() {
12192
+ if (existsSync(CONFIG_FILE)) {
12193
+ await unlink(CONFIG_FILE);
12194
+ }
12195
+ }
12196
+
12197
+ // src/lib/auth.ts
12198
+ function buildHeaders() {
12199
+ const headers = {
12200
+ "Content-Type": "application/json"
12201
+ };
12202
+ const bypassSecret = process.env.VERCEL_AUTOMATION_BYPASS_SECRET;
12203
+ if (bypassSecret) {
12204
+ headers["x-vercel-protection-bypass"] = bypassSecret;
12205
+ }
12206
+ return headers;
12207
+ }
12208
+ async function requestDeviceCode(apiUrl) {
12209
+ const response = await fetch(`${apiUrl}/api/cli/auth/device`, {
12210
+ method: "POST",
12211
+ headers: buildHeaders(),
12212
+ body: JSON.stringify({})
12213
+ });
12214
+ if (!response.ok) {
12215
+ throw new Error(`Failed to request device code: ${response.statusText}`);
12216
+ }
12217
+ return response.json();
12218
+ }
12219
+ async function exchangeToken(apiUrl, deviceCode) {
12220
+ const response = await fetch(`${apiUrl}/api/cli/auth/token`, {
12221
+ method: "POST",
12222
+ headers: buildHeaders(),
12223
+ body: JSON.stringify({ device_code: deviceCode })
12224
+ });
12225
+ return response.json();
12226
+ }
12227
+ function delay(ms) {
12228
+ return new Promise((resolve) => setTimeout(resolve, ms));
12229
+ }
12230
+ async function authenticate(apiUrl) {
12231
+ const targetApiUrl = apiUrl ?? await getApiUrl();
12232
+ console.log(chalk.blue("Initiating authentication..."));
12233
+ const deviceAuth = await requestDeviceCode(targetApiUrl);
12234
+ console.log(chalk.green("\nDevice code generated"));
12235
+ const verificationUrl = `${targetApiUrl}/cli-auth`;
12236
+ console.log(chalk.cyan(`
12237
+ To authenticate, visit: ${verificationUrl}`));
12238
+ console.log(`And enter this code: ${chalk.bold(deviceAuth.user_code)}`);
12239
+ console.log(
12240
+ `
12241
+ The code expires in ${Math.floor(deviceAuth.expires_in / 60)} minutes.`
12242
+ );
12243
+ console.log(chalk.blue("\nWaiting for authentication..."));
12244
+ const startTime = Date.now();
12245
+ const maxWaitTime = deviceAuth.expires_in * 1e3;
12246
+ const pollInterval = (deviceAuth.interval || 5) * 1e3;
12247
+ let isFirstPoll = true;
12248
+ while (Date.now() - startTime < maxWaitTime) {
12249
+ if (!isFirstPoll) {
12250
+ await delay(pollInterval);
12251
+ }
12252
+ isFirstPoll = false;
12253
+ const tokenResult = await exchangeToken(
12254
+ targetApiUrl,
12255
+ deviceAuth.device_code
12256
+ );
12257
+ if (tokenResult.access_token) {
12258
+ await saveConfig({
12259
+ token: tokenResult.access_token,
12260
+ apiUrl: targetApiUrl
12261
+ });
12262
+ console.log(chalk.green("\nAuthentication successful!"));
12263
+ console.log("Your credentials have been saved.");
12264
+ return;
12265
+ }
12266
+ if (tokenResult.error === "authorization_pending") {
12267
+ process.stdout.write(chalk.gray("."));
12268
+ continue;
12269
+ }
12270
+ if (tokenResult.error === "expired_token") {
12271
+ console.log(
12272
+ chalk.red("\nThe device code has expired. Please try again.")
12273
+ );
12274
+ process.exit(1);
12275
+ }
12276
+ if (tokenResult.error) {
12277
+ console.log(
12278
+ chalk.red(
12279
+ `
12280
+ Authentication failed: ${tokenResult.error_description ?? tokenResult.error}`
12281
+ )
12282
+ );
12283
+ process.exit(1);
12284
+ }
12285
+ }
12286
+ console.log(chalk.red("\nAuthentication timed out. Please try again."));
12287
+ process.exit(1);
12288
+ }
12289
+ async function logout() {
12290
+ await clearConfig();
12291
+ console.log(chalk.green("Successfully logged out"));
12292
+ console.log("Your credentials have been cleared.");
12293
+ }
12294
+ async function checkAuthStatus() {
12295
+ const config2 = await loadConfig();
12296
+ if (config2.token) {
12297
+ console.log(chalk.green("Authenticated"));
12298
+ console.log("You are logged in to VM0.");
12299
+ } else {
12300
+ console.log(chalk.yellow("Not authenticated"));
12301
+ console.log("Run 'vm0 auth login' to authenticate.");
12302
+ }
12303
+ if (process.env.VM0_TOKEN) {
12304
+ console.log(chalk.blue("Using token from VM0_TOKEN environment variable"));
12305
+ }
12306
+ }
12307
+
12308
+ // src/commands/build.ts
12309
+ import { Command } from "commander";
12310
+ import chalk2 from "chalk";
12311
+ import { readFile as readFile2 } from "fs/promises";
12312
+ import { existsSync as existsSync2 } from "fs";
12313
+ import { parse as parseYaml } from "yaml";
12314
+
12315
+ // src/lib/api-client.ts
12316
+ var ApiClient = class {
12317
+ async getHeaders() {
12318
+ const token = await getToken();
12319
+ if (!token) {
12320
+ throw new Error("Not authenticated. Run: vm0 auth login");
12321
+ }
12322
+ return {
12323
+ Authorization: `Bearer ${token}`,
12324
+ "Content-Type": "application/json"
12325
+ };
12326
+ }
12327
+ async getBaseUrl() {
12328
+ const apiUrl = await getApiUrl();
12329
+ if (!apiUrl) {
12330
+ throw new Error("API URL not configured");
12331
+ }
12332
+ return apiUrl;
12333
+ }
12334
+ async getConfigByName(name) {
12335
+ const baseUrl = await this.getBaseUrl();
12336
+ const headers = await this.getHeaders();
12337
+ const response = await fetch(
12338
+ `${baseUrl}/api/agent/configs?name=${encodeURIComponent(name)}`,
12339
+ {
12340
+ method: "GET",
12341
+ headers
12342
+ }
12343
+ );
12344
+ if (!response.ok) {
12345
+ const error43 = await response.json();
12346
+ throw new Error(error43.error || `Config not found: ${name}`);
12347
+ }
12348
+ return await response.json();
12349
+ }
12350
+ async createOrUpdateConfig(body) {
12351
+ const baseUrl = await this.getBaseUrl();
12352
+ const headers = await this.getHeaders();
12353
+ const response = await fetch(`${baseUrl}/api/agent/configs`, {
12354
+ method: "POST",
12355
+ headers,
12356
+ body: JSON.stringify(body)
12357
+ });
12358
+ if (!response.ok) {
12359
+ const error43 = await response.json();
12360
+ throw new Error(error43.error || "Failed to create config");
12361
+ }
12362
+ return await response.json();
12363
+ }
12364
+ async createRun(body) {
12365
+ const baseUrl = await this.getBaseUrl();
12366
+ const headers = await this.getHeaders();
12367
+ const response = await fetch(`${baseUrl}/api/agent/runs`, {
12368
+ method: "POST",
12369
+ headers,
12370
+ body: JSON.stringify(body)
12371
+ });
12372
+ if (!response.ok) {
12373
+ const error43 = await response.json();
12374
+ throw new Error(error43.error || "Failed to create run");
12375
+ }
12376
+ return await response.json();
12377
+ }
12378
+ async getEvents(runId, options) {
12379
+ const baseUrl = await this.getBaseUrl();
12380
+ const headers = await this.getHeaders();
12381
+ const since = options?.since ?? 0;
12382
+ const limit = options?.limit ?? 100;
12383
+ const response = await fetch(
12384
+ `${baseUrl}/api/agent/runs/${runId}/events?since=${since}&limit=${limit}`,
12385
+ {
12386
+ method: "GET",
12387
+ headers
12388
+ }
12389
+ );
12390
+ if (!response.ok) {
12391
+ const error43 = await response.json();
12392
+ throw new Error(error43.error || "Failed to fetch events");
12393
+ }
12394
+ return await response.json();
12395
+ }
12396
+ };
12397
+ var apiClient = new ApiClient();
12398
+
12399
+ // src/lib/yaml-validator.ts
12400
+ function validateAgentName(name) {
12401
+ const nameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{1,62}[a-zA-Z0-9])?$/;
12402
+ return nameRegex.test(name);
12403
+ }
12404
+ function validateAgentConfig(config2) {
12405
+ if (!config2 || typeof config2 !== "object") {
12406
+ return { valid: false, error: "Config must be an object" };
12407
+ }
12408
+ const cfg = config2;
12409
+ if (!cfg.version) {
12410
+ return { valid: false, error: "Missing config.version" };
12411
+ }
12412
+ if (!cfg.agent || typeof cfg.agent !== "object") {
12413
+ return { valid: false, error: "Missing config.agent" };
12414
+ }
12415
+ const agent = cfg.agent;
12416
+ if (!agent.name) {
12417
+ return { valid: false, error: "Missing agent.name" };
12418
+ }
12419
+ if (typeof agent.name !== "string") {
12420
+ return { valid: false, error: "agent.name must be a string" };
12421
+ }
12422
+ if (!validateAgentName(agent.name)) {
12423
+ return {
12424
+ valid: false,
12425
+ error: "Invalid agent.name format. Must be 3-64 characters, letters, numbers, and hyphens only. Must start and end with letter or number."
12426
+ };
12427
+ }
12428
+ return { valid: true };
12429
+ }
12430
+
12431
+ // src/commands/build.ts
12432
+ var buildCommand = new Command().name("build").description("Create or update agent configuration").argument("<config-file>", "Path to config YAML file").action(async (configFile) => {
12433
+ try {
12434
+ if (!existsSync2(configFile)) {
12435
+ console.error(chalk2.red(`\u2717 Config file not found: ${configFile}`));
12436
+ process.exit(1);
12437
+ }
12438
+ const content = await readFile2(configFile, "utf8");
12439
+ let config2;
12440
+ try {
12441
+ config2 = parseYaml(content);
12442
+ } catch (error43) {
12443
+ console.error(chalk2.red("\u2717 Invalid YAML format"));
12444
+ if (error43 instanceof Error) {
12445
+ console.error(chalk2.gray(` ${error43.message}`));
12446
+ }
12447
+ process.exit(1);
12448
+ }
12449
+ const validation = validateAgentConfig(config2);
12450
+ if (!validation.valid) {
12451
+ console.error(chalk2.red(`\u2717 ${validation.error}`));
12452
+ process.exit(1);
12453
+ }
12454
+ console.log(chalk2.blue("Uploading configuration..."));
12455
+ const response = await apiClient.createOrUpdateConfig({ config: config2 });
12456
+ if (response.action === "created") {
12457
+ console.log(chalk2.green(`\u2713 Config created: ${response.name}`));
12458
+ } else {
12459
+ console.log(chalk2.green(`\u2713 Config updated: ${response.name}`));
12460
+ }
12461
+ console.log(chalk2.gray(` Config ID: ${response.configId}`));
12462
+ console.log();
12463
+ console.log(" Run your agent:");
12464
+ console.log(chalk2.cyan(` vm0 run ${response.name} "your prompt"`));
12465
+ } catch (error43) {
12466
+ if (error43 instanceof Error) {
12467
+ if (error43.message.includes("Not authenticated")) {
12468
+ console.error(chalk2.red("\u2717 Not authenticated. Run: vm0 auth login"));
12469
+ } else if (error43.message.includes("Failed to create config")) {
12470
+ console.error(chalk2.red("\u2717 Failed to create config"));
12471
+ console.error(chalk2.gray(` ${error43.message}`));
12472
+ } else {
12473
+ console.error(chalk2.red("\u2717 Failed to create config"));
12474
+ console.error(chalk2.gray(` ${error43.message}`));
12475
+ }
12476
+ } else {
12477
+ console.error(chalk2.red("\u2717 An unexpected error occurred"));
12478
+ }
12479
+ process.exit(1);
12480
+ }
12481
+ });
12482
+
12483
+ // src/commands/run.ts
12484
+ import { Command as Command2 } from "commander";
12485
+ import chalk4 from "chalk";
12486
+
12487
+ // src/lib/event-parser.ts
12488
+ var ClaudeEventParser = class {
12489
+ /**
12490
+ * Parse a raw Claude Code JSONL event into a simplified format
12491
+ * Returns null if the event type is unknown or malformed
12492
+ */
12493
+ static parse(rawEvent) {
12494
+ if (!rawEvent || typeof rawEvent !== "object" || !("type" in rawEvent)) {
12495
+ return null;
12496
+ }
12497
+ switch (rawEvent.type) {
12498
+ case "system":
12499
+ return this.parseSystemEvent(rawEvent);
12500
+ case "assistant":
12501
+ return this.parseAssistantMessage(rawEvent);
12502
+ case "user":
12503
+ return this.parseUserMessage(rawEvent);
12504
+ case "result":
12505
+ return this.parseResultEvent(rawEvent);
12506
+ default:
12507
+ return null;
12508
+ }
12509
+ }
12510
+ static parseSystemEvent(event) {
12511
+ if (event.subtype !== "init") {
12512
+ return null;
12513
+ }
12514
+ return {
12515
+ type: "init",
12516
+ timestamp: /* @__PURE__ */ new Date(),
12517
+ data: {
12518
+ sessionId: event.session_id,
12519
+ model: event.model,
12520
+ tools: event.tools,
12521
+ ...event.cwd && { cwd: event.cwd }
12522
+ }
12523
+ };
12524
+ }
12525
+ static parseAssistantMessage(event) {
12526
+ if (!event.message?.content || event.message.content.length === 0) {
12527
+ return null;
12528
+ }
12529
+ const content = event.message.content[0];
12530
+ if (!content) {
12531
+ return null;
12532
+ }
12533
+ if (content.type === "text") {
12534
+ return {
12535
+ type: "text",
12536
+ timestamp: /* @__PURE__ */ new Date(),
12537
+ data: { text: content.text }
12538
+ };
12539
+ }
12540
+ if (content.type === "tool_use") {
12541
+ return {
12542
+ type: "tool_use",
12543
+ timestamp: /* @__PURE__ */ new Date(),
12544
+ data: {
12545
+ tool: content.name,
12546
+ toolUseId: content.id,
12547
+ input: content.input || {}
12548
+ }
12549
+ };
12550
+ }
12551
+ return null;
12552
+ }
12553
+ static parseUserMessage(event) {
12554
+ if (!event.message?.content || event.message.content.length === 0) {
12555
+ return null;
12556
+ }
12557
+ const content = event.message.content[0];
12558
+ if (!content) {
12559
+ return null;
12560
+ }
12561
+ if (content.type === "tool_result") {
12562
+ return {
12563
+ type: "tool_result",
12564
+ timestamp: /* @__PURE__ */ new Date(),
12565
+ data: {
12566
+ toolUseId: content.tool_use_id,
12567
+ result: content.content,
12568
+ isError: content.is_error || false
12569
+ }
12570
+ };
12571
+ }
12572
+ return null;
12573
+ }
12574
+ static parseResultEvent(event) {
12575
+ return {
12576
+ type: "result",
12577
+ timestamp: /* @__PURE__ */ new Date(),
12578
+ data: {
12579
+ success: !event.is_error,
12580
+ result: event.result,
12581
+ durationMs: event.duration_ms,
12582
+ numTurns: event.num_turns,
12583
+ cost: event.total_cost_usd,
12584
+ usage: event.usage
12585
+ }
12586
+ };
12587
+ }
12588
+ };
12589
+
12590
+ // src/lib/event-renderer.ts
12591
+ import chalk3 from "chalk";
12592
+ var EventRenderer = class {
12593
+ /**
12594
+ * Render a parsed event to console
12595
+ */
12596
+ static render(event) {
12597
+ switch (event.type) {
12598
+ case "init":
12599
+ this.renderInit(event);
12600
+ break;
12601
+ case "text":
12602
+ this.renderText(event);
12603
+ break;
12604
+ case "tool_use":
12605
+ this.renderToolUse(event);
12606
+ break;
12607
+ case "tool_result":
12608
+ this.renderToolResult(event);
12609
+ break;
12610
+ case "result":
12611
+ this.renderResult(event);
12612
+ break;
12613
+ }
12614
+ }
12615
+ static renderInit(event) {
12616
+ console.log(chalk3.cyan("[init]") + " Starting Claude Code agent");
12617
+ console.log(` Session: ${chalk3.gray(String(event.data.sessionId || ""))}`);
12618
+ console.log(` Model: ${chalk3.gray(String(event.data.model || ""))}`);
12619
+ console.log(
12620
+ ` Tools: ${chalk3.gray(
12621
+ Array.isArray(event.data.tools) ? event.data.tools.join(", ") : String(event.data.tools || "")
12622
+ )}`
12623
+ );
12624
+ }
12625
+ static renderText(event) {
12626
+ const text = String(event.data.text || "");
12627
+ console.log(chalk3.blue("[text]") + " " + text);
12628
+ }
12629
+ static renderToolUse(event) {
12630
+ const tool = String(event.data.tool || "");
12631
+ console.log(chalk3.yellow("[tool_use]") + " " + tool);
12632
+ const input = event.data.input;
12633
+ if (input && typeof input === "object") {
12634
+ for (const [key, value] of Object.entries(input)) {
12635
+ if (value !== void 0 && value !== null) {
12636
+ const valueStr = String(value);
12637
+ const displayValue = valueStr.length > 100 ? valueStr.substring(0, 100) + "..." : valueStr;
12638
+ console.log(` ${key}: ${chalk3.gray(displayValue)}`);
12639
+ }
12640
+ }
12641
+ }
12642
+ }
12643
+ static renderToolResult(event) {
12644
+ const isError = Boolean(event.data.isError);
12645
+ const status = isError ? "Error" : "Completed";
12646
+ const color = isError ? chalk3.red : chalk3.green;
12647
+ console.log(color("[tool_result]") + " " + status);
12648
+ const result = String(event.data.result || "");
12649
+ const displayResult = result.length > 200 ? result.substring(0, 200) + "..." : result;
12650
+ console.log(` ${chalk3.gray(displayResult)}`);
12651
+ }
12652
+ static renderResult(event) {
12653
+ const success2 = Boolean(event.data.success);
12654
+ const status = success2 ? "\u2713 completed successfully" : "\u2717 failed";
12655
+ const color = success2 ? chalk3.green : chalk3.red;
12656
+ console.log(color("[result]") + " " + status);
12657
+ const durationMs = Number(event.data.durationMs || 0);
12658
+ const durationSec = (durationMs / 1e3).toFixed(1);
12659
+ console.log(` Duration: ${chalk3.gray(durationSec + "s")}`);
12660
+ const cost = Number(event.data.cost || 0);
12661
+ console.log(` Cost: ${chalk3.gray("$" + cost.toFixed(4))}`);
12662
+ const numTurns = Number(event.data.numTurns || 0);
12663
+ console.log(` Turns: ${chalk3.gray(String(numTurns))}`);
12664
+ const usage = event.data.usage;
12665
+ if (usage && typeof usage === "object") {
12666
+ const inputTokens = Number(usage.input_tokens || 0);
12667
+ const outputTokens = Number(usage.output_tokens || 0);
12668
+ const formatTokens = (count) => {
12669
+ if (count >= 1e3) {
12670
+ return Math.floor(count / 1e3) + "k";
12671
+ }
12672
+ return String(count);
12673
+ };
12674
+ console.log(
12675
+ ` Tokens: ${chalk3.gray(
12676
+ `input=${formatTokens(inputTokens)} output=${formatTokens(outputTokens)}`
12677
+ )}`
12678
+ );
12679
+ }
12680
+ }
12681
+ };
12682
+
12683
+ // src/commands/run.ts
12684
+ function collectEnvVars(value, previous) {
12685
+ const [key, ...valueParts] = value.split("=");
12686
+ const val = valueParts.join("=");
12687
+ if (!key || val === void 0 || val === "") {
12688
+ throw new Error(`Invalid env var format: ${value} (expected key=value)`);
12689
+ }
12690
+ return { ...previous, [key]: val };
12691
+ }
12692
+ function isUUID(str) {
12693
+ return /^[0-9a-f-]{36}$/i.test(str);
12694
+ }
12695
+ async function pollEvents(runId) {
12696
+ let nextSequence = 0;
12697
+ let complete = false;
12698
+ const pollIntervalMs = 500;
12699
+ while (!complete) {
12700
+ try {
12701
+ const response = await apiClient.getEvents(runId, {
12702
+ since: nextSequence
12703
+ });
12704
+ for (const event of response.events) {
12705
+ const parsed = ClaudeEventParser.parse(event.eventData);
12706
+ if (parsed) {
12707
+ EventRenderer.render(parsed);
12708
+ if (parsed.type === "result") {
12709
+ complete = true;
12710
+ }
12711
+ }
12712
+ }
12713
+ nextSequence = response.nextSequence;
12714
+ if (response.events.length === 0 && !complete) {
12715
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
12716
+ }
12717
+ } catch (error43) {
12718
+ console.error(
12719
+ chalk4.red("\u2717 Failed to poll events:"),
12720
+ error43 instanceof Error ? error43.message : "Unknown error"
12721
+ );
12722
+ throw error43;
12723
+ }
12724
+ }
12725
+ }
12726
+ var runCommand = new Command2().name("run").description("Execute an agent").argument(
12727
+ "<identifier>",
12728
+ "Agent name or config ID (e.g., 'my-agent' or 'cfg-abc-123')"
12729
+ ).argument("<prompt>", "Prompt for the agent").option(
12730
+ "-e, --env <key=value>",
12731
+ "Environment variables (repeatable)",
12732
+ collectEnvVars,
12733
+ {}
12734
+ ).action(
12735
+ async (identifier, prompt, options) => {
12736
+ try {
12737
+ let configId;
12738
+ if (isUUID(identifier)) {
12739
+ configId = identifier;
12740
+ console.log(chalk4.gray(` Using config ID: ${configId}`));
12741
+ } else {
12742
+ console.log(chalk4.gray(` Resolving agent name: ${identifier}`));
12743
+ try {
12744
+ const config2 = await apiClient.getConfigByName(identifier);
12745
+ configId = config2.id;
12746
+ console.log(chalk4.gray(` Resolved to config ID: ${configId}`));
12747
+ } catch (error43) {
12748
+ if (error43 instanceof Error) {
12749
+ console.error(chalk4.red(`\u2717 Agent not found: ${identifier}`));
12750
+ console.error(
12751
+ chalk4.gray(
12752
+ " Make sure you've built the agent with: vm0 build"
12753
+ )
12754
+ );
12755
+ }
12756
+ process.exit(1);
12757
+ }
12758
+ }
12759
+ console.log(chalk4.blue("\nCreating agent run..."));
12760
+ console.log(chalk4.gray(` Prompt: ${prompt}`));
12761
+ if (Object.keys(options.env).length > 0) {
12762
+ console.log(
12763
+ chalk4.gray(` Variables: ${JSON.stringify(options.env)}`)
12764
+ );
12765
+ }
12766
+ console.log();
12767
+ console.log(chalk4.blue("Executing in sandbox..."));
12768
+ console.log();
12769
+ const response = await apiClient.createRun({
12770
+ agentConfigId: configId,
12771
+ prompt,
12772
+ dynamicVars: Object.keys(options.env).length > 0 ? options.env : void 0
12773
+ });
12774
+ await pollEvents(response.runId);
12775
+ } catch (error43) {
12776
+ if (error43 instanceof Error) {
12777
+ if (error43.message.includes("Not authenticated")) {
12778
+ console.error(
12779
+ chalk4.red("\u2717 Not authenticated. Run: vm0 auth login")
12780
+ );
12781
+ } else if (error43.message.includes("not found")) {
12782
+ console.error(chalk4.red(`\u2717 Agent not found: ${identifier}`));
12783
+ console.error(
12784
+ chalk4.gray(" Make sure you've built the agent with: vm0 build")
12785
+ );
12786
+ } else {
12787
+ console.error(chalk4.red("\u2717 Run failed"));
12788
+ console.error(chalk4.gray(` ${error43.message}`));
12789
+ }
12790
+ } else {
12791
+ console.error(chalk4.red("\u2717 An unexpected error occurred"));
12792
+ }
12793
+ process.exit(1);
12794
+ }
12795
+ }
12796
+ );
12797
+
12798
+ // src/index.ts
12799
+ var program = new Command3();
12800
+ program.name("vm0").description("VM0 CLI - A modern build tool").version("0.1.0");
12154
12801
  program.command("hello").description("Say hello from the App").action(() => {
12155
- console.log(chalk.blue("Welcome to the Vm0 CLI!"));
12156
- console.log(chalk.green(`Core says: ${FOO}`));
12802
+ console.log(chalk5.blue("Welcome to the VM0 CLI!"));
12803
+ console.log(chalk5.green(`Core says: ${FOO}`));
12157
12804
  });
12158
- program.command("info").description("Display environment information").action(() => {
12159
- console.log(chalk.cyan("System Information:"));
12805
+ program.command("info").description("Display environment information").action(async () => {
12806
+ console.log(chalk5.cyan("System Information:"));
12160
12807
  console.log(`Node Version: ${process.version}`);
12161
12808
  console.log(`Platform: ${process.platform}`);
12162
12809
  console.log(`Architecture: ${process.arch}`);
12810
+ const apiUrl = await getApiUrl();
12811
+ console.log(`API Host: ${apiUrl}`);
12812
+ });
12813
+ var authCommand = program.command("auth").description("Authentication commands");
12814
+ authCommand.command("login").description("Log in to VM0 (use API_HOST env var to set API URL)").action(async () => {
12815
+ await authenticate();
12163
12816
  });
12164
- program.parse();
12817
+ authCommand.command("logout").description("Log out of VM0").action(async () => {
12818
+ await logout();
12819
+ });
12820
+ authCommand.command("status").description("Show current authentication status").action(async () => {
12821
+ await checkAuthStatus();
12822
+ });
12823
+ program.addCommand(buildCommand);
12824
+ program.addCommand(runCommand);
12825
+ if (process.argv[1]?.endsWith("index.js") || process.argv[1]?.endsWith("index.ts") || process.argv[1]?.endsWith("vm0")) {
12826
+ program.parse();
12827
+ }
12828
+ export {
12829
+ program
12830
+ };
12165
12831
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "CLI application",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,6 +11,7 @@
11
11
  ],
12
12
  "dependencies": {
13
13
  "chalk": "^5.6.0",
14
- "commander": "^14.0.0"
14
+ "commander": "^14.0.0",
15
+ "yaml": "^2.3.4"
15
16
  }
16
17
  }