@vm0/cli 9.85.2 → 9.86.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/{chunk-HODD5NE4.js → chunk-MAYVCUG7.js} +803 -11
- package/chunk-MAYVCUG7.js.map +1 -0
- package/index.js +253 -993
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/zero.js +320 -138
- package/zero.js.map +1 -1
- package/chunk-HODD5NE4.js.map +0 -1
package/index.js
CHANGED
|
@@ -2,15 +2,21 @@
|
|
|
2
2
|
import {
|
|
3
3
|
ALL_RUN_STATUSES,
|
|
4
4
|
ApiRequestError,
|
|
5
|
+
ClaudeEventParser,
|
|
6
|
+
EventRenderer,
|
|
5
7
|
agentDefinitionSchema,
|
|
6
8
|
cancelRun,
|
|
7
9
|
clearConfig,
|
|
10
|
+
collectKeyValue,
|
|
11
|
+
collectVolumeVersions,
|
|
8
12
|
commitStorage,
|
|
9
13
|
configureGlobalProxyFromEnv,
|
|
10
14
|
createOrUpdateCompose,
|
|
11
15
|
createRun,
|
|
12
16
|
expandFirewallConfigs,
|
|
13
17
|
extractAndGroupVariables,
|
|
18
|
+
extractSecretNames,
|
|
19
|
+
extractVarNames,
|
|
14
20
|
getActiveOrg,
|
|
15
21
|
getAgentEvents,
|
|
16
22
|
getApiUrl,
|
|
@@ -18,8 +24,6 @@ import {
|
|
|
18
24
|
getComposeById,
|
|
19
25
|
getComposeByName,
|
|
20
26
|
getComposeVersion,
|
|
21
|
-
getEvents,
|
|
22
|
-
getFrameworkDisplayName,
|
|
23
27
|
getInstructionsFilename,
|
|
24
28
|
getInstructionsStorageName,
|
|
25
29
|
getMetrics,
|
|
@@ -32,26 +36,31 @@ import {
|
|
|
32
36
|
getToken,
|
|
33
37
|
getZeroOrg,
|
|
34
38
|
isInteractive,
|
|
35
|
-
|
|
39
|
+
isUUID,
|
|
36
40
|
listRuns,
|
|
37
41
|
listStorages,
|
|
38
42
|
listZeroConnectors,
|
|
39
43
|
listZeroSecrets,
|
|
40
44
|
listZeroVariables,
|
|
41
45
|
loadConfig,
|
|
46
|
+
loadValues,
|
|
42
47
|
parseGitHubTreeUrl,
|
|
43
48
|
parseGitHubUrl,
|
|
49
|
+
parseIdentifier,
|
|
44
50
|
parseSkillFrontmatter,
|
|
51
|
+
pollEvents,
|
|
45
52
|
prepareStorage,
|
|
46
53
|
promptConfirm,
|
|
47
54
|
promptText,
|
|
55
|
+
renderRunCreated,
|
|
48
56
|
resolveSkillRef,
|
|
49
57
|
resolveSkills,
|
|
50
58
|
saveConfig,
|
|
51
59
|
searchLogs,
|
|
60
|
+
showNextSteps,
|
|
52
61
|
volumeConfigSchema,
|
|
53
62
|
withErrorHandler
|
|
54
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-MAYVCUG7.js";
|
|
55
64
|
|
|
56
65
|
// src/index.ts
|
|
57
66
|
import { Command as Command44 } from "commander";
|
|
@@ -436,7 +445,7 @@ function getConfigPath() {
|
|
|
436
445
|
return join(homedir(), ".vm0", "config.json");
|
|
437
446
|
}
|
|
438
447
|
var infoCommand = new Command6().name("info").description("Display environment and debug information").action(async () => {
|
|
439
|
-
console.log(chalk3.bold(`VM0 CLI v${"9.
|
|
448
|
+
console.log(chalk3.bold(`VM0 CLI v${"9.86.0"}`));
|
|
440
449
|
console.log();
|
|
441
450
|
const config = await loadConfig();
|
|
442
451
|
const hasEnvToken = !!process.env.VM0_TOKEN;
|
|
@@ -1540,7 +1549,7 @@ var composeCommand = new Command7().name("compose").description("Create or updat
|
|
|
1540
1549
|
options.autoUpdate = false;
|
|
1541
1550
|
}
|
|
1542
1551
|
if (options.autoUpdate !== false) {
|
|
1543
|
-
await startSilentUpgrade("9.
|
|
1552
|
+
await startSilentUpgrade("9.86.0");
|
|
1544
1553
|
}
|
|
1545
1554
|
try {
|
|
1546
1555
|
let result;
|
|
@@ -1568,755 +1577,6 @@ var composeCommand = new Command7().name("compose").description("Create or updat
|
|
|
1568
1577
|
|
|
1569
1578
|
// src/commands/run/run.ts
|
|
1570
1579
|
import { Command as Command8, Option as Option2 } from "commander";
|
|
1571
|
-
|
|
1572
|
-
// src/commands/run/shared.ts
|
|
1573
|
-
import chalk7 from "chalk";
|
|
1574
|
-
import * as fs6 from "fs";
|
|
1575
|
-
import { config as dotenvConfig } from "dotenv";
|
|
1576
|
-
|
|
1577
|
-
// src/lib/events/claude-event-parser.ts
|
|
1578
|
-
var ClaudeEventParser = class {
|
|
1579
|
-
/**
|
|
1580
|
-
* Parse a raw Claude Code JSONL event into a simplified format
|
|
1581
|
-
* Returns null if the event type is unknown or malformed
|
|
1582
|
-
*/
|
|
1583
|
-
static parse(rawEvent) {
|
|
1584
|
-
if (!rawEvent || typeof rawEvent !== "object" || !("type" in rawEvent)) {
|
|
1585
|
-
return null;
|
|
1586
|
-
}
|
|
1587
|
-
switch (rawEvent.type) {
|
|
1588
|
-
case "system":
|
|
1589
|
-
return this.parseSystemEvent(rawEvent);
|
|
1590
|
-
case "assistant":
|
|
1591
|
-
return this.parseAssistantMessage(rawEvent);
|
|
1592
|
-
case "user":
|
|
1593
|
-
return this.parseUserMessage(rawEvent);
|
|
1594
|
-
case "result":
|
|
1595
|
-
return this.parseResultEvent(rawEvent);
|
|
1596
|
-
default:
|
|
1597
|
-
return null;
|
|
1598
|
-
}
|
|
1599
|
-
}
|
|
1600
|
-
static parseSystemEvent(event) {
|
|
1601
|
-
if (event.subtype !== "init") {
|
|
1602
|
-
return null;
|
|
1603
|
-
}
|
|
1604
|
-
return {
|
|
1605
|
-
type: "init",
|
|
1606
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
1607
|
-
data: {
|
|
1608
|
-
framework: "claude-code",
|
|
1609
|
-
sessionId: event.session_id,
|
|
1610
|
-
model: event.model,
|
|
1611
|
-
tools: event.tools,
|
|
1612
|
-
...event.cwd && { cwd: event.cwd }
|
|
1613
|
-
}
|
|
1614
|
-
};
|
|
1615
|
-
}
|
|
1616
|
-
static parseAssistantMessage(event) {
|
|
1617
|
-
if (!event.message?.content || event.message.content.length === 0) {
|
|
1618
|
-
return null;
|
|
1619
|
-
}
|
|
1620
|
-
const content = event.message.content[0];
|
|
1621
|
-
if (!content) {
|
|
1622
|
-
return null;
|
|
1623
|
-
}
|
|
1624
|
-
if (content.type === "text") {
|
|
1625
|
-
return {
|
|
1626
|
-
type: "text",
|
|
1627
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
1628
|
-
data: { text: content.text }
|
|
1629
|
-
};
|
|
1630
|
-
}
|
|
1631
|
-
if (content.type === "tool_use") {
|
|
1632
|
-
return {
|
|
1633
|
-
type: "tool_use",
|
|
1634
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
1635
|
-
data: {
|
|
1636
|
-
tool: content.name,
|
|
1637
|
-
toolUseId: content.id,
|
|
1638
|
-
input: content.input || {}
|
|
1639
|
-
}
|
|
1640
|
-
};
|
|
1641
|
-
}
|
|
1642
|
-
return null;
|
|
1643
|
-
}
|
|
1644
|
-
static parseUserMessage(event) {
|
|
1645
|
-
if (!event.message?.content || event.message.content.length === 0) {
|
|
1646
|
-
return null;
|
|
1647
|
-
}
|
|
1648
|
-
const content = event.message.content[0];
|
|
1649
|
-
if (!content) {
|
|
1650
|
-
return null;
|
|
1651
|
-
}
|
|
1652
|
-
if (content.type === "tool_result") {
|
|
1653
|
-
return {
|
|
1654
|
-
type: "tool_result",
|
|
1655
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
1656
|
-
data: {
|
|
1657
|
-
toolUseId: content.tool_use_id,
|
|
1658
|
-
result: content.content,
|
|
1659
|
-
isError: content.is_error || false
|
|
1660
|
-
}
|
|
1661
|
-
};
|
|
1662
|
-
}
|
|
1663
|
-
return null;
|
|
1664
|
-
}
|
|
1665
|
-
static parseResultEvent(event) {
|
|
1666
|
-
return {
|
|
1667
|
-
type: "result",
|
|
1668
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
1669
|
-
data: {
|
|
1670
|
-
success: !event.is_error,
|
|
1671
|
-
result: event.result,
|
|
1672
|
-
durationMs: event.duration_ms,
|
|
1673
|
-
numTurns: event.num_turns,
|
|
1674
|
-
cost: event.total_cost_usd,
|
|
1675
|
-
usage: event.usage
|
|
1676
|
-
}
|
|
1677
|
-
};
|
|
1678
|
-
}
|
|
1679
|
-
};
|
|
1680
|
-
|
|
1681
|
-
// src/lib/events/event-parser-factory.ts
|
|
1682
|
-
function parseEvent(rawEvent) {
|
|
1683
|
-
return ClaudeEventParser.parse(rawEvent);
|
|
1684
|
-
}
|
|
1685
|
-
|
|
1686
|
-
// src/lib/events/event-renderer.ts
|
|
1687
|
-
import chalk6 from "chalk";
|
|
1688
|
-
|
|
1689
|
-
// src/lib/events/tool-formatters.ts
|
|
1690
|
-
import chalk5 from "chalk";
|
|
1691
|
-
function pluralize(count, singular, plural) {
|
|
1692
|
-
return count === 1 ? singular : plural;
|
|
1693
|
-
}
|
|
1694
|
-
function truncate(text, maxLength) {
|
|
1695
|
-
if (text.length <= maxLength) return text;
|
|
1696
|
-
return text.slice(0, maxLength - 3) + "...";
|
|
1697
|
-
}
|
|
1698
|
-
function formatToolHeader(data) {
|
|
1699
|
-
const { tool, input } = data;
|
|
1700
|
-
const headline = getToolHeadline(tool, input);
|
|
1701
|
-
return [headline];
|
|
1702
|
-
}
|
|
1703
|
-
var toolHeadlineFormatters = {
|
|
1704
|
-
Read: (input) => `Read${chalk5.dim(`(${String(input.file_path || "")})`)}`,
|
|
1705
|
-
Edit: (input) => `Edit${chalk5.dim(`(${String(input.file_path || "")})`)}`,
|
|
1706
|
-
Write: (input) => `Write${chalk5.dim(`(${String(input.file_path || "")})`)}`,
|
|
1707
|
-
Bash: (input) => `Bash${chalk5.dim(`(${truncate(String(input.command || ""), 60)})`)}`,
|
|
1708
|
-
Glob: (input) => `Glob${chalk5.dim(`(${String(input.pattern || "")})`)}`,
|
|
1709
|
-
Grep: (input) => `Grep${chalk5.dim(`(${String(input.pattern || "")})`)}`,
|
|
1710
|
-
Task: (input) => `Task${chalk5.dim(`(${truncate(String(input.description || ""), 60)})`)}`,
|
|
1711
|
-
WebFetch: (input) => `WebFetch${chalk5.dim(`(${truncate(String(input.url || ""), 60)})`)}`,
|
|
1712
|
-
WebSearch: (input) => `WebSearch${chalk5.dim(`(${truncate(String(input.query || ""), 60)})`)}`,
|
|
1713
|
-
TodoWrite: () => "TodoWrite"
|
|
1714
|
-
};
|
|
1715
|
-
function getToolHeadline(tool, input) {
|
|
1716
|
-
const formatter = toolHeadlineFormatters[tool];
|
|
1717
|
-
return formatter ? formatter(input) : tool;
|
|
1718
|
-
}
|
|
1719
|
-
function formatToolResult(toolUse, result, verbose) {
|
|
1720
|
-
const { tool, input } = toolUse;
|
|
1721
|
-
const { result: resultText, isError } = result;
|
|
1722
|
-
const lines = [];
|
|
1723
|
-
if (tool === "Read" && !isError && resultText) {
|
|
1724
|
-
const readLines = formatReadContent(resultText, verbose);
|
|
1725
|
-
lines.push(...readLines);
|
|
1726
|
-
return lines;
|
|
1727
|
-
}
|
|
1728
|
-
if (tool === "TodoWrite" && !isError) {
|
|
1729
|
-
const todoLines = formatTodoList(input);
|
|
1730
|
-
lines.push(...todoLines);
|
|
1731
|
-
return lines;
|
|
1732
|
-
}
|
|
1733
|
-
if (tool === "Edit" && !isError) {
|
|
1734
|
-
const editLines = formatEditDiff(input, verbose);
|
|
1735
|
-
lines.push(...editLines);
|
|
1736
|
-
return lines;
|
|
1737
|
-
}
|
|
1738
|
-
if (tool === "Write" && !isError) {
|
|
1739
|
-
const writeLines = formatWritePreview(input, verbose);
|
|
1740
|
-
lines.push(...writeLines);
|
|
1741
|
-
return lines;
|
|
1742
|
-
}
|
|
1743
|
-
if (isError) {
|
|
1744
|
-
const errorMsg = resultText ? truncate(resultText, 80) : "Error";
|
|
1745
|
-
lines.push(`\u2514 \u2717 ${chalk5.dim(errorMsg)}`);
|
|
1746
|
-
return lines;
|
|
1747
|
-
}
|
|
1748
|
-
if (resultText) {
|
|
1749
|
-
const resultLines = resultText.split("\n");
|
|
1750
|
-
if (verbose) {
|
|
1751
|
-
for (let i = 0; i < resultLines.length; i++) {
|
|
1752
|
-
const prefix = i === 0 ? "\u2514 " : " ";
|
|
1753
|
-
lines.push(`${prefix}${chalk5.dim(resultLines[i])}`);
|
|
1754
|
-
}
|
|
1755
|
-
} else if (resultLines.length > 0) {
|
|
1756
|
-
const previewCount = Math.min(3, resultLines.length);
|
|
1757
|
-
for (let i = 0; i < previewCount; i++) {
|
|
1758
|
-
const prefix = i === 0 ? "\u2514 " : " ";
|
|
1759
|
-
lines.push(`${prefix}${chalk5.dim(resultLines[i])}`);
|
|
1760
|
-
}
|
|
1761
|
-
const remaining = resultLines.length - previewCount;
|
|
1762
|
-
if (remaining > 0) {
|
|
1763
|
-
lines.push(
|
|
1764
|
-
` ${chalk5.dim(`\u2026 +${remaining} ${pluralize(remaining, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
1765
|
-
);
|
|
1766
|
-
}
|
|
1767
|
-
}
|
|
1768
|
-
} else {
|
|
1769
|
-
lines.push(`\u2514 \u2713 ${chalk5.dim("Done")}`);
|
|
1770
|
-
}
|
|
1771
|
-
return lines;
|
|
1772
|
-
}
|
|
1773
|
-
function formatReadContent(resultText, verbose) {
|
|
1774
|
-
const lines = [];
|
|
1775
|
-
const rawLines = resultText.split("\n");
|
|
1776
|
-
const contentLines = [];
|
|
1777
|
-
const lineNumberPattern = /^\s*\d+→(.*)$/;
|
|
1778
|
-
for (const line of rawLines) {
|
|
1779
|
-
const match = line.match(lineNumberPattern);
|
|
1780
|
-
if (match) {
|
|
1781
|
-
contentLines.push(match[1] ?? "");
|
|
1782
|
-
}
|
|
1783
|
-
}
|
|
1784
|
-
const displayLines = contentLines.length > 0 ? contentLines : rawLines.filter((line) => line.trim().length > 0);
|
|
1785
|
-
const totalLines = displayLines.length;
|
|
1786
|
-
if (totalLines === 0) {
|
|
1787
|
-
lines.push(`\u2514 \u2713 ${chalk5.dim("(empty)")}`);
|
|
1788
|
-
return lines;
|
|
1789
|
-
}
|
|
1790
|
-
if (verbose) {
|
|
1791
|
-
for (let i = 0; i < displayLines.length; i++) {
|
|
1792
|
-
const prefix = i === 0 ? "\u2514 " : " ";
|
|
1793
|
-
lines.push(`${prefix}${chalk5.dim(displayLines[i] ?? "")}`);
|
|
1794
|
-
}
|
|
1795
|
-
} else {
|
|
1796
|
-
const previewCount = Math.min(3, totalLines);
|
|
1797
|
-
for (let i = 0; i < previewCount; i++) {
|
|
1798
|
-
const prefix = i === 0 ? "\u2514 " : " ";
|
|
1799
|
-
lines.push(`${prefix}${chalk5.dim(displayLines[i] ?? "")}`);
|
|
1800
|
-
}
|
|
1801
|
-
const remaining = totalLines - previewCount;
|
|
1802
|
-
if (remaining > 0) {
|
|
1803
|
-
lines.push(
|
|
1804
|
-
` ${chalk5.dim(`\u2026 +${remaining} ${pluralize(remaining, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
1805
|
-
);
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
1808
|
-
return lines;
|
|
1809
|
-
}
|
|
1810
|
-
function formatWritePreview(input, verbose) {
|
|
1811
|
-
const lines = [];
|
|
1812
|
-
const content = String(input.content || "");
|
|
1813
|
-
const contentLines = content.split("\n");
|
|
1814
|
-
const totalLines = contentLines.length;
|
|
1815
|
-
if (verbose) {
|
|
1816
|
-
for (let i = 0; i < contentLines.length; i++) {
|
|
1817
|
-
const prefix = i === 0 ? "\u23BF " : " ";
|
|
1818
|
-
lines.push(`${prefix}${chalk5.dim(contentLines[i] ?? "")}`);
|
|
1819
|
-
}
|
|
1820
|
-
} else {
|
|
1821
|
-
const previewCount = Math.min(3, totalLines);
|
|
1822
|
-
for (let i = 0; i < previewCount; i++) {
|
|
1823
|
-
const prefix = i === 0 ? "\u23BF " : " ";
|
|
1824
|
-
lines.push(`${prefix}${chalk5.dim(contentLines[i] ?? "")}`);
|
|
1825
|
-
}
|
|
1826
|
-
const remaining = totalLines - previewCount;
|
|
1827
|
-
if (remaining > 0) {
|
|
1828
|
-
lines.push(
|
|
1829
|
-
` ${chalk5.dim(`\u2026 +${remaining} ${pluralize(remaining, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
1830
|
-
);
|
|
1831
|
-
}
|
|
1832
|
-
}
|
|
1833
|
-
return lines;
|
|
1834
|
-
}
|
|
1835
|
-
function formatEditDiff(input, verbose) {
|
|
1836
|
-
const lines = [];
|
|
1837
|
-
const oldString = String(input.old_string || "");
|
|
1838
|
-
const newString = String(input.new_string || "");
|
|
1839
|
-
const oldLines = oldString.split("\n");
|
|
1840
|
-
const newLines = newString.split("\n");
|
|
1841
|
-
const removed = oldLines.length;
|
|
1842
|
-
const added = newLines.length;
|
|
1843
|
-
const summary = `Added ${added} ${pluralize(added, "line", "lines")}, removed ${removed} ${pluralize(removed, "line", "lines")}`;
|
|
1844
|
-
lines.push(`\u23BF ${chalk5.dim(summary)}`);
|
|
1845
|
-
if (verbose) {
|
|
1846
|
-
for (const line of oldLines) {
|
|
1847
|
-
lines.push(` - ${chalk5.dim(line)}`);
|
|
1848
|
-
}
|
|
1849
|
-
for (const line of newLines) {
|
|
1850
|
-
lines.push(` + ${chalk5.dim(line)}`);
|
|
1851
|
-
}
|
|
1852
|
-
} else {
|
|
1853
|
-
const previewLimit = 3;
|
|
1854
|
-
const showOld = Math.min(previewLimit, oldLines.length);
|
|
1855
|
-
const showNew = Math.min(previewLimit, newLines.length);
|
|
1856
|
-
for (let i = 0; i < showOld; i++) {
|
|
1857
|
-
lines.push(` - ${chalk5.dim(truncate(oldLines[i] ?? "", 60))}`);
|
|
1858
|
-
}
|
|
1859
|
-
const remainingOld = oldLines.length - previewLimit;
|
|
1860
|
-
if (remainingOld > 0) {
|
|
1861
|
-
lines.push(
|
|
1862
|
-
` ${chalk5.dim(`\u2026 +${remainingOld} ${pluralize(remainingOld, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
1863
|
-
);
|
|
1864
|
-
}
|
|
1865
|
-
for (let i = 0; i < showNew; i++) {
|
|
1866
|
-
lines.push(` + ${chalk5.dim(truncate(newLines[i] ?? "", 60))}`);
|
|
1867
|
-
}
|
|
1868
|
-
const remainingNew = newLines.length - previewLimit;
|
|
1869
|
-
if (remainingNew > 0) {
|
|
1870
|
-
lines.push(
|
|
1871
|
-
` ${chalk5.dim(`\u2026 +${remainingNew} ${pluralize(remainingNew, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
1872
|
-
);
|
|
1873
|
-
}
|
|
1874
|
-
}
|
|
1875
|
-
return lines;
|
|
1876
|
-
}
|
|
1877
|
-
function formatTodoList(input) {
|
|
1878
|
-
const lines = [];
|
|
1879
|
-
const todos = input.todos;
|
|
1880
|
-
if (!todos || !Array.isArray(todos)) {
|
|
1881
|
-
lines.push("\u2514 \u2713 Done");
|
|
1882
|
-
return lines;
|
|
1883
|
-
}
|
|
1884
|
-
for (let i = 0; i < todos.length; i++) {
|
|
1885
|
-
const todo = todos[i];
|
|
1886
|
-
const content = todo.content || "Unknown task";
|
|
1887
|
-
const status = todo.status || "pending";
|
|
1888
|
-
const icon = getTodoStatusIcon(status);
|
|
1889
|
-
const styledContent = formatTodoContent(content, status);
|
|
1890
|
-
const prefix = i === 0 ? "\u2514 " : " ";
|
|
1891
|
-
lines.push(`${prefix}${icon} ${styledContent}`);
|
|
1892
|
-
}
|
|
1893
|
-
return lines;
|
|
1894
|
-
}
|
|
1895
|
-
function getTodoStatusIcon(status) {
|
|
1896
|
-
switch (status) {
|
|
1897
|
-
case "completed":
|
|
1898
|
-
return "\u2713";
|
|
1899
|
-
case "in_progress":
|
|
1900
|
-
return "\u25B8";
|
|
1901
|
-
case "pending":
|
|
1902
|
-
default:
|
|
1903
|
-
return "\u25FB";
|
|
1904
|
-
}
|
|
1905
|
-
}
|
|
1906
|
-
function formatTodoContent(content, status) {
|
|
1907
|
-
switch (status) {
|
|
1908
|
-
case "completed":
|
|
1909
|
-
return chalk5.dim.strikethrough(content);
|
|
1910
|
-
case "in_progress":
|
|
1911
|
-
return content;
|
|
1912
|
-
case "pending":
|
|
1913
|
-
default:
|
|
1914
|
-
return chalk5.dim(content);
|
|
1915
|
-
}
|
|
1916
|
-
}
|
|
1917
|
-
|
|
1918
|
-
// src/lib/events/event-renderer.ts
|
|
1919
|
-
var EventRenderer = class _EventRenderer {
|
|
1920
|
-
pendingToolUse = /* @__PURE__ */ new Map();
|
|
1921
|
-
options;
|
|
1922
|
-
lastEventType = null;
|
|
1923
|
-
frameworkDisplayName = "Agent";
|
|
1924
|
-
constructor(options) {
|
|
1925
|
-
this.options = options ?? {};
|
|
1926
|
-
}
|
|
1927
|
-
/**
|
|
1928
|
-
* Render run started info
|
|
1929
|
-
* Called immediately after run is created, before polling events
|
|
1930
|
-
*/
|
|
1931
|
-
static renderRunStarted(info) {
|
|
1932
|
-
console.log(chalk6.bold("\u25B6 Run started"));
|
|
1933
|
-
console.log(` Run ID: ${chalk6.dim(info.runId)}`);
|
|
1934
|
-
if (info.sandboxId) {
|
|
1935
|
-
console.log(` Sandbox: ${chalk6.dim(info.sandboxId)}`);
|
|
1936
|
-
}
|
|
1937
|
-
console.log(chalk6.dim(` (use "vm0 logs ${info.runId}" to view logs)`));
|
|
1938
|
-
console.log();
|
|
1939
|
-
}
|
|
1940
|
-
/**
|
|
1941
|
-
* Format timestamp for display (without milliseconds, matching metrics format)
|
|
1942
|
-
*/
|
|
1943
|
-
static formatTimestamp(timestamp) {
|
|
1944
|
-
return timestamp.toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
1945
|
-
}
|
|
1946
|
-
/**
|
|
1947
|
-
* Render a parsed event to console
|
|
1948
|
-
*/
|
|
1949
|
-
render(event) {
|
|
1950
|
-
const timestampPrefix = this.options.showTimestamp ? `[${_EventRenderer.formatTimestamp(event.timestamp)}] ` : "";
|
|
1951
|
-
switch (event.type) {
|
|
1952
|
-
case "init":
|
|
1953
|
-
this.renderInit(event, timestampPrefix);
|
|
1954
|
-
break;
|
|
1955
|
-
case "text":
|
|
1956
|
-
this.renderText(event, timestampPrefix);
|
|
1957
|
-
break;
|
|
1958
|
-
case "tool_use":
|
|
1959
|
-
this.handleToolUse(event, timestampPrefix);
|
|
1960
|
-
break;
|
|
1961
|
-
case "tool_result":
|
|
1962
|
-
this.handleToolResult(event, timestampPrefix);
|
|
1963
|
-
break;
|
|
1964
|
-
case "result":
|
|
1965
|
-
this.renderResult(event, timestampPrefix);
|
|
1966
|
-
break;
|
|
1967
|
-
}
|
|
1968
|
-
}
|
|
1969
|
-
/**
|
|
1970
|
-
* Render run completed state
|
|
1971
|
-
* Note: This is run lifecycle status, not an event
|
|
1972
|
-
*/
|
|
1973
|
-
static renderRunCompleted(result) {
|
|
1974
|
-
console.log("");
|
|
1975
|
-
console.log(chalk6.green("\u2713 Run completed successfully"));
|
|
1976
|
-
if (result) {
|
|
1977
|
-
console.log(` Checkpoint: ${chalk6.dim(result.checkpointId)}`);
|
|
1978
|
-
console.log(` Session: ${chalk6.dim(result.agentSessionId)}`);
|
|
1979
|
-
console.log(` Conversation: ${chalk6.dim(result.conversationId)}`);
|
|
1980
|
-
if (result.artifact && Object.keys(result.artifact).length > 0) {
|
|
1981
|
-
console.log(` Artifact:`);
|
|
1982
|
-
for (const [name, version] of Object.entries(result.artifact)) {
|
|
1983
|
-
console.log(
|
|
1984
|
-
` ${name}: ${chalk6.dim(_EventRenderer.formatVersion(version))}`
|
|
1985
|
-
);
|
|
1986
|
-
}
|
|
1987
|
-
}
|
|
1988
|
-
if (result.volumes && Object.keys(result.volumes).length > 0) {
|
|
1989
|
-
console.log(` Volumes:`);
|
|
1990
|
-
for (const [name, version] of Object.entries(result.volumes)) {
|
|
1991
|
-
console.log(
|
|
1992
|
-
` ${name}: ${chalk6.dim(_EventRenderer.formatVersion(version))}`
|
|
1993
|
-
);
|
|
1994
|
-
}
|
|
1995
|
-
}
|
|
1996
|
-
}
|
|
1997
|
-
}
|
|
1998
|
-
/**
|
|
1999
|
-
* Render run failed state
|
|
2000
|
-
* Note: This is run lifecycle status, not an event
|
|
2001
|
-
*/
|
|
2002
|
-
static renderRunFailed(error, runId) {
|
|
2003
|
-
console.error("");
|
|
2004
|
-
console.error(chalk6.red("\u2717 Run failed"));
|
|
2005
|
-
console.error(` Error: ${chalk6.red(error || "Unknown error")}`);
|
|
2006
|
-
console.error(
|
|
2007
|
-
chalk6.dim(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
2008
|
-
);
|
|
2009
|
-
}
|
|
2010
|
-
/**
|
|
2011
|
-
* Handle tool_use event - buffer it for later grouping with result (when buffered)
|
|
2012
|
-
* or render immediately (when not buffered, e.g., historical log viewing)
|
|
2013
|
-
*/
|
|
2014
|
-
handleToolUse(event, prefix) {
|
|
2015
|
-
const toolUseId = String(event.data.toolUseId || "");
|
|
2016
|
-
const tool = String(event.data.tool || "");
|
|
2017
|
-
const input = event.data.input || {};
|
|
2018
|
-
const toolUseData = { tool, input };
|
|
2019
|
-
if (this.options.buffered !== false) {
|
|
2020
|
-
this.pendingToolUse.set(toolUseId, { toolUse: toolUseData, prefix });
|
|
2021
|
-
} else {
|
|
2022
|
-
this.renderToolUseOnly(toolUseData, prefix);
|
|
2023
|
-
}
|
|
2024
|
-
}
|
|
2025
|
-
/**
|
|
2026
|
-
* Render a tool_use event without waiting for result (for historical log viewing)
|
|
2027
|
-
*/
|
|
2028
|
-
renderToolUseOnly(toolUse, prefix) {
|
|
2029
|
-
if (this.lastEventType === "text") {
|
|
2030
|
-
console.log();
|
|
2031
|
-
}
|
|
2032
|
-
const cont = this.getContinuationPrefix();
|
|
2033
|
-
const headerLines = formatToolHeader(toolUse);
|
|
2034
|
-
for (let i = 0; i < headerLines.length; i++) {
|
|
2035
|
-
if (i === 0) {
|
|
2036
|
-
console.log(prefix + "\u25CF " + headerLines[i]);
|
|
2037
|
-
} else {
|
|
2038
|
-
console.log(cont + headerLines[i]);
|
|
2039
|
-
}
|
|
2040
|
-
}
|
|
2041
|
-
console.log();
|
|
2042
|
-
this.lastEventType = "tool";
|
|
2043
|
-
}
|
|
2044
|
-
/**
|
|
2045
|
-
* Handle tool_result event - lookup buffered tool_use and render grouped
|
|
2046
|
-
*/
|
|
2047
|
-
handleToolResult(event, prefix) {
|
|
2048
|
-
const toolUseId = String(event.data.toolUseId || "");
|
|
2049
|
-
const result = String(event.data.result || "");
|
|
2050
|
-
const isError = Boolean(event.data.isError);
|
|
2051
|
-
const pending = this.pendingToolUse.get(toolUseId);
|
|
2052
|
-
if (pending) {
|
|
2053
|
-
this.renderGroupedTool(pending.toolUse, { result, isError }, prefix);
|
|
2054
|
-
this.pendingToolUse.delete(toolUseId);
|
|
2055
|
-
}
|
|
2056
|
-
}
|
|
2057
|
-
/**
|
|
2058
|
-
* Get continuation prefix (simple indent, no timestamp alignment)
|
|
2059
|
-
*/
|
|
2060
|
-
getContinuationPrefix() {
|
|
2061
|
-
return " ";
|
|
2062
|
-
}
|
|
2063
|
-
/**
|
|
2064
|
-
* Render grouped tool output (tool_use + tool_result together)
|
|
2065
|
-
*/
|
|
2066
|
-
renderGroupedTool(toolUse, result, prefix) {
|
|
2067
|
-
if (this.lastEventType === "text") {
|
|
2068
|
-
console.log();
|
|
2069
|
-
}
|
|
2070
|
-
const verbose = this.options.verbose ?? false;
|
|
2071
|
-
const cont = this.getContinuationPrefix();
|
|
2072
|
-
const headerLines = formatToolHeader(toolUse);
|
|
2073
|
-
const resultLines = formatToolResult(toolUse, result, verbose);
|
|
2074
|
-
for (let i = 0; i < headerLines.length; i++) {
|
|
2075
|
-
if (i === 0) {
|
|
2076
|
-
console.log(prefix + "\u25CF " + headerLines[i]);
|
|
2077
|
-
} else {
|
|
2078
|
-
console.log(cont + headerLines[i]);
|
|
2079
|
-
}
|
|
2080
|
-
}
|
|
2081
|
-
for (const line of resultLines) {
|
|
2082
|
-
console.log(cont + line);
|
|
2083
|
-
}
|
|
2084
|
-
console.log();
|
|
2085
|
-
this.lastEventType = "tool";
|
|
2086
|
-
}
|
|
2087
|
-
renderInit(event, prefix) {
|
|
2088
|
-
const frameworkStr = String(event.data.framework || "claude-code");
|
|
2089
|
-
const displayName = isSupportedFramework(frameworkStr) ? getFrameworkDisplayName(frameworkStr) : frameworkStr;
|
|
2090
|
-
this.frameworkDisplayName = displayName;
|
|
2091
|
-
console.log(prefix + chalk6.bold(`\u25B7 ${displayName} Started`));
|
|
2092
|
-
console.log(` Session: ${chalk6.dim(String(event.data.sessionId || ""))}`);
|
|
2093
|
-
if (event.data.model) {
|
|
2094
|
-
console.log(` Model: ${chalk6.dim(String(event.data.model))}`);
|
|
2095
|
-
}
|
|
2096
|
-
console.log(
|
|
2097
|
-
` Tools: ${chalk6.dim(
|
|
2098
|
-
Array.isArray(event.data.tools) ? event.data.tools.join(", ") : String(event.data.tools || "")
|
|
2099
|
-
)}`
|
|
2100
|
-
);
|
|
2101
|
-
console.log();
|
|
2102
|
-
this.lastEventType = "init";
|
|
2103
|
-
}
|
|
2104
|
-
renderText(event, prefix) {
|
|
2105
|
-
const text = String(event.data.text || "");
|
|
2106
|
-
console.log(prefix + "\u25CF " + text);
|
|
2107
|
-
this.lastEventType = "text";
|
|
2108
|
-
}
|
|
2109
|
-
renderResult(event, prefix) {
|
|
2110
|
-
console.log();
|
|
2111
|
-
const success = Boolean(event.data.success);
|
|
2112
|
-
if (success) {
|
|
2113
|
-
console.log(
|
|
2114
|
-
prefix + chalk6.bold(`\u25C6 ${this.frameworkDisplayName} Completed`)
|
|
2115
|
-
);
|
|
2116
|
-
} else {
|
|
2117
|
-
console.log(prefix + chalk6.bold(`\u25C6 ${this.frameworkDisplayName} Failed`));
|
|
2118
|
-
}
|
|
2119
|
-
const durationMs = Number(event.data.durationMs || 0);
|
|
2120
|
-
const durationSec = (durationMs / 1e3).toFixed(1);
|
|
2121
|
-
console.log(` Duration: ${chalk6.dim(durationSec + "s")}`);
|
|
2122
|
-
const numTurns = Number(event.data.numTurns || 0);
|
|
2123
|
-
console.log(` Turns: ${chalk6.dim(String(numTurns))}`);
|
|
2124
|
-
const usage = event.data.usage;
|
|
2125
|
-
if (usage && typeof usage === "object") {
|
|
2126
|
-
const inputTokens = Number(usage.input_tokens || 0);
|
|
2127
|
-
const outputTokens = Number(usage.output_tokens || 0);
|
|
2128
|
-
const formatTokens = (count) => {
|
|
2129
|
-
if (count >= 1e3) {
|
|
2130
|
-
return Math.floor(count / 1e3) + "k";
|
|
2131
|
-
}
|
|
2132
|
-
return String(count);
|
|
2133
|
-
};
|
|
2134
|
-
console.log(
|
|
2135
|
-
` Tokens: ${chalk6.dim(
|
|
2136
|
-
`input=${formatTokens(inputTokens)} output=${formatTokens(outputTokens)}`
|
|
2137
|
-
)}`
|
|
2138
|
-
);
|
|
2139
|
-
}
|
|
2140
|
-
this.lastEventType = "result";
|
|
2141
|
-
}
|
|
2142
|
-
/**
|
|
2143
|
-
* Format version ID for display (show short 8-character prefix)
|
|
2144
|
-
*/
|
|
2145
|
-
static formatVersion(version) {
|
|
2146
|
-
if (version.length === 64 && /^[a-f0-9]+$/i.test(version)) {
|
|
2147
|
-
return version.slice(0, 8);
|
|
2148
|
-
}
|
|
2149
|
-
return version;
|
|
2150
|
-
}
|
|
2151
|
-
};
|
|
2152
|
-
|
|
2153
|
-
// src/commands/run/shared.ts
|
|
2154
|
-
function collectKeyValue(value, previous) {
|
|
2155
|
-
const [key, ...valueParts] = value.split("=");
|
|
2156
|
-
const val = valueParts.join("=");
|
|
2157
|
-
if (!key || val === void 0 || val === "") {
|
|
2158
|
-
throw new Error(`Invalid format: ${value} (expected KEY=value)`);
|
|
2159
|
-
}
|
|
2160
|
-
return { ...previous, [key]: val };
|
|
2161
|
-
}
|
|
2162
|
-
function collectVolumeVersions(value, previous) {
|
|
2163
|
-
const [volumeName, ...versionParts] = value.split("=");
|
|
2164
|
-
const version = versionParts.join("=");
|
|
2165
|
-
if (!volumeName || version === void 0 || version === "") {
|
|
2166
|
-
throw new Error(
|
|
2167
|
-
`Invalid volume-version format: ${value} (expected volumeName=version)`
|
|
2168
|
-
);
|
|
2169
|
-
}
|
|
2170
|
-
return { ...previous, [volumeName]: version };
|
|
2171
|
-
}
|
|
2172
|
-
function isUUID(str) {
|
|
2173
|
-
return /^[0-9a-f-]{36}$/i.test(str);
|
|
2174
|
-
}
|
|
2175
|
-
function extractVarNames(composeContent) {
|
|
2176
|
-
const grouped = extractAndGroupVariables(composeContent);
|
|
2177
|
-
return grouped.vars.map((r) => r.name);
|
|
2178
|
-
}
|
|
2179
|
-
function extractSecretNames(composeContent) {
|
|
2180
|
-
const grouped = extractAndGroupVariables(composeContent);
|
|
2181
|
-
return grouped.secrets.map((r) => r.name);
|
|
2182
|
-
}
|
|
2183
|
-
function loadValues(cliValues, configNames, envFilePath) {
|
|
2184
|
-
const result = { ...cliValues };
|
|
2185
|
-
const missingNames = configNames.filter((name) => !(name in result));
|
|
2186
|
-
if (missingNames.length > 0) {
|
|
2187
|
-
const envValues = {};
|
|
2188
|
-
for (const name of missingNames) {
|
|
2189
|
-
const envValue = process.env[name];
|
|
2190
|
-
if (envValue !== void 0) {
|
|
2191
|
-
envValues[name] = envValue;
|
|
2192
|
-
}
|
|
2193
|
-
}
|
|
2194
|
-
let fileValues = {};
|
|
2195
|
-
if (envFilePath) {
|
|
2196
|
-
if (!fs6.existsSync(envFilePath)) {
|
|
2197
|
-
throw new Error(`Environment file not found: ${envFilePath}`);
|
|
2198
|
-
}
|
|
2199
|
-
const dotenvResult = dotenvConfig({ path: envFilePath, quiet: true });
|
|
2200
|
-
if (dotenvResult.parsed) {
|
|
2201
|
-
fileValues = Object.fromEntries(
|
|
2202
|
-
Object.entries(dotenvResult.parsed).filter(
|
|
2203
|
-
([key]) => missingNames.includes(key)
|
|
2204
|
-
)
|
|
2205
|
-
);
|
|
2206
|
-
}
|
|
2207
|
-
}
|
|
2208
|
-
Object.assign(result, envValues, fileValues);
|
|
2209
|
-
}
|
|
2210
|
-
return Object.keys(result).length > 0 ? result : void 0;
|
|
2211
|
-
}
|
|
2212
|
-
function parseIdentifier(identifier) {
|
|
2213
|
-
if (isUUID(identifier)) {
|
|
2214
|
-
return { name: identifier };
|
|
2215
|
-
}
|
|
2216
|
-
let org;
|
|
2217
|
-
let rest = identifier;
|
|
2218
|
-
const slashIndex = identifier.indexOf("/");
|
|
2219
|
-
if (slashIndex > 0) {
|
|
2220
|
-
org = identifier.slice(0, slashIndex);
|
|
2221
|
-
rest = identifier.slice(slashIndex + 1);
|
|
2222
|
-
}
|
|
2223
|
-
const colonIndex = rest.indexOf(":");
|
|
2224
|
-
if (colonIndex > 0 && colonIndex < rest.length - 1) {
|
|
2225
|
-
return {
|
|
2226
|
-
org,
|
|
2227
|
-
name: rest.slice(0, colonIndex),
|
|
2228
|
-
version: rest.slice(colonIndex + 1)
|
|
2229
|
-
};
|
|
2230
|
-
}
|
|
2231
|
-
return { org, name: rest };
|
|
2232
|
-
}
|
|
2233
|
-
function renderRunCreated(response) {
|
|
2234
|
-
if (response.status === "queued") {
|
|
2235
|
-
console.log(chalk7.yellow("\u26A0 Run queued \u2014 concurrency limit reached"));
|
|
2236
|
-
console.log(` Run ID: ${chalk7.dim(response.runId)}`);
|
|
2237
|
-
console.log(
|
|
2238
|
-
chalk7.dim(" Will start automatically when a slot is available")
|
|
2239
|
-
);
|
|
2240
|
-
console.log();
|
|
2241
|
-
} else {
|
|
2242
|
-
EventRenderer.renderRunStarted({
|
|
2243
|
-
runId: response.runId,
|
|
2244
|
-
sandboxId: response.sandboxId
|
|
2245
|
-
});
|
|
2246
|
-
}
|
|
2247
|
-
}
|
|
2248
|
-
async function pollEvents(runId, options) {
|
|
2249
|
-
const renderer = new EventRenderer({ verbose: options?.verbose });
|
|
2250
|
-
let nextSequence = -1;
|
|
2251
|
-
let complete = false;
|
|
2252
|
-
let result = { succeeded: true, runId };
|
|
2253
|
-
const pollIntervalMs = 1e3;
|
|
2254
|
-
while (!complete) {
|
|
2255
|
-
const response = await getEvents(runId, {
|
|
2256
|
-
since: nextSequence
|
|
2257
|
-
});
|
|
2258
|
-
for (const event of response.events) {
|
|
2259
|
-
const eventData = event.eventData;
|
|
2260
|
-
const parsed = parseEvent(eventData);
|
|
2261
|
-
if (parsed) {
|
|
2262
|
-
renderer.render(parsed);
|
|
2263
|
-
}
|
|
2264
|
-
}
|
|
2265
|
-
nextSequence = response.nextSequence;
|
|
2266
|
-
const runStatus = response.run.status;
|
|
2267
|
-
if (runStatus === "completed") {
|
|
2268
|
-
complete = true;
|
|
2269
|
-
EventRenderer.renderRunCompleted(response.run.result);
|
|
2270
|
-
result = {
|
|
2271
|
-
succeeded: true,
|
|
2272
|
-
runId,
|
|
2273
|
-
sessionId: response.run.result?.agentSessionId,
|
|
2274
|
-
checkpointId: response.run.result?.checkpointId
|
|
2275
|
-
};
|
|
2276
|
-
} else if (runStatus === "failed") {
|
|
2277
|
-
complete = true;
|
|
2278
|
-
EventRenderer.renderRunFailed(response.run.error, runId);
|
|
2279
|
-
result = { succeeded: false, runId };
|
|
2280
|
-
} else if (runStatus === "timeout") {
|
|
2281
|
-
complete = true;
|
|
2282
|
-
console.error(chalk7.red("\n\u2717 Run timed out"));
|
|
2283
|
-
console.error(
|
|
2284
|
-
chalk7.dim(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
2285
|
-
);
|
|
2286
|
-
result = { succeeded: false, runId };
|
|
2287
|
-
} else if (runStatus === "cancelled") {
|
|
2288
|
-
complete = true;
|
|
2289
|
-
console.error(chalk7.yellow("\n\u2717 Run cancelled"));
|
|
2290
|
-
result = { succeeded: false, runId };
|
|
2291
|
-
}
|
|
2292
|
-
if (!complete) {
|
|
2293
|
-
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
2294
|
-
}
|
|
2295
|
-
}
|
|
2296
|
-
return result;
|
|
2297
|
-
}
|
|
2298
|
-
function showNextSteps(result) {
|
|
2299
|
-
const { runId, sessionId, checkpointId } = result;
|
|
2300
|
-
console.log();
|
|
2301
|
-
console.log(" View agent logs:");
|
|
2302
|
-
console.log(chalk7.cyan(` vm0 logs ${runId}`));
|
|
2303
|
-
if (sessionId) {
|
|
2304
|
-
console.log(" Continue with session (latest conversation and artifact):");
|
|
2305
|
-
console.log(
|
|
2306
|
-
chalk7.cyan(` vm0 run continue ${sessionId} "your next prompt"`)
|
|
2307
|
-
);
|
|
2308
|
-
}
|
|
2309
|
-
if (checkpointId) {
|
|
2310
|
-
console.log(
|
|
2311
|
-
" Resume from checkpoint (snapshotted conversation and artifact):"
|
|
2312
|
-
);
|
|
2313
|
-
console.log(
|
|
2314
|
-
chalk7.cyan(` vm0 run resume ${checkpointId} "your next prompt"`)
|
|
2315
|
-
);
|
|
2316
|
-
}
|
|
2317
|
-
}
|
|
2318
|
-
|
|
2319
|
-
// src/commands/run/run.ts
|
|
2320
1580
|
var mainRunCommand = new Command8().name("run").description("Run an agent").argument(
|
|
2321
1581
|
"<agent-name>",
|
|
2322
1582
|
"Agent reference: [org/]name[:version] (e.g., 'my-agent', 'lancy/my-agent:abc123', 'my-agent:latest')"
|
|
@@ -2363,7 +1623,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
2363
1623
|
withErrorHandler(
|
|
2364
1624
|
async (identifier, prompt, options) => {
|
|
2365
1625
|
if (options.autoUpdate !== false) {
|
|
2366
|
-
await startSilentUpgrade("9.
|
|
1626
|
+
await startSilentUpgrade("9.86.0");
|
|
2367
1627
|
}
|
|
2368
1628
|
const { org, name, version } = parseIdentifier(identifier);
|
|
2369
1629
|
let composeId;
|
|
@@ -2604,7 +1864,7 @@ var continueCommand = new Command10().name("continue").description(
|
|
|
2604
1864
|
|
|
2605
1865
|
// src/commands/run/list.ts
|
|
2606
1866
|
import { Command as Command11 } from "commander";
|
|
2607
|
-
import
|
|
1867
|
+
import chalk5 from "chalk";
|
|
2608
1868
|
|
|
2609
1869
|
// src/lib/utils/time-parser.ts
|
|
2610
1870
|
function parseTime(timeStr) {
|
|
@@ -2657,16 +1917,16 @@ function formatRunStatus(status, width) {
|
|
|
2657
1917
|
const paddedStatus = width ? status.padEnd(width) : status;
|
|
2658
1918
|
switch (status) {
|
|
2659
1919
|
case "queued":
|
|
2660
|
-
return
|
|
1920
|
+
return chalk5.blue(paddedStatus);
|
|
2661
1921
|
case "running":
|
|
2662
|
-
return
|
|
1922
|
+
return chalk5.green(paddedStatus);
|
|
2663
1923
|
case "pending":
|
|
2664
|
-
return
|
|
1924
|
+
return chalk5.yellow(paddedStatus);
|
|
2665
1925
|
case "completed":
|
|
2666
|
-
return
|
|
1926
|
+
return chalk5.dim(paddedStatus);
|
|
2667
1927
|
case "failed":
|
|
2668
1928
|
case "timeout":
|
|
2669
|
-
return
|
|
1929
|
+
return chalk5.red(paddedStatus);
|
|
2670
1930
|
default:
|
|
2671
1931
|
return paddedStatus;
|
|
2672
1932
|
}
|
|
@@ -2717,7 +1977,7 @@ function displayRuns(runs) {
|
|
|
2717
1977
|
"STATUS".padEnd(statusWidth),
|
|
2718
1978
|
"CREATED"
|
|
2719
1979
|
].join(" ");
|
|
2720
|
-
console.log(
|
|
1980
|
+
console.log(chalk5.dim(header));
|
|
2721
1981
|
for (const run of runs) {
|
|
2722
1982
|
const row = [
|
|
2723
1983
|
run.id.padEnd(UUID_LENGTH),
|
|
@@ -2730,10 +1990,10 @@ function displayRuns(runs) {
|
|
|
2730
1990
|
}
|
|
2731
1991
|
function displayEmptyState(hasFilters) {
|
|
2732
1992
|
if (hasFilters) {
|
|
2733
|
-
console.log(
|
|
1993
|
+
console.log(chalk5.dim("No runs found matching filters"));
|
|
2734
1994
|
} else {
|
|
2735
|
-
console.log(
|
|
2736
|
-
console.log(
|
|
1995
|
+
console.log(chalk5.dim("No active runs"));
|
|
1996
|
+
console.log(chalk5.dim(' Run: vm0 run <agent> "<prompt>"'));
|
|
2737
1997
|
}
|
|
2738
1998
|
}
|
|
2739
1999
|
var listCommand = new Command11().name("list").alias("ls").description("List runs").option(
|
|
@@ -2770,17 +2030,17 @@ var listCommand = new Command11().name("list").alias("ls").description("List run
|
|
|
2770
2030
|
|
|
2771
2031
|
// src/commands/run/kill.ts
|
|
2772
2032
|
import { Command as Command12 } from "commander";
|
|
2773
|
-
import
|
|
2033
|
+
import chalk6 from "chalk";
|
|
2774
2034
|
var killCommand = new Command12().name("kill").description("Kill (cancel) a pending or running run").argument("<run-id>", "Run ID to kill").action(
|
|
2775
2035
|
withErrorHandler(async (runId) => {
|
|
2776
2036
|
await cancelRun(runId);
|
|
2777
|
-
console.log(
|
|
2037
|
+
console.log(chalk6.green(`\u2713 Run ${runId} cancelled`));
|
|
2778
2038
|
})
|
|
2779
2039
|
);
|
|
2780
2040
|
|
|
2781
2041
|
// src/commands/run/queue.ts
|
|
2782
2042
|
import { Command as Command13 } from "commander";
|
|
2783
|
-
import
|
|
2043
|
+
import chalk7 from "chalk";
|
|
2784
2044
|
var queueCommand = new Command13().name("queue").description("Show org run queue status").action(
|
|
2785
2045
|
withErrorHandler(async () => {
|
|
2786
2046
|
const data = await getRunQueue();
|
|
@@ -2788,7 +2048,7 @@ var queueCommand = new Command13().name("queue").description("Show org run queue
|
|
|
2788
2048
|
const limitDisplay = concurrency.limit === 0 ? "unlimited" : `${concurrency.active}/${concurrency.limit} slots used`;
|
|
2789
2049
|
console.log(`Concurrency: ${limitDisplay} (${concurrency.tier} tier)`);
|
|
2790
2050
|
if (queue.length === 0) {
|
|
2791
|
-
console.log(
|
|
2051
|
+
console.log(chalk7.dim("Queue: empty \u2014 all slots available"));
|
|
2792
2052
|
return;
|
|
2793
2053
|
}
|
|
2794
2054
|
console.log(
|
|
@@ -2810,9 +2070,9 @@ var queueCommand = new Command13().name("queue").description("Show org run queue
|
|
|
2810
2070
|
"USER".padEnd(emailWidth),
|
|
2811
2071
|
"CREATED"
|
|
2812
2072
|
].join(" ");
|
|
2813
|
-
console.log(
|
|
2073
|
+
console.log(chalk7.dim(header));
|
|
2814
2074
|
for (const entry of queue) {
|
|
2815
|
-
const marker = entry.runId !== null ?
|
|
2075
|
+
const marker = entry.runId !== null ? chalk7.cyan(" \u2190 you") : "";
|
|
2816
2076
|
const row = [
|
|
2817
2077
|
String(entry.position).padEnd(posWidth),
|
|
2818
2078
|
(entry.agentName ?? "-").padEnd(agentWidth),
|
|
@@ -2837,12 +2097,12 @@ import { Command as Command20 } from "commander";
|
|
|
2837
2097
|
|
|
2838
2098
|
// src/commands/volume/init.ts
|
|
2839
2099
|
import { Command as Command14 } from "commander";
|
|
2840
|
-
import
|
|
2100
|
+
import chalk8 from "chalk";
|
|
2841
2101
|
import path7 from "path";
|
|
2842
2102
|
|
|
2843
2103
|
// src/lib/storage/storage-utils.ts
|
|
2844
2104
|
import { readFile as readFile4, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
2845
|
-
import { existsSync as
|
|
2105
|
+
import { existsSync as existsSync5 } from "fs";
|
|
2846
2106
|
import { parse as parseYaml2, stringify as stringifyYaml } from "yaml";
|
|
2847
2107
|
import path6 from "path";
|
|
2848
2108
|
var CONFIG_DIR = ".vm0";
|
|
@@ -2858,9 +2118,9 @@ async function readStorageConfig(basePath = process.cwd()) {
|
|
|
2858
2118
|
const configPath = path6.join(basePath, CONFIG_DIR, CONFIG_FILE);
|
|
2859
2119
|
const legacyConfigPath = path6.join(basePath, CONFIG_DIR, "volume.yaml");
|
|
2860
2120
|
let actualPath = null;
|
|
2861
|
-
if (
|
|
2121
|
+
if (existsSync5(configPath)) {
|
|
2862
2122
|
actualPath = configPath;
|
|
2863
|
-
} else if (
|
|
2123
|
+
} else if (existsSync5(legacyConfigPath)) {
|
|
2864
2124
|
actualPath = legacyConfigPath;
|
|
2865
2125
|
}
|
|
2866
2126
|
if (!actualPath) {
|
|
@@ -2876,7 +2136,7 @@ async function readStorageConfig(basePath = process.cwd()) {
|
|
|
2876
2136
|
async function writeStorageConfig(storageName, basePath = process.cwd(), type2 = "volume") {
|
|
2877
2137
|
const configDir = path6.join(basePath, CONFIG_DIR);
|
|
2878
2138
|
const configPath = path6.join(configDir, CONFIG_FILE);
|
|
2879
|
-
if (!
|
|
2139
|
+
if (!existsSync5(configDir)) {
|
|
2880
2140
|
await mkdir3(configDir, { recursive: true });
|
|
2881
2141
|
}
|
|
2882
2142
|
const config = {
|
|
@@ -2895,10 +2155,10 @@ var initCommand = new Command14().name("init").description("Initialize a volume
|
|
|
2895
2155
|
const existingConfig = await readStorageConfig(cwd);
|
|
2896
2156
|
if (existingConfig) {
|
|
2897
2157
|
console.log(
|
|
2898
|
-
|
|
2158
|
+
chalk8.yellow(`Volume already initialized: ${existingConfig.name}`)
|
|
2899
2159
|
);
|
|
2900
2160
|
console.log(
|
|
2901
|
-
|
|
2161
|
+
chalk8.dim(`Config file: ${path7.join(cwd, ".vm0", "storage.yaml")}`)
|
|
2902
2162
|
);
|
|
2903
2163
|
return;
|
|
2904
2164
|
}
|
|
@@ -2922,7 +2182,7 @@ var initCommand = new Command14().name("init").description("Initialize a volume
|
|
|
2922
2182
|
}
|
|
2923
2183
|
);
|
|
2924
2184
|
if (name === void 0) {
|
|
2925
|
-
console.log(
|
|
2185
|
+
console.log(chalk8.dim("Cancelled"));
|
|
2926
2186
|
return;
|
|
2927
2187
|
}
|
|
2928
2188
|
volumeName = name;
|
|
@@ -2935,9 +2195,9 @@ var initCommand = new Command14().name("init").description("Initialize a volume
|
|
|
2935
2195
|
});
|
|
2936
2196
|
}
|
|
2937
2197
|
await writeStorageConfig(volumeName, cwd);
|
|
2938
|
-
console.log(
|
|
2198
|
+
console.log(chalk8.green(`\u2713 Initialized volume: ${volumeName}`));
|
|
2939
2199
|
console.log(
|
|
2940
|
-
|
|
2200
|
+
chalk8.dim(
|
|
2941
2201
|
` Config saved to ${path7.join(cwd, ".vm0", "storage.yaml")}`
|
|
2942
2202
|
)
|
|
2943
2203
|
);
|
|
@@ -2946,7 +2206,7 @@ var initCommand = new Command14().name("init").description("Initialize a volume
|
|
|
2946
2206
|
|
|
2947
2207
|
// src/commands/volume/push.ts
|
|
2948
2208
|
import { Command as Command15 } from "commander";
|
|
2949
|
-
import
|
|
2209
|
+
import chalk9 from "chalk";
|
|
2950
2210
|
var pushCommand = new Command15().name("push").description("Push local files to cloud volume").option(
|
|
2951
2211
|
"-f, --force",
|
|
2952
2212
|
"Force upload even if content unchanged (recreate archive)"
|
|
@@ -2962,41 +2222,41 @@ var pushCommand = new Command15().name("push").description("Push local files to
|
|
|
2962
2222
|
console.log(`Pushing volume: ${config.name}`);
|
|
2963
2223
|
const result = await directUpload(config.name, "volume", cwd, {
|
|
2964
2224
|
onProgress: (message) => {
|
|
2965
|
-
console.log(
|
|
2225
|
+
console.log(chalk9.dim(message));
|
|
2966
2226
|
},
|
|
2967
2227
|
force: options.force
|
|
2968
2228
|
});
|
|
2969
2229
|
const shortVersion = result.versionId.slice(0, 8);
|
|
2970
2230
|
if (result.empty) {
|
|
2971
|
-
console.log(
|
|
2231
|
+
console.log(chalk9.dim("No files found (empty volume)"));
|
|
2972
2232
|
} else if (result.deduplicated) {
|
|
2973
|
-
console.log(
|
|
2233
|
+
console.log(chalk9.green("\u2713 Content unchanged (deduplicated)"));
|
|
2974
2234
|
} else {
|
|
2975
|
-
console.log(
|
|
2235
|
+
console.log(chalk9.green("\u2713 Upload complete"));
|
|
2976
2236
|
}
|
|
2977
|
-
console.log(
|
|
2978
|
-
console.log(
|
|
2979
|
-
console.log(
|
|
2237
|
+
console.log(chalk9.dim(` Version: ${shortVersion}`));
|
|
2238
|
+
console.log(chalk9.dim(` Files: ${result.fileCount.toLocaleString()}`));
|
|
2239
|
+
console.log(chalk9.dim(` Size: ${formatBytes(result.size)}`));
|
|
2980
2240
|
})
|
|
2981
2241
|
);
|
|
2982
2242
|
|
|
2983
2243
|
// src/commands/volume/pull.ts
|
|
2984
2244
|
import { Command as Command16 } from "commander";
|
|
2985
|
-
import
|
|
2245
|
+
import chalk11 from "chalk";
|
|
2986
2246
|
import path8 from "path";
|
|
2987
|
-
import * as
|
|
2247
|
+
import * as fs6 from "fs";
|
|
2988
2248
|
import * as os4 from "os";
|
|
2989
2249
|
import * as tar3 from "tar";
|
|
2990
2250
|
|
|
2991
2251
|
// src/lib/storage/pull-utils.ts
|
|
2992
|
-
import
|
|
2252
|
+
import chalk10 from "chalk";
|
|
2993
2253
|
async function handleEmptyStorageResponse(cwd) {
|
|
2994
|
-
console.log(
|
|
2254
|
+
console.log(chalk10.dim("Syncing local files..."));
|
|
2995
2255
|
const removedCount = await removeExtraFiles(cwd, /* @__PURE__ */ new Set());
|
|
2996
2256
|
if (removedCount > 0) {
|
|
2997
|
-
console.log(
|
|
2257
|
+
console.log(chalk10.green(`\u2713 Removed ${removedCount} files not in remote`));
|
|
2998
2258
|
}
|
|
2999
|
-
console.log(
|
|
2259
|
+
console.log(chalk10.green("\u2713 Synced (0 files)"));
|
|
3000
2260
|
return { removedCount };
|
|
3001
2261
|
}
|
|
3002
2262
|
|
|
@@ -3015,7 +2275,7 @@ var pullCommand = new Command16().name("pull").description("Pull cloud files to
|
|
|
3015
2275
|
} else {
|
|
3016
2276
|
console.log(`Pulling volume: ${config.name}`);
|
|
3017
2277
|
}
|
|
3018
|
-
console.log(
|
|
2278
|
+
console.log(chalk11.dim("Getting download URL..."));
|
|
3019
2279
|
const downloadInfo = await getStorageDownload({
|
|
3020
2280
|
name: config.name,
|
|
3021
2281
|
type: "volume",
|
|
@@ -3029,18 +2289,18 @@ var pullCommand = new Command16().name("pull").description("Pull cloud files to
|
|
|
3029
2289
|
if (!downloadUrl) {
|
|
3030
2290
|
throw new Error("No download URL returned");
|
|
3031
2291
|
}
|
|
3032
|
-
console.log(
|
|
2292
|
+
console.log(chalk11.dim("Downloading from S3..."));
|
|
3033
2293
|
const s3Response = await fetch(downloadUrl);
|
|
3034
2294
|
if (!s3Response.ok) {
|
|
3035
2295
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
3036
2296
|
}
|
|
3037
2297
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
3038
2298
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
3039
|
-
console.log(
|
|
3040
|
-
const tmpDir =
|
|
2299
|
+
console.log(chalk11.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
2300
|
+
const tmpDir = fs6.mkdtempSync(path8.join(os4.tmpdir(), "vm0-"));
|
|
3041
2301
|
const tarPath = path8.join(tmpDir, "volume.tar.gz");
|
|
3042
|
-
await
|
|
3043
|
-
console.log(
|
|
2302
|
+
await fs6.promises.writeFile(tarPath, tarBuffer);
|
|
2303
|
+
console.log(chalk11.dim("Syncing local files..."));
|
|
3044
2304
|
const remoteFiles = await listTarFiles(tarPath);
|
|
3045
2305
|
const remoteFilesSet = new Set(
|
|
3046
2306
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -3048,24 +2308,24 @@ var pullCommand = new Command16().name("pull").description("Pull cloud files to
|
|
|
3048
2308
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
3049
2309
|
if (removedCount > 0) {
|
|
3050
2310
|
console.log(
|
|
3051
|
-
|
|
2311
|
+
chalk11.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
3052
2312
|
);
|
|
3053
2313
|
}
|
|
3054
|
-
console.log(
|
|
2314
|
+
console.log(chalk11.dim("Extracting files..."));
|
|
3055
2315
|
await tar3.extract({
|
|
3056
2316
|
file: tarPath,
|
|
3057
2317
|
cwd,
|
|
3058
2318
|
gzip: true
|
|
3059
2319
|
});
|
|
3060
|
-
await
|
|
3061
|
-
await
|
|
3062
|
-
console.log(
|
|
2320
|
+
await fs6.promises.unlink(tarPath);
|
|
2321
|
+
await fs6.promises.rmdir(tmpDir);
|
|
2322
|
+
console.log(chalk11.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
3063
2323
|
})
|
|
3064
2324
|
);
|
|
3065
2325
|
|
|
3066
2326
|
// src/commands/volume/status.ts
|
|
3067
2327
|
import { Command as Command17 } from "commander";
|
|
3068
|
-
import
|
|
2328
|
+
import chalk12 from "chalk";
|
|
3069
2329
|
var statusCommand2 = new Command17().name("status").description("Show status of cloud volume").action(
|
|
3070
2330
|
withErrorHandler(async () => {
|
|
3071
2331
|
const cwd = process.cwd();
|
|
@@ -3089,13 +2349,13 @@ var statusCommand2 = new Command17().name("status").description("Show status of
|
|
|
3089
2349
|
});
|
|
3090
2350
|
const shortVersion = info.versionId.slice(0, 8);
|
|
3091
2351
|
if ("empty" in info) {
|
|
3092
|
-
console.log(
|
|
3093
|
-
console.log(
|
|
2352
|
+
console.log(chalk12.green("\u2713 Found (empty)"));
|
|
2353
|
+
console.log(chalk12.dim(` Version: ${shortVersion}`));
|
|
3094
2354
|
} else {
|
|
3095
|
-
console.log(
|
|
3096
|
-
console.log(
|
|
3097
|
-
console.log(
|
|
3098
|
-
console.log(
|
|
2355
|
+
console.log(chalk12.green("\u2713 Found"));
|
|
2356
|
+
console.log(chalk12.dim(` Version: ${shortVersion}`));
|
|
2357
|
+
console.log(chalk12.dim(` Files: ${info.fileCount.toLocaleString()}`));
|
|
2358
|
+
console.log(chalk12.dim(` Size: ${formatBytes(info.size)}`));
|
|
3099
2359
|
}
|
|
3100
2360
|
} catch (error) {
|
|
3101
2361
|
if (error instanceof ApiRequestError && error.status === 404) {
|
|
@@ -3110,14 +2370,14 @@ var statusCommand2 = new Command17().name("status").description("Show status of
|
|
|
3110
2370
|
|
|
3111
2371
|
// src/commands/volume/list.ts
|
|
3112
2372
|
import { Command as Command18 } from "commander";
|
|
3113
|
-
import
|
|
2373
|
+
import chalk13 from "chalk";
|
|
3114
2374
|
var listCommand2 = new Command18().name("list").alias("ls").description("List all remote volumes").action(
|
|
3115
2375
|
withErrorHandler(async () => {
|
|
3116
2376
|
const items = await listStorages({ type: "volume" });
|
|
3117
2377
|
if (items.length === 0) {
|
|
3118
|
-
console.log(
|
|
2378
|
+
console.log(chalk13.dim("No volumes found"));
|
|
3119
2379
|
console.log(
|
|
3120
|
-
|
|
2380
|
+
chalk13.dim(" Create one with: vm0 volume init && vm0 volume push")
|
|
3121
2381
|
);
|
|
3122
2382
|
return;
|
|
3123
2383
|
}
|
|
@@ -3136,7 +2396,7 @@ var listCommand2 = new Command18().name("list").alias("ls").description("List al
|
|
|
3136
2396
|
"FILES".padStart(filesWidth),
|
|
3137
2397
|
"UPDATED"
|
|
3138
2398
|
].join(" ");
|
|
3139
|
-
console.log(
|
|
2399
|
+
console.log(chalk13.dim(header));
|
|
3140
2400
|
for (const item of items) {
|
|
3141
2401
|
const row = [
|
|
3142
2402
|
item.name.padEnd(nameWidth),
|
|
@@ -3151,12 +2411,12 @@ var listCommand2 = new Command18().name("list").alias("ls").description("List al
|
|
|
3151
2411
|
|
|
3152
2412
|
// src/commands/volume/clone.ts
|
|
3153
2413
|
import { Command as Command19 } from "commander";
|
|
3154
|
-
import
|
|
2414
|
+
import chalk15 from "chalk";
|
|
3155
2415
|
|
|
3156
2416
|
// src/lib/storage/clone-utils.ts
|
|
3157
|
-
import
|
|
2417
|
+
import chalk14 from "chalk";
|
|
3158
2418
|
import path9 from "path";
|
|
3159
|
-
import * as
|
|
2419
|
+
import * as fs7 from "fs";
|
|
3160
2420
|
import * as os5 from "os";
|
|
3161
2421
|
import * as tar4 from "tar";
|
|
3162
2422
|
async function cloneStorage(name, type2, destination, options = {}) {
|
|
@@ -3165,18 +2425,18 @@ async function cloneStorage(name, type2, destination, options = {}) {
|
|
|
3165
2425
|
if (dirStatus.exists && !dirStatus.empty) {
|
|
3166
2426
|
throw new Error(`Directory "${destination}" is not empty`);
|
|
3167
2427
|
}
|
|
3168
|
-
console.log(
|
|
2428
|
+
console.log(chalk14.dim(`Checking remote ${typeLabel}...`));
|
|
3169
2429
|
const downloadInfo = await getStorageDownload({
|
|
3170
2430
|
name,
|
|
3171
2431
|
type: type2,
|
|
3172
2432
|
version: options.version
|
|
3173
2433
|
});
|
|
3174
|
-
console.log(
|
|
3175
|
-
await
|
|
2434
|
+
console.log(chalk14.dim(`Creating directory: ${destination}/`));
|
|
2435
|
+
await fs7.promises.mkdir(destination, { recursive: true });
|
|
3176
2436
|
if ("empty" in downloadInfo) {
|
|
3177
2437
|
await writeStorageConfig(name, destination, type2);
|
|
3178
|
-
console.log(
|
|
3179
|
-
console.log(
|
|
2438
|
+
console.log(chalk14.green(`\u2713 Cloned empty ${typeLabel}: ${name}`));
|
|
2439
|
+
console.log(chalk14.dim(`\u2713 Initialized .vm0/storage.yaml`));
|
|
3180
2440
|
return {
|
|
3181
2441
|
success: true,
|
|
3182
2442
|
fileCount: 0,
|
|
@@ -3188,30 +2448,30 @@ async function cloneStorage(name, type2, destination, options = {}) {
|
|
|
3188
2448
|
if (!downloadUrl) {
|
|
3189
2449
|
throw new Error("No download URL returned");
|
|
3190
2450
|
}
|
|
3191
|
-
console.log(
|
|
2451
|
+
console.log(chalk14.dim("Downloading from S3..."));
|
|
3192
2452
|
const s3Response = await fetch(downloadUrl);
|
|
3193
2453
|
if (!s3Response.ok) {
|
|
3194
|
-
await
|
|
2454
|
+
await fs7.promises.rm(destination, { recursive: true, force: true });
|
|
3195
2455
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
3196
2456
|
}
|
|
3197
2457
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
3198
2458
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
3199
|
-
console.log(
|
|
3200
|
-
const tmpDir =
|
|
2459
|
+
console.log(chalk14.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
2460
|
+
const tmpDir = fs7.mkdtempSync(path9.join(os5.tmpdir(), "vm0-clone-"));
|
|
3201
2461
|
const tarPath = path9.join(tmpDir, "archive.tar.gz");
|
|
3202
|
-
await
|
|
2462
|
+
await fs7.promises.writeFile(tarPath, tarBuffer);
|
|
3203
2463
|
const files = await listTarFiles(tarPath);
|
|
3204
|
-
console.log(
|
|
2464
|
+
console.log(chalk14.dim("Extracting files..."));
|
|
3205
2465
|
await tar4.extract({
|
|
3206
2466
|
file: tarPath,
|
|
3207
2467
|
cwd: destination,
|
|
3208
2468
|
gzip: true
|
|
3209
2469
|
});
|
|
3210
|
-
await
|
|
3211
|
-
await
|
|
3212
|
-
console.log(
|
|
2470
|
+
await fs7.promises.unlink(tarPath);
|
|
2471
|
+
await fs7.promises.rmdir(tmpDir);
|
|
2472
|
+
console.log(chalk14.green(`\u2713 Extracted ${files.length} files`));
|
|
3213
2473
|
await writeStorageConfig(name, destination, type2);
|
|
3214
|
-
console.log(
|
|
2474
|
+
console.log(chalk14.green(`\u2713 Initialized .vm0/storage.yaml`));
|
|
3215
2475
|
return {
|
|
3216
2476
|
success: true,
|
|
3217
2477
|
fileCount: downloadInfo.fileCount,
|
|
@@ -3226,10 +2486,10 @@ var cloneCommand = new Command19().name("clone").description("Clone a remote vol
|
|
|
3226
2486
|
const targetDir = destination || name;
|
|
3227
2487
|
console.log(`Cloning volume: ${name}`);
|
|
3228
2488
|
const result = await cloneStorage(name, "volume", targetDir);
|
|
3229
|
-
console.log(
|
|
2489
|
+
console.log(chalk15.green(`
|
|
3230
2490
|
\u2713 Successfully cloned volume: ${name}`));
|
|
3231
|
-
console.log(
|
|
3232
|
-
console.log(
|
|
2491
|
+
console.log(chalk15.dim(` Location: ${targetDir}/`));
|
|
2492
|
+
console.log(chalk15.dim(` Version: ${result.versionId.slice(0, 8)}`));
|
|
3233
2493
|
})
|
|
3234
2494
|
);
|
|
3235
2495
|
|
|
@@ -3241,7 +2501,7 @@ import { Command as Command27 } from "commander";
|
|
|
3241
2501
|
|
|
3242
2502
|
// src/commands/artifact/init.ts
|
|
3243
2503
|
import { Command as Command21 } from "commander";
|
|
3244
|
-
import
|
|
2504
|
+
import chalk16 from "chalk";
|
|
3245
2505
|
import path10 from "path";
|
|
3246
2506
|
var initCommand2 = new Command21().name("init").description("Initialize an artifact in the current directory").option(
|
|
3247
2507
|
"-n, --name <name>",
|
|
@@ -3254,24 +2514,24 @@ var initCommand2 = new Command21().name("init").description("Initialize an artif
|
|
|
3254
2514
|
if (existingConfig) {
|
|
3255
2515
|
if (existingConfig.type === "artifact") {
|
|
3256
2516
|
console.log(
|
|
3257
|
-
|
|
2517
|
+
chalk16.yellow(
|
|
3258
2518
|
`Artifact already initialized: ${existingConfig.name}`
|
|
3259
2519
|
)
|
|
3260
2520
|
);
|
|
3261
2521
|
} else {
|
|
3262
2522
|
console.log(
|
|
3263
|
-
|
|
2523
|
+
chalk16.yellow(
|
|
3264
2524
|
`Directory already initialized as volume: ${existingConfig.name}`
|
|
3265
2525
|
)
|
|
3266
2526
|
);
|
|
3267
2527
|
console.log(
|
|
3268
|
-
|
|
2528
|
+
chalk16.dim(
|
|
3269
2529
|
" To change type, delete .vm0/storage.yaml and reinitialize"
|
|
3270
2530
|
)
|
|
3271
2531
|
);
|
|
3272
2532
|
}
|
|
3273
2533
|
console.log(
|
|
3274
|
-
|
|
2534
|
+
chalk16.dim(`Config file: ${path10.join(cwd, ".vm0", "storage.yaml")}`)
|
|
3275
2535
|
);
|
|
3276
2536
|
return;
|
|
3277
2537
|
}
|
|
@@ -3295,7 +2555,7 @@ var initCommand2 = new Command21().name("init").description("Initialize an artif
|
|
|
3295
2555
|
}
|
|
3296
2556
|
);
|
|
3297
2557
|
if (name === void 0) {
|
|
3298
|
-
console.log(
|
|
2558
|
+
console.log(chalk16.dim("Cancelled"));
|
|
3299
2559
|
return;
|
|
3300
2560
|
}
|
|
3301
2561
|
artifactName = name;
|
|
@@ -3308,9 +2568,9 @@ var initCommand2 = new Command21().name("init").description("Initialize an artif
|
|
|
3308
2568
|
});
|
|
3309
2569
|
}
|
|
3310
2570
|
await writeStorageConfig(artifactName, cwd, "artifact");
|
|
3311
|
-
console.log(
|
|
2571
|
+
console.log(chalk16.green(`\u2713 Initialized artifact: ${artifactName}`));
|
|
3312
2572
|
console.log(
|
|
3313
|
-
|
|
2573
|
+
chalk16.dim(
|
|
3314
2574
|
` Config saved to ${path10.join(cwd, ".vm0", "storage.yaml")}`
|
|
3315
2575
|
)
|
|
3316
2576
|
);
|
|
@@ -3319,7 +2579,7 @@ var initCommand2 = new Command21().name("init").description("Initialize an artif
|
|
|
3319
2579
|
|
|
3320
2580
|
// src/commands/artifact/push.ts
|
|
3321
2581
|
import { Command as Command22 } from "commander";
|
|
3322
|
-
import
|
|
2582
|
+
import chalk17 from "chalk";
|
|
3323
2583
|
var pushCommand2 = new Command22().name("push").description("Push local files to cloud artifact").option(
|
|
3324
2584
|
"-f, --force",
|
|
3325
2585
|
"Force upload even if content unchanged (recreate archive)"
|
|
@@ -3341,29 +2601,29 @@ var pushCommand2 = new Command22().name("push").description("Push local files to
|
|
|
3341
2601
|
console.log(`Pushing artifact: ${config.name}`);
|
|
3342
2602
|
const result = await directUpload(config.name, "artifact", cwd, {
|
|
3343
2603
|
onProgress: (message) => {
|
|
3344
|
-
console.log(
|
|
2604
|
+
console.log(chalk17.dim(message));
|
|
3345
2605
|
},
|
|
3346
2606
|
force: options.force
|
|
3347
2607
|
});
|
|
3348
2608
|
const shortVersion = result.versionId.slice(0, 8);
|
|
3349
2609
|
if (result.empty) {
|
|
3350
|
-
console.log(
|
|
2610
|
+
console.log(chalk17.dim("No files found (empty artifact)"));
|
|
3351
2611
|
} else if (result.deduplicated) {
|
|
3352
|
-
console.log(
|
|
2612
|
+
console.log(chalk17.green("\u2713 Content unchanged (deduplicated)"));
|
|
3353
2613
|
} else {
|
|
3354
|
-
console.log(
|
|
2614
|
+
console.log(chalk17.green("\u2713 Upload complete"));
|
|
3355
2615
|
}
|
|
3356
|
-
console.log(
|
|
3357
|
-
console.log(
|
|
3358
|
-
console.log(
|
|
2616
|
+
console.log(chalk17.dim(` Version: ${shortVersion}`));
|
|
2617
|
+
console.log(chalk17.dim(` Files: ${result.fileCount.toLocaleString()}`));
|
|
2618
|
+
console.log(chalk17.dim(` Size: ${formatBytes(result.size)}`));
|
|
3359
2619
|
})
|
|
3360
2620
|
);
|
|
3361
2621
|
|
|
3362
2622
|
// src/commands/artifact/pull.ts
|
|
3363
2623
|
import { Command as Command23 } from "commander";
|
|
3364
|
-
import
|
|
2624
|
+
import chalk18 from "chalk";
|
|
3365
2625
|
import path11 from "path";
|
|
3366
|
-
import * as
|
|
2626
|
+
import * as fs8 from "fs";
|
|
3367
2627
|
import * as os6 from "os";
|
|
3368
2628
|
import * as tar5 from "tar";
|
|
3369
2629
|
var pullCommand2 = new Command23().name("pull").description("Pull cloud artifact to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(
|
|
@@ -3386,7 +2646,7 @@ var pullCommand2 = new Command23().name("pull").description("Pull cloud artifact
|
|
|
3386
2646
|
} else {
|
|
3387
2647
|
console.log(`Pulling artifact: ${config.name}`);
|
|
3388
2648
|
}
|
|
3389
|
-
console.log(
|
|
2649
|
+
console.log(chalk18.dim("Getting download URL..."));
|
|
3390
2650
|
const downloadInfo = await getStorageDownload({
|
|
3391
2651
|
name: config.name,
|
|
3392
2652
|
type: "artifact",
|
|
@@ -3400,18 +2660,18 @@ var pullCommand2 = new Command23().name("pull").description("Pull cloud artifact
|
|
|
3400
2660
|
if (!downloadUrl) {
|
|
3401
2661
|
throw new Error("No download URL returned");
|
|
3402
2662
|
}
|
|
3403
|
-
console.log(
|
|
2663
|
+
console.log(chalk18.dim("Downloading from S3..."));
|
|
3404
2664
|
const s3Response = await fetch(downloadUrl);
|
|
3405
2665
|
if (!s3Response.ok) {
|
|
3406
2666
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
3407
2667
|
}
|
|
3408
2668
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
3409
2669
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
3410
|
-
console.log(
|
|
3411
|
-
const tmpDir =
|
|
2670
|
+
console.log(chalk18.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
2671
|
+
const tmpDir = fs8.mkdtempSync(path11.join(os6.tmpdir(), "vm0-"));
|
|
3412
2672
|
const tarPath = path11.join(tmpDir, "artifact.tar.gz");
|
|
3413
|
-
await
|
|
3414
|
-
console.log(
|
|
2673
|
+
await fs8.promises.writeFile(tarPath, tarBuffer);
|
|
2674
|
+
console.log(chalk18.dim("Syncing local files..."));
|
|
3415
2675
|
const remoteFiles = await listTarFiles(tarPath);
|
|
3416
2676
|
const remoteFilesSet = new Set(
|
|
3417
2677
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -3419,24 +2679,24 @@ var pullCommand2 = new Command23().name("pull").description("Pull cloud artifact
|
|
|
3419
2679
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
3420
2680
|
if (removedCount > 0) {
|
|
3421
2681
|
console.log(
|
|
3422
|
-
|
|
2682
|
+
chalk18.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
3423
2683
|
);
|
|
3424
2684
|
}
|
|
3425
|
-
console.log(
|
|
2685
|
+
console.log(chalk18.dim("Extracting files..."));
|
|
3426
2686
|
await tar5.extract({
|
|
3427
2687
|
file: tarPath,
|
|
3428
2688
|
cwd,
|
|
3429
2689
|
gzip: true
|
|
3430
2690
|
});
|
|
3431
|
-
await
|
|
3432
|
-
await
|
|
3433
|
-
console.log(
|
|
2691
|
+
await fs8.promises.unlink(tarPath);
|
|
2692
|
+
await fs8.promises.rmdir(tmpDir);
|
|
2693
|
+
console.log(chalk18.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
3434
2694
|
})
|
|
3435
2695
|
);
|
|
3436
2696
|
|
|
3437
2697
|
// src/commands/artifact/status.ts
|
|
3438
2698
|
import { Command as Command24 } from "commander";
|
|
3439
|
-
import
|
|
2699
|
+
import chalk19 from "chalk";
|
|
3440
2700
|
var statusCommand3 = new Command24().name("status").description("Show status of cloud artifact").action(
|
|
3441
2701
|
withErrorHandler(async () => {
|
|
3442
2702
|
const cwd = process.cwd();
|
|
@@ -3460,13 +2720,13 @@ var statusCommand3 = new Command24().name("status").description("Show status of
|
|
|
3460
2720
|
});
|
|
3461
2721
|
const shortVersion = info.versionId.slice(0, 8);
|
|
3462
2722
|
if ("empty" in info) {
|
|
3463
|
-
console.log(
|
|
3464
|
-
console.log(
|
|
2723
|
+
console.log(chalk19.green("\u2713 Found (empty)"));
|
|
2724
|
+
console.log(chalk19.dim(` Version: ${shortVersion}`));
|
|
3465
2725
|
} else {
|
|
3466
|
-
console.log(
|
|
3467
|
-
console.log(
|
|
3468
|
-
console.log(
|
|
3469
|
-
console.log(
|
|
2726
|
+
console.log(chalk19.green("\u2713 Found"));
|
|
2727
|
+
console.log(chalk19.dim(` Version: ${shortVersion}`));
|
|
2728
|
+
console.log(chalk19.dim(` Files: ${info.fileCount.toLocaleString()}`));
|
|
2729
|
+
console.log(chalk19.dim(` Size: ${formatBytes(info.size)}`));
|
|
3470
2730
|
}
|
|
3471
2731
|
} catch (error) {
|
|
3472
2732
|
if (error instanceof ApiRequestError && error.status === 404) {
|
|
@@ -3481,14 +2741,14 @@ var statusCommand3 = new Command24().name("status").description("Show status of
|
|
|
3481
2741
|
|
|
3482
2742
|
// src/commands/artifact/list.ts
|
|
3483
2743
|
import { Command as Command25 } from "commander";
|
|
3484
|
-
import
|
|
2744
|
+
import chalk20 from "chalk";
|
|
3485
2745
|
var listCommand3 = new Command25().name("list").alias("ls").description("List all remote artifacts").action(
|
|
3486
2746
|
withErrorHandler(async () => {
|
|
3487
2747
|
const items = await listStorages({ type: "artifact" });
|
|
3488
2748
|
if (items.length === 0) {
|
|
3489
|
-
console.log(
|
|
2749
|
+
console.log(chalk20.dim("No artifacts found"));
|
|
3490
2750
|
console.log(
|
|
3491
|
-
|
|
2751
|
+
chalk20.dim(
|
|
3492
2752
|
" Create one with: vm0 artifact init && vm0 artifact push"
|
|
3493
2753
|
)
|
|
3494
2754
|
);
|
|
@@ -3509,7 +2769,7 @@ var listCommand3 = new Command25().name("list").alias("ls").description("List al
|
|
|
3509
2769
|
"FILES".padStart(filesWidth),
|
|
3510
2770
|
"UPDATED"
|
|
3511
2771
|
].join(" ");
|
|
3512
|
-
console.log(
|
|
2772
|
+
console.log(chalk20.dim(header));
|
|
3513
2773
|
for (const item of items) {
|
|
3514
2774
|
const row = [
|
|
3515
2775
|
item.name.padEnd(nameWidth),
|
|
@@ -3524,16 +2784,16 @@ var listCommand3 = new Command25().name("list").alias("ls").description("List al
|
|
|
3524
2784
|
|
|
3525
2785
|
// src/commands/artifact/clone.ts
|
|
3526
2786
|
import { Command as Command26 } from "commander";
|
|
3527
|
-
import
|
|
2787
|
+
import chalk21 from "chalk";
|
|
3528
2788
|
var cloneCommand2 = new Command26().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(
|
|
3529
2789
|
withErrorHandler(async (name, destination) => {
|
|
3530
2790
|
const targetDir = destination || name;
|
|
3531
2791
|
console.log(`Cloning artifact: ${name}`);
|
|
3532
2792
|
const result = await cloneStorage(name, "artifact", targetDir);
|
|
3533
|
-
console.log(
|
|
2793
|
+
console.log(chalk21.green(`
|
|
3534
2794
|
\u2713 Successfully cloned artifact: ${name}`));
|
|
3535
|
-
console.log(
|
|
3536
|
-
console.log(
|
|
2795
|
+
console.log(chalk21.dim(` Location: ${targetDir}/`));
|
|
2796
|
+
console.log(chalk21.dim(` Version: ${result.versionId.slice(0, 8)}`));
|
|
3537
2797
|
})
|
|
3538
2798
|
);
|
|
3539
2799
|
|
|
@@ -3545,7 +2805,7 @@ import { Command as Command34 } from "commander";
|
|
|
3545
2805
|
|
|
3546
2806
|
// src/commands/memory/init.ts
|
|
3547
2807
|
import { Command as Command28 } from "commander";
|
|
3548
|
-
import
|
|
2808
|
+
import chalk22 from "chalk";
|
|
3549
2809
|
import path12 from "path";
|
|
3550
2810
|
var initCommand3 = new Command28().name("init").description("Initialize a memory in the current directory").option("-n, --name <name>", "Memory name (required in non-interactive mode)").action(
|
|
3551
2811
|
withErrorHandler(async (options) => {
|
|
@@ -3555,22 +2815,22 @@ var initCommand3 = new Command28().name("init").description("Initialize a memory
|
|
|
3555
2815
|
if (existingConfig) {
|
|
3556
2816
|
if (existingConfig.type === "memory") {
|
|
3557
2817
|
console.log(
|
|
3558
|
-
|
|
2818
|
+
chalk22.yellow(`Memory already initialized: ${existingConfig.name}`)
|
|
3559
2819
|
);
|
|
3560
2820
|
} else {
|
|
3561
2821
|
console.log(
|
|
3562
|
-
|
|
2822
|
+
chalk22.yellow(
|
|
3563
2823
|
`Directory already initialized as ${existingConfig.type}: ${existingConfig.name}`
|
|
3564
2824
|
)
|
|
3565
2825
|
);
|
|
3566
2826
|
console.log(
|
|
3567
|
-
|
|
2827
|
+
chalk22.dim(
|
|
3568
2828
|
" To change type, delete .vm0/storage.yaml and reinitialize"
|
|
3569
2829
|
)
|
|
3570
2830
|
);
|
|
3571
2831
|
}
|
|
3572
2832
|
console.log(
|
|
3573
|
-
|
|
2833
|
+
chalk22.dim(`Config file: ${path12.join(cwd, ".vm0", "storage.yaml")}`)
|
|
3574
2834
|
);
|
|
3575
2835
|
return;
|
|
3576
2836
|
}
|
|
@@ -3594,7 +2854,7 @@ var initCommand3 = new Command28().name("init").description("Initialize a memory
|
|
|
3594
2854
|
}
|
|
3595
2855
|
);
|
|
3596
2856
|
if (name === void 0) {
|
|
3597
|
-
console.log(
|
|
2857
|
+
console.log(chalk22.dim("Cancelled"));
|
|
3598
2858
|
return;
|
|
3599
2859
|
}
|
|
3600
2860
|
memoryName = name;
|
|
@@ -3607,9 +2867,9 @@ var initCommand3 = new Command28().name("init").description("Initialize a memory
|
|
|
3607
2867
|
});
|
|
3608
2868
|
}
|
|
3609
2869
|
await writeStorageConfig(memoryName, cwd, "memory");
|
|
3610
|
-
console.log(
|
|
2870
|
+
console.log(chalk22.green(`\u2713 Initialized memory: ${memoryName}`));
|
|
3611
2871
|
console.log(
|
|
3612
|
-
|
|
2872
|
+
chalk22.dim(
|
|
3613
2873
|
` Config saved to ${path12.join(cwd, ".vm0", "storage.yaml")}`
|
|
3614
2874
|
)
|
|
3615
2875
|
);
|
|
@@ -3618,7 +2878,7 @@ var initCommand3 = new Command28().name("init").description("Initialize a memory
|
|
|
3618
2878
|
|
|
3619
2879
|
// src/commands/memory/push.ts
|
|
3620
2880
|
import { Command as Command29 } from "commander";
|
|
3621
|
-
import
|
|
2881
|
+
import chalk23 from "chalk";
|
|
3622
2882
|
var pushCommand3 = new Command29().name("push").description("Push local files to cloud memory").option(
|
|
3623
2883
|
"-f, --force",
|
|
3624
2884
|
"Force upload even if content unchanged (recreate archive)"
|
|
@@ -3640,42 +2900,42 @@ var pushCommand3 = new Command29().name("push").description("Push local files to
|
|
|
3640
2900
|
console.log(`Pushing memory: ${config.name}`);
|
|
3641
2901
|
const result = await directUpload(config.name, "memory", cwd, {
|
|
3642
2902
|
onProgress: (message) => {
|
|
3643
|
-
console.log(
|
|
2903
|
+
console.log(chalk23.dim(message));
|
|
3644
2904
|
},
|
|
3645
2905
|
force: options.force
|
|
3646
2906
|
});
|
|
3647
2907
|
const shortVersion = result.versionId.slice(0, 8);
|
|
3648
2908
|
if (result.empty) {
|
|
3649
|
-
console.log(
|
|
2909
|
+
console.log(chalk23.dim("No files found (empty memory)"));
|
|
3650
2910
|
} else if (result.deduplicated) {
|
|
3651
|
-
console.log(
|
|
2911
|
+
console.log(chalk23.green("\u2713 Content unchanged (deduplicated)"));
|
|
3652
2912
|
} else {
|
|
3653
|
-
console.log(
|
|
2913
|
+
console.log(chalk23.green("\u2713 Upload complete"));
|
|
3654
2914
|
}
|
|
3655
|
-
console.log(
|
|
3656
|
-
console.log(
|
|
3657
|
-
console.log(
|
|
2915
|
+
console.log(chalk23.dim(` Version: ${shortVersion}`));
|
|
2916
|
+
console.log(chalk23.dim(` Files: ${result.fileCount.toLocaleString()}`));
|
|
2917
|
+
console.log(chalk23.dim(` Size: ${formatBytes(result.size)}`));
|
|
3658
2918
|
})
|
|
3659
2919
|
);
|
|
3660
2920
|
|
|
3661
2921
|
// src/commands/memory/pull.ts
|
|
3662
2922
|
import { Command as Command30 } from "commander";
|
|
3663
|
-
import
|
|
2923
|
+
import chalk24 from "chalk";
|
|
3664
2924
|
var pullCommand3 = new Command30().name("pull").description("Pull remote memory to local directory (latest version)").argument("[name]", "Memory name to pull", "memory").argument("[destination]", "Destination directory (default: memory name)").action(
|
|
3665
2925
|
withErrorHandler(async (name, destination) => {
|
|
3666
2926
|
const targetDir = destination || name;
|
|
3667
2927
|
console.log(`Pulling memory: ${name}`);
|
|
3668
2928
|
const result = await cloneStorage(name, "memory", targetDir);
|
|
3669
|
-
console.log(
|
|
2929
|
+
console.log(chalk24.green(`
|
|
3670
2930
|
\u2713 Successfully pulled memory: ${name}`));
|
|
3671
|
-
console.log(
|
|
3672
|
-
console.log(
|
|
2931
|
+
console.log(chalk24.dim(` Location: ${targetDir}/`));
|
|
2932
|
+
console.log(chalk24.dim(` Version: ${result.versionId.slice(0, 8)}`));
|
|
3673
2933
|
})
|
|
3674
2934
|
);
|
|
3675
2935
|
|
|
3676
2936
|
// src/commands/memory/status.ts
|
|
3677
2937
|
import { Command as Command31 } from "commander";
|
|
3678
|
-
import
|
|
2938
|
+
import chalk25 from "chalk";
|
|
3679
2939
|
var statusCommand4 = new Command31().name("status").description("Show status of cloud memory").action(
|
|
3680
2940
|
withErrorHandler(async () => {
|
|
3681
2941
|
const cwd = process.cwd();
|
|
@@ -3699,13 +2959,13 @@ var statusCommand4 = new Command31().name("status").description("Show status of
|
|
|
3699
2959
|
});
|
|
3700
2960
|
const shortVersion = info.versionId.slice(0, 8);
|
|
3701
2961
|
if ("empty" in info) {
|
|
3702
|
-
console.log(
|
|
3703
|
-
console.log(
|
|
2962
|
+
console.log(chalk25.green("\u2713 Found (empty)"));
|
|
2963
|
+
console.log(chalk25.dim(` Version: ${shortVersion}`));
|
|
3704
2964
|
} else {
|
|
3705
|
-
console.log(
|
|
3706
|
-
console.log(
|
|
3707
|
-
console.log(
|
|
3708
|
-
console.log(
|
|
2965
|
+
console.log(chalk25.green("\u2713 Found"));
|
|
2966
|
+
console.log(chalk25.dim(` Version: ${shortVersion}`));
|
|
2967
|
+
console.log(chalk25.dim(` Files: ${info.fileCount.toLocaleString()}`));
|
|
2968
|
+
console.log(chalk25.dim(` Size: ${formatBytes(info.size)}`));
|
|
3709
2969
|
}
|
|
3710
2970
|
} catch (error) {
|
|
3711
2971
|
if (error instanceof ApiRequestError && error.status === 404) {
|
|
@@ -3720,14 +2980,14 @@ var statusCommand4 = new Command31().name("status").description("Show status of
|
|
|
3720
2980
|
|
|
3721
2981
|
// src/commands/memory/list.ts
|
|
3722
2982
|
import { Command as Command32 } from "commander";
|
|
3723
|
-
import
|
|
2983
|
+
import chalk26 from "chalk";
|
|
3724
2984
|
var listCommand4 = new Command32().name("list").alias("ls").description("List all remote memory storages").action(
|
|
3725
2985
|
withErrorHandler(async () => {
|
|
3726
2986
|
const items = await listStorages({ type: "memory" });
|
|
3727
2987
|
if (items.length === 0) {
|
|
3728
|
-
console.log(
|
|
2988
|
+
console.log(chalk26.dim("No memory storages found"));
|
|
3729
2989
|
console.log(
|
|
3730
|
-
|
|
2990
|
+
chalk26.dim(" Memory is created automatically on first agent run")
|
|
3731
2991
|
);
|
|
3732
2992
|
return;
|
|
3733
2993
|
}
|
|
@@ -3746,7 +3006,7 @@ var listCommand4 = new Command32().name("list").alias("ls").description("List al
|
|
|
3746
3006
|
"FILES".padStart(filesWidth),
|
|
3747
3007
|
"UPDATED"
|
|
3748
3008
|
].join(" ");
|
|
3749
|
-
console.log(
|
|
3009
|
+
console.log(chalk26.dim(header));
|
|
3750
3010
|
for (const item of items) {
|
|
3751
3011
|
const row = [
|
|
3752
3012
|
item.name.padEnd(nameWidth),
|
|
@@ -3761,16 +3021,16 @@ var listCommand4 = new Command32().name("list").alias("ls").description("List al
|
|
|
3761
3021
|
|
|
3762
3022
|
// src/commands/memory/clone.ts
|
|
3763
3023
|
import { Command as Command33 } from "commander";
|
|
3764
|
-
import
|
|
3024
|
+
import chalk27 from "chalk";
|
|
3765
3025
|
var cloneCommand3 = new Command33().name("clone").description("Clone a remote memory to local directory (latest version)").argument("<name>", "Memory name to clone").argument("[destination]", "Destination directory (default: memory name)").action(
|
|
3766
3026
|
withErrorHandler(async (name, destination) => {
|
|
3767
3027
|
const targetDir = destination || name;
|
|
3768
3028
|
console.log(`Cloning memory: ${name}`);
|
|
3769
3029
|
const result = await cloneStorage(name, "memory", targetDir);
|
|
3770
|
-
console.log(
|
|
3030
|
+
console.log(chalk27.green(`
|
|
3771
3031
|
\u2713 Successfully cloned memory: ${name}`));
|
|
3772
|
-
console.log(
|
|
3773
|
-
console.log(
|
|
3032
|
+
console.log(chalk27.dim(` Location: ${targetDir}/`));
|
|
3033
|
+
console.log(chalk27.dim(` Version: ${result.versionId.slice(0, 8)}`));
|
|
3774
3034
|
})
|
|
3775
3035
|
);
|
|
3776
3036
|
|
|
@@ -3779,9 +3039,9 @@ var memoryCommand = new Command34().name("memory").description("Manage agent lon
|
|
|
3779
3039
|
|
|
3780
3040
|
// src/commands/cook/cook.ts
|
|
3781
3041
|
import { Command as Command35, Option as Option5 } from "commander";
|
|
3782
|
-
import
|
|
3042
|
+
import chalk29 from "chalk";
|
|
3783
3043
|
import { readFile as readFile6, mkdir as mkdir5 } from "fs/promises";
|
|
3784
|
-
import { existsSync as
|
|
3044
|
+
import { existsSync as existsSync8 } from "fs";
|
|
3785
3045
|
import path13 from "path";
|
|
3786
3046
|
import { parse as parseYaml3 } from "yaml";
|
|
3787
3047
|
|
|
@@ -3789,12 +3049,12 @@ import { parse as parseYaml3 } from "yaml";
|
|
|
3789
3049
|
import { homedir as homedir2 } from "os";
|
|
3790
3050
|
import { join as join8 } from "path";
|
|
3791
3051
|
import { readFile as readFile5, writeFile as writeFile4, mkdir as mkdir4 } from "fs/promises";
|
|
3792
|
-
import { existsSync as
|
|
3052
|
+
import { existsSync as existsSync6 } from "fs";
|
|
3793
3053
|
var CONFIG_DIR2 = join8(homedir2(), ".vm0");
|
|
3794
3054
|
var COOK_STATE_FILE = join8(CONFIG_DIR2, "cook.json");
|
|
3795
3055
|
var STALE_THRESHOLD_MS = 48 * 60 * 60 * 1e3;
|
|
3796
3056
|
async function loadCookStateFile() {
|
|
3797
|
-
if (!
|
|
3057
|
+
if (!existsSync6(COOK_STATE_FILE)) {
|
|
3798
3058
|
return { ppid: {} };
|
|
3799
3059
|
}
|
|
3800
3060
|
try {
|
|
@@ -3851,12 +3111,12 @@ async function saveCookState(state) {
|
|
|
3851
3111
|
}
|
|
3852
3112
|
|
|
3853
3113
|
// src/commands/cook/utils.ts
|
|
3854
|
-
import
|
|
3855
|
-
import { existsSync as
|
|
3114
|
+
import chalk28 from "chalk";
|
|
3115
|
+
import { existsSync as existsSync7 } from "fs";
|
|
3856
3116
|
var CONFIG_FILE2 = "vm0.yaml";
|
|
3857
3117
|
var ARTIFACT_DIR = "artifact";
|
|
3858
3118
|
function printCommand(cmd) {
|
|
3859
|
-
console.log(
|
|
3119
|
+
console.log(chalk28.dim(`> ${cmd}`));
|
|
3860
3120
|
}
|
|
3861
3121
|
function execVm0Command(args, options = {}) {
|
|
3862
3122
|
return new Promise((resolve, reject) => {
|
|
@@ -3953,9 +3213,9 @@ async function autoPullArtifact(runOutput, artifactDir) {
|
|
|
3953
3213
|
runOutput,
|
|
3954
3214
|
ARTIFACT_DIR
|
|
3955
3215
|
);
|
|
3956
|
-
if (serverVersion &&
|
|
3216
|
+
if (serverVersion && existsSync7(artifactDir)) {
|
|
3957
3217
|
console.log();
|
|
3958
|
-
console.log(
|
|
3218
|
+
console.log(chalk28.bold("Pulling updated artifact:"));
|
|
3959
3219
|
printCommand(`cd ${ARTIFACT_DIR}`);
|
|
3960
3220
|
printCommand(`vm0 artifact pull ${serverVersion}`);
|
|
3961
3221
|
try {
|
|
@@ -3965,9 +3225,9 @@ async function autoPullArtifact(runOutput, artifactDir) {
|
|
|
3965
3225
|
});
|
|
3966
3226
|
printCommand("cd ..");
|
|
3967
3227
|
} catch (error) {
|
|
3968
|
-
console.error(
|
|
3228
|
+
console.error(chalk28.red(`\u2717 Artifact pull failed`));
|
|
3969
3229
|
if (error instanceof Error) {
|
|
3970
|
-
console.error(
|
|
3230
|
+
console.error(chalk28.dim(` ${error.message}`));
|
|
3971
3231
|
}
|
|
3972
3232
|
}
|
|
3973
3233
|
}
|
|
@@ -3975,8 +3235,8 @@ async function autoPullArtifact(runOutput, artifactDir) {
|
|
|
3975
3235
|
|
|
3976
3236
|
// src/commands/cook/cook.ts
|
|
3977
3237
|
async function loadAndValidateConfig2() {
|
|
3978
|
-
console.log(
|
|
3979
|
-
if (!
|
|
3238
|
+
console.log(chalk29.bold(`Reading config: ${CONFIG_FILE2}`));
|
|
3239
|
+
if (!existsSync8(CONFIG_FILE2)) {
|
|
3980
3240
|
throw new Error(`Config file not found: ${CONFIG_FILE2}`);
|
|
3981
3241
|
}
|
|
3982
3242
|
let config;
|
|
@@ -3997,7 +3257,7 @@ async function loadAndValidateConfig2() {
|
|
|
3997
3257
|
const agentName = agentNames[0];
|
|
3998
3258
|
const volumeCount = config.volumes ? Object.keys(config.volumes).length : 0;
|
|
3999
3259
|
console.log(
|
|
4000
|
-
|
|
3260
|
+
chalk29.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
|
|
4001
3261
|
);
|
|
4002
3262
|
return { config, agentName, volumeCount };
|
|
4003
3263
|
}
|
|
@@ -4006,10 +3266,10 @@ async function processVolumes(config, cwd) {
|
|
|
4006
3266
|
return;
|
|
4007
3267
|
}
|
|
4008
3268
|
console.log();
|
|
4009
|
-
console.log(
|
|
3269
|
+
console.log(chalk29.bold("Processing volumes:"));
|
|
4010
3270
|
for (const volumeConfig of Object.values(config.volumes)) {
|
|
4011
3271
|
const volumeDir = path13.join(cwd, volumeConfig.name);
|
|
4012
|
-
if (!
|
|
3272
|
+
if (!existsSync8(volumeDir)) {
|
|
4013
3273
|
throw new Error(`Directory not found: ${volumeConfig.name}`, {
|
|
4014
3274
|
cause: new Error("Create the directory and add files first")
|
|
4015
3275
|
});
|
|
@@ -4040,10 +3300,10 @@ async function processVolumes(config, cwd) {
|
|
|
4040
3300
|
}
|
|
4041
3301
|
async function processArtifact(cwd) {
|
|
4042
3302
|
console.log();
|
|
4043
|
-
console.log(
|
|
3303
|
+
console.log(chalk29.bold("Processing artifact:"));
|
|
4044
3304
|
const artifactDir = path13.join(cwd, ARTIFACT_DIR);
|
|
4045
3305
|
try {
|
|
4046
|
-
if (!
|
|
3306
|
+
if (!existsSync8(artifactDir)) {
|
|
4047
3307
|
printCommand(`mkdir ${ARTIFACT_DIR}`);
|
|
4048
3308
|
await mkdir5(artifactDir, { recursive: true });
|
|
4049
3309
|
}
|
|
@@ -4072,7 +3332,7 @@ async function processArtifact(cwd) {
|
|
|
4072
3332
|
}
|
|
4073
3333
|
async function composeAgent(cwd, skipConfirm) {
|
|
4074
3334
|
console.log();
|
|
4075
|
-
console.log(
|
|
3335
|
+
console.log(chalk29.bold("Composing agent:"));
|
|
4076
3336
|
const composeArgs = skipConfirm ? ["compose", "--yes", CONFIG_FILE2] : ["compose", CONFIG_FILE2];
|
|
4077
3337
|
printCommand(`vm0 ${composeArgs.join(" ")}`);
|
|
4078
3338
|
try {
|
|
@@ -4086,7 +3346,7 @@ async function composeAgent(cwd, skipConfirm) {
|
|
|
4086
3346
|
}
|
|
4087
3347
|
async function runAgent(agentName, artifactDir, prompt, cwd, options) {
|
|
4088
3348
|
console.log();
|
|
4089
|
-
console.log(
|
|
3349
|
+
console.log(chalk29.bold("Running agent:"));
|
|
4090
3350
|
printCommand(
|
|
4091
3351
|
`vm0 run ${agentName} --artifact-name ${ARTIFACT_DIR} "${prompt}"`
|
|
4092
3352
|
);
|
|
@@ -4119,7 +3379,7 @@ var cookAction = new Command35().name("cook").description("Quick start: prepare,
|
|
|
4119
3379
|
withErrorHandler(
|
|
4120
3380
|
async (prompt, options) => {
|
|
4121
3381
|
if (options.autoUpdate !== false) {
|
|
4122
|
-
const shouldExit = await checkAndUpgrade("9.
|
|
3382
|
+
const shouldExit = await checkAndUpgrade("9.86.0", prompt);
|
|
4123
3383
|
if (shouldExit) {
|
|
4124
3384
|
process.exit(0);
|
|
4125
3385
|
}
|
|
@@ -4302,7 +3562,7 @@ var cookCommand = cookAction;
|
|
|
4302
3562
|
|
|
4303
3563
|
// src/commands/logs/index.ts
|
|
4304
3564
|
import { Command as Command40 } from "commander";
|
|
4305
|
-
import
|
|
3565
|
+
import chalk31 from "chalk";
|
|
4306
3566
|
|
|
4307
3567
|
// src/lib/utils/paginate.ts
|
|
4308
3568
|
async function paginate(options) {
|
|
@@ -4329,7 +3589,7 @@ async function paginate(options) {
|
|
|
4329
3589
|
|
|
4330
3590
|
// src/commands/logs/search.ts
|
|
4331
3591
|
import { Command as Command39 } from "commander";
|
|
4332
|
-
import
|
|
3592
|
+
import chalk30 from "chalk";
|
|
4333
3593
|
var SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
4334
3594
|
function renderEvent(event, renderer) {
|
|
4335
3595
|
const eventData = event.eventData;
|
|
@@ -4385,7 +3645,7 @@ function renderResults(response) {
|
|
|
4385
3645
|
isFirstGroup = false;
|
|
4386
3646
|
const firstTimestamp = group.results[0].matchedEvent.createdAt;
|
|
4387
3647
|
console.log(
|
|
4388
|
-
|
|
3648
|
+
chalk30.bold(formatRunHeader(runId, group.agentName, firstTimestamp))
|
|
4389
3649
|
);
|
|
4390
3650
|
for (const result of group.results) {
|
|
4391
3651
|
const renderer = new EventRenderer({
|
|
@@ -4405,7 +3665,7 @@ function renderResults(response) {
|
|
|
4405
3665
|
if (response.hasMore) {
|
|
4406
3666
|
console.log();
|
|
4407
3667
|
console.log(
|
|
4408
|
-
|
|
3668
|
+
chalk30.dim(
|
|
4409
3669
|
` Showing first ${response.results.length} matches. Use --limit to see more.`
|
|
4410
3670
|
)
|
|
4411
3671
|
);
|
|
@@ -4426,9 +3686,9 @@ var searchCommand = new Command39().name("search").description("Search agent eve
|
|
|
4426
3686
|
after
|
|
4427
3687
|
});
|
|
4428
3688
|
if (response.results.length === 0) {
|
|
4429
|
-
console.log(
|
|
3689
|
+
console.log(chalk30.dim("No matches found"));
|
|
4430
3690
|
console.log(
|
|
4431
|
-
|
|
3691
|
+
chalk30.dim(
|
|
4432
3692
|
" Try a broader search with --since 30d or a different keyword"
|
|
4433
3693
|
)
|
|
4434
3694
|
);
|
|
@@ -4464,37 +3724,37 @@ function formatMetric(metric) {
|
|
|
4464
3724
|
function formatNetworkDeny(entry) {
|
|
4465
3725
|
const method = entry.method || "???";
|
|
4466
3726
|
const url = entry.url || entry.host || "unknown";
|
|
4467
|
-
const firewall = entry.firewall_name ? ` ${
|
|
4468
|
-
return `[${entry.timestamp}] ${method.padEnd(6)} ${
|
|
3727
|
+
const firewall = entry.firewall_name ? ` ${chalk31.cyan(`[${entry.firewall_name}]`)}` : "";
|
|
3728
|
+
return `[${entry.timestamp}] ${method.padEnd(6)} ${chalk31.red.bold("DENY")} ${chalk31.dim(url)}${firewall}`;
|
|
4469
3729
|
}
|
|
4470
3730
|
function formatNetworkRequest(entry) {
|
|
4471
3731
|
let statusColor;
|
|
4472
3732
|
const status = entry.status || 0;
|
|
4473
3733
|
if (status >= 200 && status < 300) {
|
|
4474
|
-
statusColor =
|
|
3734
|
+
statusColor = chalk31.green;
|
|
4475
3735
|
} else if (status >= 300 && status < 400) {
|
|
4476
|
-
statusColor =
|
|
3736
|
+
statusColor = chalk31.yellow;
|
|
4477
3737
|
} else if (status >= 400) {
|
|
4478
|
-
statusColor =
|
|
3738
|
+
statusColor = chalk31.red;
|
|
4479
3739
|
} else {
|
|
4480
|
-
statusColor =
|
|
3740
|
+
statusColor = chalk31.gray;
|
|
4481
3741
|
}
|
|
4482
3742
|
let latencyColor;
|
|
4483
3743
|
const latencyMs = entry.latency_ms || 0;
|
|
4484
3744
|
if (latencyMs < 500) {
|
|
4485
|
-
latencyColor =
|
|
3745
|
+
latencyColor = chalk31.green;
|
|
4486
3746
|
} else if (latencyMs < 2e3) {
|
|
4487
|
-
latencyColor =
|
|
3747
|
+
latencyColor = chalk31.yellow;
|
|
4488
3748
|
} else {
|
|
4489
|
-
latencyColor =
|
|
3749
|
+
latencyColor = chalk31.red;
|
|
4490
3750
|
}
|
|
4491
3751
|
const method = entry.method || "???";
|
|
4492
3752
|
const requestSize = entry.request_size || 0;
|
|
4493
3753
|
const responseSize = entry.response_size || 0;
|
|
4494
3754
|
const url = entry.url || entry.host || "unknown";
|
|
4495
|
-
const firewall = entry.firewall_name ? ` ${
|
|
4496
|
-
const error = entry.firewall_error ? ` ${
|
|
4497
|
-
return `[${entry.timestamp}] ${method.padEnd(6)} ${statusColor(status)} ${latencyColor(latencyMs + "ms")} ${formatBytes(requestSize)}/${formatBytes(responseSize)} ${
|
|
3755
|
+
const firewall = entry.firewall_name ? ` ${chalk31.cyan(`[${entry.firewall_name}]`)}` : "";
|
|
3756
|
+
const error = entry.firewall_error ? ` ${chalk31.red(entry.firewall_error)}` : "";
|
|
3757
|
+
return `[${entry.timestamp}] ${method.padEnd(6)} ${statusColor(status)} ${latencyColor(latencyMs + "ms")} ${formatBytes(requestSize)}/${formatBytes(responseSize)} ${chalk31.dim(url)}${firewall}${error}`;
|
|
4498
3758
|
}
|
|
4499
3759
|
function formatNetworkTcp(entry) {
|
|
4500
3760
|
const host = entry.host || "unknown";
|
|
@@ -4502,15 +3762,15 @@ function formatNetworkTcp(entry) {
|
|
|
4502
3762
|
const requestSize = entry.request_size || 0;
|
|
4503
3763
|
const responseSize = entry.response_size || 0;
|
|
4504
3764
|
const latencyMs = entry.latency_ms || 0;
|
|
4505
|
-
const error = entry.error ? ` ${
|
|
4506
|
-
return `[${entry.timestamp}] ${
|
|
3765
|
+
const error = entry.error ? ` ${chalk31.red(entry.error)}` : "";
|
|
3766
|
+
return `[${entry.timestamp}] ${chalk31.blue("TCP")} ${latencyMs}ms ${formatBytes(requestSize)}/${formatBytes(responseSize)} ${chalk31.dim(`${host}:${port}`)}${error}`;
|
|
4507
3767
|
}
|
|
4508
3768
|
function formatNetworkOther(entry) {
|
|
4509
3769
|
const proto = (entry.type || "???").toUpperCase();
|
|
4510
3770
|
const host = entry.host || "unknown";
|
|
4511
3771
|
const port = entry.port || 0;
|
|
4512
3772
|
const size = entry.request_size || 0;
|
|
4513
|
-
return `[${entry.timestamp}] ${
|
|
3773
|
+
return `[${entry.timestamp}] ${chalk31.magenta(proto.padEnd(5))} ${formatBytes(size)} ${chalk31.dim(`${host}:${port}`)}`;
|
|
4514
3774
|
}
|
|
4515
3775
|
function formatNetworkLog(entry) {
|
|
4516
3776
|
if (entry.type === "tcp") return formatNetworkTcp(entry);
|
|
@@ -4618,7 +3878,7 @@ async function showAgentEvents(runId, options, platformUrl) {
|
|
|
4618
3878
|
order: options.order
|
|
4619
3879
|
});
|
|
4620
3880
|
if (firstResponse.events.length === 0) {
|
|
4621
|
-
console.log(
|
|
3881
|
+
console.log(chalk31.yellow("No agent events found for this run"));
|
|
4622
3882
|
return;
|
|
4623
3883
|
}
|
|
4624
3884
|
let allEvents;
|
|
@@ -4650,7 +3910,7 @@ async function showAgentEvents(runId, options, platformUrl) {
|
|
|
4650
3910
|
for (const event of events) {
|
|
4651
3911
|
renderAgentEvent(event, renderer);
|
|
4652
3912
|
}
|
|
4653
|
-
console.log(
|
|
3913
|
+
console.log(chalk31.dim(`View on platform: ${platformUrl}`));
|
|
4654
3914
|
}
|
|
4655
3915
|
async function showSystemLog(runId, options) {
|
|
4656
3916
|
const limit = options.targetCount === "all" ? PAGE_LIMIT : Math.min(options.targetCount, PAGE_LIMIT);
|
|
@@ -4660,7 +3920,7 @@ async function showSystemLog(runId, options) {
|
|
|
4660
3920
|
order: options.order
|
|
4661
3921
|
});
|
|
4662
3922
|
if (!response.systemLog) {
|
|
4663
|
-
console.log(
|
|
3923
|
+
console.log(chalk31.yellow("No system log found for this run"));
|
|
4664
3924
|
return;
|
|
4665
3925
|
}
|
|
4666
3926
|
console.log(response.systemLog);
|
|
@@ -4672,7 +3932,7 @@ async function showMetrics(runId, options) {
|
|
|
4672
3932
|
order: options.order
|
|
4673
3933
|
});
|
|
4674
3934
|
if (firstResponse.metrics.length === 0) {
|
|
4675
|
-
console.log(
|
|
3935
|
+
console.log(chalk31.yellow("No metrics found for this run"));
|
|
4676
3936
|
return;
|
|
4677
3937
|
}
|
|
4678
3938
|
let allMetrics;
|
|
@@ -4712,7 +3972,7 @@ async function showNetworkLogs(runId, options) {
|
|
|
4712
3972
|
});
|
|
4713
3973
|
if (firstResponse.networkLogs.length === 0) {
|
|
4714
3974
|
console.log(
|
|
4715
|
-
|
|
3975
|
+
chalk31.yellow(
|
|
4716
3976
|
"No network logs found for this run. Network logs are only captured when using a runner with proxy enabled"
|
|
4717
3977
|
)
|
|
4718
3978
|
);
|
|
@@ -4750,9 +4010,9 @@ async function showNetworkLogs(runId, options) {
|
|
|
4750
4010
|
|
|
4751
4011
|
// src/commands/init/index.ts
|
|
4752
4012
|
import { Command as Command41 } from "commander";
|
|
4753
|
-
import
|
|
4013
|
+
import chalk32 from "chalk";
|
|
4754
4014
|
import path16 from "path";
|
|
4755
|
-
import { existsSync as
|
|
4015
|
+
import { existsSync as existsSync9 } from "fs";
|
|
4756
4016
|
import { writeFile as writeFile5 } from "fs/promises";
|
|
4757
4017
|
var VM0_YAML_FILE = "vm0.yaml";
|
|
4758
4018
|
var AGENTS_MD_FILE = "AGENTS.md";
|
|
@@ -4784,8 +4044,8 @@ You are a HackerNews AI content curator.
|
|
|
4784
4044
|
}
|
|
4785
4045
|
function checkExistingFiles() {
|
|
4786
4046
|
const existingFiles = [];
|
|
4787
|
-
if (
|
|
4788
|
-
if (
|
|
4047
|
+
if (existsSync9(VM0_YAML_FILE)) existingFiles.push(VM0_YAML_FILE);
|
|
4048
|
+
if (existsSync9(AGENTS_MD_FILE)) existingFiles.push(AGENTS_MD_FILE);
|
|
4789
4049
|
return existingFiles;
|
|
4790
4050
|
}
|
|
4791
4051
|
var initCommand4 = new Command41().name("init").description("Initialize a new VM0 project in the current directory").option("-f, --force", "Overwrite existing files").option("-n, --name <name>", "Agent name (required in non-interactive mode)").action(
|
|
@@ -4817,7 +4077,7 @@ var initCommand4 = new Command41().name("init").description("Initialize a new VM
|
|
|
4817
4077
|
}
|
|
4818
4078
|
);
|
|
4819
4079
|
if (name === void 0) {
|
|
4820
|
-
console.log(
|
|
4080
|
+
console.log(chalk32.dim("Cancelled"));
|
|
4821
4081
|
return;
|
|
4822
4082
|
}
|
|
4823
4083
|
agentName = name;
|
|
@@ -4831,27 +4091,27 @@ var initCommand4 = new Command41().name("init").description("Initialize a new VM
|
|
|
4831
4091
|
}
|
|
4832
4092
|
await writeFile5(VM0_YAML_FILE, generateVm0Yaml(agentName));
|
|
4833
4093
|
const vm0Status = existingFiles.includes(VM0_YAML_FILE) ? " (overwritten)" : "";
|
|
4834
|
-
console.log(
|
|
4094
|
+
console.log(chalk32.green(`\u2713 Created ${VM0_YAML_FILE}${vm0Status}`));
|
|
4835
4095
|
await writeFile5(AGENTS_MD_FILE, generateAgentsMd());
|
|
4836
4096
|
const agentsStatus = existingFiles.includes(AGENTS_MD_FILE) ? " (overwritten)" : "";
|
|
4837
|
-
console.log(
|
|
4097
|
+
console.log(chalk32.green(`\u2713 Created ${AGENTS_MD_FILE}${agentsStatus}`));
|
|
4838
4098
|
console.log();
|
|
4839
4099
|
console.log("Next steps:");
|
|
4840
4100
|
console.log(
|
|
4841
|
-
` 1. Set up model provider (one-time): ${
|
|
4101
|
+
` 1. Set up model provider (one-time): ${chalk32.cyan("zero org model-provider setup")}`
|
|
4842
4102
|
);
|
|
4843
4103
|
console.log(
|
|
4844
|
-
` 2. Edit ${
|
|
4104
|
+
` 2. Edit ${chalk32.cyan("AGENTS.md")} to customize your agent's workflow`
|
|
4845
4105
|
);
|
|
4846
4106
|
console.log(
|
|
4847
|
-
` 3. Run your agent: ${
|
|
4107
|
+
` 3. Run your agent: ${chalk32.cyan(`vm0 cook "let's start working"`)}`
|
|
4848
4108
|
);
|
|
4849
4109
|
})
|
|
4850
4110
|
);
|
|
4851
4111
|
|
|
4852
4112
|
// src/commands/upgrade/index.ts
|
|
4853
4113
|
import { Command as Command42 } from "commander";
|
|
4854
|
-
import
|
|
4114
|
+
import chalk33 from "chalk";
|
|
4855
4115
|
var upgradeCommand = new Command42().name("upgrade").description("Upgrade vm0 CLI to the latest version").action(
|
|
4856
4116
|
withErrorHandler(async () => {
|
|
4857
4117
|
console.log("Checking for updates...");
|
|
@@ -4859,13 +4119,13 @@ var upgradeCommand = new Command42().name("upgrade").description("Upgrade vm0 CL
|
|
|
4859
4119
|
if (latestVersion === null) {
|
|
4860
4120
|
throw new Error("Could not check for updates. Please try again later.");
|
|
4861
4121
|
}
|
|
4862
|
-
if (latestVersion === "9.
|
|
4863
|
-
console.log(
|
|
4122
|
+
if (latestVersion === "9.86.0") {
|
|
4123
|
+
console.log(chalk33.green(`\u2713 Already up to date (${"9.86.0"})`));
|
|
4864
4124
|
return;
|
|
4865
4125
|
}
|
|
4866
4126
|
console.log(
|
|
4867
|
-
|
|
4868
|
-
`Current version: ${"9.
|
|
4127
|
+
chalk33.yellow(
|
|
4128
|
+
`Current version: ${"9.86.0"} -> Latest version: ${latestVersion}`
|
|
4869
4129
|
)
|
|
4870
4130
|
);
|
|
4871
4131
|
console.log();
|
|
@@ -4873,26 +4133,26 @@ var upgradeCommand = new Command42().name("upgrade").description("Upgrade vm0 CL
|
|
|
4873
4133
|
if (!isAutoUpgradeSupported(packageManager)) {
|
|
4874
4134
|
if (packageManager === "unknown") {
|
|
4875
4135
|
console.log(
|
|
4876
|
-
|
|
4136
|
+
chalk33.yellow(
|
|
4877
4137
|
"Could not detect your package manager for auto-upgrade."
|
|
4878
4138
|
)
|
|
4879
4139
|
);
|
|
4880
4140
|
} else {
|
|
4881
4141
|
console.log(
|
|
4882
|
-
|
|
4142
|
+
chalk33.yellow(
|
|
4883
4143
|
`Auto-upgrade is not supported for ${packageManager}.`
|
|
4884
4144
|
)
|
|
4885
4145
|
);
|
|
4886
4146
|
}
|
|
4887
|
-
console.log(
|
|
4888
|
-
console.log(
|
|
4147
|
+
console.log(chalk33.yellow("Please upgrade manually:"));
|
|
4148
|
+
console.log(chalk33.cyan(` ${getManualUpgradeCommand(packageManager)}`));
|
|
4889
4149
|
return;
|
|
4890
4150
|
}
|
|
4891
4151
|
console.log(`Upgrading via ${packageManager}...`);
|
|
4892
4152
|
const success = await performUpgrade(packageManager);
|
|
4893
4153
|
if (success) {
|
|
4894
4154
|
console.log(
|
|
4895
|
-
|
|
4155
|
+
chalk33.green(`\u2713 Upgraded from ${"9.86.0"} to ${latestVersion}`)
|
|
4896
4156
|
);
|
|
4897
4157
|
return;
|
|
4898
4158
|
}
|
|
@@ -4906,7 +4166,7 @@ var upgradeCommand = new Command42().name("upgrade").description("Upgrade vm0 CL
|
|
|
4906
4166
|
|
|
4907
4167
|
// src/commands/whoami.ts
|
|
4908
4168
|
import { Command as Command43 } from "commander";
|
|
4909
|
-
import
|
|
4169
|
+
import chalk34 from "chalk";
|
|
4910
4170
|
function isInsideSandbox() {
|
|
4911
4171
|
return !!process.env.VM0_RUN_ID;
|
|
4912
4172
|
}
|
|
@@ -4918,12 +4178,12 @@ async function showSandboxInfo() {
|
|
|
4918
4178
|
const apiUrl = process.env.VM0_API_URL;
|
|
4919
4179
|
const hasAgentInfo = agentId || cliAgentType;
|
|
4920
4180
|
if (hasAgentInfo) {
|
|
4921
|
-
console.log(
|
|
4181
|
+
console.log(chalk34.bold("Agent:"));
|
|
4922
4182
|
if (agentId) console.log(` ID: ${agentId}`);
|
|
4923
4183
|
if (cliAgentType) console.log(` Framework: ${cliAgentType}`);
|
|
4924
4184
|
console.log();
|
|
4925
4185
|
}
|
|
4926
|
-
console.log(
|
|
4186
|
+
console.log(chalk34.bold("Run:"));
|
|
4927
4187
|
if (runId) console.log(` ID: ${runId}`);
|
|
4928
4188
|
if (activeOrg) console.log(` Org: ${activeOrg}`);
|
|
4929
4189
|
if (apiUrl) console.log(` API: ${apiUrl}`);
|
|
@@ -4932,19 +4192,19 @@ async function showLocalInfo() {
|
|
|
4932
4192
|
const token = await getToken();
|
|
4933
4193
|
const apiUrl = await getApiUrl();
|
|
4934
4194
|
const activeOrg = await getActiveOrg();
|
|
4935
|
-
console.log(
|
|
4195
|
+
console.log(chalk34.bold("Auth:"));
|
|
4936
4196
|
if (token) {
|
|
4937
4197
|
const tokenSource = process.env.VM0_TOKEN ? "VM0_TOKEN env var" : "config file";
|
|
4938
4198
|
console.log(
|
|
4939
|
-
` Status: ${
|
|
4199
|
+
` Status: ${chalk34.green("Authenticated")} (via ${tokenSource})`
|
|
4940
4200
|
);
|
|
4941
4201
|
} else {
|
|
4942
|
-
console.log(` Status: ${
|
|
4202
|
+
console.log(` Status: ${chalk34.dim("Not authenticated")}`);
|
|
4943
4203
|
}
|
|
4944
4204
|
console.log(` API: ${apiUrl}`);
|
|
4945
4205
|
console.log();
|
|
4946
4206
|
if (activeOrg) {
|
|
4947
|
-
console.log(
|
|
4207
|
+
console.log(chalk34.bold("Org:"));
|
|
4948
4208
|
console.log(` Active: ${activeOrg}`);
|
|
4949
4209
|
}
|
|
4950
4210
|
}
|
|
@@ -4960,7 +4220,7 @@ var whoamiCommand = new Command43().name("whoami").description("Show current ide
|
|
|
4960
4220
|
|
|
4961
4221
|
// src/index.ts
|
|
4962
4222
|
var program = new Command44();
|
|
4963
|
-
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.
|
|
4223
|
+
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.86.0");
|
|
4964
4224
|
program.addCommand(authCommand);
|
|
4965
4225
|
program.addCommand(infoCommand);
|
|
4966
4226
|
program.addCommand(composeCommand);
|