@vm0/cli 9.6.1 → 9.7.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.
- package/index.js +992 -732
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -3183,10 +3183,6 @@ var FEATURE_SWITCHES = {
|
|
|
3183
3183
|
["platformApiKeys" /* PlatformApiKeys */]: {
|
|
3184
3184
|
maintainer: "ethan@vm0.ai",
|
|
3185
3185
|
enabled: false
|
|
3186
|
-
},
|
|
3187
|
-
["platformLogs" /* PlatformLogs */]: {
|
|
3188
|
-
maintainer: "ethan@vm0.ai",
|
|
3189
|
-
enabled: false
|
|
3190
3186
|
}
|
|
3191
3187
|
};
|
|
3192
3188
|
|
|
@@ -4610,22 +4606,216 @@ var composeCommand = new Command7().name("compose").description("Create or updat
|
|
|
4610
4606
|
|
|
4611
4607
|
// src/commands/run/run.ts
|
|
4612
4608
|
import { Command as Command8, Option } from "commander";
|
|
4613
|
-
import
|
|
4609
|
+
import chalk8 from "chalk";
|
|
4614
4610
|
|
|
4615
4611
|
// src/lib/events/event-renderer.ts
|
|
4612
|
+
import chalk5 from "chalk";
|
|
4613
|
+
|
|
4614
|
+
// src/lib/events/tool-formatters.ts
|
|
4616
4615
|
import chalk4 from "chalk";
|
|
4617
|
-
|
|
4616
|
+
function pluralize(count, singular, plural) {
|
|
4617
|
+
return count === 1 ? singular : plural;
|
|
4618
|
+
}
|
|
4619
|
+
function truncate(text, maxLength) {
|
|
4620
|
+
if (text.length <= maxLength) return text;
|
|
4621
|
+
return text.slice(0, maxLength - 3) + "...";
|
|
4622
|
+
}
|
|
4623
|
+
function formatToolHeader(data) {
|
|
4624
|
+
const { tool, input } = data;
|
|
4625
|
+
const headline = getToolHeadline(tool, input);
|
|
4626
|
+
return [headline];
|
|
4627
|
+
}
|
|
4628
|
+
var toolHeadlineFormatters = {
|
|
4629
|
+
Read: (input) => `Read(${chalk4.dim(String(input.file_path || ""))})`,
|
|
4630
|
+
Edit: (input) => `Edit(${chalk4.dim(String(input.file_path || ""))})`,
|
|
4631
|
+
Write: (input) => `Write(${chalk4.dim(String(input.file_path || ""))})`,
|
|
4632
|
+
Bash: (input) => `Bash(${chalk4.dim(truncate(String(input.command || ""), 60))})`,
|
|
4633
|
+
Glob: (input) => `Glob(${chalk4.dim(String(input.pattern || ""))})`,
|
|
4634
|
+
Grep: (input) => `Grep(${chalk4.dim(String(input.pattern || ""))})`,
|
|
4635
|
+
Task: (input) => `Task(${chalk4.dim(truncate(String(input.description || ""), 60))})`,
|
|
4636
|
+
WebFetch: (input) => `WebFetch(${chalk4.dim(truncate(String(input.url || ""), 60))})`,
|
|
4637
|
+
WebSearch: (input) => `WebSearch(${chalk4.dim(truncate(String(input.query || ""), 60))})`,
|
|
4638
|
+
TodoWrite: () => "TodoWrite"
|
|
4639
|
+
};
|
|
4640
|
+
function getToolHeadline(tool, input) {
|
|
4641
|
+
const formatter = toolHeadlineFormatters[tool];
|
|
4642
|
+
return formatter ? formatter(input) : tool;
|
|
4643
|
+
}
|
|
4644
|
+
function formatToolResult(toolUse, result, verbose) {
|
|
4645
|
+
const { tool, input } = toolUse;
|
|
4646
|
+
const { result: resultText, isError } = result;
|
|
4647
|
+
const lines = [];
|
|
4648
|
+
if (tool === "TodoWrite" && !isError) {
|
|
4649
|
+
const todoLines = formatTodoList(input);
|
|
4650
|
+
lines.push(...todoLines);
|
|
4651
|
+
return lines;
|
|
4652
|
+
}
|
|
4653
|
+
if (tool === "Edit" && !isError) {
|
|
4654
|
+
const editLines = formatEditDiff(input, verbose);
|
|
4655
|
+
lines.push(...editLines);
|
|
4656
|
+
return lines;
|
|
4657
|
+
}
|
|
4658
|
+
if (tool === "Write" && !isError) {
|
|
4659
|
+
const writeLines = formatWritePreview(input, verbose);
|
|
4660
|
+
lines.push(...writeLines);
|
|
4661
|
+
return lines;
|
|
4662
|
+
}
|
|
4663
|
+
if (isError) {
|
|
4664
|
+
const errorMsg = resultText ? truncate(resultText, 80) : "Error";
|
|
4665
|
+
lines.push(`\u2514 \u2717 ${chalk4.dim(errorMsg)}`);
|
|
4666
|
+
return lines;
|
|
4667
|
+
}
|
|
4668
|
+
if (resultText) {
|
|
4669
|
+
const resultLines = resultText.split("\n");
|
|
4670
|
+
if (verbose) {
|
|
4671
|
+
for (let i = 0; i < resultLines.length; i++) {
|
|
4672
|
+
const prefix = i === 0 ? "\u2514 " : " ";
|
|
4673
|
+
lines.push(`${prefix}${chalk4.dim(resultLines[i])}`);
|
|
4674
|
+
}
|
|
4675
|
+
} else if (resultLines.length > 0) {
|
|
4676
|
+
const previewCount = Math.min(3, resultLines.length);
|
|
4677
|
+
for (let i = 0; i < previewCount; i++) {
|
|
4678
|
+
const prefix = i === 0 ? "\u2514 " : " ";
|
|
4679
|
+
lines.push(`${prefix}${chalk4.dim(resultLines[i])}`);
|
|
4680
|
+
}
|
|
4681
|
+
const remaining = resultLines.length - previewCount;
|
|
4682
|
+
if (remaining > 0) {
|
|
4683
|
+
lines.push(
|
|
4684
|
+
` ${chalk4.dim(`\u2026 +${remaining} ${pluralize(remaining, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
4685
|
+
);
|
|
4686
|
+
}
|
|
4687
|
+
}
|
|
4688
|
+
} else {
|
|
4689
|
+
lines.push(`\u2514 \u2713 ${chalk4.dim("Done")}`);
|
|
4690
|
+
}
|
|
4691
|
+
return lines;
|
|
4692
|
+
}
|
|
4693
|
+
function formatWritePreview(input, verbose) {
|
|
4694
|
+
const lines = [];
|
|
4695
|
+
const content = String(input.content || "");
|
|
4696
|
+
const contentLines = content.split("\n");
|
|
4697
|
+
const totalLines = contentLines.length;
|
|
4698
|
+
if (verbose) {
|
|
4699
|
+
for (let i = 0; i < contentLines.length; i++) {
|
|
4700
|
+
const prefix = i === 0 ? "\u23BF " : " ";
|
|
4701
|
+
lines.push(`${prefix}${chalk4.dim(contentLines[i] ?? "")}`);
|
|
4702
|
+
}
|
|
4703
|
+
} else {
|
|
4704
|
+
const previewCount = Math.min(3, totalLines);
|
|
4705
|
+
for (let i = 0; i < previewCount; i++) {
|
|
4706
|
+
const prefix = i === 0 ? "\u23BF " : " ";
|
|
4707
|
+
lines.push(`${prefix}${chalk4.dim(contentLines[i] ?? "")}`);
|
|
4708
|
+
}
|
|
4709
|
+
const remaining = totalLines - previewCount;
|
|
4710
|
+
if (remaining > 0) {
|
|
4711
|
+
lines.push(
|
|
4712
|
+
` ${chalk4.dim(`\u2026 +${remaining} ${pluralize(remaining, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
4713
|
+
);
|
|
4714
|
+
}
|
|
4715
|
+
}
|
|
4716
|
+
return lines;
|
|
4717
|
+
}
|
|
4718
|
+
function formatEditDiff(input, verbose) {
|
|
4719
|
+
const lines = [];
|
|
4720
|
+
const oldString = String(input.old_string || "");
|
|
4721
|
+
const newString = String(input.new_string || "");
|
|
4722
|
+
const oldLines = oldString.split("\n");
|
|
4723
|
+
const newLines = newString.split("\n");
|
|
4724
|
+
const removed = oldLines.length;
|
|
4725
|
+
const added = newLines.length;
|
|
4726
|
+
const summary = `Added ${added} ${pluralize(added, "line", "lines")}, removed ${removed} ${pluralize(removed, "line", "lines")}`;
|
|
4727
|
+
lines.push(`\u23BF ${chalk4.dim(summary)}`);
|
|
4728
|
+
if (verbose) {
|
|
4729
|
+
for (const line of oldLines) {
|
|
4730
|
+
lines.push(` ${chalk4.dim(`- ${line}`)}`);
|
|
4731
|
+
}
|
|
4732
|
+
for (const line of newLines) {
|
|
4733
|
+
lines.push(` ${chalk4.dim(`+ ${line}`)}`);
|
|
4734
|
+
}
|
|
4735
|
+
} else {
|
|
4736
|
+
const previewLimit = 3;
|
|
4737
|
+
const showOld = Math.min(previewLimit, oldLines.length);
|
|
4738
|
+
const showNew = Math.min(previewLimit, newLines.length);
|
|
4739
|
+
for (let i = 0; i < showOld; i++) {
|
|
4740
|
+
lines.push(` ${chalk4.dim(`- ${truncate(oldLines[i] ?? "", 60)}`)}`);
|
|
4741
|
+
}
|
|
4742
|
+
const remainingOld = oldLines.length - previewLimit;
|
|
4743
|
+
if (remainingOld > 0) {
|
|
4744
|
+
lines.push(
|
|
4745
|
+
` ${chalk4.dim(` \u2026 +${remainingOld} ${pluralize(remainingOld, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
4746
|
+
);
|
|
4747
|
+
}
|
|
4748
|
+
for (let i = 0; i < showNew; i++) {
|
|
4749
|
+
lines.push(` ${chalk4.dim(`+ ${truncate(newLines[i] ?? "", 60)}`)}`);
|
|
4750
|
+
}
|
|
4751
|
+
const remainingNew = newLines.length - previewLimit;
|
|
4752
|
+
if (remainingNew > 0) {
|
|
4753
|
+
lines.push(
|
|
4754
|
+
` ${chalk4.dim(` \u2026 +${remainingNew} ${pluralize(remainingNew, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
4755
|
+
);
|
|
4756
|
+
}
|
|
4757
|
+
}
|
|
4758
|
+
return lines;
|
|
4759
|
+
}
|
|
4760
|
+
function formatTodoList(input) {
|
|
4761
|
+
const lines = [];
|
|
4762
|
+
const todos = input.todos;
|
|
4763
|
+
if (!todos || !Array.isArray(todos)) {
|
|
4764
|
+
lines.push("\u2514 \u2713 Done");
|
|
4765
|
+
return lines;
|
|
4766
|
+
}
|
|
4767
|
+
for (const todo of todos) {
|
|
4768
|
+
const content = todo.content || "Unknown task";
|
|
4769
|
+
const status = todo.status || "pending";
|
|
4770
|
+
const icon = getTodoStatusIcon(status);
|
|
4771
|
+
const styledContent = formatTodoContent(content, status);
|
|
4772
|
+
lines.push(` ${icon} ${styledContent}`);
|
|
4773
|
+
}
|
|
4774
|
+
return lines;
|
|
4775
|
+
}
|
|
4776
|
+
function getTodoStatusIcon(status) {
|
|
4777
|
+
switch (status) {
|
|
4778
|
+
case "completed":
|
|
4779
|
+
return "\u2713";
|
|
4780
|
+
case "in_progress":
|
|
4781
|
+
return "\u25B8";
|
|
4782
|
+
case "pending":
|
|
4783
|
+
default:
|
|
4784
|
+
return "\u25FB";
|
|
4785
|
+
}
|
|
4786
|
+
}
|
|
4787
|
+
function formatTodoContent(content, status) {
|
|
4788
|
+
switch (status) {
|
|
4789
|
+
case "completed":
|
|
4790
|
+
return chalk4.dim.strikethrough(content);
|
|
4791
|
+
case "in_progress":
|
|
4792
|
+
return content;
|
|
4793
|
+
case "pending":
|
|
4794
|
+
default:
|
|
4795
|
+
return chalk4.dim(content);
|
|
4796
|
+
}
|
|
4797
|
+
}
|
|
4798
|
+
|
|
4799
|
+
// src/lib/events/event-renderer.ts
|
|
4800
|
+
var EventRenderer = class _EventRenderer {
|
|
4801
|
+
pendingToolUse = /* @__PURE__ */ new Map();
|
|
4802
|
+
options;
|
|
4803
|
+
lastEventType = null;
|
|
4804
|
+
frameworkDisplayName = "Agent";
|
|
4805
|
+
constructor(options) {
|
|
4806
|
+
this.options = options ?? {};
|
|
4807
|
+
}
|
|
4618
4808
|
/**
|
|
4619
4809
|
* Render run started info
|
|
4620
4810
|
* Called immediately after run is created, before polling events
|
|
4621
4811
|
*/
|
|
4622
4812
|
static renderRunStarted(info) {
|
|
4623
|
-
console.log(
|
|
4624
|
-
console.log(` Run ID: ${
|
|
4813
|
+
console.log(chalk5.bold("\u25B6 Run started"));
|
|
4814
|
+
console.log(` Run ID: ${chalk5.dim(info.runId)}`);
|
|
4625
4815
|
if (info.sandboxId) {
|
|
4626
|
-
console.log(` Sandbox: ${
|
|
4816
|
+
console.log(` Sandbox: ${chalk5.dim(info.sandboxId)}`);
|
|
4627
4817
|
}
|
|
4628
|
-
console.log(
|
|
4818
|
+
console.log(chalk5.dim(` (use "vm0 logs ${info.runId}" to view logs)`));
|
|
4629
4819
|
console.log();
|
|
4630
4820
|
}
|
|
4631
4821
|
/**
|
|
@@ -4637,8 +4827,8 @@ var EventRenderer = class {
|
|
|
4637
4827
|
/**
|
|
4638
4828
|
* Render a parsed event to console
|
|
4639
4829
|
*/
|
|
4640
|
-
|
|
4641
|
-
const timestampPrefix = options
|
|
4830
|
+
render(event) {
|
|
4831
|
+
const timestampPrefix = this.options.showTimestamp ? `[${_EventRenderer.formatTimestamp(event.timestamp)}] ` : "";
|
|
4642
4832
|
switch (event.type) {
|
|
4643
4833
|
case "init":
|
|
4644
4834
|
this.renderInit(event, timestampPrefix);
|
|
@@ -4647,10 +4837,10 @@ var EventRenderer = class {
|
|
|
4647
4837
|
this.renderText(event, timestampPrefix);
|
|
4648
4838
|
break;
|
|
4649
4839
|
case "tool_use":
|
|
4650
|
-
this.
|
|
4840
|
+
this.handleToolUse(event, timestampPrefix);
|
|
4651
4841
|
break;
|
|
4652
4842
|
case "tool_result":
|
|
4653
|
-
this.
|
|
4843
|
+
this.handleToolResult(event, timestampPrefix);
|
|
4654
4844
|
break;
|
|
4655
4845
|
case "result":
|
|
4656
4846
|
this.renderResult(event, timestampPrefix);
|
|
@@ -4663,21 +4853,25 @@ var EventRenderer = class {
|
|
|
4663
4853
|
*/
|
|
4664
4854
|
static renderRunCompleted(result) {
|
|
4665
4855
|
console.log("");
|
|
4666
|
-
console.log(
|
|
4856
|
+
console.log(chalk5.green("\u2713 Run completed successfully"));
|
|
4667
4857
|
if (result) {
|
|
4668
|
-
console.log(` Checkpoint: ${
|
|
4669
|
-
console.log(` Session: ${
|
|
4670
|
-
console.log(` Conversation: ${
|
|
4858
|
+
console.log(` Checkpoint: ${chalk5.dim(result.checkpointId)}`);
|
|
4859
|
+
console.log(` Session: ${chalk5.dim(result.agentSessionId)}`);
|
|
4860
|
+
console.log(` Conversation: ${chalk5.dim(result.conversationId)}`);
|
|
4671
4861
|
if (result.artifact && Object.keys(result.artifact).length > 0) {
|
|
4672
4862
|
console.log(` Artifact:`);
|
|
4673
4863
|
for (const [name, version] of Object.entries(result.artifact)) {
|
|
4674
|
-
console.log(
|
|
4864
|
+
console.log(
|
|
4865
|
+
` ${name}: ${chalk5.dim(_EventRenderer.formatVersion(version))}`
|
|
4866
|
+
);
|
|
4675
4867
|
}
|
|
4676
4868
|
}
|
|
4677
4869
|
if (result.volumes && Object.keys(result.volumes).length > 0) {
|
|
4678
4870
|
console.log(` Volumes:`);
|
|
4679
4871
|
for (const [name, version] of Object.entries(result.volumes)) {
|
|
4680
|
-
console.log(
|
|
4872
|
+
console.log(
|
|
4873
|
+
` ${name}: ${chalk5.dim(_EventRenderer.formatVersion(version))}`
|
|
4874
|
+
);
|
|
4681
4875
|
}
|
|
4682
4876
|
}
|
|
4683
4877
|
}
|
|
@@ -4688,61 +4882,128 @@ var EventRenderer = class {
|
|
|
4688
4882
|
*/
|
|
4689
4883
|
static renderRunFailed(error, runId) {
|
|
4690
4884
|
console.log("");
|
|
4691
|
-
console.log(
|
|
4692
|
-
console.log(` Error: ${
|
|
4885
|
+
console.log(chalk5.red("\u2717 Run failed"));
|
|
4886
|
+
console.log(` Error: ${chalk5.red(error || "Unknown error")}`);
|
|
4693
4887
|
console.log(
|
|
4694
|
-
|
|
4888
|
+
chalk5.dim(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
4695
4889
|
);
|
|
4696
4890
|
}
|
|
4697
|
-
|
|
4891
|
+
/**
|
|
4892
|
+
* Handle tool_use event - buffer it for later grouping with result (when buffered)
|
|
4893
|
+
* or render immediately (when not buffered, e.g., historical log viewing)
|
|
4894
|
+
*/
|
|
4895
|
+
handleToolUse(event, prefix) {
|
|
4896
|
+
const toolUseId = String(event.data.toolUseId || "");
|
|
4897
|
+
const tool = String(event.data.tool || "");
|
|
4898
|
+
const input = event.data.input || {};
|
|
4899
|
+
const toolUseData = { tool, input };
|
|
4900
|
+
if (this.options.buffered !== false) {
|
|
4901
|
+
this.pendingToolUse.set(toolUseId, { toolUse: toolUseData, prefix });
|
|
4902
|
+
} else {
|
|
4903
|
+
this.renderToolUseOnly(toolUseData, prefix);
|
|
4904
|
+
}
|
|
4905
|
+
}
|
|
4906
|
+
/**
|
|
4907
|
+
* Render a tool_use event without waiting for result (for historical log viewing)
|
|
4908
|
+
*/
|
|
4909
|
+
renderToolUseOnly(toolUse, prefix) {
|
|
4910
|
+
if (this.lastEventType === "text") {
|
|
4911
|
+
console.log();
|
|
4912
|
+
}
|
|
4913
|
+
const cont = this.getContinuationPrefix();
|
|
4914
|
+
const headerLines = formatToolHeader(toolUse);
|
|
4915
|
+
for (let i = 0; i < headerLines.length; i++) {
|
|
4916
|
+
if (i === 0) {
|
|
4917
|
+
console.log(prefix + "\u25CF " + headerLines[i]);
|
|
4918
|
+
} else {
|
|
4919
|
+
console.log(cont + headerLines[i]);
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
console.log();
|
|
4923
|
+
this.lastEventType = "tool";
|
|
4924
|
+
}
|
|
4925
|
+
/**
|
|
4926
|
+
* Handle tool_result event - lookup buffered tool_use and render grouped
|
|
4927
|
+
*/
|
|
4928
|
+
handleToolResult(event, prefix) {
|
|
4929
|
+
const toolUseId = String(event.data.toolUseId || "");
|
|
4930
|
+
const result = String(event.data.result || "");
|
|
4931
|
+
const isError = Boolean(event.data.isError);
|
|
4932
|
+
const pending = this.pendingToolUse.get(toolUseId);
|
|
4933
|
+
if (pending) {
|
|
4934
|
+
this.renderGroupedTool(pending.toolUse, { result, isError }, prefix);
|
|
4935
|
+
this.pendingToolUse.delete(toolUseId);
|
|
4936
|
+
}
|
|
4937
|
+
}
|
|
4938
|
+
/**
|
|
4939
|
+
* Get continuation prefix (simple indent, no timestamp alignment)
|
|
4940
|
+
*/
|
|
4941
|
+
getContinuationPrefix() {
|
|
4942
|
+
return " ";
|
|
4943
|
+
}
|
|
4944
|
+
/**
|
|
4945
|
+
* Render grouped tool output (tool_use + tool_result together)
|
|
4946
|
+
*/
|
|
4947
|
+
renderGroupedTool(toolUse, result, prefix) {
|
|
4948
|
+
if (this.lastEventType === "text") {
|
|
4949
|
+
console.log();
|
|
4950
|
+
}
|
|
4951
|
+
const verbose = this.options.verbose ?? false;
|
|
4952
|
+
const cont = this.getContinuationPrefix();
|
|
4953
|
+
const headerLines = formatToolHeader(toolUse);
|
|
4954
|
+
const resultLines = formatToolResult(toolUse, result, verbose);
|
|
4955
|
+
for (let i = 0; i < headerLines.length; i++) {
|
|
4956
|
+
if (i === 0) {
|
|
4957
|
+
console.log(prefix + "\u25CF " + headerLines[i]);
|
|
4958
|
+
} else {
|
|
4959
|
+
console.log(cont + headerLines[i]);
|
|
4960
|
+
}
|
|
4961
|
+
}
|
|
4962
|
+
for (const line of resultLines) {
|
|
4963
|
+
console.log(cont + line);
|
|
4964
|
+
}
|
|
4965
|
+
console.log();
|
|
4966
|
+
this.lastEventType = "tool";
|
|
4967
|
+
}
|
|
4968
|
+
renderInit(event, prefix) {
|
|
4698
4969
|
const frameworkStr = String(event.data.framework || "claude-code");
|
|
4699
4970
|
const displayName = isSupportedFramework(frameworkStr) ? getFrameworkDisplayName(frameworkStr) : frameworkStr;
|
|
4700
|
-
|
|
4701
|
-
console.log(
|
|
4971
|
+
this.frameworkDisplayName = displayName;
|
|
4972
|
+
console.log(prefix + chalk5.bold(`\u25B7 ${displayName} Started`));
|
|
4973
|
+
console.log(` Session: ${chalk5.dim(String(event.data.sessionId || ""))}`);
|
|
4702
4974
|
if (event.data.model) {
|
|
4703
|
-
console.log(` Model: ${
|
|
4975
|
+
console.log(` Model: ${chalk5.dim(String(event.data.model))}`);
|
|
4704
4976
|
}
|
|
4705
4977
|
console.log(
|
|
4706
|
-
` Tools: ${
|
|
4978
|
+
` Tools: ${chalk5.dim(
|
|
4707
4979
|
Array.isArray(event.data.tools) ? event.data.tools.join(", ") : String(event.data.tools || "")
|
|
4708
4980
|
)}`
|
|
4709
4981
|
);
|
|
4982
|
+
console.log();
|
|
4983
|
+
this.lastEventType = "init";
|
|
4710
4984
|
}
|
|
4711
|
-
|
|
4985
|
+
renderText(event, prefix) {
|
|
4712
4986
|
const text = String(event.data.text || "");
|
|
4713
|
-
console.log(prefix + "
|
|
4987
|
+
console.log(prefix + "\u25CF " + text);
|
|
4988
|
+
this.lastEventType = "text";
|
|
4714
4989
|
}
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
console.log(prefix + "[tool_use] " + tool);
|
|
4718
|
-
const input = event.data.input;
|
|
4719
|
-
if (input && typeof input === "object") {
|
|
4720
|
-
for (const [key, value] of Object.entries(input)) {
|
|
4721
|
-
if (value !== void 0 && value !== null) {
|
|
4722
|
-
const displayValue = typeof value === "object" ? JSON.stringify(value, null, 2) : String(value);
|
|
4723
|
-
console.log(` ${key}: ${chalk4.dim(displayValue)}`);
|
|
4724
|
-
}
|
|
4725
|
-
}
|
|
4726
|
-
}
|
|
4727
|
-
}
|
|
4728
|
-
static renderToolResult(event, prefix) {
|
|
4729
|
-
const isError = Boolean(event.data.isError);
|
|
4730
|
-
const status = isError ? "Error" : "Completed";
|
|
4731
|
-
console.log(prefix + "[tool_result] " + status);
|
|
4732
|
-
const result = String(event.data.result || "");
|
|
4733
|
-
console.log(` ${chalk4.dim(result)}`);
|
|
4734
|
-
}
|
|
4735
|
-
static renderResult(event, prefix) {
|
|
4990
|
+
renderResult(event, prefix) {
|
|
4991
|
+
console.log();
|
|
4736
4992
|
const success = Boolean(event.data.success);
|
|
4737
|
-
|
|
4738
|
-
|
|
4993
|
+
if (success) {
|
|
4994
|
+
console.log(
|
|
4995
|
+
prefix + chalk5.bold(`\u25C6 ${this.frameworkDisplayName} Completed`)
|
|
4996
|
+
);
|
|
4997
|
+
} else {
|
|
4998
|
+
console.log(prefix + chalk5.bold(`\u25C6 ${this.frameworkDisplayName} Failed`));
|
|
4999
|
+
}
|
|
4739
5000
|
const durationMs = Number(event.data.durationMs || 0);
|
|
4740
5001
|
const durationSec = (durationMs / 1e3).toFixed(1);
|
|
4741
|
-
console.log(` Duration: ${
|
|
5002
|
+
console.log(` Duration: ${chalk5.dim(durationSec + "s")}`);
|
|
4742
5003
|
const cost = Number(event.data.cost || 0);
|
|
4743
|
-
console.log(` Cost: ${
|
|
5004
|
+
console.log(` Cost: ${chalk5.dim("$" + cost.toFixed(4))}`);
|
|
4744
5005
|
const numTurns = Number(event.data.numTurns || 0);
|
|
4745
|
-
console.log(` Turns: ${
|
|
5006
|
+
console.log(` Turns: ${chalk5.dim(String(numTurns))}`);
|
|
4746
5007
|
const usage = event.data.usage;
|
|
4747
5008
|
if (usage && typeof usage === "object") {
|
|
4748
5009
|
const inputTokens = Number(usage.input_tokens || 0);
|
|
@@ -4754,11 +5015,12 @@ var EventRenderer = class {
|
|
|
4754
5015
|
return String(count);
|
|
4755
5016
|
};
|
|
4756
5017
|
console.log(
|
|
4757
|
-
` Tokens: ${
|
|
5018
|
+
` Tokens: ${chalk5.dim(
|
|
4758
5019
|
`input=${formatTokens(inputTokens)} output=${formatTokens(outputTokens)}`
|
|
4759
5020
|
)}`
|
|
4760
5021
|
);
|
|
4761
5022
|
}
|
|
5023
|
+
this.lastEventType = "result";
|
|
4762
5024
|
}
|
|
4763
5025
|
/**
|
|
4764
5026
|
* Format version ID for display (show short 8-character prefix)
|
|
@@ -4772,7 +5034,7 @@ var EventRenderer = class {
|
|
|
4772
5034
|
};
|
|
4773
5035
|
|
|
4774
5036
|
// src/commands/run/shared.ts
|
|
4775
|
-
import
|
|
5037
|
+
import chalk7 from "chalk";
|
|
4776
5038
|
import * as fs5 from "fs";
|
|
4777
5039
|
import { config as dotenvConfig } from "dotenv";
|
|
4778
5040
|
|
|
@@ -5098,7 +5360,7 @@ function parseEvent(rawEvent, framework) {
|
|
|
5098
5360
|
}
|
|
5099
5361
|
|
|
5100
5362
|
// src/lib/events/codex-event-renderer.ts
|
|
5101
|
-
import
|
|
5363
|
+
import chalk6 from "chalk";
|
|
5102
5364
|
var CodexEventRenderer = class {
|
|
5103
5365
|
/**
|
|
5104
5366
|
* Check if an event is a Codex event
|
|
@@ -5145,13 +5407,13 @@ var CodexEventRenderer = class {
|
|
|
5145
5407
|
const cached = event.usage.cached_input_tokens || 0;
|
|
5146
5408
|
const cachedStr = cached ? ` (${cached} cached)` : "";
|
|
5147
5409
|
console.log(
|
|
5148
|
-
"[turn.completed]" +
|
|
5410
|
+
"[turn.completed]" + chalk6.dim(` ${input} in / ${output} out${cachedStr}`)
|
|
5149
5411
|
);
|
|
5150
5412
|
}
|
|
5151
5413
|
}
|
|
5152
5414
|
static renderTurnFailed(event) {
|
|
5153
5415
|
console.log(
|
|
5154
|
-
|
|
5416
|
+
chalk6.red("[turn.failed]") + (event.error ? ` ${event.error}` : "")
|
|
5155
5417
|
);
|
|
5156
5418
|
}
|
|
5157
5419
|
// eslint-disable-next-line complexity -- TODO: refactor complex function
|
|
@@ -5177,15 +5439,15 @@ var CodexEventRenderer = class {
|
|
|
5177
5439
|
if (output) {
|
|
5178
5440
|
const lines = output.split("\n").filter((l) => l.trim());
|
|
5179
5441
|
const preview = lines.slice(0, 3).join("\n ");
|
|
5180
|
-
const more = lines.length > 3 ?
|
|
5442
|
+
const more = lines.length > 3 ? chalk6.dim(` ... (${lines.length - 3} more lines)`) : "";
|
|
5181
5443
|
console.log(
|
|
5182
|
-
"[output]" + (exitCode !== 0 ?
|
|
5444
|
+
"[output]" + (exitCode !== 0 ? chalk6.red(` exit=${exitCode}`) : "")
|
|
5183
5445
|
);
|
|
5184
5446
|
if (preview) {
|
|
5185
5447
|
console.log(" " + preview + more);
|
|
5186
5448
|
}
|
|
5187
5449
|
} else if (exitCode !== 0) {
|
|
5188
|
-
console.log(
|
|
5450
|
+
console.log(chalk6.red("[output]") + chalk6.red(` exit=${exitCode}`));
|
|
5189
5451
|
}
|
|
5190
5452
|
}
|
|
5191
5453
|
return;
|
|
@@ -5195,7 +5457,7 @@ var CodexEventRenderer = class {
|
|
|
5195
5457
|
const icon = c20.kind === "add" ? "+" : c20.kind === "delete" ? "-" : "~";
|
|
5196
5458
|
return `${icon}${c20.path}`;
|
|
5197
5459
|
}).join(", ");
|
|
5198
|
-
console.log(
|
|
5460
|
+
console.log(chalk6.green("[files]") + ` ${summary}`);
|
|
5199
5461
|
return;
|
|
5200
5462
|
}
|
|
5201
5463
|
if (itemType === "file_edit" || itemType === "file_write" || itemType === "file_read") {
|
|
@@ -5208,7 +5470,7 @@ var CodexEventRenderer = class {
|
|
|
5208
5470
|
}
|
|
5209
5471
|
static renderError(event) {
|
|
5210
5472
|
console.log(
|
|
5211
|
-
|
|
5473
|
+
chalk6.red("[error]") + ` ${event.message || event.error || "Unknown error"}`
|
|
5212
5474
|
);
|
|
5213
5475
|
}
|
|
5214
5476
|
};
|
|
@@ -6250,16 +6512,16 @@ function parseIdentifier(identifier) {
|
|
|
6250
6512
|
}
|
|
6251
6513
|
return { scope, name: rest };
|
|
6252
6514
|
}
|
|
6253
|
-
function
|
|
6254
|
-
const
|
|
6255
|
-
const parsed = parseEvent(eventData);
|
|
6256
|
-
if (parsed) {
|
|
6257
|
-
EventRenderer.render(parsed);
|
|
6258
|
-
}
|
|
6259
|
-
}
|
|
6260
|
-
async function streamRealtimeEvents(runId) {
|
|
6515
|
+
async function streamRealtimeEvents(runId, options) {
|
|
6516
|
+
const renderer = new EventRenderer({ verbose: options?.verbose });
|
|
6261
6517
|
return streamEvents(runId, {
|
|
6262
|
-
onEvent:
|
|
6518
|
+
onEvent: (event) => {
|
|
6519
|
+
const eventData = event;
|
|
6520
|
+
const parsed = parseEvent(eventData);
|
|
6521
|
+
if (parsed) {
|
|
6522
|
+
renderer.render(parsed);
|
|
6523
|
+
}
|
|
6524
|
+
},
|
|
6263
6525
|
onRunCompleted: (result) => {
|
|
6264
6526
|
EventRenderer.renderRunCompleted(result);
|
|
6265
6527
|
},
|
|
@@ -6267,14 +6529,15 @@ async function streamRealtimeEvents(runId) {
|
|
|
6267
6529
|
EventRenderer.renderRunFailed(error, rid);
|
|
6268
6530
|
},
|
|
6269
6531
|
onTimeout: (rid) => {
|
|
6270
|
-
console.error(
|
|
6532
|
+
console.error(chalk7.red("\n\u2717 Run timed out"));
|
|
6271
6533
|
console.error(
|
|
6272
|
-
|
|
6534
|
+
chalk7.dim(` (use "vm0 logs ${rid} --system" to view system logs)`)
|
|
6273
6535
|
);
|
|
6274
6536
|
}
|
|
6275
6537
|
});
|
|
6276
6538
|
}
|
|
6277
|
-
async function pollEvents(runId) {
|
|
6539
|
+
async function pollEvents(runId, options) {
|
|
6540
|
+
const renderer = new EventRenderer({ verbose: options?.verbose });
|
|
6278
6541
|
let nextSequence = -1;
|
|
6279
6542
|
let complete = false;
|
|
6280
6543
|
let result = { succeeded: true, runId };
|
|
@@ -6290,7 +6553,7 @@ async function pollEvents(runId) {
|
|
|
6290
6553
|
} else {
|
|
6291
6554
|
const parsed = parseEvent(eventData);
|
|
6292
6555
|
if (parsed) {
|
|
6293
|
-
|
|
6556
|
+
renderer.render(parsed);
|
|
6294
6557
|
}
|
|
6295
6558
|
}
|
|
6296
6559
|
}
|
|
@@ -6311,9 +6574,9 @@ async function pollEvents(runId) {
|
|
|
6311
6574
|
result = { succeeded: false, runId };
|
|
6312
6575
|
} else if (runStatus === "timeout") {
|
|
6313
6576
|
complete = true;
|
|
6314
|
-
console.error(
|
|
6577
|
+
console.error(chalk7.red("\n\u2717 Run timed out"));
|
|
6315
6578
|
console.error(
|
|
6316
|
-
|
|
6579
|
+
chalk7.dim(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
6317
6580
|
);
|
|
6318
6581
|
result = { succeeded: false, runId };
|
|
6319
6582
|
}
|
|
@@ -6327,11 +6590,11 @@ function showNextSteps(result) {
|
|
|
6327
6590
|
const { runId, sessionId, checkpointId } = result;
|
|
6328
6591
|
console.log();
|
|
6329
6592
|
console.log(" View agent logs:");
|
|
6330
|
-
console.log(
|
|
6593
|
+
console.log(chalk7.cyan(` vm0 logs ${runId}`));
|
|
6331
6594
|
if (sessionId) {
|
|
6332
6595
|
console.log(" Continue with session (latest conversation and artifact):");
|
|
6333
6596
|
console.log(
|
|
6334
|
-
|
|
6597
|
+
chalk7.cyan(` vm0 run continue ${sessionId} "your next prompt"`)
|
|
6335
6598
|
);
|
|
6336
6599
|
}
|
|
6337
6600
|
if (checkpointId) {
|
|
@@ -6339,23 +6602,43 @@ function showNextSteps(result) {
|
|
|
6339
6602
|
" Resume from checkpoint (snapshotted conversation and artifact):"
|
|
6340
6603
|
);
|
|
6341
6604
|
console.log(
|
|
6342
|
-
|
|
6605
|
+
chalk7.cyan(` vm0 run resume ${checkpointId} "your next prompt"`)
|
|
6343
6606
|
);
|
|
6344
6607
|
}
|
|
6345
6608
|
}
|
|
6346
6609
|
function handleGenericRunError(error, commandLabel) {
|
|
6347
6610
|
if (error instanceof ApiRequestError && error.code === "concurrent_run_limit_exceeded") {
|
|
6348
|
-
console.error(
|
|
6349
|
-
console.error(
|
|
6611
|
+
console.error(chalk7.red(`\u2717 ${commandLabel} failed`));
|
|
6612
|
+
console.error(chalk7.dim(` ${error.message}`));
|
|
6350
6613
|
console.log();
|
|
6351
6614
|
console.log(" To view active runs:");
|
|
6352
|
-
console.log(
|
|
6615
|
+
console.log(chalk7.cyan(" vm0 run list"));
|
|
6353
6616
|
console.log(" To cancel a run:");
|
|
6354
|
-
console.log(
|
|
6617
|
+
console.log(chalk7.cyan(" vm0 run kill <run-id>"));
|
|
6618
|
+
} else {
|
|
6619
|
+
console.error(chalk7.red(`\u2717 ${commandLabel} failed`));
|
|
6620
|
+
console.error(chalk7.dim(` ${error.message}`));
|
|
6621
|
+
}
|
|
6622
|
+
}
|
|
6623
|
+
function handleResumeOrContinueError(error, commandLabel, resourceId, resourceLabel) {
|
|
6624
|
+
if (error instanceof Error) {
|
|
6625
|
+
if (error.message.includes("Not authenticated")) {
|
|
6626
|
+
console.error(chalk7.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
6627
|
+
} else if (error.message.includes("Realtime connection failed")) {
|
|
6628
|
+
console.error(chalk7.red("\u2717 Realtime streaming failed"));
|
|
6629
|
+
console.error(chalk7.dim(` ${error.message}`));
|
|
6630
|
+
console.error(chalk7.dim(" Try running without --experimental-realtime"));
|
|
6631
|
+
} else if (error.message.startsWith("Environment file not found:")) {
|
|
6632
|
+
console.error(chalk7.red(`\u2717 ${error.message}`));
|
|
6633
|
+
} else if (error.message.includes("not found")) {
|
|
6634
|
+
console.error(chalk7.red(`\u2717 ${resourceLabel} not found: ${resourceId}`));
|
|
6635
|
+
} else {
|
|
6636
|
+
handleGenericRunError(error, commandLabel);
|
|
6637
|
+
}
|
|
6355
6638
|
} else {
|
|
6356
|
-
console.error(
|
|
6357
|
-
console.error(chalk6.dim(` ${error.message}`));
|
|
6639
|
+
console.error(chalk7.red("\u2717 An unexpected error occurred"));
|
|
6358
6640
|
}
|
|
6641
|
+
process.exit(1);
|
|
6359
6642
|
}
|
|
6360
6643
|
|
|
6361
6644
|
// src/commands/run/run.ts
|
|
@@ -6392,7 +6675,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6392
6675
|
).option(
|
|
6393
6676
|
"--model-provider <type>",
|
|
6394
6677
|
"Override model provider (e.g., anthropic-api-key)"
|
|
6395
|
-
).addOption(new Option("--debug-no-mock-claude").hideHelp()).action(
|
|
6678
|
+
).option("--verbose", "Show full tool inputs and outputs").addOption(new Option("--debug-no-mock-claude").hideHelp()).action(
|
|
6396
6679
|
async (identifier, prompt, options) => {
|
|
6397
6680
|
try {
|
|
6398
6681
|
const { scope, name, version } = parseIdentifier(identifier);
|
|
@@ -6405,9 +6688,9 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6405
6688
|
} else {
|
|
6406
6689
|
const compose = await getComposeByName(name, scope);
|
|
6407
6690
|
if (!compose) {
|
|
6408
|
-
console.error(
|
|
6691
|
+
console.error(chalk8.red(`\u2717 Agent not found: ${identifier}`));
|
|
6409
6692
|
console.error(
|
|
6410
|
-
|
|
6693
|
+
chalk8.dim(
|
|
6411
6694
|
" Make sure you've composed the agent with: vm0 compose"
|
|
6412
6695
|
)
|
|
6413
6696
|
);
|
|
@@ -6447,9 +6730,9 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6447
6730
|
debugNoMockClaude: options.debugNoMockClaude || void 0
|
|
6448
6731
|
});
|
|
6449
6732
|
if (response.status === "failed") {
|
|
6450
|
-
console.error(
|
|
6733
|
+
console.error(chalk8.red("\u2717 Run preparation failed"));
|
|
6451
6734
|
if (response.error) {
|
|
6452
|
-
console.error(
|
|
6735
|
+
console.error(chalk8.dim(` ${response.error}`));
|
|
6453
6736
|
}
|
|
6454
6737
|
process.exit(1);
|
|
6455
6738
|
}
|
|
@@ -6457,7 +6740,9 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6457
6740
|
runId: response.runId,
|
|
6458
6741
|
sandboxId: response.sandboxId
|
|
6459
6742
|
});
|
|
6460
|
-
const result = options.experimentalRealtime ? await streamRealtimeEvents(response.runId
|
|
6743
|
+
const result = options.experimentalRealtime ? await streamRealtimeEvents(response.runId, {
|
|
6744
|
+
verbose: options.verbose
|
|
6745
|
+
}) : await pollEvents(response.runId, { verbose: options.verbose });
|
|
6461
6746
|
if (!result.succeeded) {
|
|
6462
6747
|
process.exit(1);
|
|
6463
6748
|
}
|
|
@@ -6466,23 +6751,23 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6466
6751
|
if (error instanceof Error) {
|
|
6467
6752
|
if (error.message.includes("Not authenticated")) {
|
|
6468
6753
|
console.error(
|
|
6469
|
-
|
|
6754
|
+
chalk8.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
6470
6755
|
);
|
|
6471
6756
|
} else if (error.message.includes("Realtime connection failed")) {
|
|
6472
|
-
console.error(
|
|
6473
|
-
console.error(
|
|
6757
|
+
console.error(chalk8.red("\u2717 Realtime streaming failed"));
|
|
6758
|
+
console.error(chalk8.dim(` ${error.message}`));
|
|
6474
6759
|
console.error(
|
|
6475
|
-
|
|
6760
|
+
chalk8.dim(" Try running without --experimental-realtime")
|
|
6476
6761
|
);
|
|
6477
6762
|
} else if (error.message.startsWith("Version not found:")) {
|
|
6478
|
-
console.error(
|
|
6479
|
-
console.error(
|
|
6763
|
+
console.error(chalk8.red(`\u2717 ${error.message}`));
|
|
6764
|
+
console.error(chalk8.dim(" Make sure the version hash is correct"));
|
|
6480
6765
|
} else if (error.message.startsWith("Environment file not found:")) {
|
|
6481
|
-
console.error(
|
|
6766
|
+
console.error(chalk8.red(`\u2717 ${error.message}`));
|
|
6482
6767
|
} else if (error.message.includes("not found")) {
|
|
6483
|
-
console.error(
|
|
6768
|
+
console.error(chalk8.red(`\u2717 Agent not found: ${identifier}`));
|
|
6484
6769
|
console.error(
|
|
6485
|
-
|
|
6770
|
+
chalk8.dim(
|
|
6486
6771
|
" Make sure you've composed the agent with: vm0 compose"
|
|
6487
6772
|
)
|
|
6488
6773
|
);
|
|
@@ -6490,7 +6775,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6490
6775
|
handleGenericRunError(error, "Run");
|
|
6491
6776
|
}
|
|
6492
6777
|
} else {
|
|
6493
|
-
console.error(
|
|
6778
|
+
console.error(chalk8.red("\u2717 An unexpected error occurred"));
|
|
6494
6779
|
}
|
|
6495
6780
|
process.exit(1);
|
|
6496
6781
|
}
|
|
@@ -6499,7 +6784,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6499
6784
|
|
|
6500
6785
|
// src/commands/run/resume.ts
|
|
6501
6786
|
import { Command as Command9, Option as Option2 } from "commander";
|
|
6502
|
-
import
|
|
6787
|
+
import chalk9 from "chalk";
|
|
6503
6788
|
var resumeCommand = new Command9().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(
|
|
6504
6789
|
"--env-file <path>",
|
|
6505
6790
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
@@ -6524,7 +6809,7 @@ var resumeCommand = new Command9().name("resume").description("Resume an agent r
|
|
|
6524
6809
|
).option(
|
|
6525
6810
|
"--model-provider <type>",
|
|
6526
6811
|
"Override model provider (e.g., anthropic-api-key)"
|
|
6527
|
-
).addOption(new Option2("--debug-no-mock-claude").hideHelp()).action(
|
|
6812
|
+
).option("--verbose", "Show full tool inputs and outputs").addOption(new Option2("--debug-no-mock-claude").hideHelp()).action(
|
|
6528
6813
|
async (checkpointId, prompt, options, command) => {
|
|
6529
6814
|
const allOpts = command.optsWithGlobals();
|
|
6530
6815
|
const vars = { ...allOpts.vars, ...options.vars };
|
|
@@ -6532,9 +6817,9 @@ var resumeCommand = new Command9().name("resume").description("Resume an agent r
|
|
|
6532
6817
|
try {
|
|
6533
6818
|
if (!isUUID(checkpointId)) {
|
|
6534
6819
|
console.error(
|
|
6535
|
-
|
|
6820
|
+
chalk9.red(`\u2717 Invalid checkpoint ID format: ${checkpointId}`)
|
|
6536
6821
|
);
|
|
6537
|
-
console.error(
|
|
6822
|
+
console.error(chalk9.dim(" Checkpoint ID must be a valid UUID"));
|
|
6538
6823
|
process.exit(1);
|
|
6539
6824
|
}
|
|
6540
6825
|
const checkpointInfo = await getCheckpoint(checkpointId);
|
|
@@ -6551,9 +6836,9 @@ var resumeCommand = new Command9().name("resume").description("Resume an agent r
|
|
|
6551
6836
|
debugNoMockClaude: options.debugNoMockClaude || allOpts.debugNoMockClaude || void 0
|
|
6552
6837
|
});
|
|
6553
6838
|
if (response.status === "failed") {
|
|
6554
|
-
console.error(
|
|
6839
|
+
console.error(chalk9.red("\u2717 Run preparation failed"));
|
|
6555
6840
|
if (response.error) {
|
|
6556
|
-
console.error(
|
|
6841
|
+
console.error(chalk9.dim(` ${response.error}`));
|
|
6557
6842
|
}
|
|
6558
6843
|
process.exit(1);
|
|
6559
6844
|
}
|
|
@@ -6562,41 +6847,26 @@ var resumeCommand = new Command9().name("resume").description("Resume an agent r
|
|
|
6562
6847
|
sandboxId: response.sandboxId
|
|
6563
6848
|
});
|
|
6564
6849
|
const experimentalRealtime = options.experimentalRealtime || allOpts.experimentalRealtime;
|
|
6565
|
-
const
|
|
6850
|
+
const verbose = options.verbose || allOpts.verbose;
|
|
6851
|
+
const result = experimentalRealtime ? await streamRealtimeEvents(response.runId, { verbose }) : await pollEvents(response.runId, { verbose });
|
|
6566
6852
|
if (!result.succeeded) {
|
|
6567
6853
|
process.exit(1);
|
|
6568
6854
|
}
|
|
6569
6855
|
showNextSteps(result);
|
|
6570
6856
|
} catch (error) {
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
console.error(chalk8.red("\u2717 Realtime streaming failed"));
|
|
6578
|
-
console.error(chalk8.dim(` ${error.message}`));
|
|
6579
|
-
console.error(
|
|
6580
|
-
chalk8.dim(" Try running without --experimental-realtime")
|
|
6581
|
-
);
|
|
6582
|
-
} else if (error.message.startsWith("Environment file not found:")) {
|
|
6583
|
-
console.error(chalk8.red(`\u2717 ${error.message}`));
|
|
6584
|
-
} else if (error.message.includes("not found")) {
|
|
6585
|
-
console.error(chalk8.red(`\u2717 Checkpoint not found: ${checkpointId}`));
|
|
6586
|
-
} else {
|
|
6587
|
-
handleGenericRunError(error, "Resume");
|
|
6588
|
-
}
|
|
6589
|
-
} else {
|
|
6590
|
-
console.error(chalk8.red("\u2717 An unexpected error occurred"));
|
|
6591
|
-
}
|
|
6592
|
-
process.exit(1);
|
|
6857
|
+
handleResumeOrContinueError(
|
|
6858
|
+
error,
|
|
6859
|
+
"Resume",
|
|
6860
|
+
checkpointId,
|
|
6861
|
+
"Checkpoint"
|
|
6862
|
+
);
|
|
6593
6863
|
}
|
|
6594
6864
|
}
|
|
6595
6865
|
);
|
|
6596
6866
|
|
|
6597
6867
|
// src/commands/run/continue.ts
|
|
6598
6868
|
import { Command as Command10, Option as Option3 } from "commander";
|
|
6599
|
-
import
|
|
6869
|
+
import chalk10 from "chalk";
|
|
6600
6870
|
var continueCommand = new Command10().name("continue").description(
|
|
6601
6871
|
"Continue an agent run from a session (uses latest artifact version)"
|
|
6602
6872
|
).argument("<agentSessionId>", "Agent session ID to continue from").argument("<prompt>", "Prompt for the continued agent").option(
|
|
@@ -6623,7 +6893,7 @@ var continueCommand = new Command10().name("continue").description(
|
|
|
6623
6893
|
).option(
|
|
6624
6894
|
"--model-provider <type>",
|
|
6625
6895
|
"Override model provider (e.g., anthropic-api-key)"
|
|
6626
|
-
).addOption(new Option3("--debug-no-mock-claude").hideHelp()).action(
|
|
6896
|
+
).option("--verbose", "Show full tool inputs and outputs").addOption(new Option3("--debug-no-mock-claude").hideHelp()).action(
|
|
6627
6897
|
async (agentSessionId, prompt, options, command) => {
|
|
6628
6898
|
const allOpts = command.optsWithGlobals();
|
|
6629
6899
|
const vars = { ...allOpts.vars, ...options.vars };
|
|
@@ -6631,9 +6901,9 @@ var continueCommand = new Command10().name("continue").description(
|
|
|
6631
6901
|
try {
|
|
6632
6902
|
if (!isUUID(agentSessionId)) {
|
|
6633
6903
|
console.error(
|
|
6634
|
-
|
|
6904
|
+
chalk10.red(`\u2717 Invalid agent session ID format: ${agentSessionId}`)
|
|
6635
6905
|
);
|
|
6636
|
-
console.error(
|
|
6906
|
+
console.error(chalk10.dim(" Agent session ID must be a valid UUID"));
|
|
6637
6907
|
process.exit(1);
|
|
6638
6908
|
}
|
|
6639
6909
|
const sessionInfo = await getSession(agentSessionId);
|
|
@@ -6650,9 +6920,9 @@ var continueCommand = new Command10().name("continue").description(
|
|
|
6650
6920
|
debugNoMockClaude: options.debugNoMockClaude || allOpts.debugNoMockClaude || void 0
|
|
6651
6921
|
});
|
|
6652
6922
|
if (response.status === "failed") {
|
|
6653
|
-
console.error(
|
|
6923
|
+
console.error(chalk10.red("\u2717 Run preparation failed"));
|
|
6654
6924
|
if (response.error) {
|
|
6655
|
-
console.error(
|
|
6925
|
+
console.error(chalk10.dim(` ${response.error}`));
|
|
6656
6926
|
}
|
|
6657
6927
|
process.exit(1);
|
|
6658
6928
|
}
|
|
@@ -6661,56 +6931,39 @@ var continueCommand = new Command10().name("continue").description(
|
|
|
6661
6931
|
sandboxId: response.sandboxId
|
|
6662
6932
|
});
|
|
6663
6933
|
const experimentalRealtime = options.experimentalRealtime || allOpts.experimentalRealtime;
|
|
6664
|
-
const
|
|
6934
|
+
const verbose = options.verbose || allOpts.verbose;
|
|
6935
|
+
const result = experimentalRealtime ? await streamRealtimeEvents(response.runId, { verbose }) : await pollEvents(response.runId, { verbose });
|
|
6665
6936
|
if (!result.succeeded) {
|
|
6666
6937
|
process.exit(1);
|
|
6667
6938
|
}
|
|
6668
6939
|
showNextSteps(result);
|
|
6669
6940
|
} catch (error) {
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
console.error(chalk9.red("\u2717 Realtime streaming failed"));
|
|
6677
|
-
console.error(chalk9.dim(` ${error.message}`));
|
|
6678
|
-
console.error(
|
|
6679
|
-
chalk9.dim(" Try running without --experimental-realtime")
|
|
6680
|
-
);
|
|
6681
|
-
} else if (error.message.startsWith("Environment file not found:")) {
|
|
6682
|
-
console.error(chalk9.red(`\u2717 ${error.message}`));
|
|
6683
|
-
} else if (error.message.includes("not found")) {
|
|
6684
|
-
console.error(
|
|
6685
|
-
chalk9.red(`\u2717 Agent session not found: ${agentSessionId}`)
|
|
6686
|
-
);
|
|
6687
|
-
} else {
|
|
6688
|
-
handleGenericRunError(error, "Continue");
|
|
6689
|
-
}
|
|
6690
|
-
} else {
|
|
6691
|
-
console.error(chalk9.red("\u2717 An unexpected error occurred"));
|
|
6692
|
-
}
|
|
6693
|
-
process.exit(1);
|
|
6941
|
+
handleResumeOrContinueError(
|
|
6942
|
+
error,
|
|
6943
|
+
"Continue",
|
|
6944
|
+
agentSessionId,
|
|
6945
|
+
"Agent session"
|
|
6946
|
+
);
|
|
6694
6947
|
}
|
|
6695
6948
|
}
|
|
6696
6949
|
);
|
|
6697
6950
|
|
|
6698
6951
|
// src/commands/run/list.ts
|
|
6699
6952
|
import { Command as Command11 } from "commander";
|
|
6700
|
-
import
|
|
6953
|
+
import chalk11 from "chalk";
|
|
6701
6954
|
var UUID_LENGTH = 36;
|
|
6702
6955
|
function formatRunStatus(status, width) {
|
|
6703
6956
|
const paddedStatus = width ? status.padEnd(width) : status;
|
|
6704
6957
|
switch (status) {
|
|
6705
6958
|
case "running":
|
|
6706
|
-
return
|
|
6959
|
+
return chalk11.green(paddedStatus);
|
|
6707
6960
|
case "pending":
|
|
6708
|
-
return
|
|
6961
|
+
return chalk11.yellow(paddedStatus);
|
|
6709
6962
|
case "completed":
|
|
6710
|
-
return
|
|
6963
|
+
return chalk11.blue(paddedStatus);
|
|
6711
6964
|
case "failed":
|
|
6712
6965
|
case "timeout":
|
|
6713
|
-
return
|
|
6966
|
+
return chalk11.red(paddedStatus);
|
|
6714
6967
|
default:
|
|
6715
6968
|
return paddedStatus;
|
|
6716
6969
|
}
|
|
@@ -6720,7 +6973,7 @@ var listCommand = new Command11().name("list").alias("ls").description("List act
|
|
|
6720
6973
|
const response = await listRuns({ limit: 100 });
|
|
6721
6974
|
const activeRuns = response.runs;
|
|
6722
6975
|
if (activeRuns.length === 0) {
|
|
6723
|
-
console.log(
|
|
6976
|
+
console.log(chalk11.dim("No active runs"));
|
|
6724
6977
|
return;
|
|
6725
6978
|
}
|
|
6726
6979
|
const agentWidth = Math.max(
|
|
@@ -6734,7 +6987,7 @@ var listCommand = new Command11().name("list").alias("ls").description("List act
|
|
|
6734
6987
|
"STATUS".padEnd(statusWidth),
|
|
6735
6988
|
"CREATED"
|
|
6736
6989
|
].join(" ");
|
|
6737
|
-
console.log(
|
|
6990
|
+
console.log(chalk11.dim(header));
|
|
6738
6991
|
for (const run of activeRuns) {
|
|
6739
6992
|
const row = [
|
|
6740
6993
|
run.id.padEnd(UUID_LENGTH),
|
|
@@ -6745,12 +6998,12 @@ var listCommand = new Command11().name("list").alias("ls").description("List act
|
|
|
6745
6998
|
console.log(row);
|
|
6746
6999
|
}
|
|
6747
7000
|
} catch (error) {
|
|
6748
|
-
console.error(
|
|
7001
|
+
console.error(chalk11.red("\u2717 Failed to list runs"));
|
|
6749
7002
|
if (error instanceof Error) {
|
|
6750
7003
|
if (error.message.includes("Not authenticated")) {
|
|
6751
|
-
console.error(
|
|
7004
|
+
console.error(chalk11.dim(" Run: vm0 auth login"));
|
|
6752
7005
|
} else {
|
|
6753
|
-
console.error(
|
|
7006
|
+
console.error(chalk11.dim(` ${error.message}`));
|
|
6754
7007
|
}
|
|
6755
7008
|
}
|
|
6756
7009
|
process.exit(1);
|
|
@@ -6759,22 +7012,22 @@ var listCommand = new Command11().name("list").alias("ls").description("List act
|
|
|
6759
7012
|
|
|
6760
7013
|
// src/commands/run/kill.ts
|
|
6761
7014
|
import { Command as Command12 } from "commander";
|
|
6762
|
-
import
|
|
7015
|
+
import chalk12 from "chalk";
|
|
6763
7016
|
var killCommand = new Command12().name("kill").description("Kill (cancel) a pending or running run").argument("<run-id>", "Run ID to kill").action(async (runId) => {
|
|
6764
7017
|
try {
|
|
6765
7018
|
await cancelRun(runId);
|
|
6766
|
-
console.log(
|
|
7019
|
+
console.log(chalk12.green(`\u2713 Run ${runId} cancelled`));
|
|
6767
7020
|
} catch (error) {
|
|
6768
|
-
console.error(
|
|
7021
|
+
console.error(chalk12.red("\u2717 Failed to kill run"));
|
|
6769
7022
|
if (error instanceof Error) {
|
|
6770
7023
|
if (error.message.includes("Not authenticated")) {
|
|
6771
|
-
console.error(
|
|
7024
|
+
console.error(chalk12.dim(" Run: vm0 auth login"));
|
|
6772
7025
|
} else if (error.message.includes("not found") || error.message.includes("No such run")) {
|
|
6773
|
-
console.error(
|
|
7026
|
+
console.error(chalk12.dim(` Run not found: ${runId}`));
|
|
6774
7027
|
} else if (error.message.includes("cannot be cancelled")) {
|
|
6775
|
-
console.error(
|
|
7028
|
+
console.error(chalk12.dim(` ${error.message}`));
|
|
6776
7029
|
} else {
|
|
6777
|
-
console.error(
|
|
7030
|
+
console.error(chalk12.dim(` ${error.message}`));
|
|
6778
7031
|
}
|
|
6779
7032
|
}
|
|
6780
7033
|
process.exit(1);
|
|
@@ -6793,7 +7046,7 @@ import { Command as Command19 } from "commander";
|
|
|
6793
7046
|
|
|
6794
7047
|
// src/commands/volume/init.ts
|
|
6795
7048
|
import { Command as Command13 } from "commander";
|
|
6796
|
-
import
|
|
7049
|
+
import chalk13 from "chalk";
|
|
6797
7050
|
import path6 from "path";
|
|
6798
7051
|
|
|
6799
7052
|
// src/lib/storage/storage-utils.ts
|
|
@@ -6851,10 +7104,10 @@ var initCommand = new Command13().name("init").description("Initialize a volume
|
|
|
6851
7104
|
const existingConfig = await readStorageConfig(cwd);
|
|
6852
7105
|
if (existingConfig) {
|
|
6853
7106
|
console.log(
|
|
6854
|
-
|
|
7107
|
+
chalk13.yellow(`Volume already initialized: ${existingConfig.name}`)
|
|
6855
7108
|
);
|
|
6856
7109
|
console.log(
|
|
6857
|
-
|
|
7110
|
+
chalk13.dim(`Config file: ${path6.join(cwd, ".vm0", "storage.yaml")}`)
|
|
6858
7111
|
);
|
|
6859
7112
|
return;
|
|
6860
7113
|
}
|
|
@@ -6863,10 +7116,10 @@ var initCommand = new Command13().name("init").description("Initialize a volume
|
|
|
6863
7116
|
volumeName = options.name;
|
|
6864
7117
|
} else if (!isInteractive()) {
|
|
6865
7118
|
console.error(
|
|
6866
|
-
|
|
7119
|
+
chalk13.red("\u2717 --name flag is required in non-interactive mode")
|
|
6867
7120
|
);
|
|
6868
7121
|
console.error(
|
|
6869
|
-
|
|
7122
|
+
chalk13.dim(" Usage: vm0 volume init --name <volume-name>")
|
|
6870
7123
|
);
|
|
6871
7124
|
process.exit(1);
|
|
6872
7125
|
} else {
|
|
@@ -6882,34 +7135,34 @@ var initCommand = new Command13().name("init").description("Initialize a volume
|
|
|
6882
7135
|
}
|
|
6883
7136
|
);
|
|
6884
7137
|
if (name === void 0) {
|
|
6885
|
-
console.log(
|
|
7138
|
+
console.log(chalk13.dim("Cancelled"));
|
|
6886
7139
|
return;
|
|
6887
7140
|
}
|
|
6888
7141
|
volumeName = name;
|
|
6889
7142
|
}
|
|
6890
7143
|
if (!isValidStorageName(volumeName)) {
|
|
6891
|
-
console.error(
|
|
7144
|
+
console.error(chalk13.red(`\u2717 Invalid volume name: "${volumeName}"`));
|
|
6892
7145
|
console.error(
|
|
6893
|
-
|
|
7146
|
+
chalk13.dim(
|
|
6894
7147
|
" Volume names must be 3-64 characters, lowercase alphanumeric with hyphens"
|
|
6895
7148
|
)
|
|
6896
7149
|
);
|
|
6897
7150
|
console.error(
|
|
6898
|
-
|
|
7151
|
+
chalk13.dim(" Example: my-dataset, user-data-v2, training-set-2024")
|
|
6899
7152
|
);
|
|
6900
7153
|
process.exit(1);
|
|
6901
7154
|
}
|
|
6902
7155
|
await writeStorageConfig(volumeName, cwd);
|
|
6903
|
-
console.log(
|
|
7156
|
+
console.log(chalk13.green(`\u2713 Initialized volume: ${volumeName}`));
|
|
6904
7157
|
console.log(
|
|
6905
|
-
|
|
7158
|
+
chalk13.dim(
|
|
6906
7159
|
` Config saved to ${path6.join(cwd, ".vm0", "storage.yaml")}`
|
|
6907
7160
|
)
|
|
6908
7161
|
);
|
|
6909
7162
|
} catch (error) {
|
|
6910
|
-
console.error(
|
|
7163
|
+
console.error(chalk13.red("\u2717 Failed to initialize volume"));
|
|
6911
7164
|
if (error instanceof Error) {
|
|
6912
|
-
console.error(
|
|
7165
|
+
console.error(chalk13.dim(` ${error.message}`));
|
|
6913
7166
|
}
|
|
6914
7167
|
process.exit(1);
|
|
6915
7168
|
}
|
|
@@ -6917,7 +7170,7 @@ var initCommand = new Command13().name("init").description("Initialize a volume
|
|
|
6917
7170
|
|
|
6918
7171
|
// src/commands/volume/push.ts
|
|
6919
7172
|
import { Command as Command14 } from "commander";
|
|
6920
|
-
import
|
|
7173
|
+
import chalk14 from "chalk";
|
|
6921
7174
|
var pushCommand = new Command14().name("push").description("Push local files to cloud volume").option(
|
|
6922
7175
|
"-f, --force",
|
|
6923
7176
|
"Force upload even if content unchanged (recreate archive)"
|
|
@@ -6926,35 +7179,35 @@ var pushCommand = new Command14().name("push").description("Push local files to
|
|
|
6926
7179
|
const cwd = process.cwd();
|
|
6927
7180
|
const config = await readStorageConfig(cwd);
|
|
6928
7181
|
if (!config) {
|
|
6929
|
-
console.error(
|
|
6930
|
-
console.error(
|
|
7182
|
+
console.error(chalk14.red("\u2717 No volume initialized in this directory"));
|
|
7183
|
+
console.error(chalk14.dim(" Run: vm0 volume init"));
|
|
6931
7184
|
process.exit(1);
|
|
6932
7185
|
}
|
|
6933
7186
|
console.log(`Pushing volume: ${config.name}`);
|
|
6934
7187
|
const result = await directUpload(config.name, "volume", cwd, {
|
|
6935
7188
|
onProgress: (message) => {
|
|
6936
|
-
console.log(
|
|
7189
|
+
console.log(chalk14.dim(message));
|
|
6937
7190
|
},
|
|
6938
7191
|
force: options.force
|
|
6939
7192
|
});
|
|
6940
7193
|
const shortVersion = result.versionId.slice(0, 8);
|
|
6941
7194
|
if (result.empty) {
|
|
6942
|
-
console.log(
|
|
7195
|
+
console.log(chalk14.dim("No files found (empty volume)"));
|
|
6943
7196
|
} else if (result.deduplicated) {
|
|
6944
|
-
console.log(
|
|
7197
|
+
console.log(chalk14.green("\u2713 Content unchanged (deduplicated)"));
|
|
6945
7198
|
} else {
|
|
6946
|
-
console.log(
|
|
7199
|
+
console.log(chalk14.green("\u2713 Upload complete"));
|
|
6947
7200
|
}
|
|
6948
|
-
console.log(
|
|
6949
|
-
console.log(
|
|
6950
|
-
console.log(
|
|
7201
|
+
console.log(chalk14.dim(` Version: ${shortVersion}`));
|
|
7202
|
+
console.log(chalk14.dim(` Files: ${result.fileCount.toLocaleString()}`));
|
|
7203
|
+
console.log(chalk14.dim(` Size: ${formatBytes(result.size)}`));
|
|
6951
7204
|
} catch (error) {
|
|
6952
|
-
console.error(
|
|
7205
|
+
console.error(chalk14.red("\u2717 Push failed"));
|
|
6953
7206
|
if (error instanceof Error) {
|
|
6954
7207
|
if (error.message.includes("Not authenticated")) {
|
|
6955
|
-
console.error(
|
|
7208
|
+
console.error(chalk14.dim(" Run: vm0 auth login"));
|
|
6956
7209
|
} else {
|
|
6957
|
-
console.error(
|
|
7210
|
+
console.error(chalk14.dim(` ${error.message}`));
|
|
6958
7211
|
}
|
|
6959
7212
|
}
|
|
6960
7213
|
process.exit(1);
|
|
@@ -6963,21 +7216,21 @@ var pushCommand = new Command14().name("push").description("Push local files to
|
|
|
6963
7216
|
|
|
6964
7217
|
// src/commands/volume/pull.ts
|
|
6965
7218
|
import { Command as Command15 } from "commander";
|
|
6966
|
-
import
|
|
7219
|
+
import chalk16 from "chalk";
|
|
6967
7220
|
import path7 from "path";
|
|
6968
7221
|
import * as fs6 from "fs";
|
|
6969
7222
|
import * as os4 from "os";
|
|
6970
7223
|
import * as tar3 from "tar";
|
|
6971
7224
|
|
|
6972
7225
|
// src/lib/storage/pull-utils.ts
|
|
6973
|
-
import
|
|
7226
|
+
import chalk15 from "chalk";
|
|
6974
7227
|
async function handleEmptyStorageResponse(cwd) {
|
|
6975
|
-
console.log(
|
|
7228
|
+
console.log(chalk15.dim("Syncing local files..."));
|
|
6976
7229
|
const removedCount = await removeExtraFiles(cwd, /* @__PURE__ */ new Set());
|
|
6977
7230
|
if (removedCount > 0) {
|
|
6978
|
-
console.log(
|
|
7231
|
+
console.log(chalk15.green(`\u2713 Removed ${removedCount} files not in remote`));
|
|
6979
7232
|
}
|
|
6980
|
-
console.log(
|
|
7233
|
+
console.log(chalk15.green("\u2713 Synced (0 files)"));
|
|
6981
7234
|
return { removedCount };
|
|
6982
7235
|
}
|
|
6983
7236
|
|
|
@@ -6987,8 +7240,8 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
6987
7240
|
const cwd = process.cwd();
|
|
6988
7241
|
const config = await readStorageConfig(cwd);
|
|
6989
7242
|
if (!config) {
|
|
6990
|
-
console.error(
|
|
6991
|
-
console.error(
|
|
7243
|
+
console.error(chalk16.red("\u2717 No volume initialized in this directory"));
|
|
7244
|
+
console.error(chalk16.dim(" Run: vm0 volume init"));
|
|
6992
7245
|
process.exit(1);
|
|
6993
7246
|
}
|
|
6994
7247
|
if (versionId) {
|
|
@@ -6996,7 +7249,7 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
6996
7249
|
} else {
|
|
6997
7250
|
console.log(`Pulling volume: ${config.name}`);
|
|
6998
7251
|
}
|
|
6999
|
-
console.log(
|
|
7252
|
+
console.log(chalk16.dim("Getting download URL..."));
|
|
7000
7253
|
const downloadInfo = await getStorageDownload({
|
|
7001
7254
|
name: config.name,
|
|
7002
7255
|
type: "volume",
|
|
@@ -7010,18 +7263,18 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7010
7263
|
if (!downloadUrl) {
|
|
7011
7264
|
throw new Error("No download URL returned");
|
|
7012
7265
|
}
|
|
7013
|
-
console.log(
|
|
7266
|
+
console.log(chalk16.dim("Downloading from S3..."));
|
|
7014
7267
|
const s3Response = await fetch(downloadUrl);
|
|
7015
7268
|
if (!s3Response.ok) {
|
|
7016
7269
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
7017
7270
|
}
|
|
7018
7271
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
7019
7272
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
7020
|
-
console.log(
|
|
7273
|
+
console.log(chalk16.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
7021
7274
|
const tmpDir = fs6.mkdtempSync(path7.join(os4.tmpdir(), "vm0-"));
|
|
7022
7275
|
const tarPath = path7.join(tmpDir, "volume.tar.gz");
|
|
7023
7276
|
await fs6.promises.writeFile(tarPath, tarBuffer);
|
|
7024
|
-
console.log(
|
|
7277
|
+
console.log(chalk16.dim("Syncing local files..."));
|
|
7025
7278
|
const remoteFiles = await listTarFiles(tarPath);
|
|
7026
7279
|
const remoteFilesSet = new Set(
|
|
7027
7280
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -7029,10 +7282,10 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7029
7282
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
7030
7283
|
if (removedCount > 0) {
|
|
7031
7284
|
console.log(
|
|
7032
|
-
|
|
7285
|
+
chalk16.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
7033
7286
|
);
|
|
7034
7287
|
}
|
|
7035
|
-
console.log(
|
|
7288
|
+
console.log(chalk16.dim("Extracting files..."));
|
|
7036
7289
|
await tar3.extract({
|
|
7037
7290
|
file: tarPath,
|
|
7038
7291
|
cwd,
|
|
@@ -7040,14 +7293,14 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7040
7293
|
});
|
|
7041
7294
|
await fs6.promises.unlink(tarPath);
|
|
7042
7295
|
await fs6.promises.rmdir(tmpDir);
|
|
7043
|
-
console.log(
|
|
7296
|
+
console.log(chalk16.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
7044
7297
|
} catch (error) {
|
|
7045
|
-
console.error(
|
|
7298
|
+
console.error(chalk16.red("\u2717 Pull failed"));
|
|
7046
7299
|
if (error instanceof Error) {
|
|
7047
7300
|
if (error.message.includes("Not authenticated")) {
|
|
7048
|
-
console.error(
|
|
7301
|
+
console.error(chalk16.dim(" Run: vm0 auth login"));
|
|
7049
7302
|
} else {
|
|
7050
|
-
console.error(
|
|
7303
|
+
console.error(chalk16.dim(` ${error.message}`));
|
|
7051
7304
|
}
|
|
7052
7305
|
}
|
|
7053
7306
|
process.exit(1);
|
|
@@ -7056,23 +7309,23 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7056
7309
|
|
|
7057
7310
|
// src/commands/volume/status.ts
|
|
7058
7311
|
import { Command as Command16 } from "commander";
|
|
7059
|
-
import
|
|
7312
|
+
import chalk17 from "chalk";
|
|
7060
7313
|
var statusCommand2 = new Command16().name("status").description("Show status of cloud volume").action(async () => {
|
|
7061
7314
|
try {
|
|
7062
7315
|
const cwd = process.cwd();
|
|
7063
7316
|
const config = await readStorageConfig(cwd);
|
|
7064
7317
|
if (!config) {
|
|
7065
|
-
console.error(
|
|
7066
|
-
console.error(
|
|
7318
|
+
console.error(chalk17.red("\u2717 No volume initialized in this directory"));
|
|
7319
|
+
console.error(chalk17.dim(" Run: vm0 volume init"));
|
|
7067
7320
|
process.exit(1);
|
|
7068
7321
|
}
|
|
7069
7322
|
if (config.type !== "volume") {
|
|
7070
7323
|
console.error(
|
|
7071
|
-
|
|
7324
|
+
chalk17.red(
|
|
7072
7325
|
"\u2717 This directory is initialized as an artifact, not a volume"
|
|
7073
7326
|
)
|
|
7074
7327
|
);
|
|
7075
|
-
console.error(
|
|
7328
|
+
console.error(chalk17.dim(" Use: vm0 artifact status"));
|
|
7076
7329
|
process.exit(1);
|
|
7077
7330
|
}
|
|
7078
7331
|
console.log(`Checking volume: ${config.name}`);
|
|
@@ -7082,25 +7335,25 @@ var statusCommand2 = new Command16().name("status").description("Show status of
|
|
|
7082
7335
|
});
|
|
7083
7336
|
const shortVersion = info.versionId.slice(0, 8);
|
|
7084
7337
|
if ("empty" in info) {
|
|
7085
|
-
console.log(
|
|
7086
|
-
console.log(
|
|
7338
|
+
console.log(chalk17.green("\u2713 Found (empty)"));
|
|
7339
|
+
console.log(chalk17.dim(` Version: ${shortVersion}`));
|
|
7087
7340
|
} else {
|
|
7088
|
-
console.log(
|
|
7089
|
-
console.log(
|
|
7090
|
-
console.log(
|
|
7091
|
-
console.log(
|
|
7341
|
+
console.log(chalk17.green("\u2713 Found"));
|
|
7342
|
+
console.log(chalk17.dim(` Version: ${shortVersion}`));
|
|
7343
|
+
console.log(chalk17.dim(` Files: ${info.fileCount.toLocaleString()}`));
|
|
7344
|
+
console.log(chalk17.dim(` Size: ${formatBytes(info.size)}`));
|
|
7092
7345
|
}
|
|
7093
7346
|
} catch (error) {
|
|
7094
7347
|
if (error instanceof Error && error.message.includes("not found")) {
|
|
7095
|
-
console.error(
|
|
7096
|
-
console.error(
|
|
7348
|
+
console.error(chalk17.red("\u2717 Not found on remote"));
|
|
7349
|
+
console.error(chalk17.dim(" Run: vm0 volume push"));
|
|
7097
7350
|
} else {
|
|
7098
|
-
console.error(
|
|
7351
|
+
console.error(chalk17.red("\u2717 Status check failed"));
|
|
7099
7352
|
if (error instanceof Error) {
|
|
7100
7353
|
if (error.message.includes("Not authenticated")) {
|
|
7101
|
-
console.error(
|
|
7354
|
+
console.error(chalk17.dim(" Run: vm0 auth login"));
|
|
7102
7355
|
} else {
|
|
7103
|
-
console.error(
|
|
7356
|
+
console.error(chalk17.dim(` ${error.message}`));
|
|
7104
7357
|
}
|
|
7105
7358
|
}
|
|
7106
7359
|
}
|
|
@@ -7110,14 +7363,14 @@ var statusCommand2 = new Command16().name("status").description("Show status of
|
|
|
7110
7363
|
|
|
7111
7364
|
// src/commands/volume/list.ts
|
|
7112
7365
|
import { Command as Command17 } from "commander";
|
|
7113
|
-
import
|
|
7366
|
+
import chalk18 from "chalk";
|
|
7114
7367
|
var listCommand2 = new Command17().name("list").alias("ls").description("List all remote volumes").action(async () => {
|
|
7115
7368
|
try {
|
|
7116
7369
|
const items = await listStorages({ type: "volume" });
|
|
7117
7370
|
if (items.length === 0) {
|
|
7118
|
-
console.log(
|
|
7371
|
+
console.log(chalk18.dim("No volumes found"));
|
|
7119
7372
|
console.log(
|
|
7120
|
-
|
|
7373
|
+
chalk18.dim(" Create one with: vm0 volume init && vm0 volume push")
|
|
7121
7374
|
);
|
|
7122
7375
|
return;
|
|
7123
7376
|
}
|
|
@@ -7136,7 +7389,7 @@ var listCommand2 = new Command17().name("list").alias("ls").description("List al
|
|
|
7136
7389
|
"FILES".padStart(filesWidth),
|
|
7137
7390
|
"UPDATED"
|
|
7138
7391
|
].join(" ");
|
|
7139
|
-
console.log(
|
|
7392
|
+
console.log(chalk18.dim(header));
|
|
7140
7393
|
for (const item of items) {
|
|
7141
7394
|
const row = [
|
|
7142
7395
|
item.name.padEnd(nameWidth),
|
|
@@ -7147,12 +7400,12 @@ var listCommand2 = new Command17().name("list").alias("ls").description("List al
|
|
|
7147
7400
|
console.log(row);
|
|
7148
7401
|
}
|
|
7149
7402
|
} catch (error) {
|
|
7150
|
-
console.error(
|
|
7403
|
+
console.error(chalk18.red("\u2717 Failed to list volumes"));
|
|
7151
7404
|
if (error instanceof Error) {
|
|
7152
7405
|
if (error.message.includes("Not authenticated")) {
|
|
7153
|
-
console.error(
|
|
7406
|
+
console.error(chalk18.dim(" Run: vm0 auth login"));
|
|
7154
7407
|
} else {
|
|
7155
|
-
console.error(
|
|
7408
|
+
console.error(chalk18.dim(` ${error.message}`));
|
|
7156
7409
|
}
|
|
7157
7410
|
}
|
|
7158
7411
|
process.exit(1);
|
|
@@ -7161,10 +7414,10 @@ var listCommand2 = new Command17().name("list").alias("ls").description("List al
|
|
|
7161
7414
|
|
|
7162
7415
|
// src/commands/volume/clone.ts
|
|
7163
7416
|
import { Command as Command18 } from "commander";
|
|
7164
|
-
import
|
|
7417
|
+
import chalk20 from "chalk";
|
|
7165
7418
|
|
|
7166
7419
|
// src/lib/storage/clone-utils.ts
|
|
7167
|
-
import
|
|
7420
|
+
import chalk19 from "chalk";
|
|
7168
7421
|
import path8 from "path";
|
|
7169
7422
|
import * as fs7 from "fs";
|
|
7170
7423
|
import * as os5 from "os";
|
|
@@ -7174,18 +7427,18 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7174
7427
|
if (fs7.existsSync(destination)) {
|
|
7175
7428
|
throw new Error(`Directory "${destination}" already exists`);
|
|
7176
7429
|
}
|
|
7177
|
-
console.log(
|
|
7430
|
+
console.log(chalk19.dim(`Checking remote ${typeLabel}...`));
|
|
7178
7431
|
const downloadInfo = await getStorageDownload({
|
|
7179
7432
|
name,
|
|
7180
7433
|
type,
|
|
7181
7434
|
version: options.version
|
|
7182
7435
|
});
|
|
7183
|
-
console.log(
|
|
7436
|
+
console.log(chalk19.dim(`Creating directory: ${destination}/`));
|
|
7184
7437
|
await fs7.promises.mkdir(destination, { recursive: true });
|
|
7185
7438
|
if ("empty" in downloadInfo) {
|
|
7186
7439
|
await writeStorageConfig(name, destination, type);
|
|
7187
|
-
console.log(
|
|
7188
|
-
console.log(
|
|
7440
|
+
console.log(chalk19.green(`\u2713 Cloned empty ${typeLabel}: ${name}`));
|
|
7441
|
+
console.log(chalk19.dim(`\u2713 Initialized .vm0/storage.yaml`));
|
|
7189
7442
|
return {
|
|
7190
7443
|
success: true,
|
|
7191
7444
|
fileCount: 0,
|
|
@@ -7197,7 +7450,7 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7197
7450
|
if (!downloadUrl) {
|
|
7198
7451
|
throw new Error("No download URL returned");
|
|
7199
7452
|
}
|
|
7200
|
-
console.log(
|
|
7453
|
+
console.log(chalk19.dim("Downloading from S3..."));
|
|
7201
7454
|
const s3Response = await fetch(downloadUrl);
|
|
7202
7455
|
if (!s3Response.ok) {
|
|
7203
7456
|
await fs7.promises.rm(destination, { recursive: true, force: true });
|
|
@@ -7205,12 +7458,12 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7205
7458
|
}
|
|
7206
7459
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
7207
7460
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
7208
|
-
console.log(
|
|
7461
|
+
console.log(chalk19.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
7209
7462
|
const tmpDir = fs7.mkdtempSync(path8.join(os5.tmpdir(), "vm0-clone-"));
|
|
7210
7463
|
const tarPath = path8.join(tmpDir, "archive.tar.gz");
|
|
7211
7464
|
await fs7.promises.writeFile(tarPath, tarBuffer);
|
|
7212
7465
|
const files = await listTarFiles(tarPath);
|
|
7213
|
-
console.log(
|
|
7466
|
+
console.log(chalk19.dim("Extracting files..."));
|
|
7214
7467
|
await tar4.extract({
|
|
7215
7468
|
file: tarPath,
|
|
7216
7469
|
cwd: destination,
|
|
@@ -7218,9 +7471,9 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7218
7471
|
});
|
|
7219
7472
|
await fs7.promises.unlink(tarPath);
|
|
7220
7473
|
await fs7.promises.rmdir(tmpDir);
|
|
7221
|
-
console.log(
|
|
7474
|
+
console.log(chalk19.green(`\u2713 Extracted ${files.length} files`));
|
|
7222
7475
|
await writeStorageConfig(name, destination, type);
|
|
7223
|
-
console.log(
|
|
7476
|
+
console.log(chalk19.green(`\u2713 Initialized .vm0/storage.yaml`));
|
|
7224
7477
|
return {
|
|
7225
7478
|
success: true,
|
|
7226
7479
|
fileCount: downloadInfo.fileCount,
|
|
@@ -7235,17 +7488,17 @@ var cloneCommand = new Command18().name("clone").description("Clone a remote vol
|
|
|
7235
7488
|
const targetDir = destination || name;
|
|
7236
7489
|
console.log(`Cloning volume: ${name}`);
|
|
7237
7490
|
const result = await cloneStorage(name, "volume", targetDir);
|
|
7238
|
-
console.log(
|
|
7491
|
+
console.log(chalk20.green(`
|
|
7239
7492
|
\u2713 Successfully cloned volume: ${name}`));
|
|
7240
|
-
console.log(
|
|
7241
|
-
console.log(
|
|
7493
|
+
console.log(chalk20.dim(` Location: ${targetDir}/`));
|
|
7494
|
+
console.log(chalk20.dim(` Version: ${result.versionId.slice(0, 8)}`));
|
|
7242
7495
|
} catch (error) {
|
|
7243
|
-
console.error(
|
|
7496
|
+
console.error(chalk20.red("\u2717 Clone failed"));
|
|
7244
7497
|
if (error instanceof Error) {
|
|
7245
7498
|
if (error.message.includes("Not authenticated")) {
|
|
7246
|
-
console.error(
|
|
7499
|
+
console.error(chalk20.dim(" Run: vm0 auth login"));
|
|
7247
7500
|
} else {
|
|
7248
|
-
console.error(
|
|
7501
|
+
console.error(chalk20.dim(` ${error.message}`));
|
|
7249
7502
|
}
|
|
7250
7503
|
}
|
|
7251
7504
|
process.exit(1);
|
|
@@ -7260,7 +7513,7 @@ import { Command as Command26 } from "commander";
|
|
|
7260
7513
|
|
|
7261
7514
|
// src/commands/artifact/init.ts
|
|
7262
7515
|
import { Command as Command20 } from "commander";
|
|
7263
|
-
import
|
|
7516
|
+
import chalk21 from "chalk";
|
|
7264
7517
|
import path9 from "path";
|
|
7265
7518
|
var initCommand2 = new Command20().name("init").description("Initialize an artifact in the current directory").option(
|
|
7266
7519
|
"-n, --name <name>",
|
|
@@ -7273,24 +7526,24 @@ var initCommand2 = new Command20().name("init").description("Initialize an artif
|
|
|
7273
7526
|
if (existingConfig) {
|
|
7274
7527
|
if (existingConfig.type === "artifact") {
|
|
7275
7528
|
console.log(
|
|
7276
|
-
|
|
7529
|
+
chalk21.yellow(
|
|
7277
7530
|
`Artifact already initialized: ${existingConfig.name}`
|
|
7278
7531
|
)
|
|
7279
7532
|
);
|
|
7280
7533
|
} else {
|
|
7281
7534
|
console.log(
|
|
7282
|
-
|
|
7535
|
+
chalk21.yellow(
|
|
7283
7536
|
`Directory already initialized as volume: ${existingConfig.name}`
|
|
7284
7537
|
)
|
|
7285
7538
|
);
|
|
7286
7539
|
console.log(
|
|
7287
|
-
|
|
7540
|
+
chalk21.dim(
|
|
7288
7541
|
" To change type, delete .vm0/storage.yaml and reinitialize"
|
|
7289
7542
|
)
|
|
7290
7543
|
);
|
|
7291
7544
|
}
|
|
7292
7545
|
console.log(
|
|
7293
|
-
|
|
7546
|
+
chalk21.dim(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
|
|
7294
7547
|
);
|
|
7295
7548
|
return;
|
|
7296
7549
|
}
|
|
@@ -7299,10 +7552,10 @@ var initCommand2 = new Command20().name("init").description("Initialize an artif
|
|
|
7299
7552
|
artifactName = options.name;
|
|
7300
7553
|
} else if (!isInteractive()) {
|
|
7301
7554
|
console.error(
|
|
7302
|
-
|
|
7555
|
+
chalk21.red("\u2717 --name flag is required in non-interactive mode")
|
|
7303
7556
|
);
|
|
7304
7557
|
console.error(
|
|
7305
|
-
|
|
7558
|
+
chalk21.dim(" Usage: vm0 artifact init --name <artifact-name>")
|
|
7306
7559
|
);
|
|
7307
7560
|
process.exit(1);
|
|
7308
7561
|
} else {
|
|
@@ -7318,34 +7571,34 @@ var initCommand2 = new Command20().name("init").description("Initialize an artif
|
|
|
7318
7571
|
}
|
|
7319
7572
|
);
|
|
7320
7573
|
if (name === void 0) {
|
|
7321
|
-
console.log(
|
|
7574
|
+
console.log(chalk21.dim("Cancelled"));
|
|
7322
7575
|
return;
|
|
7323
7576
|
}
|
|
7324
7577
|
artifactName = name;
|
|
7325
7578
|
}
|
|
7326
7579
|
if (!isValidStorageName(artifactName)) {
|
|
7327
|
-
console.error(
|
|
7580
|
+
console.error(chalk21.red(`\u2717 Invalid artifact name: "${artifactName}"`));
|
|
7328
7581
|
console.error(
|
|
7329
|
-
|
|
7582
|
+
chalk21.dim(
|
|
7330
7583
|
" Artifact names must be 3-64 characters, lowercase alphanumeric with hyphens"
|
|
7331
7584
|
)
|
|
7332
7585
|
);
|
|
7333
7586
|
console.error(
|
|
7334
|
-
|
|
7587
|
+
chalk21.dim(" Example: my-project, user-workspace, code-artifact")
|
|
7335
7588
|
);
|
|
7336
7589
|
process.exit(1);
|
|
7337
7590
|
}
|
|
7338
7591
|
await writeStorageConfig(artifactName, cwd, "artifact");
|
|
7339
|
-
console.log(
|
|
7592
|
+
console.log(chalk21.green(`\u2713 Initialized artifact: ${artifactName}`));
|
|
7340
7593
|
console.log(
|
|
7341
|
-
|
|
7594
|
+
chalk21.dim(
|
|
7342
7595
|
` Config saved to ${path9.join(cwd, ".vm0", "storage.yaml")}`
|
|
7343
7596
|
)
|
|
7344
7597
|
);
|
|
7345
7598
|
} catch (error) {
|
|
7346
|
-
console.error(
|
|
7599
|
+
console.error(chalk21.red("\u2717 Failed to initialize artifact"));
|
|
7347
7600
|
if (error instanceof Error) {
|
|
7348
|
-
console.error(
|
|
7601
|
+
console.error(chalk21.dim(` ${error.message}`));
|
|
7349
7602
|
}
|
|
7350
7603
|
process.exit(1);
|
|
7351
7604
|
}
|
|
@@ -7353,7 +7606,7 @@ var initCommand2 = new Command20().name("init").description("Initialize an artif
|
|
|
7353
7606
|
|
|
7354
7607
|
// src/commands/artifact/push.ts
|
|
7355
7608
|
import { Command as Command21 } from "commander";
|
|
7356
|
-
import
|
|
7609
|
+
import chalk22 from "chalk";
|
|
7357
7610
|
var pushCommand2 = new Command21().name("push").description("Push local files to cloud artifact").option(
|
|
7358
7611
|
"-f, --force",
|
|
7359
7612
|
"Force upload even if content unchanged (recreate archive)"
|
|
@@ -7362,41 +7615,41 @@ var pushCommand2 = new Command21().name("push").description("Push local files to
|
|
|
7362
7615
|
const cwd = process.cwd();
|
|
7363
7616
|
const config = await readStorageConfig(cwd);
|
|
7364
7617
|
if (!config) {
|
|
7365
|
-
console.error(
|
|
7366
|
-
console.error(
|
|
7618
|
+
console.error(chalk22.red("\u2717 No artifact initialized in this directory"));
|
|
7619
|
+
console.error(chalk22.dim(" Run: vm0 artifact init"));
|
|
7367
7620
|
process.exit(1);
|
|
7368
7621
|
}
|
|
7369
7622
|
if (config.type !== "artifact") {
|
|
7370
7623
|
console.error(
|
|
7371
|
-
|
|
7624
|
+
chalk22.red(
|
|
7372
7625
|
`\u2717 This directory is initialized as a volume, not an artifact`
|
|
7373
7626
|
)
|
|
7374
7627
|
);
|
|
7375
|
-
console.error(
|
|
7628
|
+
console.error(chalk22.dim(" Use: vm0 volume push"));
|
|
7376
7629
|
process.exit(1);
|
|
7377
7630
|
}
|
|
7378
7631
|
console.log(`Pushing artifact: ${config.name}`);
|
|
7379
7632
|
const result = await directUpload(config.name, "artifact", cwd, {
|
|
7380
7633
|
onProgress: (message) => {
|
|
7381
|
-
console.log(
|
|
7634
|
+
console.log(chalk22.dim(message));
|
|
7382
7635
|
},
|
|
7383
7636
|
force: options.force
|
|
7384
7637
|
});
|
|
7385
7638
|
const shortVersion = result.versionId.slice(0, 8);
|
|
7386
7639
|
if (result.empty) {
|
|
7387
|
-
console.log(
|
|
7640
|
+
console.log(chalk22.dim("No files found (empty artifact)"));
|
|
7388
7641
|
} else if (result.deduplicated) {
|
|
7389
|
-
console.log(
|
|
7642
|
+
console.log(chalk22.green("\u2713 Content unchanged (deduplicated)"));
|
|
7390
7643
|
} else {
|
|
7391
|
-
console.log(
|
|
7644
|
+
console.log(chalk22.green("\u2713 Upload complete"));
|
|
7392
7645
|
}
|
|
7393
|
-
console.log(
|
|
7394
|
-
console.log(
|
|
7395
|
-
console.log(
|
|
7646
|
+
console.log(chalk22.dim(` Version: ${shortVersion}`));
|
|
7647
|
+
console.log(chalk22.dim(` Files: ${result.fileCount.toLocaleString()}`));
|
|
7648
|
+
console.log(chalk22.dim(` Size: ${formatBytes(result.size)}`));
|
|
7396
7649
|
} catch (error) {
|
|
7397
|
-
console.error(
|
|
7650
|
+
console.error(chalk22.red("\u2717 Push failed"));
|
|
7398
7651
|
if (error instanceof Error) {
|
|
7399
|
-
console.error(
|
|
7652
|
+
console.error(chalk22.dim(` ${error.message}`));
|
|
7400
7653
|
}
|
|
7401
7654
|
process.exit(1);
|
|
7402
7655
|
}
|
|
@@ -7404,7 +7657,7 @@ var pushCommand2 = new Command21().name("push").description("Push local files to
|
|
|
7404
7657
|
|
|
7405
7658
|
// src/commands/artifact/pull.ts
|
|
7406
7659
|
import { Command as Command22 } from "commander";
|
|
7407
|
-
import
|
|
7660
|
+
import chalk23 from "chalk";
|
|
7408
7661
|
import path10 from "path";
|
|
7409
7662
|
import * as fs8 from "fs";
|
|
7410
7663
|
import * as os6 from "os";
|
|
@@ -7414,17 +7667,17 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7414
7667
|
const cwd = process.cwd();
|
|
7415
7668
|
const config = await readStorageConfig(cwd);
|
|
7416
7669
|
if (!config) {
|
|
7417
|
-
console.error(
|
|
7418
|
-
console.error(
|
|
7670
|
+
console.error(chalk23.red("\u2717 No artifact initialized in this directory"));
|
|
7671
|
+
console.error(chalk23.dim(" Run: vm0 artifact init"));
|
|
7419
7672
|
process.exit(1);
|
|
7420
7673
|
}
|
|
7421
7674
|
if (config.type !== "artifact") {
|
|
7422
7675
|
console.error(
|
|
7423
|
-
|
|
7676
|
+
chalk23.red(
|
|
7424
7677
|
`\u2717 This directory is initialized as a volume, not an artifact`
|
|
7425
7678
|
)
|
|
7426
7679
|
);
|
|
7427
|
-
console.error(
|
|
7680
|
+
console.error(chalk23.dim(" Use: vm0 volume pull"));
|
|
7428
7681
|
process.exit(1);
|
|
7429
7682
|
}
|
|
7430
7683
|
if (versionId) {
|
|
@@ -7432,7 +7685,7 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7432
7685
|
} else {
|
|
7433
7686
|
console.log(`Pulling artifact: ${config.name}`);
|
|
7434
7687
|
}
|
|
7435
|
-
console.log(
|
|
7688
|
+
console.log(chalk23.dim("Getting download URL..."));
|
|
7436
7689
|
const downloadInfo = await getStorageDownload({
|
|
7437
7690
|
name: config.name,
|
|
7438
7691
|
type: "artifact",
|
|
@@ -7446,18 +7699,18 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7446
7699
|
if (!downloadUrl) {
|
|
7447
7700
|
throw new Error("No download URL returned");
|
|
7448
7701
|
}
|
|
7449
|
-
console.log(
|
|
7702
|
+
console.log(chalk23.dim("Downloading from S3..."));
|
|
7450
7703
|
const s3Response = await fetch(downloadUrl);
|
|
7451
7704
|
if (!s3Response.ok) {
|
|
7452
7705
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
7453
7706
|
}
|
|
7454
7707
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
7455
7708
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
7456
|
-
console.log(
|
|
7709
|
+
console.log(chalk23.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
7457
7710
|
const tmpDir = fs8.mkdtempSync(path10.join(os6.tmpdir(), "vm0-"));
|
|
7458
7711
|
const tarPath = path10.join(tmpDir, "artifact.tar.gz");
|
|
7459
7712
|
await fs8.promises.writeFile(tarPath, tarBuffer);
|
|
7460
|
-
console.log(
|
|
7713
|
+
console.log(chalk23.dim("Syncing local files..."));
|
|
7461
7714
|
const remoteFiles = await listTarFiles(tarPath);
|
|
7462
7715
|
const remoteFilesSet = new Set(
|
|
7463
7716
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -7465,10 +7718,10 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7465
7718
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
7466
7719
|
if (removedCount > 0) {
|
|
7467
7720
|
console.log(
|
|
7468
|
-
|
|
7721
|
+
chalk23.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
7469
7722
|
);
|
|
7470
7723
|
}
|
|
7471
|
-
console.log(
|
|
7724
|
+
console.log(chalk23.dim("Extracting files..."));
|
|
7472
7725
|
await tar5.extract({
|
|
7473
7726
|
file: tarPath,
|
|
7474
7727
|
cwd,
|
|
@@ -7476,11 +7729,11 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7476
7729
|
});
|
|
7477
7730
|
await fs8.promises.unlink(tarPath);
|
|
7478
7731
|
await fs8.promises.rmdir(tmpDir);
|
|
7479
|
-
console.log(
|
|
7732
|
+
console.log(chalk23.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
7480
7733
|
} catch (error) {
|
|
7481
|
-
console.error(
|
|
7734
|
+
console.error(chalk23.red("\u2717 Pull failed"));
|
|
7482
7735
|
if (error instanceof Error) {
|
|
7483
|
-
console.error(
|
|
7736
|
+
console.error(chalk23.dim(` ${error.message}`));
|
|
7484
7737
|
}
|
|
7485
7738
|
process.exit(1);
|
|
7486
7739
|
}
|
|
@@ -7488,23 +7741,23 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7488
7741
|
|
|
7489
7742
|
// src/commands/artifact/status.ts
|
|
7490
7743
|
import { Command as Command23 } from "commander";
|
|
7491
|
-
import
|
|
7744
|
+
import chalk24 from "chalk";
|
|
7492
7745
|
var statusCommand3 = new Command23().name("status").description("Show status of cloud artifact").action(async () => {
|
|
7493
7746
|
try {
|
|
7494
7747
|
const cwd = process.cwd();
|
|
7495
7748
|
const config = await readStorageConfig(cwd);
|
|
7496
7749
|
if (!config) {
|
|
7497
|
-
console.error(
|
|
7498
|
-
console.error(
|
|
7750
|
+
console.error(chalk24.red("\u2717 No artifact initialized in this directory"));
|
|
7751
|
+
console.error(chalk24.dim(" Run: vm0 artifact init"));
|
|
7499
7752
|
process.exit(1);
|
|
7500
7753
|
}
|
|
7501
7754
|
if (config.type !== "artifact") {
|
|
7502
7755
|
console.error(
|
|
7503
|
-
|
|
7756
|
+
chalk24.red(
|
|
7504
7757
|
"\u2717 This directory is initialized as a volume, not an artifact"
|
|
7505
7758
|
)
|
|
7506
7759
|
);
|
|
7507
|
-
console.error(
|
|
7760
|
+
console.error(chalk24.dim(" Use: vm0 volume status"));
|
|
7508
7761
|
process.exit(1);
|
|
7509
7762
|
}
|
|
7510
7763
|
console.log(`Checking artifact: ${config.name}`);
|
|
@@ -7514,22 +7767,22 @@ var statusCommand3 = new Command23().name("status").description("Show status of
|
|
|
7514
7767
|
});
|
|
7515
7768
|
const shortVersion = info.versionId.slice(0, 8);
|
|
7516
7769
|
if ("empty" in info) {
|
|
7517
|
-
console.log(
|
|
7518
|
-
console.log(
|
|
7770
|
+
console.log(chalk24.green("\u2713 Found (empty)"));
|
|
7771
|
+
console.log(chalk24.dim(` Version: ${shortVersion}`));
|
|
7519
7772
|
} else {
|
|
7520
|
-
console.log(
|
|
7521
|
-
console.log(
|
|
7522
|
-
console.log(
|
|
7523
|
-
console.log(
|
|
7773
|
+
console.log(chalk24.green("\u2713 Found"));
|
|
7774
|
+
console.log(chalk24.dim(` Version: ${shortVersion}`));
|
|
7775
|
+
console.log(chalk24.dim(` Files: ${info.fileCount.toLocaleString()}`));
|
|
7776
|
+
console.log(chalk24.dim(` Size: ${formatBytes(info.size)}`));
|
|
7524
7777
|
}
|
|
7525
7778
|
} catch (error) {
|
|
7526
7779
|
if (error instanceof Error && error.message.includes("not found")) {
|
|
7527
|
-
console.error(
|
|
7528
|
-
console.error(
|
|
7780
|
+
console.error(chalk24.red("\u2717 Not found on remote"));
|
|
7781
|
+
console.error(chalk24.dim(" Run: vm0 artifact push"));
|
|
7529
7782
|
} else {
|
|
7530
|
-
console.error(
|
|
7783
|
+
console.error(chalk24.red("\u2717 Status check failed"));
|
|
7531
7784
|
if (error instanceof Error) {
|
|
7532
|
-
console.error(
|
|
7785
|
+
console.error(chalk24.dim(` ${error.message}`));
|
|
7533
7786
|
}
|
|
7534
7787
|
}
|
|
7535
7788
|
process.exit(1);
|
|
@@ -7538,14 +7791,14 @@ var statusCommand3 = new Command23().name("status").description("Show status of
|
|
|
7538
7791
|
|
|
7539
7792
|
// src/commands/artifact/list.ts
|
|
7540
7793
|
import { Command as Command24 } from "commander";
|
|
7541
|
-
import
|
|
7794
|
+
import chalk25 from "chalk";
|
|
7542
7795
|
var listCommand3 = new Command24().name("list").alias("ls").description("List all remote artifacts").action(async () => {
|
|
7543
7796
|
try {
|
|
7544
7797
|
const items = await listStorages({ type: "artifact" });
|
|
7545
7798
|
if (items.length === 0) {
|
|
7546
|
-
console.log(
|
|
7799
|
+
console.log(chalk25.dim("No artifacts found"));
|
|
7547
7800
|
console.log(
|
|
7548
|
-
|
|
7801
|
+
chalk25.dim(
|
|
7549
7802
|
" Create one with: vm0 artifact init && vm0 artifact push"
|
|
7550
7803
|
)
|
|
7551
7804
|
);
|
|
@@ -7566,7 +7819,7 @@ var listCommand3 = new Command24().name("list").alias("ls").description("List al
|
|
|
7566
7819
|
"FILES".padStart(filesWidth),
|
|
7567
7820
|
"UPDATED"
|
|
7568
7821
|
].join(" ");
|
|
7569
|
-
console.log(
|
|
7822
|
+
console.log(chalk25.dim(header));
|
|
7570
7823
|
for (const item of items) {
|
|
7571
7824
|
const row = [
|
|
7572
7825
|
item.name.padEnd(nameWidth),
|
|
@@ -7577,12 +7830,12 @@ var listCommand3 = new Command24().name("list").alias("ls").description("List al
|
|
|
7577
7830
|
console.log(row);
|
|
7578
7831
|
}
|
|
7579
7832
|
} catch (error) {
|
|
7580
|
-
console.error(
|
|
7833
|
+
console.error(chalk25.red("\u2717 Failed to list artifacts"));
|
|
7581
7834
|
if (error instanceof Error) {
|
|
7582
7835
|
if (error.message.includes("Not authenticated")) {
|
|
7583
|
-
console.error(
|
|
7836
|
+
console.error(chalk25.dim(" Run: vm0 auth login"));
|
|
7584
7837
|
} else {
|
|
7585
|
-
console.error(
|
|
7838
|
+
console.error(chalk25.dim(` ${error.message}`));
|
|
7586
7839
|
}
|
|
7587
7840
|
}
|
|
7588
7841
|
process.exit(1);
|
|
@@ -7591,23 +7844,23 @@ var listCommand3 = new Command24().name("list").alias("ls").description("List al
|
|
|
7591
7844
|
|
|
7592
7845
|
// src/commands/artifact/clone.ts
|
|
7593
7846
|
import { Command as Command25 } from "commander";
|
|
7594
|
-
import
|
|
7847
|
+
import chalk26 from "chalk";
|
|
7595
7848
|
var cloneCommand2 = new Command25().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) => {
|
|
7596
7849
|
try {
|
|
7597
7850
|
const targetDir = destination || name;
|
|
7598
7851
|
console.log(`Cloning artifact: ${name}`);
|
|
7599
7852
|
const result = await cloneStorage(name, "artifact", targetDir);
|
|
7600
|
-
console.log(
|
|
7853
|
+
console.log(chalk26.green(`
|
|
7601
7854
|
\u2713 Successfully cloned artifact: ${name}`));
|
|
7602
|
-
console.log(
|
|
7603
|
-
console.log(
|
|
7855
|
+
console.log(chalk26.dim(` Location: ${targetDir}/`));
|
|
7856
|
+
console.log(chalk26.dim(` Version: ${result.versionId.slice(0, 8)}`));
|
|
7604
7857
|
} catch (error) {
|
|
7605
|
-
console.error(
|
|
7858
|
+
console.error(chalk26.red("\u2717 Clone failed"));
|
|
7606
7859
|
if (error instanceof Error) {
|
|
7607
7860
|
if (error.message.includes("Not authenticated")) {
|
|
7608
|
-
console.error(
|
|
7861
|
+
console.error(chalk26.dim(" Run: vm0 auth login"));
|
|
7609
7862
|
} else {
|
|
7610
|
-
console.error(
|
|
7863
|
+
console.error(chalk26.dim(` ${error.message}`));
|
|
7611
7864
|
}
|
|
7612
7865
|
}
|
|
7613
7866
|
process.exit(1);
|
|
@@ -7619,7 +7872,7 @@ var artifactCommand = new Command26().name("artifact").description("Manage artif
|
|
|
7619
7872
|
|
|
7620
7873
|
// src/commands/cook/cook.ts
|
|
7621
7874
|
import { Command as Command27, Option as Option4 } from "commander";
|
|
7622
|
-
import
|
|
7875
|
+
import chalk29 from "chalk";
|
|
7623
7876
|
import { readFile as readFile7, mkdir as mkdir6 } from "fs/promises";
|
|
7624
7877
|
import { existsSync as existsSync9 } from "fs";
|
|
7625
7878
|
import path11 from "path";
|
|
@@ -7628,7 +7881,7 @@ import { config as dotenvConfig2 } from "dotenv";
|
|
|
7628
7881
|
|
|
7629
7882
|
// src/lib/utils/update-checker.ts
|
|
7630
7883
|
import { spawn } from "child_process";
|
|
7631
|
-
import
|
|
7884
|
+
import chalk27 from "chalk";
|
|
7632
7885
|
var PACKAGE_NAME = "@vm0/cli";
|
|
7633
7886
|
var NPM_REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`;
|
|
7634
7887
|
var TIMEOUT_MS = 5e3;
|
|
@@ -7712,21 +7965,21 @@ function performUpgrade(packageManager) {
|
|
|
7712
7965
|
async function checkAndUpgrade(currentVersion, prompt) {
|
|
7713
7966
|
const latestVersion = await getLatestVersion();
|
|
7714
7967
|
if (latestVersion === null) {
|
|
7715
|
-
console.log(
|
|
7968
|
+
console.log(chalk27.yellow("Warning: Could not check for updates"));
|
|
7716
7969
|
console.log();
|
|
7717
7970
|
return false;
|
|
7718
7971
|
}
|
|
7719
7972
|
if (latestVersion === currentVersion) {
|
|
7720
7973
|
return false;
|
|
7721
7974
|
}
|
|
7722
|
-
console.log(
|
|
7975
|
+
console.log(chalk27.yellow("vm0 is currently in Early Access (EA)."));
|
|
7723
7976
|
console.log(
|
|
7724
|
-
|
|
7977
|
+
chalk27.yellow(
|
|
7725
7978
|
`Current version: ${currentVersion} -> Latest version: ${latestVersion}`
|
|
7726
7979
|
)
|
|
7727
7980
|
);
|
|
7728
7981
|
console.log(
|
|
7729
|
-
|
|
7982
|
+
chalk27.yellow(
|
|
7730
7983
|
"Please always use the latest version for best compatibility."
|
|
7731
7984
|
)
|
|
7732
7985
|
);
|
|
@@ -7735,33 +7988,33 @@ async function checkAndUpgrade(currentVersion, prompt) {
|
|
|
7735
7988
|
if (!isAutoUpgradeSupported(packageManager)) {
|
|
7736
7989
|
if (packageManager === "unknown") {
|
|
7737
7990
|
console.log(
|
|
7738
|
-
|
|
7991
|
+
chalk27.yellow("Could not detect your package manager for auto-upgrade.")
|
|
7739
7992
|
);
|
|
7740
7993
|
} else {
|
|
7741
7994
|
console.log(
|
|
7742
|
-
|
|
7995
|
+
chalk27.yellow(`Auto-upgrade is not supported for ${packageManager}.`)
|
|
7743
7996
|
);
|
|
7744
7997
|
}
|
|
7745
|
-
console.log(
|
|
7746
|
-
console.log(
|
|
7998
|
+
console.log(chalk27.yellow("Please upgrade manually:"));
|
|
7999
|
+
console.log(chalk27.cyan(` ${getManualUpgradeCommand(packageManager)}`));
|
|
7747
8000
|
console.log();
|
|
7748
8001
|
return false;
|
|
7749
8002
|
}
|
|
7750
8003
|
console.log(`Upgrading via ${packageManager}...`);
|
|
7751
8004
|
const success = await performUpgrade(packageManager);
|
|
7752
8005
|
if (success) {
|
|
7753
|
-
console.log(
|
|
8006
|
+
console.log(chalk27.green(`Upgraded to ${latestVersion}`));
|
|
7754
8007
|
console.log();
|
|
7755
8008
|
console.log("To continue, run:");
|
|
7756
|
-
console.log(
|
|
8009
|
+
console.log(chalk27.cyan(` ${buildRerunCommand(prompt)}`));
|
|
7757
8010
|
return true;
|
|
7758
8011
|
}
|
|
7759
8012
|
console.log();
|
|
7760
|
-
console.log(
|
|
7761
|
-
console.log(
|
|
8013
|
+
console.log(chalk27.red("Upgrade failed. Please run manually:"));
|
|
8014
|
+
console.log(chalk27.cyan(` ${getManualUpgradeCommand(packageManager)}`));
|
|
7762
8015
|
console.log();
|
|
7763
8016
|
console.log("Then re-run:");
|
|
7764
|
-
console.log(
|
|
8017
|
+
console.log(chalk27.cyan(` ${buildRerunCommand(prompt)}`));
|
|
7765
8018
|
return true;
|
|
7766
8019
|
}
|
|
7767
8020
|
|
|
@@ -7831,13 +8084,13 @@ async function saveCookState(state) {
|
|
|
7831
8084
|
}
|
|
7832
8085
|
|
|
7833
8086
|
// src/commands/cook/utils.ts
|
|
7834
|
-
import
|
|
8087
|
+
import chalk28 from "chalk";
|
|
7835
8088
|
import { spawn as spawn2 } from "child_process";
|
|
7836
8089
|
import { existsSync as existsSync8 } from "fs";
|
|
7837
8090
|
var CONFIG_FILE2 = "vm0.yaml";
|
|
7838
8091
|
var ARTIFACT_DIR = "artifact";
|
|
7839
8092
|
function printCommand(cmd) {
|
|
7840
|
-
console.log(
|
|
8093
|
+
console.log(chalk28.dim(`> ${cmd}`));
|
|
7841
8094
|
}
|
|
7842
8095
|
function execVm0Command(args, options = {}) {
|
|
7843
8096
|
return new Promise((resolve, reject) => {
|
|
@@ -7938,7 +8191,7 @@ async function autoPullArtifact(runOutput, artifactDir) {
|
|
|
7938
8191
|
);
|
|
7939
8192
|
if (serverVersion && existsSync8(artifactDir)) {
|
|
7940
8193
|
console.log();
|
|
7941
|
-
console.log(
|
|
8194
|
+
console.log(chalk28.bold("Pulling updated artifact:"));
|
|
7942
8195
|
printCommand(`cd ${ARTIFACT_DIR}`);
|
|
7943
8196
|
printCommand(`vm0 artifact pull ${serverVersion}`);
|
|
7944
8197
|
try {
|
|
@@ -7948,9 +8201,9 @@ async function autoPullArtifact(runOutput, artifactDir) {
|
|
|
7948
8201
|
});
|
|
7949
8202
|
printCommand("cd ..");
|
|
7950
8203
|
} catch (error) {
|
|
7951
|
-
console.error(
|
|
8204
|
+
console.error(chalk28.red(`\u2717 Artifact pull failed`));
|
|
7952
8205
|
if (error instanceof Error) {
|
|
7953
|
-
console.error(
|
|
8206
|
+
console.error(chalk28.dim(` ${error.message}`));
|
|
7954
8207
|
}
|
|
7955
8208
|
}
|
|
7956
8209
|
}
|
|
@@ -7986,9 +8239,9 @@ function checkMissingVariables(varNames, envFilePath) {
|
|
|
7986
8239
|
return missing;
|
|
7987
8240
|
}
|
|
7988
8241
|
async function loadAndValidateConfig2() {
|
|
7989
|
-
console.log(
|
|
8242
|
+
console.log(chalk29.bold(`Reading config: ${CONFIG_FILE2}`));
|
|
7990
8243
|
if (!existsSync9(CONFIG_FILE2)) {
|
|
7991
|
-
console.error(
|
|
8244
|
+
console.error(chalk29.red(`\u2717 Config file not found: ${CONFIG_FILE2}`));
|
|
7992
8245
|
process.exit(1);
|
|
7993
8246
|
}
|
|
7994
8247
|
let config;
|
|
@@ -7996,22 +8249,22 @@ async function loadAndValidateConfig2() {
|
|
|
7996
8249
|
const content = await readFile7(CONFIG_FILE2, "utf8");
|
|
7997
8250
|
config = parseYaml4(content);
|
|
7998
8251
|
} catch (error) {
|
|
7999
|
-
console.error(
|
|
8252
|
+
console.error(chalk29.red("\u2717 Invalid YAML format"));
|
|
8000
8253
|
if (error instanceof Error) {
|
|
8001
|
-
console.error(
|
|
8254
|
+
console.error(chalk29.dim(` ${error.message}`));
|
|
8002
8255
|
}
|
|
8003
8256
|
process.exit(1);
|
|
8004
8257
|
}
|
|
8005
8258
|
const validation = validateAgentCompose(config);
|
|
8006
8259
|
if (!validation.valid) {
|
|
8007
|
-
console.error(
|
|
8260
|
+
console.error(chalk29.red(`\u2717 ${validation.error}`));
|
|
8008
8261
|
process.exit(1);
|
|
8009
8262
|
}
|
|
8010
8263
|
const agentNames = Object.keys(config.agents);
|
|
8011
8264
|
const agentName = agentNames[0];
|
|
8012
8265
|
const volumeCount = config.volumes ? Object.keys(config.volumes).length : 0;
|
|
8013
8266
|
console.log(
|
|
8014
|
-
|
|
8267
|
+
chalk29.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
|
|
8015
8268
|
);
|
|
8016
8269
|
return { config, agentName, volumeCount };
|
|
8017
8270
|
}
|
|
@@ -8024,12 +8277,12 @@ function validateEnvVariables(config, envFile) {
|
|
|
8024
8277
|
const missingVars = checkMissingVariables(requiredVarNames, envFile);
|
|
8025
8278
|
if (missingVars.length > 0) {
|
|
8026
8279
|
console.log();
|
|
8027
|
-
console.error(
|
|
8280
|
+
console.error(chalk29.red("\u2717 Missing required variables:"));
|
|
8028
8281
|
for (const varName of missingVars) {
|
|
8029
|
-
console.error(
|
|
8282
|
+
console.error(chalk29.red(` ${varName}`));
|
|
8030
8283
|
}
|
|
8031
8284
|
console.error(
|
|
8032
|
-
|
|
8285
|
+
chalk29.dim(
|
|
8033
8286
|
"\n Provide via --env-file, or set as environment variables"
|
|
8034
8287
|
)
|
|
8035
8288
|
);
|
|
@@ -8037,7 +8290,7 @@ function validateEnvVariables(config, envFile) {
|
|
|
8037
8290
|
}
|
|
8038
8291
|
} catch (error) {
|
|
8039
8292
|
if (error instanceof Error) {
|
|
8040
|
-
console.error(
|
|
8293
|
+
console.error(chalk29.red(`\u2717 ${error.message}`));
|
|
8041
8294
|
}
|
|
8042
8295
|
process.exit(1);
|
|
8043
8296
|
}
|
|
@@ -8047,12 +8300,12 @@ async function processVolumes(config, cwd) {
|
|
|
8047
8300
|
return;
|
|
8048
8301
|
}
|
|
8049
8302
|
console.log();
|
|
8050
|
-
console.log(
|
|
8303
|
+
console.log(chalk29.bold("Processing volumes:"));
|
|
8051
8304
|
for (const volumeConfig of Object.values(config.volumes)) {
|
|
8052
8305
|
const volumeDir = path11.join(cwd, volumeConfig.name);
|
|
8053
8306
|
if (!existsSync9(volumeDir)) {
|
|
8054
|
-
console.error(
|
|
8055
|
-
console.error(
|
|
8307
|
+
console.error(chalk29.red(`\u2717 Directory not found: ${volumeConfig.name}`));
|
|
8308
|
+
console.error(chalk29.dim(" Create the directory and add files first"));
|
|
8056
8309
|
process.exit(1);
|
|
8057
8310
|
}
|
|
8058
8311
|
try {
|
|
@@ -8072,9 +8325,9 @@ async function processVolumes(config, cwd) {
|
|
|
8072
8325
|
});
|
|
8073
8326
|
printCommand("cd ..");
|
|
8074
8327
|
} catch (error) {
|
|
8075
|
-
console.error(
|
|
8328
|
+
console.error(chalk29.red(`\u2717 Failed`));
|
|
8076
8329
|
if (error instanceof Error) {
|
|
8077
|
-
console.error(
|
|
8330
|
+
console.error(chalk29.dim(` ${error.message}`));
|
|
8078
8331
|
}
|
|
8079
8332
|
process.exit(1);
|
|
8080
8333
|
}
|
|
@@ -8082,7 +8335,7 @@ async function processVolumes(config, cwd) {
|
|
|
8082
8335
|
}
|
|
8083
8336
|
async function processArtifact(cwd) {
|
|
8084
8337
|
console.log();
|
|
8085
|
-
console.log(
|
|
8338
|
+
console.log(chalk29.bold("Processing artifact:"));
|
|
8086
8339
|
const artifactDir = path11.join(cwd, ARTIFACT_DIR);
|
|
8087
8340
|
try {
|
|
8088
8341
|
if (!existsSync9(artifactDir)) {
|
|
@@ -8105,9 +8358,9 @@ async function processArtifact(cwd) {
|
|
|
8105
8358
|
});
|
|
8106
8359
|
printCommand("cd ..");
|
|
8107
8360
|
} catch (error) {
|
|
8108
|
-
console.error(
|
|
8361
|
+
console.error(chalk29.red(`\u2717 Failed`));
|
|
8109
8362
|
if (error instanceof Error) {
|
|
8110
|
-
console.error(
|
|
8363
|
+
console.error(chalk29.dim(` ${error.message}`));
|
|
8111
8364
|
}
|
|
8112
8365
|
process.exit(1);
|
|
8113
8366
|
}
|
|
@@ -8115,22 +8368,22 @@ async function processArtifact(cwd) {
|
|
|
8115
8368
|
}
|
|
8116
8369
|
async function composeAgent(cwd, skipConfirm) {
|
|
8117
8370
|
console.log();
|
|
8118
|
-
console.log(
|
|
8371
|
+
console.log(chalk29.bold("Composing agent:"));
|
|
8119
8372
|
const composeArgs = skipConfirm ? ["compose", "--yes", CONFIG_FILE2] : ["compose", CONFIG_FILE2];
|
|
8120
8373
|
printCommand(`vm0 ${composeArgs.join(" ")}`);
|
|
8121
8374
|
try {
|
|
8122
8375
|
await execVm0Command(composeArgs, { cwd });
|
|
8123
8376
|
} catch (error) {
|
|
8124
|
-
console.error(
|
|
8377
|
+
console.error(chalk29.red(`\u2717 Compose failed`));
|
|
8125
8378
|
if (error instanceof Error) {
|
|
8126
|
-
console.error(
|
|
8379
|
+
console.error(chalk29.dim(` ${error.message}`));
|
|
8127
8380
|
}
|
|
8128
8381
|
process.exit(1);
|
|
8129
8382
|
}
|
|
8130
8383
|
}
|
|
8131
|
-
async function runAgent(agentName, artifactDir, prompt, cwd,
|
|
8384
|
+
async function runAgent(agentName, artifactDir, prompt, cwd, options) {
|
|
8132
8385
|
console.log();
|
|
8133
|
-
console.log(
|
|
8386
|
+
console.log(chalk29.bold("Running agent:"));
|
|
8134
8387
|
printCommand(
|
|
8135
8388
|
`vm0 run ${agentName} --artifact-name ${ARTIFACT_DIR} "${prompt}"`
|
|
8136
8389
|
);
|
|
@@ -8142,7 +8395,8 @@ async function runAgent(agentName, artifactDir, prompt, cwd, debugNoMockClaude)
|
|
|
8142
8395
|
agentName,
|
|
8143
8396
|
"--artifact-name",
|
|
8144
8397
|
ARTIFACT_DIR,
|
|
8145
|
-
...
|
|
8398
|
+
...options.verbose ? ["--verbose"] : [],
|
|
8399
|
+
...options.debugNoMockClaude ? ["--debug-no-mock-claude"] : [],
|
|
8146
8400
|
prompt
|
|
8147
8401
|
];
|
|
8148
8402
|
runOutput = await execVm0RunWithCapture(runArgs, { cwd });
|
|
@@ -8162,10 +8416,10 @@ async function runAgent(agentName, artifactDir, prompt, cwd, debugNoMockClaude)
|
|
|
8162
8416
|
var cookAction = new Command27().name("cook").description("Quick start: prepare, compose and run agent from vm0.yaml").argument("[prompt]", "Prompt for the agent").option(
|
|
8163
8417
|
"--env-file <path>",
|
|
8164
8418
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
8165
|
-
).option("-y, --yes", "Skip confirmation prompts").addOption(new Option4("--debug-no-mock-claude").hideHelp()).addOption(new Option4("--no-auto-update").hideHelp()).action(
|
|
8419
|
+
).option("-y, --yes", "Skip confirmation prompts").option("-v, --verbose", "Show full tool inputs and outputs").addOption(new Option4("--debug-no-mock-claude").hideHelp()).addOption(new Option4("--no-auto-update").hideHelp()).action(
|
|
8166
8420
|
async (prompt, options) => {
|
|
8167
8421
|
if (!options.noAutoUpdate) {
|
|
8168
|
-
const shouldExit = await checkAndUpgrade("9.
|
|
8422
|
+
const shouldExit = await checkAndUpgrade("9.7.0", prompt);
|
|
8169
8423
|
if (shouldExit) {
|
|
8170
8424
|
process.exit(0);
|
|
8171
8425
|
}
|
|
@@ -8177,13 +8431,10 @@ var cookAction = new Command27().name("cook").description("Quick start: prepare,
|
|
|
8177
8431
|
const artifactDir = await processArtifact(cwd);
|
|
8178
8432
|
await composeAgent(cwd, options.yes ?? false);
|
|
8179
8433
|
if (prompt) {
|
|
8180
|
-
await runAgent(
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
cwd,
|
|
8185
|
-
options.debugNoMockClaude ?? false
|
|
8186
|
-
);
|
|
8434
|
+
await runAgent(agentName, artifactDir, prompt, cwd, {
|
|
8435
|
+
verbose: options.verbose,
|
|
8436
|
+
debugNoMockClaude: options.debugNoMockClaude
|
|
8437
|
+
});
|
|
8187
8438
|
} else {
|
|
8188
8439
|
console.log();
|
|
8189
8440
|
console.log("To run your agent:");
|
|
@@ -8196,7 +8447,7 @@ var cookAction = new Command27().name("cook").description("Quick start: prepare,
|
|
|
8196
8447
|
|
|
8197
8448
|
// src/commands/cook/logs.ts
|
|
8198
8449
|
import { Command as Command28 } from "commander";
|
|
8199
|
-
import
|
|
8450
|
+
import chalk30 from "chalk";
|
|
8200
8451
|
var logsCommand = new Command28().name("logs").description("View logs from the last cook run").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(
|
|
8201
8452
|
"--since <time>",
|
|
8202
8453
|
"Show logs since timestamp (e.g., 5m, 2h, 1d, 2024-01-15T10:30:00Z)"
|
|
@@ -8204,8 +8455,8 @@ var logsCommand = new Command28().name("logs").description("View logs from the l
|
|
|
8204
8455
|
async (options) => {
|
|
8205
8456
|
const state = await loadCookState();
|
|
8206
8457
|
if (!state.lastRunId) {
|
|
8207
|
-
console.error(
|
|
8208
|
-
console.error(
|
|
8458
|
+
console.error(chalk30.red("\u2717 No previous run found"));
|
|
8459
|
+
console.error(chalk30.dim(" Run 'vm0 cook <prompt>' first"));
|
|
8209
8460
|
process.exit(1);
|
|
8210
8461
|
}
|
|
8211
8462
|
const args = ["logs", state.lastRunId];
|
|
@@ -8245,19 +8496,19 @@ var logsCommand = new Command28().name("logs").description("View logs from the l
|
|
|
8245
8496
|
|
|
8246
8497
|
// src/commands/cook/continue.ts
|
|
8247
8498
|
import { Command as Command29, Option as Option5 } from "commander";
|
|
8248
|
-
import
|
|
8499
|
+
import chalk31 from "chalk";
|
|
8249
8500
|
import path12 from "path";
|
|
8250
8501
|
var continueCommand2 = new Command29().name("continue").description(
|
|
8251
8502
|
"Continue from the last session (latest conversation and artifact)"
|
|
8252
8503
|
).argument("<prompt>", "Prompt for the continued agent").option(
|
|
8253
8504
|
"--env-file <path>",
|
|
8254
8505
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
8255
|
-
).addOption(new Option5("--debug-no-mock-claude").hideHelp()).action(
|
|
8506
|
+
).option("-v, --verbose", "Show full tool inputs and outputs").addOption(new Option5("--debug-no-mock-claude").hideHelp()).action(
|
|
8256
8507
|
async (prompt, options) => {
|
|
8257
8508
|
const state = await loadCookState();
|
|
8258
8509
|
if (!state.lastSessionId) {
|
|
8259
|
-
console.error(
|
|
8260
|
-
console.error(
|
|
8510
|
+
console.error(chalk31.red("\u2717 No previous session found"));
|
|
8511
|
+
console.error(chalk31.dim(" Run 'vm0 cook <prompt>' first"));
|
|
8261
8512
|
process.exit(1);
|
|
8262
8513
|
}
|
|
8263
8514
|
const cwd = process.cwd();
|
|
@@ -8274,6 +8525,7 @@ var continueCommand2 = new Command29().name("continue").description(
|
|
|
8274
8525
|
"run",
|
|
8275
8526
|
"continue",
|
|
8276
8527
|
...options.envFile ? ["--env-file", options.envFile] : [],
|
|
8528
|
+
...options.verbose ? ["--verbose"] : [],
|
|
8277
8529
|
state.lastSessionId,
|
|
8278
8530
|
...options.debugNoMockClaude ? ["--debug-no-mock-claude"] : [],
|
|
8279
8531
|
prompt
|
|
@@ -8297,19 +8549,19 @@ var continueCommand2 = new Command29().name("continue").description(
|
|
|
8297
8549
|
|
|
8298
8550
|
// src/commands/cook/resume.ts
|
|
8299
8551
|
import { Command as Command30, Option as Option6 } from "commander";
|
|
8300
|
-
import
|
|
8552
|
+
import chalk32 from "chalk";
|
|
8301
8553
|
import path13 from "path";
|
|
8302
8554
|
var resumeCommand2 = new Command30().name("resume").description(
|
|
8303
8555
|
"Resume from the last checkpoint (snapshotted conversation and artifact)"
|
|
8304
8556
|
).argument("<prompt>", "Prompt for the resumed agent").option(
|
|
8305
8557
|
"--env-file <path>",
|
|
8306
8558
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
8307
|
-
).addOption(new Option6("--debug-no-mock-claude").hideHelp()).action(
|
|
8559
|
+
).option("-v, --verbose", "Show full tool inputs and outputs").addOption(new Option6("--debug-no-mock-claude").hideHelp()).action(
|
|
8308
8560
|
async (prompt, options) => {
|
|
8309
8561
|
const state = await loadCookState();
|
|
8310
8562
|
if (!state.lastCheckpointId) {
|
|
8311
|
-
console.error(
|
|
8312
|
-
console.error(
|
|
8563
|
+
console.error(chalk32.red("\u2717 No previous checkpoint found"));
|
|
8564
|
+
console.error(chalk32.dim(" Run 'vm0 cook <prompt>' first"));
|
|
8313
8565
|
process.exit(1);
|
|
8314
8566
|
}
|
|
8315
8567
|
const cwd = process.cwd();
|
|
@@ -8326,6 +8578,7 @@ var resumeCommand2 = new Command30().name("resume").description(
|
|
|
8326
8578
|
"run",
|
|
8327
8579
|
"resume",
|
|
8328
8580
|
...options.envFile ? ["--env-file", options.envFile] : [],
|
|
8581
|
+
...options.verbose ? ["--verbose"] : [],
|
|
8329
8582
|
state.lastCheckpointId,
|
|
8330
8583
|
...options.debugNoMockClaude ? ["--debug-no-mock-claude"] : [],
|
|
8331
8584
|
prompt
|
|
@@ -8355,7 +8608,7 @@ var cookCommand = cookAction;
|
|
|
8355
8608
|
|
|
8356
8609
|
// src/commands/logs/index.ts
|
|
8357
8610
|
import { Command as Command31 } from "commander";
|
|
8358
|
-
import
|
|
8611
|
+
import chalk33 from "chalk";
|
|
8359
8612
|
|
|
8360
8613
|
// src/lib/utils/time-parser.ts
|
|
8361
8614
|
function parseTime(timeStr) {
|
|
@@ -8409,38 +8662,44 @@ function formatMetric(metric) {
|
|
|
8409
8662
|
}
|
|
8410
8663
|
function formatNetworkLog(entry) {
|
|
8411
8664
|
if (entry.mode === "sni" || !entry.method) {
|
|
8412
|
-
const actionColor = entry.action === "ALLOW" ?
|
|
8665
|
+
const actionColor = entry.action === "ALLOW" ? chalk33.green : chalk33.red;
|
|
8413
8666
|
const host = entry.host || "unknown";
|
|
8414
8667
|
const port = entry.port || 443;
|
|
8415
|
-
return `[${entry.timestamp}] ${
|
|
8668
|
+
return `[${entry.timestamp}] ${chalk33.cyan("SNI")} ${actionColor(entry.action || "ALLOW")} ${host}:${port} ${chalk33.dim(entry.rule_matched || "")}`;
|
|
8416
8669
|
}
|
|
8417
8670
|
let statusColor;
|
|
8418
8671
|
const status = entry.status || 0;
|
|
8419
8672
|
if (status >= 200 && status < 300) {
|
|
8420
|
-
statusColor =
|
|
8673
|
+
statusColor = chalk33.green;
|
|
8421
8674
|
} else if (status >= 300 && status < 400) {
|
|
8422
|
-
statusColor =
|
|
8675
|
+
statusColor = chalk33.yellow;
|
|
8423
8676
|
} else if (status >= 400) {
|
|
8424
|
-
statusColor =
|
|
8677
|
+
statusColor = chalk33.red;
|
|
8425
8678
|
} else {
|
|
8426
|
-
statusColor =
|
|
8679
|
+
statusColor = chalk33.gray;
|
|
8427
8680
|
}
|
|
8428
8681
|
let latencyColor;
|
|
8429
8682
|
const latencyMs = entry.latency_ms || 0;
|
|
8430
8683
|
if (latencyMs < 500) {
|
|
8431
|
-
latencyColor =
|
|
8684
|
+
latencyColor = chalk33.green;
|
|
8432
8685
|
} else if (latencyMs < 2e3) {
|
|
8433
|
-
latencyColor =
|
|
8686
|
+
latencyColor = chalk33.yellow;
|
|
8434
8687
|
} else {
|
|
8435
|
-
latencyColor =
|
|
8688
|
+
latencyColor = chalk33.red;
|
|
8436
8689
|
}
|
|
8437
8690
|
const method = entry.method || "???";
|
|
8438
8691
|
const requestSize = entry.request_size || 0;
|
|
8439
8692
|
const responseSize = entry.response_size || 0;
|
|
8440
8693
|
const url = entry.url || entry.host || "unknown";
|
|
8441
|
-
return `[${entry.timestamp}] ${method.padEnd(6)} ${statusColor(status)} ${latencyColor(latencyMs + "ms")} ${formatBytes(requestSize)}/${formatBytes(responseSize)} ${
|
|
8694
|
+
return `[${entry.timestamp}] ${method.padEnd(6)} ${statusColor(status)} ${latencyColor(latencyMs + "ms")} ${formatBytes(requestSize)}/${formatBytes(responseSize)} ${chalk33.dim(url)}`;
|
|
8695
|
+
}
|
|
8696
|
+
function createLogRenderer(verbose) {
|
|
8697
|
+
return new EventRenderer({
|
|
8698
|
+
showTimestamp: true,
|
|
8699
|
+
verbose
|
|
8700
|
+
});
|
|
8442
8701
|
}
|
|
8443
|
-
function renderAgentEvent(event, provider) {
|
|
8702
|
+
function renderAgentEvent(event, provider, renderer) {
|
|
8444
8703
|
const eventData = event.eventData;
|
|
8445
8704
|
if (provider === "codex") {
|
|
8446
8705
|
CodexEventRenderer.render(eventData);
|
|
@@ -8448,7 +8707,7 @@ function renderAgentEvent(event, provider) {
|
|
|
8448
8707
|
const parsed = ClaudeEventParser.parse(eventData);
|
|
8449
8708
|
if (parsed) {
|
|
8450
8709
|
parsed.timestamp = new Date(event.createdAt);
|
|
8451
|
-
|
|
8710
|
+
renderer.render(parsed);
|
|
8452
8711
|
}
|
|
8453
8712
|
}
|
|
8454
8713
|
}
|
|
@@ -8461,7 +8720,7 @@ function getLogType(options) {
|
|
|
8461
8720
|
].filter(Boolean).length;
|
|
8462
8721
|
if (selected > 1) {
|
|
8463
8722
|
console.error(
|
|
8464
|
-
|
|
8723
|
+
chalk33.red(
|
|
8465
8724
|
"Options --agent, --system, --metrics, and --network are mutually exclusive"
|
|
8466
8725
|
)
|
|
8467
8726
|
);
|
|
@@ -8481,7 +8740,7 @@ var logsCommand2 = new Command31().name("logs").description("View logs for an ag
|
|
|
8481
8740
|
const logType = getLogType(options);
|
|
8482
8741
|
if (options.tail !== void 0 && options.head !== void 0) {
|
|
8483
8742
|
console.error(
|
|
8484
|
-
|
|
8743
|
+
chalk33.red("Options --tail and --head are mutually exclusive")
|
|
8485
8744
|
);
|
|
8486
8745
|
process.exit(1);
|
|
8487
8746
|
}
|
|
@@ -8518,17 +8777,18 @@ var logsCommand2 = new Command31().name("logs").description("View logs for an ag
|
|
|
8518
8777
|
async function showAgentEvents(runId, options) {
|
|
8519
8778
|
const response = await apiClient.getAgentEvents(runId, options);
|
|
8520
8779
|
if (response.events.length === 0) {
|
|
8521
|
-
console.log(
|
|
8780
|
+
console.log(chalk33.yellow("No agent events found for this run"));
|
|
8522
8781
|
return;
|
|
8523
8782
|
}
|
|
8524
8783
|
const events = options.order === "desc" ? [...response.events].reverse() : response.events;
|
|
8784
|
+
const renderer = createLogRenderer(true);
|
|
8525
8785
|
for (const event of events) {
|
|
8526
|
-
renderAgentEvent(event, response.framework);
|
|
8786
|
+
renderAgentEvent(event, response.framework, renderer);
|
|
8527
8787
|
}
|
|
8528
8788
|
if (response.hasMore) {
|
|
8529
8789
|
console.log();
|
|
8530
8790
|
console.log(
|
|
8531
|
-
|
|
8791
|
+
chalk33.dim(
|
|
8532
8792
|
`Showing ${response.events.length} events. Use --tail to see more.`
|
|
8533
8793
|
)
|
|
8534
8794
|
);
|
|
@@ -8537,21 +8797,21 @@ async function showAgentEvents(runId, options) {
|
|
|
8537
8797
|
async function showSystemLog(runId, options) {
|
|
8538
8798
|
const response = await apiClient.getSystemLog(runId, options);
|
|
8539
8799
|
if (!response.systemLog) {
|
|
8540
|
-
console.log(
|
|
8800
|
+
console.log(chalk33.yellow("No system log found for this run"));
|
|
8541
8801
|
return;
|
|
8542
8802
|
}
|
|
8543
8803
|
console.log(response.systemLog);
|
|
8544
8804
|
if (response.hasMore) {
|
|
8545
8805
|
console.log();
|
|
8546
8806
|
console.log(
|
|
8547
|
-
|
|
8807
|
+
chalk33.dim("More log entries available. Use --tail to see more.")
|
|
8548
8808
|
);
|
|
8549
8809
|
}
|
|
8550
8810
|
}
|
|
8551
8811
|
async function showMetrics(runId, options) {
|
|
8552
8812
|
const response = await apiClient.getMetrics(runId, options);
|
|
8553
8813
|
if (response.metrics.length === 0) {
|
|
8554
|
-
console.log(
|
|
8814
|
+
console.log(chalk33.yellow("No metrics found for this run"));
|
|
8555
8815
|
return;
|
|
8556
8816
|
}
|
|
8557
8817
|
const metrics = options.order === "desc" ? [...response.metrics].reverse() : response.metrics;
|
|
@@ -8561,7 +8821,7 @@ async function showMetrics(runId, options) {
|
|
|
8561
8821
|
if (response.hasMore) {
|
|
8562
8822
|
console.log();
|
|
8563
8823
|
console.log(
|
|
8564
|
-
|
|
8824
|
+
chalk33.dim(
|
|
8565
8825
|
`Showing ${response.metrics.length} metrics. Use --tail to see more.`
|
|
8566
8826
|
)
|
|
8567
8827
|
);
|
|
@@ -8571,7 +8831,7 @@ async function showNetworkLogs(runId, options) {
|
|
|
8571
8831
|
const response = await apiClient.getNetworkLogs(runId, options);
|
|
8572
8832
|
if (response.networkLogs.length === 0) {
|
|
8573
8833
|
console.log(
|
|
8574
|
-
|
|
8834
|
+
chalk33.yellow(
|
|
8575
8835
|
"No network logs found for this run. Network logs are only captured when experimental_firewall is enabled on an experimental_runner"
|
|
8576
8836
|
)
|
|
8577
8837
|
);
|
|
@@ -8584,7 +8844,7 @@ async function showNetworkLogs(runId, options) {
|
|
|
8584
8844
|
if (response.hasMore) {
|
|
8585
8845
|
console.log();
|
|
8586
8846
|
console.log(
|
|
8587
|
-
|
|
8847
|
+
chalk33.dim(
|
|
8588
8848
|
`Showing ${response.networkLogs.length} network logs. Use --tail to see more.`
|
|
8589
8849
|
)
|
|
8590
8850
|
);
|
|
@@ -8593,17 +8853,17 @@ async function showNetworkLogs(runId, options) {
|
|
|
8593
8853
|
function handleError2(error, runId) {
|
|
8594
8854
|
if (error instanceof Error) {
|
|
8595
8855
|
if (error.message.includes("Not authenticated")) {
|
|
8596
|
-
console.error(
|
|
8856
|
+
console.error(chalk33.red("Not authenticated. Run: vm0 auth login"));
|
|
8597
8857
|
} else if (error.message.includes("not found")) {
|
|
8598
|
-
console.error(
|
|
8858
|
+
console.error(chalk33.red(`Run not found: ${runId}`));
|
|
8599
8859
|
} else if (error.message.includes("Invalid time format")) {
|
|
8600
|
-
console.error(
|
|
8860
|
+
console.error(chalk33.red(error.message));
|
|
8601
8861
|
} else {
|
|
8602
|
-
console.error(
|
|
8603
|
-
console.error(
|
|
8862
|
+
console.error(chalk33.red("Failed to fetch logs"));
|
|
8863
|
+
console.error(chalk33.dim(` ${error.message}`));
|
|
8604
8864
|
}
|
|
8605
8865
|
} else {
|
|
8606
|
-
console.error(
|
|
8866
|
+
console.error(chalk33.red("An unexpected error occurred"));
|
|
8607
8867
|
}
|
|
8608
8868
|
}
|
|
8609
8869
|
|
|
@@ -8612,12 +8872,12 @@ import { Command as Command34 } from "commander";
|
|
|
8612
8872
|
|
|
8613
8873
|
// src/commands/scope/status.ts
|
|
8614
8874
|
import { Command as Command32 } from "commander";
|
|
8615
|
-
import
|
|
8875
|
+
import chalk34 from "chalk";
|
|
8616
8876
|
var statusCommand4 = new Command32().name("status").description("View current scope status").action(async () => {
|
|
8617
8877
|
try {
|
|
8618
8878
|
const scope = await getScope();
|
|
8619
|
-
console.log(
|
|
8620
|
-
console.log(` Slug: ${
|
|
8879
|
+
console.log(chalk34.bold("Scope Information:"));
|
|
8880
|
+
console.log(` Slug: ${chalk34.green(scope.slug)}`);
|
|
8621
8881
|
console.log(` Type: ${scope.type}`);
|
|
8622
8882
|
console.log(
|
|
8623
8883
|
` Created: ${new Date(scope.createdAt).toLocaleDateString()}`
|
|
@@ -8625,20 +8885,20 @@ var statusCommand4 = new Command32().name("status").description("View current sc
|
|
|
8625
8885
|
} catch (error) {
|
|
8626
8886
|
if (error instanceof Error) {
|
|
8627
8887
|
if (error.message.includes("Not authenticated")) {
|
|
8628
|
-
console.error(
|
|
8888
|
+
console.error(chalk34.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
8629
8889
|
} else if (error.message.includes("No scope configured")) {
|
|
8630
|
-
console.log(
|
|
8890
|
+
console.log(chalk34.yellow("No scope configured"));
|
|
8631
8891
|
console.log();
|
|
8632
8892
|
console.log("Set your scope with:");
|
|
8633
|
-
console.log(
|
|
8893
|
+
console.log(chalk34.cyan(" vm0 scope set <slug>"));
|
|
8634
8894
|
console.log();
|
|
8635
8895
|
console.log("Example:");
|
|
8636
|
-
console.log(
|
|
8896
|
+
console.log(chalk34.dim(" vm0 scope set myusername"));
|
|
8637
8897
|
} else {
|
|
8638
|
-
console.error(
|
|
8898
|
+
console.error(chalk34.red(`\u2717 ${error.message}`));
|
|
8639
8899
|
}
|
|
8640
8900
|
} else {
|
|
8641
|
-
console.error(
|
|
8901
|
+
console.error(chalk34.red("\u2717 An unexpected error occurred"));
|
|
8642
8902
|
}
|
|
8643
8903
|
process.exit(1);
|
|
8644
8904
|
}
|
|
@@ -8646,7 +8906,7 @@ var statusCommand4 = new Command32().name("status").description("View current sc
|
|
|
8646
8906
|
|
|
8647
8907
|
// src/commands/scope/set.ts
|
|
8648
8908
|
import { Command as Command33 } from "commander";
|
|
8649
|
-
import
|
|
8909
|
+
import chalk35 from "chalk";
|
|
8650
8910
|
var setCommand = new Command33().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) => {
|
|
8651
8911
|
try {
|
|
8652
8912
|
let existingScope;
|
|
@@ -8661,51 +8921,51 @@ var setCommand = new Command33().name("set").description("Set your scope slug").
|
|
|
8661
8921
|
if (existingScope) {
|
|
8662
8922
|
if (!options.force) {
|
|
8663
8923
|
console.error(
|
|
8664
|
-
|
|
8924
|
+
chalk35.yellow(`You already have a scope: ${existingScope.slug}`)
|
|
8665
8925
|
);
|
|
8666
8926
|
console.error();
|
|
8667
8927
|
console.error("To change your scope, use --force:");
|
|
8668
|
-
console.error(
|
|
8928
|
+
console.error(chalk35.cyan(` vm0 scope set ${slug} --force`));
|
|
8669
8929
|
console.error();
|
|
8670
8930
|
console.error(
|
|
8671
|
-
|
|
8931
|
+
chalk35.yellow(
|
|
8672
8932
|
"Warning: Changing your scope may break existing agent references."
|
|
8673
8933
|
)
|
|
8674
8934
|
);
|
|
8675
8935
|
process.exit(1);
|
|
8676
8936
|
}
|
|
8677
8937
|
scope = await updateScope({ slug, force: true });
|
|
8678
|
-
console.log(
|
|
8938
|
+
console.log(chalk35.green(`\u2713 Scope updated to ${scope.slug}`));
|
|
8679
8939
|
} else {
|
|
8680
8940
|
scope = await createScope({ slug });
|
|
8681
|
-
console.log(
|
|
8941
|
+
console.log(chalk35.green(`\u2713 Scope created: ${scope.slug}`));
|
|
8682
8942
|
}
|
|
8683
8943
|
console.log();
|
|
8684
8944
|
console.log("Your agents will now be namespaced as:");
|
|
8685
|
-
console.log(
|
|
8945
|
+
console.log(chalk35.cyan(` ${scope.slug}/<agent-name>`));
|
|
8686
8946
|
} catch (error) {
|
|
8687
8947
|
if (error instanceof Error) {
|
|
8688
8948
|
if (error.message.includes("Not authenticated")) {
|
|
8689
|
-
console.error(
|
|
8949
|
+
console.error(chalk35.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
8690
8950
|
} else if (error.message.includes("already exists")) {
|
|
8691
8951
|
console.error(
|
|
8692
|
-
|
|
8952
|
+
chalk35.red(
|
|
8693
8953
|
`\u2717 Scope "${slug}" is already taken. Please choose a different slug.`
|
|
8694
8954
|
)
|
|
8695
8955
|
);
|
|
8696
8956
|
} else if (error.message.includes("reserved")) {
|
|
8697
|
-
console.error(
|
|
8957
|
+
console.error(chalk35.red(`\u2717 ${error.message}`));
|
|
8698
8958
|
} else if (error.message.includes("vm0")) {
|
|
8699
8959
|
console.error(
|
|
8700
|
-
|
|
8960
|
+
chalk35.red(
|
|
8701
8961
|
"\u2717 Scope slugs cannot start with 'vm0' (reserved for system use)"
|
|
8702
8962
|
)
|
|
8703
8963
|
);
|
|
8704
8964
|
} else {
|
|
8705
|
-
console.error(
|
|
8965
|
+
console.error(chalk35.red(`\u2717 ${error.message}`));
|
|
8706
8966
|
}
|
|
8707
8967
|
} else {
|
|
8708
|
-
console.error(
|
|
8968
|
+
console.error(chalk35.red("\u2717 An unexpected error occurred"));
|
|
8709
8969
|
}
|
|
8710
8970
|
process.exit(1);
|
|
8711
8971
|
}
|
|
@@ -8719,7 +8979,7 @@ import { Command as Command37 } from "commander";
|
|
|
8719
8979
|
|
|
8720
8980
|
// src/commands/agent/list.ts
|
|
8721
8981
|
import { Command as Command35 } from "commander";
|
|
8722
|
-
import
|
|
8982
|
+
import chalk36 from "chalk";
|
|
8723
8983
|
var listCommand4 = new Command35().name("list").alias("ls").description("List all agent composes").action(async () => {
|
|
8724
8984
|
try {
|
|
8725
8985
|
const response = await httpGet("/api/agent/composes/list");
|
|
@@ -8729,9 +8989,9 @@ var listCommand4 = new Command35().name("list").alias("ls").description("List al
|
|
|
8729
8989
|
}
|
|
8730
8990
|
const data = await response.json();
|
|
8731
8991
|
if (data.composes.length === 0) {
|
|
8732
|
-
console.log(
|
|
8992
|
+
console.log(chalk36.dim("No agent composes found"));
|
|
8733
8993
|
console.log(
|
|
8734
|
-
|
|
8994
|
+
chalk36.dim(" Create one with: vm0 compose <agent-compose.yaml>")
|
|
8735
8995
|
);
|
|
8736
8996
|
return;
|
|
8737
8997
|
}
|
|
@@ -8739,9 +8999,9 @@ var listCommand4 = new Command35().name("list").alias("ls").description("List al
|
|
|
8739
8999
|
const header = ["NAME".padEnd(nameWidth), "VERSION", "UPDATED"].join(
|
|
8740
9000
|
" "
|
|
8741
9001
|
);
|
|
8742
|
-
console.log(
|
|
9002
|
+
console.log(chalk36.dim(header));
|
|
8743
9003
|
for (const compose of data.composes) {
|
|
8744
|
-
const versionShort = compose.headVersionId ? compose.headVersionId.slice(0, 8) :
|
|
9004
|
+
const versionShort = compose.headVersionId ? compose.headVersionId.slice(0, 8) : chalk36.dim("-");
|
|
8745
9005
|
const row = [
|
|
8746
9006
|
compose.name.padEnd(nameWidth),
|
|
8747
9007
|
versionShort,
|
|
@@ -8750,12 +9010,12 @@ var listCommand4 = new Command35().name("list").alias("ls").description("List al
|
|
|
8750
9010
|
console.log(row);
|
|
8751
9011
|
}
|
|
8752
9012
|
} catch (error) {
|
|
8753
|
-
console.error(
|
|
9013
|
+
console.error(chalk36.red("\u2717 Failed to list agent composes"));
|
|
8754
9014
|
if (error instanceof Error) {
|
|
8755
9015
|
if (error.message.includes("Not authenticated")) {
|
|
8756
|
-
console.error(
|
|
9016
|
+
console.error(chalk36.dim(" Run: vm0 auth login"));
|
|
8757
9017
|
} else {
|
|
8758
|
-
console.error(
|
|
9018
|
+
console.error(chalk36.dim(` ${error.message}`));
|
|
8759
9019
|
}
|
|
8760
9020
|
}
|
|
8761
9021
|
process.exit(1);
|
|
@@ -8764,7 +9024,7 @@ var listCommand4 = new Command35().name("list").alias("ls").description("List al
|
|
|
8764
9024
|
|
|
8765
9025
|
// src/commands/agent/status.ts
|
|
8766
9026
|
import { Command as Command36 } from "commander";
|
|
8767
|
-
import
|
|
9027
|
+
import chalk37 from "chalk";
|
|
8768
9028
|
|
|
8769
9029
|
// src/lib/domain/source-derivation.ts
|
|
8770
9030
|
import * as fs9 from "fs/promises";
|
|
@@ -8888,27 +9148,27 @@ function formatVariableSources(sources) {
|
|
|
8888
9148
|
if (sources.secrets.length > 0) {
|
|
8889
9149
|
console.log(` Secrets:`);
|
|
8890
9150
|
for (const secret of sources.secrets) {
|
|
8891
|
-
const sourceInfo =
|
|
9151
|
+
const sourceInfo = chalk37.dim(`(${secret.source})`);
|
|
8892
9152
|
console.log(` - ${secret.name.padEnd(20)} ${sourceInfo}`);
|
|
8893
9153
|
}
|
|
8894
9154
|
}
|
|
8895
9155
|
if (sources.vars.length > 0) {
|
|
8896
9156
|
console.log(` Vars:`);
|
|
8897
9157
|
for (const v of sources.vars) {
|
|
8898
|
-
const sourceInfo =
|
|
9158
|
+
const sourceInfo = chalk37.dim(`(${v.source})`);
|
|
8899
9159
|
console.log(` - ${v.name.padEnd(20)} ${sourceInfo}`);
|
|
8900
9160
|
}
|
|
8901
9161
|
}
|
|
8902
9162
|
if (sources.credentials.length > 0) {
|
|
8903
9163
|
console.log(` Credentials:`);
|
|
8904
9164
|
for (const cred of sources.credentials) {
|
|
8905
|
-
const sourceInfo =
|
|
9165
|
+
const sourceInfo = chalk37.dim(`(${cred.source})`);
|
|
8906
9166
|
console.log(` - ${cred.name.padEnd(20)} ${sourceInfo}`);
|
|
8907
9167
|
}
|
|
8908
9168
|
}
|
|
8909
9169
|
}
|
|
8910
9170
|
function formatAgentDetails(agentName, agent, agentSources, volumeConfigs) {
|
|
8911
|
-
console.log(` ${
|
|
9171
|
+
console.log(` ${chalk37.cyan(agentName)}:`);
|
|
8912
9172
|
console.log(` Framework: ${agent.framework}`);
|
|
8913
9173
|
if (agent.image) {
|
|
8914
9174
|
console.log(` Image: ${agent.image}`);
|
|
@@ -8927,10 +9187,10 @@ function formatAgentDetails(agentName, agent, agentSources, volumeConfigs) {
|
|
|
8927
9187
|
}
|
|
8928
9188
|
}
|
|
8929
9189
|
function formatComposeOutput(name, versionId, content, variableSources) {
|
|
8930
|
-
console.log(
|
|
8931
|
-
console.log(
|
|
9190
|
+
console.log(chalk37.bold("Name:") + ` ${name}`);
|
|
9191
|
+
console.log(chalk37.bold("Version:") + ` ${versionId}`);
|
|
8932
9192
|
console.log();
|
|
8933
|
-
console.log(
|
|
9193
|
+
console.log(chalk37.bold("Agents:"));
|
|
8934
9194
|
for (const [agentName, agent] of Object.entries(content.agents)) {
|
|
8935
9195
|
const agentSources = variableSources?.get(agentName);
|
|
8936
9196
|
formatAgentDetails(agentName, agent, agentSources, content.volumes);
|
|
@@ -8953,8 +9213,8 @@ var statusCommand5 = new Command36().name("status").description("Show status of
|
|
|
8953
9213
|
}
|
|
8954
9214
|
const compose = await getComposeByName(name);
|
|
8955
9215
|
if (!compose) {
|
|
8956
|
-
console.error(
|
|
8957
|
-
console.error(
|
|
9216
|
+
console.error(chalk37.red(`\u2717 Agent compose not found: ${name}`));
|
|
9217
|
+
console.error(chalk37.dim(" Run: vm0 agent list"));
|
|
8958
9218
|
process.exit(1);
|
|
8959
9219
|
}
|
|
8960
9220
|
let resolvedVersionId = compose.headVersionId;
|
|
@@ -8965,9 +9225,9 @@ var statusCommand5 = new Command36().name("status").description("Show status of
|
|
|
8965
9225
|
resolvedVersionId = versionInfo.versionId;
|
|
8966
9226
|
} catch (error) {
|
|
8967
9227
|
if (error instanceof Error && error.message.includes("not found")) {
|
|
8968
|
-
console.error(
|
|
9228
|
+
console.error(chalk37.red(`\u2717 Version not found: ${version}`));
|
|
8969
9229
|
console.error(
|
|
8970
|
-
|
|
9230
|
+
chalk37.dim(
|
|
8971
9231
|
` HEAD version: ${compose.headVersionId?.slice(0, 8)}`
|
|
8972
9232
|
)
|
|
8973
9233
|
);
|
|
@@ -8980,7 +9240,7 @@ var statusCommand5 = new Command36().name("status").description("Show status of
|
|
|
8980
9240
|
}
|
|
8981
9241
|
}
|
|
8982
9242
|
if (!resolvedVersionId || !compose.content) {
|
|
8983
|
-
console.error(
|
|
9243
|
+
console.error(chalk37.red(`\u2717 No version found for: ${name}`));
|
|
8984
9244
|
process.exit(1);
|
|
8985
9245
|
}
|
|
8986
9246
|
const content = compose.content;
|
|
@@ -8991,7 +9251,7 @@ var statusCommand5 = new Command36().name("status").description("Show status of
|
|
|
8991
9251
|
});
|
|
8992
9252
|
} catch {
|
|
8993
9253
|
console.error(
|
|
8994
|
-
|
|
9254
|
+
chalk37.yellow(
|
|
8995
9255
|
"\u26A0 Warning: Failed to fetch skill sources, showing basic info"
|
|
8996
9256
|
)
|
|
8997
9257
|
);
|
|
@@ -9003,12 +9263,12 @@ var statusCommand5 = new Command36().name("status").description("Show status of
|
|
|
9003
9263
|
variableSources
|
|
9004
9264
|
);
|
|
9005
9265
|
} catch (error) {
|
|
9006
|
-
console.error(
|
|
9266
|
+
console.error(chalk37.red("\u2717 Failed to get agent compose status"));
|
|
9007
9267
|
if (error instanceof Error) {
|
|
9008
9268
|
if (error.message.includes("Not authenticated")) {
|
|
9009
|
-
console.error(
|
|
9269
|
+
console.error(chalk37.dim(" Run: vm0 auth login"));
|
|
9010
9270
|
} else {
|
|
9011
|
-
console.error(
|
|
9271
|
+
console.error(chalk37.dim(` ${error.message}`));
|
|
9012
9272
|
}
|
|
9013
9273
|
}
|
|
9014
9274
|
process.exit(1);
|
|
@@ -9020,7 +9280,7 @@ var agentCommand = new Command37().name("agent").description("Manage agent compo
|
|
|
9020
9280
|
|
|
9021
9281
|
// src/commands/init/index.ts
|
|
9022
9282
|
import { Command as Command38 } from "commander";
|
|
9023
|
-
import
|
|
9283
|
+
import chalk38 from "chalk";
|
|
9024
9284
|
import path15 from "path";
|
|
9025
9285
|
import { existsSync as existsSync10 } from "fs";
|
|
9026
9286
|
import { writeFile as writeFile6 } from "fs/promises";
|
|
@@ -9062,10 +9322,10 @@ var initCommand3 = new Command38().name("init").description("Initialize a new VM
|
|
|
9062
9322
|
const existingFiles = checkExistingFiles();
|
|
9063
9323
|
if (existingFiles.length > 0 && !options.force) {
|
|
9064
9324
|
for (const file of existingFiles) {
|
|
9065
|
-
console.log(
|
|
9325
|
+
console.log(chalk38.red(`\u2717 ${file} already exists`));
|
|
9066
9326
|
}
|
|
9067
9327
|
console.log();
|
|
9068
|
-
console.log(`To overwrite: ${
|
|
9328
|
+
console.log(`To overwrite: ${chalk38.cyan("vm0 init --force")}`);
|
|
9069
9329
|
process.exit(1);
|
|
9070
9330
|
}
|
|
9071
9331
|
let agentName;
|
|
@@ -9073,9 +9333,9 @@ var initCommand3 = new Command38().name("init").description("Initialize a new VM
|
|
|
9073
9333
|
agentName = options.name.trim();
|
|
9074
9334
|
} else if (!isInteractive()) {
|
|
9075
9335
|
console.error(
|
|
9076
|
-
|
|
9336
|
+
chalk38.red("\u2717 --name flag is required in non-interactive mode")
|
|
9077
9337
|
);
|
|
9078
|
-
console.error(
|
|
9338
|
+
console.error(chalk38.dim(" Usage: vm0 init --name <agent-name>"));
|
|
9079
9339
|
process.exit(1);
|
|
9080
9340
|
} else {
|
|
9081
9341
|
const dirName = path15.basename(process.cwd());
|
|
@@ -9091,38 +9351,38 @@ var initCommand3 = new Command38().name("init").description("Initialize a new VM
|
|
|
9091
9351
|
}
|
|
9092
9352
|
);
|
|
9093
9353
|
if (name === void 0) {
|
|
9094
|
-
console.log(
|
|
9354
|
+
console.log(chalk38.dim("Cancelled"));
|
|
9095
9355
|
return;
|
|
9096
9356
|
}
|
|
9097
9357
|
agentName = name;
|
|
9098
9358
|
}
|
|
9099
9359
|
if (!agentName || !validateAgentName(agentName)) {
|
|
9100
|
-
console.log(
|
|
9360
|
+
console.log(chalk38.red("\u2717 Invalid agent name"));
|
|
9101
9361
|
console.log(
|
|
9102
|
-
|
|
9362
|
+
chalk38.dim(" Must be 3-64 characters, alphanumeric and hyphens only")
|
|
9103
9363
|
);
|
|
9104
|
-
console.log(
|
|
9364
|
+
console.log(chalk38.dim(" Must start and end with letter or number"));
|
|
9105
9365
|
process.exit(1);
|
|
9106
9366
|
}
|
|
9107
9367
|
await writeFile6(VM0_YAML_FILE, generateVm0Yaml(agentName));
|
|
9108
9368
|
const vm0Status = existingFiles.includes(VM0_YAML_FILE) ? " (overwritten)" : "";
|
|
9109
|
-
console.log(
|
|
9369
|
+
console.log(chalk38.green(`\u2713 Created ${VM0_YAML_FILE}${vm0Status}`));
|
|
9110
9370
|
await writeFile6(AGENTS_MD_FILE, generateAgentsMd());
|
|
9111
9371
|
const agentsStatus = existingFiles.includes(AGENTS_MD_FILE) ? " (overwritten)" : "";
|
|
9112
|
-
console.log(
|
|
9372
|
+
console.log(chalk38.green(`\u2713 Created ${AGENTS_MD_FILE}${agentsStatus}`));
|
|
9113
9373
|
console.log();
|
|
9114
9374
|
console.log("Next steps:");
|
|
9115
9375
|
console.log(
|
|
9116
|
-
` 1. Set up model provider (one-time): ${
|
|
9376
|
+
` 1. Set up model provider (one-time): ${chalk38.cyan("vm0 model-provider setup")}`
|
|
9117
9377
|
);
|
|
9118
9378
|
console.log(
|
|
9119
|
-
` 2. Edit ${
|
|
9379
|
+
` 2. Edit ${chalk38.cyan("AGENTS.md")} to customize your agent's workflow`
|
|
9120
9380
|
);
|
|
9121
9381
|
console.log(
|
|
9122
|
-
` Or install Claude plugin: ${
|
|
9382
|
+
` Or install Claude plugin: ${chalk38.cyan(`vm0 setup-claude && claude "/vm0-agent let's build an agent"`)}`
|
|
9123
9383
|
);
|
|
9124
9384
|
console.log(
|
|
9125
|
-
` 3. Run your agent: ${
|
|
9385
|
+
` 3. Run your agent: ${chalk38.cyan(`vm0 cook "let's start working"`)}`
|
|
9126
9386
|
);
|
|
9127
9387
|
});
|
|
9128
9388
|
|
|
@@ -9131,7 +9391,7 @@ import { Command as Command45 } from "commander";
|
|
|
9131
9391
|
|
|
9132
9392
|
// src/commands/schedule/setup.ts
|
|
9133
9393
|
import { Command as Command39 } from "commander";
|
|
9134
|
-
import
|
|
9394
|
+
import chalk40 from "chalk";
|
|
9135
9395
|
|
|
9136
9396
|
// src/lib/domain/schedule-utils.ts
|
|
9137
9397
|
import { parse as parseYaml5 } from "yaml";
|
|
@@ -9273,7 +9533,7 @@ async function resolveScheduleByAgent(agentName) {
|
|
|
9273
9533
|
}
|
|
9274
9534
|
|
|
9275
9535
|
// src/commands/schedule/gather-configuration.ts
|
|
9276
|
-
import
|
|
9536
|
+
import chalk39 from "chalk";
|
|
9277
9537
|
var defaultPromptDeps = {
|
|
9278
9538
|
isInteractive,
|
|
9279
9539
|
promptConfirm,
|
|
@@ -9307,7 +9567,7 @@ async function handleSecrets(optionSecrets, existingSecretNames, deps) {
|
|
|
9307
9567
|
if (keepSecrets) {
|
|
9308
9568
|
return { secrets: {}, preserveExistingSecrets: true };
|
|
9309
9569
|
}
|
|
9310
|
-
console.log(
|
|
9570
|
+
console.log(chalk39.dim(" Note: You'll need to provide new secret values"));
|
|
9311
9571
|
return { secrets: {}, preserveExistingSecrets: false };
|
|
9312
9572
|
}
|
|
9313
9573
|
return { secrets: {}, preserveExistingSecrets: false };
|
|
@@ -9328,17 +9588,17 @@ async function handleVars(optionVars, existingVars, deps) {
|
|
|
9328
9588
|
return {};
|
|
9329
9589
|
}
|
|
9330
9590
|
function displayMissingRequirements(missingSecrets, missingVars) {
|
|
9331
|
-
console.log(
|
|
9591
|
+
console.log(chalk39.yellow("\nAgent requires the following configuration:"));
|
|
9332
9592
|
if (missingSecrets.length > 0) {
|
|
9333
|
-
console.log(
|
|
9593
|
+
console.log(chalk39.dim(" Secrets:"));
|
|
9334
9594
|
for (const name of missingSecrets) {
|
|
9335
|
-
console.log(
|
|
9595
|
+
console.log(chalk39.dim(` ${name}`));
|
|
9336
9596
|
}
|
|
9337
9597
|
}
|
|
9338
9598
|
if (missingVars.length > 0) {
|
|
9339
|
-
console.log(
|
|
9599
|
+
console.log(chalk39.dim(" Vars:"));
|
|
9340
9600
|
for (const name of missingVars) {
|
|
9341
|
-
console.log(
|
|
9601
|
+
console.log(chalk39.dim(` ${name}`));
|
|
9342
9602
|
}
|
|
9343
9603
|
}
|
|
9344
9604
|
console.log("");
|
|
@@ -9346,7 +9606,7 @@ function displayMissingRequirements(missingSecrets, missingVars) {
|
|
|
9346
9606
|
async function promptForMissingSecrets(missingSecrets, secrets, deps) {
|
|
9347
9607
|
for (const name of missingSecrets) {
|
|
9348
9608
|
const value = await deps.promptPassword(
|
|
9349
|
-
`Enter value for secret ${
|
|
9609
|
+
`Enter value for secret ${chalk39.cyan(name)}`
|
|
9350
9610
|
);
|
|
9351
9611
|
if (value) {
|
|
9352
9612
|
secrets[name] = value;
|
|
@@ -9356,7 +9616,7 @@ async function promptForMissingSecrets(missingSecrets, secrets, deps) {
|
|
|
9356
9616
|
async function promptForMissingVars(missingVars, vars, deps) {
|
|
9357
9617
|
for (const name of missingVars) {
|
|
9358
9618
|
const value = await deps.promptText(
|
|
9359
|
-
`Enter value for var ${
|
|
9619
|
+
`Enter value for var ${chalk39.cyan(name)}`,
|
|
9360
9620
|
""
|
|
9361
9621
|
);
|
|
9362
9622
|
if (value) {
|
|
@@ -9446,7 +9706,7 @@ function expandEnvVars(value) {
|
|
|
9446
9706
|
const envValue = process.env[varName];
|
|
9447
9707
|
if (envValue === void 0) {
|
|
9448
9708
|
console.warn(
|
|
9449
|
-
|
|
9709
|
+
chalk40.yellow(` Warning: Environment variable ${varName} not set`)
|
|
9450
9710
|
);
|
|
9451
9711
|
return match;
|
|
9452
9712
|
}
|
|
@@ -9513,7 +9773,7 @@ async function gatherFrequency(optionFrequency, existingFrequency) {
|
|
|
9513
9773
|
}
|
|
9514
9774
|
if (!isInteractive()) {
|
|
9515
9775
|
console.error(
|
|
9516
|
-
|
|
9776
|
+
chalk40.red("\u2717 --frequency is required (daily|weekly|monthly|once)")
|
|
9517
9777
|
);
|
|
9518
9778
|
process.exit(1);
|
|
9519
9779
|
}
|
|
@@ -9533,7 +9793,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
9533
9793
|
const day2 = parseDayOption(optionDay, frequency);
|
|
9534
9794
|
if (day2 === void 0) {
|
|
9535
9795
|
console.error(
|
|
9536
|
-
|
|
9796
|
+
chalk40.red(
|
|
9537
9797
|
`\u2717 Invalid day: ${optionDay}. Use mon-sun for weekly or 1-31 for monthly.`
|
|
9538
9798
|
)
|
|
9539
9799
|
);
|
|
@@ -9542,7 +9802,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
9542
9802
|
return day2;
|
|
9543
9803
|
}
|
|
9544
9804
|
if (!isInteractive()) {
|
|
9545
|
-
console.error(
|
|
9805
|
+
console.error(chalk40.red("\u2717 --day is required for weekly/monthly"));
|
|
9546
9806
|
process.exit(1);
|
|
9547
9807
|
}
|
|
9548
9808
|
if (frequency === "weekly") {
|
|
@@ -9561,7 +9821,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
9561
9821
|
if (!dayStr) return null;
|
|
9562
9822
|
const day = parseInt(dayStr, 10);
|
|
9563
9823
|
if (isNaN(day) || day < 1 || day > 31) {
|
|
9564
|
-
console.error(
|
|
9824
|
+
console.error(chalk40.red("\u2717 Day must be between 1 and 31"));
|
|
9565
9825
|
process.exit(1);
|
|
9566
9826
|
}
|
|
9567
9827
|
return day;
|
|
@@ -9570,13 +9830,13 @@ async function gatherRecurringTime(optionTime, existingTime) {
|
|
|
9570
9830
|
if (optionTime) {
|
|
9571
9831
|
const validation = validateTimeFormat(optionTime);
|
|
9572
9832
|
if (validation !== true) {
|
|
9573
|
-
console.error(
|
|
9833
|
+
console.error(chalk40.red(`\u2717 Invalid time: ${validation}`));
|
|
9574
9834
|
process.exit(1);
|
|
9575
9835
|
}
|
|
9576
9836
|
return optionTime;
|
|
9577
9837
|
}
|
|
9578
9838
|
if (!isInteractive()) {
|
|
9579
|
-
console.error(
|
|
9839
|
+
console.error(chalk40.red("\u2717 --time is required (HH:MM format)"));
|
|
9580
9840
|
process.exit(1);
|
|
9581
9841
|
}
|
|
9582
9842
|
return await promptText(
|
|
@@ -9589,7 +9849,7 @@ async function gatherOneTimeSchedule(optionDay, optionTime, existingTime) {
|
|
|
9589
9849
|
if (optionDay && optionTime) {
|
|
9590
9850
|
if (!validateDateFormat(optionDay)) {
|
|
9591
9851
|
console.error(
|
|
9592
|
-
|
|
9852
|
+
chalk40.red(
|
|
9593
9853
|
`\u2717 Invalid date format: ${optionDay}. Use YYYY-MM-DD format.`
|
|
9594
9854
|
)
|
|
9595
9855
|
);
|
|
@@ -9597,16 +9857,16 @@ async function gatherOneTimeSchedule(optionDay, optionTime, existingTime) {
|
|
|
9597
9857
|
}
|
|
9598
9858
|
if (!validateTimeFormat(optionTime)) {
|
|
9599
9859
|
console.error(
|
|
9600
|
-
|
|
9860
|
+
chalk40.red(`\u2717 Invalid time format: ${optionTime}. Use HH:MM format.`)
|
|
9601
9861
|
);
|
|
9602
9862
|
process.exit(1);
|
|
9603
9863
|
}
|
|
9604
9864
|
return `${optionDay} ${optionTime}`;
|
|
9605
9865
|
}
|
|
9606
9866
|
if (!isInteractive()) {
|
|
9607
|
-
console.error(
|
|
9867
|
+
console.error(chalk40.red("\u2717 One-time schedules require interactive mode"));
|
|
9608
9868
|
console.error(
|
|
9609
|
-
|
|
9869
|
+
chalk40.dim(" Or provide --day (YYYY-MM-DD) and --time (HH:MM) flags")
|
|
9610
9870
|
);
|
|
9611
9871
|
process.exit(1);
|
|
9612
9872
|
}
|
|
@@ -9637,7 +9897,7 @@ async function gatherTimezone(optionTimezone, existingTimezone) {
|
|
|
9637
9897
|
async function gatherPromptText(optionPrompt, existingPrompt) {
|
|
9638
9898
|
if (optionPrompt) return optionPrompt;
|
|
9639
9899
|
if (!isInteractive()) {
|
|
9640
|
-
console.error(
|
|
9900
|
+
console.error(chalk40.red("\u2717 --prompt is required"));
|
|
9641
9901
|
process.exit(1);
|
|
9642
9902
|
}
|
|
9643
9903
|
return await promptText(
|
|
@@ -9648,8 +9908,8 @@ async function gatherPromptText(optionPrompt, existingPrompt) {
|
|
|
9648
9908
|
async function resolveAgent(agentName) {
|
|
9649
9909
|
const compose = await getComposeByName(agentName);
|
|
9650
9910
|
if (!compose) {
|
|
9651
|
-
console.error(
|
|
9652
|
-
console.error(
|
|
9911
|
+
console.error(chalk40.red(`\u2717 Agent not found: ${agentName}`));
|
|
9912
|
+
console.error(chalk40.dim(" Make sure the agent is composed first"));
|
|
9653
9913
|
process.exit(1);
|
|
9654
9914
|
}
|
|
9655
9915
|
return {
|
|
@@ -9696,7 +9956,7 @@ async function buildAndDeploy(params) {
|
|
|
9696
9956
|
const expandedSecrets = expandEnvVarsInObject(params.secrets);
|
|
9697
9957
|
console.log(
|
|
9698
9958
|
`
|
|
9699
|
-
Deploying schedule for agent ${
|
|
9959
|
+
Deploying schedule for agent ${chalk40.cyan(params.agentName)}...`
|
|
9700
9960
|
);
|
|
9701
9961
|
const deployResult = await deploySchedule({
|
|
9702
9962
|
name: params.scheduleName,
|
|
@@ -9712,12 +9972,12 @@ Deploying schedule for agent ${chalk39.cyan(params.agentName)}...`
|
|
|
9712
9972
|
return deployResult;
|
|
9713
9973
|
}
|
|
9714
9974
|
function handleSetupError(error) {
|
|
9715
|
-
console.error(
|
|
9975
|
+
console.error(chalk40.red("\u2717 Failed to setup schedule"));
|
|
9716
9976
|
if (error instanceof Error) {
|
|
9717
9977
|
if (error.message.includes("Not authenticated")) {
|
|
9718
|
-
console.error(
|
|
9978
|
+
console.error(chalk40.dim(" Run: vm0 auth login"));
|
|
9719
9979
|
} else {
|
|
9720
|
-
console.error(
|
|
9980
|
+
console.error(chalk40.dim(` ${error.message}`));
|
|
9721
9981
|
}
|
|
9722
9982
|
}
|
|
9723
9983
|
process.exit(1);
|
|
@@ -9725,56 +9985,56 @@ function handleSetupError(error) {
|
|
|
9725
9985
|
function displayDeployResult(agentName, deployResult) {
|
|
9726
9986
|
if (deployResult.created) {
|
|
9727
9987
|
console.log(
|
|
9728
|
-
|
|
9988
|
+
chalk40.green(`\u2713 Created schedule for agent ${chalk40.cyan(agentName)}`)
|
|
9729
9989
|
);
|
|
9730
9990
|
} else {
|
|
9731
9991
|
console.log(
|
|
9732
|
-
|
|
9992
|
+
chalk40.green(`\u2713 Updated schedule for agent ${chalk40.cyan(agentName)}`)
|
|
9733
9993
|
);
|
|
9734
9994
|
}
|
|
9735
|
-
console.log(
|
|
9995
|
+
console.log(chalk40.dim(` Timezone: ${deployResult.schedule.timezone}`));
|
|
9736
9996
|
if (deployResult.schedule.cronExpression) {
|
|
9737
|
-
console.log(
|
|
9997
|
+
console.log(chalk40.dim(` Cron: ${deployResult.schedule.cronExpression}`));
|
|
9738
9998
|
if (deployResult.schedule.nextRunAt) {
|
|
9739
9999
|
const nextRun = formatInTimezone(
|
|
9740
10000
|
deployResult.schedule.nextRunAt,
|
|
9741
10001
|
deployResult.schedule.timezone
|
|
9742
10002
|
);
|
|
9743
|
-
console.log(
|
|
10003
|
+
console.log(chalk40.dim(` Next run: ${nextRun}`));
|
|
9744
10004
|
}
|
|
9745
10005
|
} else if (deployResult.schedule.atTime) {
|
|
9746
10006
|
const atTimeFormatted = formatInTimezone(
|
|
9747
10007
|
deployResult.schedule.atTime,
|
|
9748
10008
|
deployResult.schedule.timezone
|
|
9749
10009
|
);
|
|
9750
|
-
console.log(
|
|
10010
|
+
console.log(chalk40.dim(` At: ${atTimeFormatted}`));
|
|
9751
10011
|
}
|
|
9752
10012
|
}
|
|
9753
10013
|
async function tryEnableSchedule(scheduleName, composeId, agentName) {
|
|
9754
10014
|
try {
|
|
9755
10015
|
await enableSchedule({ name: scheduleName, composeId });
|
|
9756
10016
|
console.log(
|
|
9757
|
-
|
|
10017
|
+
chalk40.green(`\u2713 Enabled schedule for agent ${chalk40.cyan(agentName)}`)
|
|
9758
10018
|
);
|
|
9759
10019
|
} catch (error) {
|
|
9760
|
-
console.error(
|
|
10020
|
+
console.error(chalk40.yellow("\u26A0 Failed to enable schedule"));
|
|
9761
10021
|
if (error instanceof ApiRequestError) {
|
|
9762
10022
|
if (error.code === "SCHEDULE_PAST") {
|
|
9763
|
-
console.error(
|
|
10023
|
+
console.error(chalk40.dim(" Scheduled time has already passed"));
|
|
9764
10024
|
} else {
|
|
9765
|
-
console.error(
|
|
10025
|
+
console.error(chalk40.dim(` ${error.message}`));
|
|
9766
10026
|
}
|
|
9767
10027
|
} else if (error instanceof Error) {
|
|
9768
|
-
console.error(
|
|
10028
|
+
console.error(chalk40.dim(` ${error.message}`));
|
|
9769
10029
|
}
|
|
9770
10030
|
console.log(
|
|
9771
|
-
` To enable manually: ${
|
|
10031
|
+
` To enable manually: ${chalk40.cyan(`vm0 schedule enable ${agentName}`)}`
|
|
9772
10032
|
);
|
|
9773
10033
|
}
|
|
9774
10034
|
}
|
|
9775
10035
|
function showEnableHint(agentName) {
|
|
9776
10036
|
console.log();
|
|
9777
|
-
console.log(` To enable: ${
|
|
10037
|
+
console.log(` To enable: ${chalk40.cyan(`vm0 schedule enable ${agentName}`)}`);
|
|
9778
10038
|
}
|
|
9779
10039
|
async function handleScheduleEnabling(params) {
|
|
9780
10040
|
const { scheduleName, composeId, agentName, enableFlag, shouldPromptEnable } = params;
|
|
@@ -9801,7 +10061,7 @@ var setupCommand = new Command39().name("setup").description("Create or edit a s
|
|
|
9801
10061
|
const requiredConfig = extractRequiredConfiguration(composeContent);
|
|
9802
10062
|
const existingSchedule = await findExistingSchedule(agentName);
|
|
9803
10063
|
console.log(
|
|
9804
|
-
|
|
10064
|
+
chalk40.dim(
|
|
9805
10065
|
existingSchedule ? `Editing existing schedule for agent ${agentName}` : `Creating new schedule for agent ${agentName}`
|
|
9806
10066
|
)
|
|
9807
10067
|
);
|
|
@@ -9811,12 +10071,12 @@ var setupCommand = new Command39().name("setup").description("Create or edit a s
|
|
|
9811
10071
|
defaults.frequency
|
|
9812
10072
|
);
|
|
9813
10073
|
if (!frequency) {
|
|
9814
|
-
console.log(
|
|
10074
|
+
console.log(chalk40.dim("Cancelled"));
|
|
9815
10075
|
return;
|
|
9816
10076
|
}
|
|
9817
10077
|
const timing = await gatherTiming(frequency, options, defaults);
|
|
9818
10078
|
if (!timing) {
|
|
9819
|
-
console.log(
|
|
10079
|
+
console.log(chalk40.dim("Cancelled"));
|
|
9820
10080
|
return;
|
|
9821
10081
|
}
|
|
9822
10082
|
const { day, time, atTime } = timing;
|
|
@@ -9825,7 +10085,7 @@ var setupCommand = new Command39().name("setup").description("Create or edit a s
|
|
|
9825
10085
|
existingSchedule?.timezone
|
|
9826
10086
|
);
|
|
9827
10087
|
if (!timezone) {
|
|
9828
|
-
console.log(
|
|
10088
|
+
console.log(chalk40.dim("Cancelled"));
|
|
9829
10089
|
return;
|
|
9830
10090
|
}
|
|
9831
10091
|
const promptText_ = await gatherPromptText(
|
|
@@ -9833,7 +10093,7 @@ var setupCommand = new Command39().name("setup").description("Create or edit a s
|
|
|
9833
10093
|
existingSchedule?.prompt
|
|
9834
10094
|
);
|
|
9835
10095
|
if (!promptText_) {
|
|
9836
|
-
console.log(
|
|
10096
|
+
console.log(chalk40.dim("Cancelled"));
|
|
9837
10097
|
return;
|
|
9838
10098
|
}
|
|
9839
10099
|
const config = await gatherConfiguration({
|
|
@@ -9872,14 +10132,14 @@ var setupCommand = new Command39().name("setup").description("Create or edit a s
|
|
|
9872
10132
|
|
|
9873
10133
|
// src/commands/schedule/list.ts
|
|
9874
10134
|
import { Command as Command40 } from "commander";
|
|
9875
|
-
import
|
|
10135
|
+
import chalk41 from "chalk";
|
|
9876
10136
|
var listCommand5 = new Command40().name("list").alias("ls").description("List all schedules").action(async () => {
|
|
9877
10137
|
try {
|
|
9878
10138
|
const result = await listSchedules();
|
|
9879
10139
|
if (result.schedules.length === 0) {
|
|
9880
|
-
console.log(
|
|
10140
|
+
console.log(chalk41.dim("No schedules found"));
|
|
9881
10141
|
console.log(
|
|
9882
|
-
|
|
10142
|
+
chalk41.dim(" Create one with: vm0 schedule setup <agent-name>")
|
|
9883
10143
|
);
|
|
9884
10144
|
return;
|
|
9885
10145
|
}
|
|
@@ -9899,10 +10159,10 @@ var listCommand5 = new Command40().name("list").alias("ls").description("List al
|
|
|
9899
10159
|
"STATUS".padEnd(8),
|
|
9900
10160
|
"NEXT RUN"
|
|
9901
10161
|
].join(" ");
|
|
9902
|
-
console.log(
|
|
10162
|
+
console.log(chalk41.dim(header));
|
|
9903
10163
|
for (const schedule of result.schedules) {
|
|
9904
10164
|
const trigger = schedule.cronExpression ? `${schedule.cronExpression} (${schedule.timezone})` : schedule.atTime || "-";
|
|
9905
|
-
const status = schedule.enabled ?
|
|
10165
|
+
const status = schedule.enabled ? chalk41.green("enabled") : chalk41.yellow("disabled");
|
|
9906
10166
|
const nextRun = schedule.enabled ? formatRelativeTime2(schedule.nextRunAt) : "-";
|
|
9907
10167
|
const row = [
|
|
9908
10168
|
schedule.composeName.padEnd(agentWidth),
|
|
@@ -9914,12 +10174,12 @@ var listCommand5 = new Command40().name("list").alias("ls").description("List al
|
|
|
9914
10174
|
console.log(row);
|
|
9915
10175
|
}
|
|
9916
10176
|
} catch (error) {
|
|
9917
|
-
console.error(
|
|
10177
|
+
console.error(chalk41.red("\u2717 Failed to list schedules"));
|
|
9918
10178
|
if (error instanceof Error) {
|
|
9919
10179
|
if (error.message.includes("Not authenticated")) {
|
|
9920
|
-
console.error(
|
|
10180
|
+
console.error(chalk41.dim(" Run: vm0 auth login"));
|
|
9921
10181
|
} else {
|
|
9922
|
-
console.error(
|
|
10182
|
+
console.error(chalk41.dim(` ${error.message}`));
|
|
9923
10183
|
}
|
|
9924
10184
|
}
|
|
9925
10185
|
process.exit(1);
|
|
@@ -9928,44 +10188,44 @@ var listCommand5 = new Command40().name("list").alias("ls").description("List al
|
|
|
9928
10188
|
|
|
9929
10189
|
// src/commands/schedule/status.ts
|
|
9930
10190
|
import { Command as Command41 } from "commander";
|
|
9931
|
-
import
|
|
10191
|
+
import chalk42 from "chalk";
|
|
9932
10192
|
function formatDateTimeStyled(dateStr) {
|
|
9933
|
-
if (!dateStr) return
|
|
10193
|
+
if (!dateStr) return chalk42.dim("-");
|
|
9934
10194
|
const formatted = formatDateTime(dateStr);
|
|
9935
|
-
return formatted.replace(/\(([^)]+)\)$/,
|
|
10195
|
+
return formatted.replace(/\(([^)]+)\)$/, chalk42.dim("($1)"));
|
|
9936
10196
|
}
|
|
9937
10197
|
function formatTrigger(schedule) {
|
|
9938
10198
|
if (schedule.cronExpression) {
|
|
9939
10199
|
return schedule.cronExpression;
|
|
9940
10200
|
}
|
|
9941
10201
|
if (schedule.atTime) {
|
|
9942
|
-
return `${schedule.atTime} ${
|
|
10202
|
+
return `${schedule.atTime} ${chalk42.dim("(one-time)")}`;
|
|
9943
10203
|
}
|
|
9944
|
-
return
|
|
10204
|
+
return chalk42.dim("-");
|
|
9945
10205
|
}
|
|
9946
10206
|
function formatRunStatus2(status) {
|
|
9947
10207
|
switch (status) {
|
|
9948
10208
|
case "completed":
|
|
9949
|
-
return
|
|
10209
|
+
return chalk42.green(status);
|
|
9950
10210
|
case "failed":
|
|
9951
10211
|
case "timeout":
|
|
9952
|
-
return
|
|
10212
|
+
return chalk42.red(status);
|
|
9953
10213
|
case "running":
|
|
9954
|
-
return
|
|
10214
|
+
return chalk42.blue(status);
|
|
9955
10215
|
case "pending":
|
|
9956
|
-
return
|
|
10216
|
+
return chalk42.yellow(status);
|
|
9957
10217
|
default:
|
|
9958
10218
|
return status;
|
|
9959
10219
|
}
|
|
9960
10220
|
}
|
|
9961
10221
|
function printRunConfiguration(schedule) {
|
|
9962
|
-
const statusText = schedule.enabled ?
|
|
10222
|
+
const statusText = schedule.enabled ? chalk42.green("enabled") : chalk42.yellow("disabled");
|
|
9963
10223
|
console.log(`${"Status:".padEnd(16)}${statusText}`);
|
|
9964
10224
|
console.log(
|
|
9965
|
-
`${"Agent:".padEnd(16)}${schedule.composeName} ${
|
|
10225
|
+
`${"Agent:".padEnd(16)}${schedule.composeName} ${chalk42.dim(`(${schedule.scopeSlug})`)}`
|
|
9966
10226
|
);
|
|
9967
10227
|
const promptPreview = schedule.prompt.length > 60 ? schedule.prompt.slice(0, 57) + "..." : schedule.prompt;
|
|
9968
|
-
console.log(`${"Prompt:".padEnd(16)}${
|
|
10228
|
+
console.log(`${"Prompt:".padEnd(16)}${chalk42.dim(promptPreview)}`);
|
|
9969
10229
|
if (schedule.vars && Object.keys(schedule.vars).length > 0) {
|
|
9970
10230
|
console.log(
|
|
9971
10231
|
`${"Variables:".padEnd(16)}${Object.keys(schedule.vars).join(", ")}`
|
|
@@ -10002,7 +10262,7 @@ async function printRecentRuns(name, composeId, limit) {
|
|
|
10002
10262
|
console.log();
|
|
10003
10263
|
console.log("Recent Runs:");
|
|
10004
10264
|
console.log(
|
|
10005
|
-
|
|
10265
|
+
chalk42.dim("RUN ID STATUS CREATED")
|
|
10006
10266
|
);
|
|
10007
10267
|
for (const run of runs) {
|
|
10008
10268
|
const id = run.id;
|
|
@@ -10013,19 +10273,19 @@ async function printRecentRuns(name, composeId, limit) {
|
|
|
10013
10273
|
}
|
|
10014
10274
|
} catch {
|
|
10015
10275
|
console.log();
|
|
10016
|
-
console.log(
|
|
10276
|
+
console.log(chalk42.dim("Recent Runs: (unable to fetch)"));
|
|
10017
10277
|
}
|
|
10018
10278
|
}
|
|
10019
10279
|
function handleStatusError(error, agentName) {
|
|
10020
|
-
console.error(
|
|
10280
|
+
console.error(chalk42.red("\u2717 Failed to get schedule status"));
|
|
10021
10281
|
if (error instanceof Error) {
|
|
10022
10282
|
if (error.message.includes("Not authenticated")) {
|
|
10023
|
-
console.error(
|
|
10283
|
+
console.error(chalk42.dim(" Run: vm0 auth login"));
|
|
10024
10284
|
} else if (error.message.includes("not found") || error.message.includes("Not found") || error.message.includes("No schedule found")) {
|
|
10025
|
-
console.error(
|
|
10026
|
-
console.error(
|
|
10285
|
+
console.error(chalk42.dim(` No schedule found for agent "${agentName}"`));
|
|
10286
|
+
console.error(chalk42.dim(" Run: vm0 schedule list"));
|
|
10027
10287
|
} else {
|
|
10028
|
-
console.error(
|
|
10288
|
+
console.error(chalk42.dim(` ${error.message}`));
|
|
10029
10289
|
}
|
|
10030
10290
|
}
|
|
10031
10291
|
process.exit(1);
|
|
@@ -10040,8 +10300,8 @@ var statusCommand6 = new Command41().name("status").description("Show detailed s
|
|
|
10040
10300
|
const { name, composeId } = resolved;
|
|
10041
10301
|
const schedule = await getScheduleByName({ name, composeId });
|
|
10042
10302
|
console.log();
|
|
10043
|
-
console.log(`Schedule for agent: ${
|
|
10044
|
-
console.log(
|
|
10303
|
+
console.log(`Schedule for agent: ${chalk42.cyan(agentName)}`);
|
|
10304
|
+
console.log(chalk42.dim("\u2501".repeat(50)));
|
|
10045
10305
|
printRunConfiguration(schedule);
|
|
10046
10306
|
printTimeSchedule(schedule);
|
|
10047
10307
|
const limit = Math.min(
|
|
@@ -10057,23 +10317,23 @@ var statusCommand6 = new Command41().name("status").description("Show detailed s
|
|
|
10057
10317
|
|
|
10058
10318
|
// src/commands/schedule/delete.ts
|
|
10059
10319
|
import { Command as Command42 } from "commander";
|
|
10060
|
-
import
|
|
10320
|
+
import chalk43 from "chalk";
|
|
10061
10321
|
var deleteCommand = new Command42().name("delete").alias("rm").description("Delete a schedule").argument("<agent-name>", "Agent name").option("-f, --force", "Skip confirmation prompt").action(async (agentName, options) => {
|
|
10062
10322
|
try {
|
|
10063
10323
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
10064
10324
|
if (!options.force) {
|
|
10065
10325
|
if (!isInteractive()) {
|
|
10066
10326
|
console.error(
|
|
10067
|
-
|
|
10327
|
+
chalk43.red("\u2717 --force required in non-interactive mode")
|
|
10068
10328
|
);
|
|
10069
10329
|
process.exit(1);
|
|
10070
10330
|
}
|
|
10071
10331
|
const confirmed = await promptConfirm(
|
|
10072
|
-
`Delete schedule for agent ${
|
|
10332
|
+
`Delete schedule for agent ${chalk43.cyan(agentName)}?`,
|
|
10073
10333
|
false
|
|
10074
10334
|
);
|
|
10075
10335
|
if (!confirmed) {
|
|
10076
|
-
console.log(
|
|
10336
|
+
console.log(chalk43.dim("Cancelled"));
|
|
10077
10337
|
return;
|
|
10078
10338
|
}
|
|
10079
10339
|
}
|
|
@@ -10082,20 +10342,20 @@ var deleteCommand = new Command42().name("delete").alias("rm").description("Dele
|
|
|
10082
10342
|
composeId: resolved.composeId
|
|
10083
10343
|
});
|
|
10084
10344
|
console.log(
|
|
10085
|
-
|
|
10345
|
+
chalk43.green(`\u2713 Deleted schedule for agent ${chalk43.cyan(agentName)}`)
|
|
10086
10346
|
);
|
|
10087
10347
|
} catch (error) {
|
|
10088
|
-
console.error(
|
|
10348
|
+
console.error(chalk43.red("\u2717 Failed to delete schedule"));
|
|
10089
10349
|
if (error instanceof Error) {
|
|
10090
10350
|
if (error.message.includes("Not authenticated")) {
|
|
10091
|
-
console.error(
|
|
10351
|
+
console.error(chalk43.dim(" Run: vm0 auth login"));
|
|
10092
10352
|
} else if (error.message.toLowerCase().includes("not found") || error.message.includes("No schedule found")) {
|
|
10093
10353
|
console.error(
|
|
10094
|
-
|
|
10354
|
+
chalk43.dim(` No schedule found for agent "${agentName}"`)
|
|
10095
10355
|
);
|
|
10096
|
-
console.error(
|
|
10356
|
+
console.error(chalk43.dim(" Run: vm0 schedule list"));
|
|
10097
10357
|
} else {
|
|
10098
|
-
console.error(
|
|
10358
|
+
console.error(chalk43.dim(` ${error.message}`));
|
|
10099
10359
|
}
|
|
10100
10360
|
}
|
|
10101
10361
|
process.exit(1);
|
|
@@ -10104,7 +10364,7 @@ var deleteCommand = new Command42().name("delete").alias("rm").description("Dele
|
|
|
10104
10364
|
|
|
10105
10365
|
// src/commands/schedule/enable.ts
|
|
10106
10366
|
import { Command as Command43 } from "commander";
|
|
10107
|
-
import
|
|
10367
|
+
import chalk44 from "chalk";
|
|
10108
10368
|
var enableCommand = new Command43().name("enable").description("Enable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
|
|
10109
10369
|
try {
|
|
10110
10370
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
@@ -10113,34 +10373,34 @@ var enableCommand = new Command43().name("enable").description("Enable a schedul
|
|
|
10113
10373
|
composeId: resolved.composeId
|
|
10114
10374
|
});
|
|
10115
10375
|
console.log(
|
|
10116
|
-
|
|
10376
|
+
chalk44.green(`\u2713 Enabled schedule for agent ${chalk44.cyan(agentName)}`)
|
|
10117
10377
|
);
|
|
10118
10378
|
} catch (error) {
|
|
10119
|
-
console.error(
|
|
10379
|
+
console.error(chalk44.red("\u2717 Failed to enable schedule"));
|
|
10120
10380
|
if (error instanceof ApiRequestError) {
|
|
10121
10381
|
if (error.code === "SCHEDULE_PAST") {
|
|
10122
|
-
console.error(
|
|
10123
|
-
console.error(
|
|
10382
|
+
console.error(chalk44.dim(" Scheduled time has already passed"));
|
|
10383
|
+
console.error(chalk44.dim(` Run: vm0 schedule setup ${agentName}`));
|
|
10124
10384
|
} else if (error.code === "NOT_FOUND") {
|
|
10125
10385
|
console.error(
|
|
10126
|
-
|
|
10386
|
+
chalk44.dim(` No schedule found for agent "${agentName}"`)
|
|
10127
10387
|
);
|
|
10128
|
-
console.error(
|
|
10388
|
+
console.error(chalk44.dim(" Run: vm0 schedule list"));
|
|
10129
10389
|
} else if (error.code === "UNAUTHORIZED") {
|
|
10130
|
-
console.error(
|
|
10390
|
+
console.error(chalk44.dim(" Run: vm0 auth login"));
|
|
10131
10391
|
} else {
|
|
10132
|
-
console.error(
|
|
10392
|
+
console.error(chalk44.dim(` ${error.message}`));
|
|
10133
10393
|
}
|
|
10134
10394
|
} else if (error instanceof Error) {
|
|
10135
10395
|
if (error.message.includes("Not authenticated")) {
|
|
10136
|
-
console.error(
|
|
10396
|
+
console.error(chalk44.dim(" Run: vm0 auth login"));
|
|
10137
10397
|
} else if (error.message.includes("No schedule found")) {
|
|
10138
10398
|
console.error(
|
|
10139
|
-
|
|
10399
|
+
chalk44.dim(` No schedule found for agent "${agentName}"`)
|
|
10140
10400
|
);
|
|
10141
|
-
console.error(
|
|
10401
|
+
console.error(chalk44.dim(" Run: vm0 schedule list"));
|
|
10142
10402
|
} else {
|
|
10143
|
-
console.error(
|
|
10403
|
+
console.error(chalk44.dim(` ${error.message}`));
|
|
10144
10404
|
}
|
|
10145
10405
|
}
|
|
10146
10406
|
process.exit(1);
|
|
@@ -10149,7 +10409,7 @@ var enableCommand = new Command43().name("enable").description("Enable a schedul
|
|
|
10149
10409
|
|
|
10150
10410
|
// src/commands/schedule/disable.ts
|
|
10151
10411
|
import { Command as Command44 } from "commander";
|
|
10152
|
-
import
|
|
10412
|
+
import chalk45 from "chalk";
|
|
10153
10413
|
var disableCommand = new Command44().name("disable").description("Disable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
|
|
10154
10414
|
try {
|
|
10155
10415
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
@@ -10158,20 +10418,20 @@ var disableCommand = new Command44().name("disable").description("Disable a sche
|
|
|
10158
10418
|
composeId: resolved.composeId
|
|
10159
10419
|
});
|
|
10160
10420
|
console.log(
|
|
10161
|
-
|
|
10421
|
+
chalk45.green(`\u2713 Disabled schedule for agent ${chalk45.cyan(agentName)}`)
|
|
10162
10422
|
);
|
|
10163
10423
|
} catch (error) {
|
|
10164
|
-
console.error(
|
|
10424
|
+
console.error(chalk45.red("\u2717 Failed to disable schedule"));
|
|
10165
10425
|
if (error instanceof Error) {
|
|
10166
10426
|
if (error.message.includes("Not authenticated")) {
|
|
10167
|
-
console.error(
|
|
10427
|
+
console.error(chalk45.dim(" Run: vm0 auth login"));
|
|
10168
10428
|
} else if (error.message.toLowerCase().includes("not found") || error.message.includes("No schedule found")) {
|
|
10169
10429
|
console.error(
|
|
10170
|
-
|
|
10430
|
+
chalk45.dim(` No schedule found for agent "${agentName}"`)
|
|
10171
10431
|
);
|
|
10172
|
-
console.error(
|
|
10432
|
+
console.error(chalk45.dim(" Run: vm0 schedule list"));
|
|
10173
10433
|
} else {
|
|
10174
|
-
console.error(
|
|
10434
|
+
console.error(chalk45.dim(` ${error.message}`));
|
|
10175
10435
|
}
|
|
10176
10436
|
}
|
|
10177
10437
|
process.exit(1);
|
|
@@ -10183,7 +10443,7 @@ var scheduleCommand = new Command45().name("schedule").description("Manage agent
|
|
|
10183
10443
|
|
|
10184
10444
|
// src/commands/usage/index.ts
|
|
10185
10445
|
import { Command as Command46 } from "commander";
|
|
10186
|
-
import
|
|
10446
|
+
import chalk46 from "chalk";
|
|
10187
10447
|
|
|
10188
10448
|
// src/lib/utils/duration-formatter.ts
|
|
10189
10449
|
function formatDuration(ms) {
|
|
@@ -10270,7 +10530,7 @@ var usageCommand = new Command46().name("usage").description("View usage statist
|
|
|
10270
10530
|
endDate = new Date(untilMs);
|
|
10271
10531
|
} catch {
|
|
10272
10532
|
console.error(
|
|
10273
|
-
|
|
10533
|
+
chalk46.red(
|
|
10274
10534
|
"\u2717 Invalid --until format. Use ISO (2026-01-01) or relative (7d, 30d)"
|
|
10275
10535
|
)
|
|
10276
10536
|
);
|
|
@@ -10285,7 +10545,7 @@ var usageCommand = new Command46().name("usage").description("View usage statist
|
|
|
10285
10545
|
startDate = new Date(sinceMs);
|
|
10286
10546
|
} catch {
|
|
10287
10547
|
console.error(
|
|
10288
|
-
|
|
10548
|
+
chalk46.red(
|
|
10289
10549
|
"\u2717 Invalid --since format. Use ISO (2026-01-01) or relative (7d, 30d)"
|
|
10290
10550
|
)
|
|
10291
10551
|
);
|
|
@@ -10295,13 +10555,13 @@ var usageCommand = new Command46().name("usage").description("View usage statist
|
|
|
10295
10555
|
startDate = new Date(endDate.getTime() - DEFAULT_RANGE_MS);
|
|
10296
10556
|
}
|
|
10297
10557
|
if (startDate >= endDate) {
|
|
10298
|
-
console.error(
|
|
10558
|
+
console.error(chalk46.red("\u2717 --since must be before --until"));
|
|
10299
10559
|
process.exit(1);
|
|
10300
10560
|
}
|
|
10301
10561
|
const rangeMs = endDate.getTime() - startDate.getTime();
|
|
10302
10562
|
if (rangeMs > MAX_RANGE_MS) {
|
|
10303
10563
|
console.error(
|
|
10304
|
-
|
|
10564
|
+
chalk46.red(
|
|
10305
10565
|
"\u2717 Time range exceeds maximum of 30 days. Use --until to specify an end date"
|
|
10306
10566
|
)
|
|
10307
10567
|
);
|
|
@@ -10318,19 +10578,19 @@ var usageCommand = new Command46().name("usage").description("View usage statist
|
|
|
10318
10578
|
);
|
|
10319
10579
|
console.log();
|
|
10320
10580
|
console.log(
|
|
10321
|
-
|
|
10581
|
+
chalk46.bold(
|
|
10322
10582
|
`Usage Summary (${formatDateRange(usage.period.start, usage.period.end)})`
|
|
10323
10583
|
)
|
|
10324
10584
|
);
|
|
10325
10585
|
console.log();
|
|
10326
|
-
console.log(
|
|
10586
|
+
console.log(chalk46.dim("DATE RUNS RUN TIME"));
|
|
10327
10587
|
for (const day of filledDaily) {
|
|
10328
10588
|
const dateDisplay = formatDateDisplay(day.date).padEnd(10);
|
|
10329
10589
|
const runsDisplay = String(day.run_count).padStart(6);
|
|
10330
10590
|
const timeDisplay = formatDuration(day.run_time_ms);
|
|
10331
10591
|
console.log(`${dateDisplay}${runsDisplay} ${timeDisplay}`);
|
|
10332
10592
|
}
|
|
10333
|
-
console.log(
|
|
10593
|
+
console.log(chalk46.dim("\u2500".repeat(29)));
|
|
10334
10594
|
const totalRunsDisplay = String(usage.summary.total_runs).padStart(6);
|
|
10335
10595
|
const totalTimeDisplay = formatDuration(usage.summary.total_run_time_ms);
|
|
10336
10596
|
console.log(
|
|
@@ -10340,13 +10600,13 @@ var usageCommand = new Command46().name("usage").description("View usage statist
|
|
|
10340
10600
|
} catch (error) {
|
|
10341
10601
|
if (error instanceof Error) {
|
|
10342
10602
|
if (error.message.includes("Not authenticated")) {
|
|
10343
|
-
console.error(
|
|
10344
|
-
console.error(
|
|
10603
|
+
console.error(chalk46.red("\u2717 Not authenticated"));
|
|
10604
|
+
console.error(chalk46.dim(" Run: vm0 auth login"));
|
|
10345
10605
|
} else {
|
|
10346
|
-
console.error(
|
|
10606
|
+
console.error(chalk46.red(`\u2717 ${error.message}`));
|
|
10347
10607
|
}
|
|
10348
10608
|
} else {
|
|
10349
|
-
console.error(
|
|
10609
|
+
console.error(chalk46.red("\u2717 An unexpected error occurred"));
|
|
10350
10610
|
}
|
|
10351
10611
|
process.exit(1);
|
|
10352
10612
|
}
|
|
@@ -10357,42 +10617,42 @@ import { Command as Command50 } from "commander";
|
|
|
10357
10617
|
|
|
10358
10618
|
// src/commands/credential/list.ts
|
|
10359
10619
|
import { Command as Command47 } from "commander";
|
|
10360
|
-
import
|
|
10620
|
+
import chalk47 from "chalk";
|
|
10361
10621
|
var listCommand6 = new Command47().name("list").alias("ls").description("List all credentials").action(async () => {
|
|
10362
10622
|
try {
|
|
10363
10623
|
const result = await listCredentials();
|
|
10364
10624
|
if (result.credentials.length === 0) {
|
|
10365
|
-
console.log(
|
|
10625
|
+
console.log(chalk47.dim("No credentials found"));
|
|
10366
10626
|
console.log();
|
|
10367
10627
|
console.log("To add a credential:");
|
|
10368
|
-
console.log(
|
|
10628
|
+
console.log(chalk47.cyan(" vm0 credential set MY_API_KEY <value>"));
|
|
10369
10629
|
return;
|
|
10370
10630
|
}
|
|
10371
|
-
console.log(
|
|
10631
|
+
console.log(chalk47.bold("Credentials:"));
|
|
10372
10632
|
console.log();
|
|
10373
10633
|
for (const credential of result.credentials) {
|
|
10374
|
-
const typeIndicator = credential.type === "model-provider" ?
|
|
10375
|
-
console.log(` ${
|
|
10634
|
+
const typeIndicator = credential.type === "model-provider" ? chalk47.dim(" [model-provider]") : "";
|
|
10635
|
+
console.log(` ${chalk47.cyan(credential.name)}${typeIndicator}`);
|
|
10376
10636
|
if (credential.description) {
|
|
10377
|
-
console.log(` ${
|
|
10637
|
+
console.log(` ${chalk47.dim(credential.description)}`);
|
|
10378
10638
|
}
|
|
10379
10639
|
console.log(
|
|
10380
|
-
` ${
|
|
10640
|
+
` ${chalk47.dim(`Updated: ${new Date(credential.updatedAt).toLocaleString()}`)}`
|
|
10381
10641
|
);
|
|
10382
10642
|
console.log();
|
|
10383
10643
|
}
|
|
10384
10644
|
console.log(
|
|
10385
|
-
|
|
10645
|
+
chalk47.dim(`Total: ${result.credentials.length} credential(s)`)
|
|
10386
10646
|
);
|
|
10387
10647
|
} catch (error) {
|
|
10388
10648
|
if (error instanceof Error) {
|
|
10389
10649
|
if (error.message.includes("Not authenticated")) {
|
|
10390
|
-
console.error(
|
|
10650
|
+
console.error(chalk47.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10391
10651
|
} else {
|
|
10392
|
-
console.error(
|
|
10652
|
+
console.error(chalk47.red(`\u2717 ${error.message}`));
|
|
10393
10653
|
}
|
|
10394
10654
|
} else {
|
|
10395
|
-
console.error(
|
|
10655
|
+
console.error(chalk47.red("\u2717 An unexpected error occurred"));
|
|
10396
10656
|
}
|
|
10397
10657
|
process.exit(1);
|
|
10398
10658
|
}
|
|
@@ -10400,7 +10660,7 @@ var listCommand6 = new Command47().name("list").alias("ls").description("List al
|
|
|
10400
10660
|
|
|
10401
10661
|
// src/commands/credential/set.ts
|
|
10402
10662
|
import { Command as Command48 } from "commander";
|
|
10403
|
-
import
|
|
10663
|
+
import chalk48 from "chalk";
|
|
10404
10664
|
var setCommand2 = new Command48().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(
|
|
10405
10665
|
async (name, value, options) => {
|
|
10406
10666
|
try {
|
|
@@ -10409,29 +10669,29 @@ var setCommand2 = new Command48().name("set").description("Create or update a cr
|
|
|
10409
10669
|
value,
|
|
10410
10670
|
description: options.description
|
|
10411
10671
|
});
|
|
10412
|
-
console.log(
|
|
10672
|
+
console.log(chalk48.green(`\u2713 Credential "${credential.name}" saved`));
|
|
10413
10673
|
console.log();
|
|
10414
10674
|
console.log("Use in vm0.yaml:");
|
|
10415
|
-
console.log(
|
|
10416
|
-
console.log(
|
|
10675
|
+
console.log(chalk48.cyan(` environment:`));
|
|
10676
|
+
console.log(chalk48.cyan(` ${name}: \${{ credentials.${name} }}`));
|
|
10417
10677
|
} catch (error) {
|
|
10418
10678
|
if (error instanceof Error) {
|
|
10419
10679
|
if (error.message.includes("Not authenticated")) {
|
|
10420
10680
|
console.error(
|
|
10421
|
-
|
|
10681
|
+
chalk48.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
10422
10682
|
);
|
|
10423
10683
|
} else if (error.message.includes("must contain only uppercase")) {
|
|
10424
|
-
console.error(
|
|
10684
|
+
console.error(chalk48.red(`\u2717 ${error.message}`));
|
|
10425
10685
|
console.log();
|
|
10426
10686
|
console.log("Examples of valid credential names:");
|
|
10427
|
-
console.log(
|
|
10428
|
-
console.log(
|
|
10429
|
-
console.log(
|
|
10687
|
+
console.log(chalk48.dim(" MY_API_KEY"));
|
|
10688
|
+
console.log(chalk48.dim(" GITHUB_TOKEN"));
|
|
10689
|
+
console.log(chalk48.dim(" AWS_ACCESS_KEY_ID"));
|
|
10430
10690
|
} else {
|
|
10431
|
-
console.error(
|
|
10691
|
+
console.error(chalk48.red(`\u2717 ${error.message}`));
|
|
10432
10692
|
}
|
|
10433
10693
|
} else {
|
|
10434
|
-
console.error(
|
|
10694
|
+
console.error(chalk48.red("\u2717 An unexpected error occurred"));
|
|
10435
10695
|
}
|
|
10436
10696
|
process.exit(1);
|
|
10437
10697
|
}
|
|
@@ -10440,19 +10700,19 @@ var setCommand2 = new Command48().name("set").description("Create or update a cr
|
|
|
10440
10700
|
|
|
10441
10701
|
// src/commands/credential/delete.ts
|
|
10442
10702
|
import { Command as Command49 } from "commander";
|
|
10443
|
-
import
|
|
10703
|
+
import chalk49 from "chalk";
|
|
10444
10704
|
var deleteCommand2 = new Command49().name("delete").description("Delete a credential").argument("<name>", "Credential name to delete").option("-y, --yes", "Skip confirmation prompt").action(async (name, options) => {
|
|
10445
10705
|
try {
|
|
10446
10706
|
try {
|
|
10447
10707
|
await getCredential(name);
|
|
10448
10708
|
} catch {
|
|
10449
|
-
console.error(
|
|
10709
|
+
console.error(chalk49.red(`\u2717 Credential "${name}" not found`));
|
|
10450
10710
|
process.exit(1);
|
|
10451
10711
|
}
|
|
10452
10712
|
if (!options.yes) {
|
|
10453
10713
|
if (!isInteractive()) {
|
|
10454
10714
|
console.error(
|
|
10455
|
-
|
|
10715
|
+
chalk49.red("\u2717 --yes flag is required in non-interactive mode")
|
|
10456
10716
|
);
|
|
10457
10717
|
process.exit(1);
|
|
10458
10718
|
}
|
|
@@ -10461,21 +10721,21 @@ var deleteCommand2 = new Command49().name("delete").description("Delete a creden
|
|
|
10461
10721
|
false
|
|
10462
10722
|
);
|
|
10463
10723
|
if (!confirmed) {
|
|
10464
|
-
console.log(
|
|
10724
|
+
console.log(chalk49.dim("Cancelled"));
|
|
10465
10725
|
return;
|
|
10466
10726
|
}
|
|
10467
10727
|
}
|
|
10468
10728
|
await deleteCredential(name);
|
|
10469
|
-
console.log(
|
|
10729
|
+
console.log(chalk49.green(`\u2713 Credential "${name}" deleted`));
|
|
10470
10730
|
} catch (error) {
|
|
10471
10731
|
if (error instanceof Error) {
|
|
10472
10732
|
if (error.message.includes("Not authenticated")) {
|
|
10473
|
-
console.error(
|
|
10733
|
+
console.error(chalk49.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10474
10734
|
} else {
|
|
10475
|
-
console.error(
|
|
10735
|
+
console.error(chalk49.red(`\u2717 ${error.message}`));
|
|
10476
10736
|
}
|
|
10477
10737
|
} else {
|
|
10478
|
-
console.error(
|
|
10738
|
+
console.error(chalk49.red("\u2717 An unexpected error occurred"));
|
|
10479
10739
|
}
|
|
10480
10740
|
process.exit(1);
|
|
10481
10741
|
}
|
|
@@ -10489,15 +10749,15 @@ import { Command as Command55 } from "commander";
|
|
|
10489
10749
|
|
|
10490
10750
|
// src/commands/model-provider/list.ts
|
|
10491
10751
|
import { Command as Command51 } from "commander";
|
|
10492
|
-
import
|
|
10752
|
+
import chalk50 from "chalk";
|
|
10493
10753
|
var listCommand7 = new Command51().name("list").alias("ls").description("List all model providers").action(async () => {
|
|
10494
10754
|
try {
|
|
10495
10755
|
const result = await listModelProviders();
|
|
10496
10756
|
if (result.modelProviders.length === 0) {
|
|
10497
|
-
console.log(
|
|
10757
|
+
console.log(chalk50.dim("No model providers configured"));
|
|
10498
10758
|
console.log();
|
|
10499
10759
|
console.log("To add a model provider:");
|
|
10500
|
-
console.log(
|
|
10760
|
+
console.log(chalk50.cyan(" vm0 model-provider setup"));
|
|
10501
10761
|
return;
|
|
10502
10762
|
}
|
|
10503
10763
|
const byFramework = result.modelProviders.reduce(
|
|
@@ -10511,15 +10771,15 @@ var listCommand7 = new Command51().name("list").alias("ls").description("List al
|
|
|
10511
10771
|
},
|
|
10512
10772
|
{}
|
|
10513
10773
|
);
|
|
10514
|
-
console.log(
|
|
10774
|
+
console.log(chalk50.bold("Model Providers:"));
|
|
10515
10775
|
console.log();
|
|
10516
10776
|
for (const [framework, providers] of Object.entries(byFramework)) {
|
|
10517
|
-
console.log(` ${
|
|
10777
|
+
console.log(` ${chalk50.cyan(framework)}:`);
|
|
10518
10778
|
for (const provider of providers) {
|
|
10519
|
-
const defaultTag = provider.isDefault ?
|
|
10779
|
+
const defaultTag = provider.isDefault ? chalk50.green(" (default)") : "";
|
|
10520
10780
|
console.log(` ${provider.type}${defaultTag}`);
|
|
10521
10781
|
console.log(
|
|
10522
|
-
|
|
10782
|
+
chalk50.dim(
|
|
10523
10783
|
` Updated: ${new Date(provider.updatedAt).toLocaleString()}`
|
|
10524
10784
|
)
|
|
10525
10785
|
);
|
|
@@ -10527,17 +10787,17 @@ var listCommand7 = new Command51().name("list").alias("ls").description("List al
|
|
|
10527
10787
|
console.log();
|
|
10528
10788
|
}
|
|
10529
10789
|
console.log(
|
|
10530
|
-
|
|
10790
|
+
chalk50.dim(`Total: ${result.modelProviders.length} provider(s)`)
|
|
10531
10791
|
);
|
|
10532
10792
|
} catch (error) {
|
|
10533
10793
|
if (error instanceof Error) {
|
|
10534
10794
|
if (error.message.includes("Not authenticated")) {
|
|
10535
|
-
console.error(
|
|
10795
|
+
console.error(chalk50.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10536
10796
|
} else {
|
|
10537
|
-
console.error(
|
|
10797
|
+
console.error(chalk50.red(`\u2717 ${error.message}`));
|
|
10538
10798
|
}
|
|
10539
10799
|
} else {
|
|
10540
|
-
console.error(
|
|
10800
|
+
console.error(chalk50.red("\u2717 An unexpected error occurred"));
|
|
10541
10801
|
}
|
|
10542
10802
|
process.exit(1);
|
|
10543
10803
|
}
|
|
@@ -10545,7 +10805,7 @@ var listCommand7 = new Command51().name("list").alias("ls").description("List al
|
|
|
10545
10805
|
|
|
10546
10806
|
// src/commands/model-provider/setup.ts
|
|
10547
10807
|
import { Command as Command52 } from "commander";
|
|
10548
|
-
import
|
|
10808
|
+
import chalk51 from "chalk";
|
|
10549
10809
|
import prompts2 from "prompts";
|
|
10550
10810
|
var providerChoices = Object.entries(MODEL_PROVIDER_TYPES).map(
|
|
10551
10811
|
([type, config]) => ({
|
|
@@ -10564,11 +10824,11 @@ var setupCommand2 = new Command52().name("setup").description("Configure a model
|
|
|
10564
10824
|
const shouldConvert = options.convert ?? false;
|
|
10565
10825
|
if (options.type && options.credential) {
|
|
10566
10826
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(options.type)) {
|
|
10567
|
-
console.error(
|
|
10827
|
+
console.error(chalk51.red(`\u2717 Invalid type "${options.type}"`));
|
|
10568
10828
|
console.log();
|
|
10569
10829
|
console.log("Valid types:");
|
|
10570
10830
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
10571
|
-
console.log(` ${
|
|
10831
|
+
console.log(` ${chalk51.cyan(t)} - ${config.label}`);
|
|
10572
10832
|
}
|
|
10573
10833
|
process.exit(1);
|
|
10574
10834
|
}
|
|
@@ -10576,16 +10836,16 @@ var setupCommand2 = new Command52().name("setup").description("Configure a model
|
|
|
10576
10836
|
credential = options.credential;
|
|
10577
10837
|
} else if (options.type || options.credential) {
|
|
10578
10838
|
console.error(
|
|
10579
|
-
|
|
10839
|
+
chalk51.red("\u2717 Both --type and --credential are required")
|
|
10580
10840
|
);
|
|
10581
10841
|
process.exit(1);
|
|
10582
10842
|
} else {
|
|
10583
10843
|
if (!isInteractive()) {
|
|
10584
|
-
console.error(
|
|
10844
|
+
console.error(chalk51.red("\u2717 Interactive mode requires a TTY"));
|
|
10585
10845
|
console.log();
|
|
10586
10846
|
console.log("Use non-interactive mode:");
|
|
10587
10847
|
console.log(
|
|
10588
|
-
|
|
10848
|
+
chalk51.cyan(
|
|
10589
10849
|
' vm0 model-provider setup --type <type> --credential "<value>"'
|
|
10590
10850
|
)
|
|
10591
10851
|
);
|
|
@@ -10616,19 +10876,19 @@ var setupCommand2 = new Command52().name("setup").description("Configure a model
|
|
|
10616
10876
|
const provider2 = await convertModelProviderCredential(type);
|
|
10617
10877
|
const defaultNote2 = provider2.isDefault ? ` (default for ${provider2.framework})` : "";
|
|
10618
10878
|
console.log(
|
|
10619
|
-
|
|
10879
|
+
chalk51.green(
|
|
10620
10880
|
`\u2713 Converted "${checkResult.credentialName}" to model provider${defaultNote2}`
|
|
10621
10881
|
)
|
|
10622
10882
|
);
|
|
10623
10883
|
return;
|
|
10624
10884
|
} else {
|
|
10625
|
-
console.log(
|
|
10885
|
+
console.log(chalk51.dim("Aborted"));
|
|
10626
10886
|
process.exit(0);
|
|
10627
10887
|
}
|
|
10628
10888
|
}
|
|
10629
10889
|
const config = MODEL_PROVIDER_TYPES[type];
|
|
10630
10890
|
console.log();
|
|
10631
|
-
console.log(
|
|
10891
|
+
console.log(chalk51.dim(config.helpText));
|
|
10632
10892
|
console.log();
|
|
10633
10893
|
const credentialResponse = await prompts2(
|
|
10634
10894
|
{
|
|
@@ -10649,24 +10909,24 @@ var setupCommand2 = new Command52().name("setup").description("Configure a model
|
|
|
10649
10909
|
const action = created ? "created" : "updated";
|
|
10650
10910
|
const defaultNote = provider.isDefault ? ` (default for ${provider.framework})` : "";
|
|
10651
10911
|
console.log(
|
|
10652
|
-
|
|
10912
|
+
chalk51.green(`\u2713 Model provider "${type}" ${action}${defaultNote}`)
|
|
10653
10913
|
);
|
|
10654
10914
|
} catch (error) {
|
|
10655
10915
|
if (error instanceof Error) {
|
|
10656
10916
|
if (error.message.includes("already exists")) {
|
|
10657
|
-
console.error(
|
|
10917
|
+
console.error(chalk51.red(`\u2717 ${error.message}`));
|
|
10658
10918
|
console.log();
|
|
10659
10919
|
console.log("To convert the existing credential, run:");
|
|
10660
|
-
console.log(
|
|
10920
|
+
console.log(chalk51.cyan(" vm0 model-provider setup --convert"));
|
|
10661
10921
|
} else if (error.message.includes("Not authenticated")) {
|
|
10662
10922
|
console.error(
|
|
10663
|
-
|
|
10923
|
+
chalk51.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
10664
10924
|
);
|
|
10665
10925
|
} else {
|
|
10666
|
-
console.error(
|
|
10926
|
+
console.error(chalk51.red(`\u2717 ${error.message}`));
|
|
10667
10927
|
}
|
|
10668
10928
|
} else {
|
|
10669
|
-
console.error(
|
|
10929
|
+
console.error(chalk51.red("\u2717 An unexpected error occurred"));
|
|
10670
10930
|
}
|
|
10671
10931
|
process.exit(1);
|
|
10672
10932
|
}
|
|
@@ -10675,31 +10935,31 @@ var setupCommand2 = new Command52().name("setup").description("Configure a model
|
|
|
10675
10935
|
|
|
10676
10936
|
// src/commands/model-provider/delete.ts
|
|
10677
10937
|
import { Command as Command53 } from "commander";
|
|
10678
|
-
import
|
|
10938
|
+
import chalk52 from "chalk";
|
|
10679
10939
|
var deleteCommand3 = new Command53().name("delete").description("Delete a model provider").argument("<type>", "Model provider type to delete").action(async (type) => {
|
|
10680
10940
|
try {
|
|
10681
10941
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(type)) {
|
|
10682
|
-
console.error(
|
|
10942
|
+
console.error(chalk52.red(`\u2717 Invalid type "${type}"`));
|
|
10683
10943
|
console.log();
|
|
10684
10944
|
console.log("Valid types:");
|
|
10685
10945
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
10686
|
-
console.log(` ${
|
|
10946
|
+
console.log(` ${chalk52.cyan(t)} - ${config.label}`);
|
|
10687
10947
|
}
|
|
10688
10948
|
process.exit(1);
|
|
10689
10949
|
}
|
|
10690
10950
|
await deleteModelProvider(type);
|
|
10691
|
-
console.log(
|
|
10951
|
+
console.log(chalk52.green(`\u2713 Model provider "${type}" deleted`));
|
|
10692
10952
|
} catch (error) {
|
|
10693
10953
|
if (error instanceof Error) {
|
|
10694
10954
|
if (error.message.includes("not found")) {
|
|
10695
|
-
console.error(
|
|
10955
|
+
console.error(chalk52.red(`\u2717 Model provider "${type}" not found`));
|
|
10696
10956
|
} else if (error.message.includes("Not authenticated")) {
|
|
10697
|
-
console.error(
|
|
10957
|
+
console.error(chalk52.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10698
10958
|
} else {
|
|
10699
|
-
console.error(
|
|
10959
|
+
console.error(chalk52.red(`\u2717 ${error.message}`));
|
|
10700
10960
|
}
|
|
10701
10961
|
} else {
|
|
10702
|
-
console.error(
|
|
10962
|
+
console.error(chalk52.red("\u2717 An unexpected error occurred"));
|
|
10703
10963
|
}
|
|
10704
10964
|
process.exit(1);
|
|
10705
10965
|
}
|
|
@@ -10707,35 +10967,35 @@ var deleteCommand3 = new Command53().name("delete").description("Delete a model
|
|
|
10707
10967
|
|
|
10708
10968
|
// src/commands/model-provider/set-default.ts
|
|
10709
10969
|
import { Command as Command54 } from "commander";
|
|
10710
|
-
import
|
|
10970
|
+
import chalk53 from "chalk";
|
|
10711
10971
|
var setDefaultCommand = new Command54().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) => {
|
|
10712
10972
|
try {
|
|
10713
10973
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(type)) {
|
|
10714
|
-
console.error(
|
|
10974
|
+
console.error(chalk53.red(`\u2717 Invalid type "${type}"`));
|
|
10715
10975
|
console.log();
|
|
10716
10976
|
console.log("Valid types:");
|
|
10717
10977
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
10718
|
-
console.log(` ${
|
|
10978
|
+
console.log(` ${chalk53.cyan(t)} - ${config.label}`);
|
|
10719
10979
|
}
|
|
10720
10980
|
process.exit(1);
|
|
10721
10981
|
}
|
|
10722
10982
|
const provider = await setModelProviderDefault(type);
|
|
10723
10983
|
console.log(
|
|
10724
|
-
|
|
10984
|
+
chalk53.green(
|
|
10725
10985
|
`\u2713 Default for ${provider.framework} set to "${provider.type}"`
|
|
10726
10986
|
)
|
|
10727
10987
|
);
|
|
10728
10988
|
} catch (error) {
|
|
10729
10989
|
if (error instanceof Error) {
|
|
10730
10990
|
if (error.message.includes("not found")) {
|
|
10731
|
-
console.error(
|
|
10991
|
+
console.error(chalk53.red(`\u2717 Model provider "${type}" not found`));
|
|
10732
10992
|
} else if (error.message.includes("Not authenticated")) {
|
|
10733
|
-
console.error(
|
|
10993
|
+
console.error(chalk53.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10734
10994
|
} else {
|
|
10735
|
-
console.error(
|
|
10995
|
+
console.error(chalk53.red(`\u2717 ${error.message}`));
|
|
10736
10996
|
}
|
|
10737
10997
|
} else {
|
|
10738
|
-
console.error(
|
|
10998
|
+
console.error(chalk53.red("\u2717 An unexpected error occurred"));
|
|
10739
10999
|
}
|
|
10740
11000
|
process.exit(1);
|
|
10741
11001
|
}
|
|
@@ -10746,24 +11006,24 @@ var modelProviderCommand = new Command55().name("model-provider").description("M
|
|
|
10746
11006
|
|
|
10747
11007
|
// src/commands/onboard/index.ts
|
|
10748
11008
|
import { Command as Command56 } from "commander";
|
|
10749
|
-
import
|
|
11009
|
+
import chalk57 from "chalk";
|
|
10750
11010
|
import { mkdir as mkdir7 } from "fs/promises";
|
|
10751
11011
|
import { existsSync as existsSync11 } from "fs";
|
|
10752
11012
|
|
|
10753
11013
|
// src/lib/ui/welcome-box.ts
|
|
10754
|
-
import
|
|
11014
|
+
import chalk54 from "chalk";
|
|
10755
11015
|
var gradientColors = [
|
|
10756
|
-
|
|
11016
|
+
chalk54.hex("#FFAB5E"),
|
|
10757
11017
|
// Line 1 - lightest
|
|
10758
|
-
|
|
11018
|
+
chalk54.hex("#FF9642"),
|
|
10759
11019
|
// Line 2
|
|
10760
|
-
|
|
11020
|
+
chalk54.hex("#FF8228"),
|
|
10761
11021
|
// Line 3
|
|
10762
|
-
|
|
11022
|
+
chalk54.hex("#FF6D0A"),
|
|
10763
11023
|
// Line 4
|
|
10764
|
-
|
|
11024
|
+
chalk54.hex("#E85D00"),
|
|
10765
11025
|
// Line 5
|
|
10766
|
-
|
|
11026
|
+
chalk54.hex("#CC4E00")
|
|
10767
11027
|
// Line 6 - darkest
|
|
10768
11028
|
];
|
|
10769
11029
|
var vm0LogoLines = [
|
|
@@ -10784,15 +11044,15 @@ function renderVm0Banner() {
|
|
|
10784
11044
|
}
|
|
10785
11045
|
function renderOnboardWelcome() {
|
|
10786
11046
|
renderVm0Banner();
|
|
10787
|
-
console.log(` ${
|
|
11047
|
+
console.log(` ${chalk54.bold("Welcome to VM0!")}`);
|
|
10788
11048
|
console.log(
|
|
10789
|
-
` ${
|
|
11049
|
+
` ${chalk54.dim("Build agentic workflows using natural language.")}`
|
|
10790
11050
|
);
|
|
10791
11051
|
console.log();
|
|
10792
11052
|
}
|
|
10793
11053
|
|
|
10794
11054
|
// src/lib/ui/step-runner.ts
|
|
10795
|
-
import
|
|
11055
|
+
import chalk55 from "chalk";
|
|
10796
11056
|
function createStepRunner(options = true) {
|
|
10797
11057
|
const opts = typeof options === "boolean" ? { interactive: options } : options;
|
|
10798
11058
|
const interactive = opts.interactive ?? true;
|
|
@@ -10807,25 +11067,25 @@ function createStepRunner(options = true) {
|
|
|
10807
11067
|
}
|
|
10808
11068
|
for (const [i, step] of completedSteps.entries()) {
|
|
10809
11069
|
if (step.failed) {
|
|
10810
|
-
console.log(
|
|
11070
|
+
console.log(chalk55.red(`\u2717 ${step.label}`));
|
|
10811
11071
|
} else {
|
|
10812
|
-
console.log(
|
|
11072
|
+
console.log(chalk55.green(`\u25CF ${step.label}`));
|
|
10813
11073
|
}
|
|
10814
11074
|
const isLastStep = i === completedSteps.length - 1;
|
|
10815
11075
|
if (!isLastStep || !isFinal) {
|
|
10816
|
-
console.log(
|
|
11076
|
+
console.log(chalk55.dim("\u2502"));
|
|
10817
11077
|
}
|
|
10818
11078
|
}
|
|
10819
11079
|
}
|
|
10820
11080
|
async function executeStep(label, fn, isFinal) {
|
|
10821
11081
|
let stepFailed = false;
|
|
10822
|
-
console.log(
|
|
11082
|
+
console.log(chalk55.yellow(`\u25CB ${label}`));
|
|
10823
11083
|
const ctx = {
|
|
10824
11084
|
connector() {
|
|
10825
|
-
console.log(
|
|
11085
|
+
console.log(chalk55.dim("\u2502"));
|
|
10826
11086
|
},
|
|
10827
11087
|
detail(message) {
|
|
10828
|
-
console.log(`${
|
|
11088
|
+
console.log(`${chalk55.dim("\u2502")} ${message}`);
|
|
10829
11089
|
},
|
|
10830
11090
|
async prompt(promptFn) {
|
|
10831
11091
|
return await promptFn();
|
|
@@ -10842,12 +11102,12 @@ function createStepRunner(options = true) {
|
|
|
10842
11102
|
redrawCompletedSteps(isFinal);
|
|
10843
11103
|
} else {
|
|
10844
11104
|
if (stepFailed) {
|
|
10845
|
-
console.log(
|
|
11105
|
+
console.log(chalk55.red(`\u2717 ${label}`));
|
|
10846
11106
|
} else {
|
|
10847
|
-
console.log(
|
|
11107
|
+
console.log(chalk55.green(`\u25CF ${label}`));
|
|
10848
11108
|
}
|
|
10849
11109
|
if (!isFinal) {
|
|
10850
|
-
console.log(
|
|
11110
|
+
console.log(chalk55.dim("\u2502"));
|
|
10851
11111
|
}
|
|
10852
11112
|
}
|
|
10853
11113
|
}
|
|
@@ -10993,7 +11253,7 @@ async function setupModelProvider(type, credential, options) {
|
|
|
10993
11253
|
|
|
10994
11254
|
// src/lib/domain/onboard/claude-setup.ts
|
|
10995
11255
|
import { spawn as spawn3 } from "child_process";
|
|
10996
|
-
import
|
|
11256
|
+
import chalk56 from "chalk";
|
|
10997
11257
|
var MARKETPLACE_NAME = "vm0-skills";
|
|
10998
11258
|
var MARKETPLACE_REPO = "vm0-ai/vm0-skills";
|
|
10999
11259
|
var PLUGIN_ID = "vm0@vm0-skills";
|
|
@@ -11031,12 +11291,12 @@ async function runClaudeCommand(args, cwd) {
|
|
|
11031
11291
|
}
|
|
11032
11292
|
function handlePluginError(error, context) {
|
|
11033
11293
|
const displayContext = context ?? "Claude plugin";
|
|
11034
|
-
console.error(
|
|
11294
|
+
console.error(chalk56.red(`Failed to install ${displayContext}`));
|
|
11035
11295
|
if (error instanceof Error) {
|
|
11036
|
-
console.error(
|
|
11296
|
+
console.error(chalk56.red(error.message));
|
|
11037
11297
|
}
|
|
11038
11298
|
console.error(
|
|
11039
|
-
|
|
11299
|
+
chalk56.dim("Please ensure Claude CLI is installed and accessible.")
|
|
11040
11300
|
);
|
|
11041
11301
|
process.exit(1);
|
|
11042
11302
|
}
|
|
@@ -11100,7 +11360,7 @@ async function handleAuthentication(ctx) {
|
|
|
11100
11360
|
return;
|
|
11101
11361
|
}
|
|
11102
11362
|
if (!ctx.interactive) {
|
|
11103
|
-
console.error(
|
|
11363
|
+
console.error(chalk57.red("Error: Not authenticated"));
|
|
11104
11364
|
console.error("Run 'vm0 auth login' first or set VM0_TOKEN");
|
|
11105
11365
|
process.exit(1);
|
|
11106
11366
|
}
|
|
@@ -11108,16 +11368,16 @@ async function handleAuthentication(ctx) {
|
|
|
11108
11368
|
onInitiating: () => {
|
|
11109
11369
|
},
|
|
11110
11370
|
onDeviceCodeReady: (url, code, expiresIn) => {
|
|
11111
|
-
step.detail(`Copy code: ${
|
|
11112
|
-
step.detail(`Open: ${
|
|
11113
|
-
step.detail(
|
|
11371
|
+
step.detail(`Copy code: ${chalk57.cyan.bold(code)}`);
|
|
11372
|
+
step.detail(`Open: ${chalk57.cyan(url)}`);
|
|
11373
|
+
step.detail(chalk57.dim(`Expires in ${expiresIn} minutes`));
|
|
11114
11374
|
},
|
|
11115
11375
|
onPolling: () => {
|
|
11116
11376
|
},
|
|
11117
11377
|
onSuccess: () => {
|
|
11118
11378
|
},
|
|
11119
11379
|
onError: (error) => {
|
|
11120
|
-
console.error(
|
|
11380
|
+
console.error(chalk57.red(`
|
|
11121
11381
|
${error.message}`));
|
|
11122
11382
|
process.exit(1);
|
|
11123
11383
|
}
|
|
@@ -11131,7 +11391,7 @@ async function handleModelProvider(ctx) {
|
|
|
11131
11391
|
return;
|
|
11132
11392
|
}
|
|
11133
11393
|
if (!ctx.interactive) {
|
|
11134
|
-
console.error(
|
|
11394
|
+
console.error(chalk57.red("Error: No model provider configured"));
|
|
11135
11395
|
console.error("Run 'vm0 model-provider setup' first");
|
|
11136
11396
|
process.exit(1);
|
|
11137
11397
|
}
|
|
@@ -11152,7 +11412,7 @@ async function handleModelProvider(ctx) {
|
|
|
11152
11412
|
const selectedChoice = choices.find((c20) => c20.type === providerType);
|
|
11153
11413
|
if (selectedChoice?.helpText) {
|
|
11154
11414
|
for (const line of selectedChoice.helpText.split("\n")) {
|
|
11155
|
-
step.detail(
|
|
11415
|
+
step.detail(chalk57.dim(line));
|
|
11156
11416
|
}
|
|
11157
11417
|
}
|
|
11158
11418
|
const credential = await step.prompt(
|
|
@@ -11161,12 +11421,12 @@ async function handleModelProvider(ctx) {
|
|
|
11161
11421
|
)
|
|
11162
11422
|
);
|
|
11163
11423
|
if (!credential) {
|
|
11164
|
-
console.log(
|
|
11424
|
+
console.log(chalk57.dim("Cancelled"));
|
|
11165
11425
|
process.exit(0);
|
|
11166
11426
|
}
|
|
11167
11427
|
const result = await setupModelProvider(providerType, credential);
|
|
11168
11428
|
step.detail(
|
|
11169
|
-
|
|
11429
|
+
chalk57.green(
|
|
11170
11430
|
`${providerType} ${result.created ? "created" : "updated"}${result.isDefault ? ` (default for ${result.framework})` : ""}`
|
|
11171
11431
|
)
|
|
11172
11432
|
);
|
|
@@ -11197,7 +11457,7 @@ async function handleAgentCreation(ctx) {
|
|
|
11197
11457
|
agentName = inputName;
|
|
11198
11458
|
if (existsSync11(agentName)) {
|
|
11199
11459
|
step.detail(
|
|
11200
|
-
|
|
11460
|
+
chalk57.yellow(`${agentName}/ already exists, choose another name`)
|
|
11201
11461
|
);
|
|
11202
11462
|
} else {
|
|
11203
11463
|
folderExists = false;
|
|
@@ -11206,22 +11466,22 @@ async function handleAgentCreation(ctx) {
|
|
|
11206
11466
|
} else {
|
|
11207
11467
|
if (!validateAgentName(agentName)) {
|
|
11208
11468
|
console.error(
|
|
11209
|
-
|
|
11469
|
+
chalk57.red(
|
|
11210
11470
|
"Invalid agent name: must be 3-64 chars, alphanumeric + hyphens"
|
|
11211
11471
|
)
|
|
11212
11472
|
);
|
|
11213
11473
|
process.exit(1);
|
|
11214
11474
|
}
|
|
11215
11475
|
if (existsSync11(agentName)) {
|
|
11216
|
-
console.error(
|
|
11476
|
+
console.error(chalk57.red(`${agentName}/ already exists`));
|
|
11217
11477
|
console.log();
|
|
11218
11478
|
console.log("Remove it first or choose a different name:");
|
|
11219
|
-
console.log(
|
|
11479
|
+
console.log(chalk57.cyan(` rm -rf ${agentName}`));
|
|
11220
11480
|
process.exit(1);
|
|
11221
11481
|
}
|
|
11222
11482
|
}
|
|
11223
11483
|
await mkdir7(agentName, { recursive: true });
|
|
11224
|
-
step.detail(
|
|
11484
|
+
step.detail(chalk57.green(`Created ${agentName}/`));
|
|
11225
11485
|
});
|
|
11226
11486
|
return agentName;
|
|
11227
11487
|
}
|
|
@@ -11237,7 +11497,7 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
11237
11497
|
shouldInstall = confirmed ?? true;
|
|
11238
11498
|
}
|
|
11239
11499
|
if (!shouldInstall) {
|
|
11240
|
-
step.detail(
|
|
11500
|
+
step.detail(chalk57.dim("Skipped"));
|
|
11241
11501
|
return;
|
|
11242
11502
|
}
|
|
11243
11503
|
const scope = "project";
|
|
@@ -11245,7 +11505,7 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
11245
11505
|
const agentDir = `${process.cwd()}/${agentName}`;
|
|
11246
11506
|
const result = await installVm0Plugin(scope, agentDir);
|
|
11247
11507
|
step.detail(
|
|
11248
|
-
|
|
11508
|
+
chalk57.green(`Installed ${result.pluginId} (scope: ${result.scope})`)
|
|
11249
11509
|
);
|
|
11250
11510
|
pluginInstalled = true;
|
|
11251
11511
|
} catch (error) {
|
|
@@ -11256,14 +11516,14 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
11256
11516
|
}
|
|
11257
11517
|
function printNextSteps(agentName, pluginInstalled) {
|
|
11258
11518
|
console.log();
|
|
11259
|
-
console.log(
|
|
11519
|
+
console.log(chalk57.bold("Next step:"));
|
|
11260
11520
|
console.log();
|
|
11261
11521
|
if (pluginInstalled) {
|
|
11262
11522
|
console.log(
|
|
11263
|
-
` ${
|
|
11523
|
+
` ${chalk57.cyan(`cd ${agentName} && claude "/${PRIMARY_SKILL_NAME} let's build an agent"`)}`
|
|
11264
11524
|
);
|
|
11265
11525
|
} else {
|
|
11266
|
-
console.log(` ${
|
|
11526
|
+
console.log(` ${chalk57.cyan(`cd ${agentName} && vm0 init`)}`);
|
|
11267
11527
|
}
|
|
11268
11528
|
console.log();
|
|
11269
11529
|
}
|
|
@@ -11291,14 +11551,14 @@ var onboardCommand = new Command56().name("onboard").description("Guided setup f
|
|
|
11291
11551
|
|
|
11292
11552
|
// src/commands/setup-claude/index.ts
|
|
11293
11553
|
import { Command as Command57 } from "commander";
|
|
11294
|
-
import
|
|
11554
|
+
import chalk58 from "chalk";
|
|
11295
11555
|
var setupClaudeCommand = new Command57().name("setup-claude").description("Install VM0 Claude Plugin").option("--agent-dir <dir>", "Agent directory to run install in").option("--scope <scope>", "Installation scope (user or project)", "project").action(async (options) => {
|
|
11296
|
-
console.log(
|
|
11556
|
+
console.log(chalk58.dim("Installing VM0 Claude Plugin..."));
|
|
11297
11557
|
const scope = options.scope === "user" ? "user" : "project";
|
|
11298
11558
|
try {
|
|
11299
11559
|
const result = await installVm0Plugin(scope, options.agentDir);
|
|
11300
11560
|
console.log(
|
|
11301
|
-
|
|
11561
|
+
chalk58.green(`\u2713 Installed ${result.pluginId} (scope: ${result.scope})`)
|
|
11302
11562
|
);
|
|
11303
11563
|
} catch (error) {
|
|
11304
11564
|
handlePluginError(error);
|
|
@@ -11307,7 +11567,7 @@ var setupClaudeCommand = new Command57().name("setup-claude").description("Insta
|
|
|
11307
11567
|
console.log("Next step:");
|
|
11308
11568
|
const cdPrefix = options.agentDir ? `cd ${options.agentDir} && ` : "";
|
|
11309
11569
|
console.log(
|
|
11310
|
-
|
|
11570
|
+
chalk58.cyan(
|
|
11311
11571
|
` ${cdPrefix}claude "/${PRIMARY_SKILL_NAME} let's build a workflow"`
|
|
11312
11572
|
)
|
|
11313
11573
|
);
|
|
@@ -11315,7 +11575,7 @@ var setupClaudeCommand = new Command57().name("setup-claude").description("Insta
|
|
|
11315
11575
|
|
|
11316
11576
|
// src/index.ts
|
|
11317
11577
|
var program = new Command58();
|
|
11318
|
-
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.
|
|
11578
|
+
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.7.0");
|
|
11319
11579
|
program.addCommand(authCommand);
|
|
11320
11580
|
program.addCommand(infoCommand);
|
|
11321
11581
|
program.addCommand(composeCommand);
|