@vm0/cli 9.37.7 → 9.38.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +354 -157
- package/package.json +2 -1
package/index.js
CHANGED
|
@@ -45,7 +45,7 @@ if (DSN) {
|
|
|
45
45
|
Sentry.init({
|
|
46
46
|
dsn: DSN,
|
|
47
47
|
environment: process.env.SENTRY_ENVIRONMENT ?? "production",
|
|
48
|
-
release: "9.
|
|
48
|
+
release: "9.38.1",
|
|
49
49
|
sendDefaultPii: false,
|
|
50
50
|
tracesSampleRate: 0,
|
|
51
51
|
shutdownTimeout: 500,
|
|
@@ -64,7 +64,7 @@ if (DSN) {
|
|
|
64
64
|
}
|
|
65
65
|
});
|
|
66
66
|
Sentry.setContext("cli", {
|
|
67
|
-
version: "9.
|
|
67
|
+
version: "9.38.1",
|
|
68
68
|
command: process.argv.slice(2).join(" ")
|
|
69
69
|
});
|
|
70
70
|
Sentry.setContext("runtime", {
|
|
@@ -607,7 +607,7 @@ function getConfigPath() {
|
|
|
607
607
|
return join2(homedir2(), ".vm0", "config.json");
|
|
608
608
|
}
|
|
609
609
|
var infoCommand = new Command6().name("info").description("Display environment and debug information").action(async () => {
|
|
610
|
-
console.log(chalk7.bold(`VM0 CLI v${"9.
|
|
610
|
+
console.log(chalk7.bold(`VM0 CLI v${"9.38.1"}`));
|
|
611
611
|
console.log();
|
|
612
612
|
const config = await loadConfig();
|
|
613
613
|
const hasEnvToken = !!process.env.VM0_TOKEN;
|
|
@@ -3626,16 +3626,12 @@ var CONNECTOR_TYPES = {
|
|
|
3626
3626
|
label: "API",
|
|
3627
3627
|
helpText: "Server-provisioned ngrok tunnel credentials.",
|
|
3628
3628
|
secrets: {
|
|
3629
|
-
|
|
3630
|
-
label: "ngrok Authtoken",
|
|
3631
|
-
required: true
|
|
3632
|
-
},
|
|
3633
|
-
COMPUTER_CONNECTOR_TOKEN: {
|
|
3629
|
+
COMPUTER_CONNECTOR_BRIDGE_TOKEN: {
|
|
3634
3630
|
label: "Bridge Token",
|
|
3635
3631
|
required: true
|
|
3636
3632
|
},
|
|
3637
|
-
|
|
3638
|
-
label: "
|
|
3633
|
+
COMPUTER_CONNECTOR_DOMAIN_ID: {
|
|
3634
|
+
label: "Domain ID",
|
|
3639
3635
|
required: true
|
|
3640
3636
|
},
|
|
3641
3637
|
COMPUTER_CONNECTOR_DOMAIN: {
|
|
@@ -3647,9 +3643,7 @@ var CONNECTOR_TYPES = {
|
|
|
3647
3643
|
},
|
|
3648
3644
|
defaultAuthMethod: "api",
|
|
3649
3645
|
environmentMapping: {
|
|
3650
|
-
|
|
3651
|
-
COMPUTER_CONNECTOR_TOKEN: "$secrets.COMPUTER_CONNECTOR_TOKEN",
|
|
3652
|
-
COMPUTER_CONNECTOR_ENDPOINT: "$secrets.COMPUTER_CONNECTOR_ENDPOINT",
|
|
3646
|
+
COMPUTER_CONNECTOR_BRIDGE_TOKEN: "$secrets.COMPUTER_CONNECTOR_BRIDGE_TOKEN",
|
|
3653
3647
|
COMPUTER_CONNECTOR_DOMAIN: "$secrets.COMPUTER_CONNECTOR_DOMAIN"
|
|
3654
3648
|
}
|
|
3655
3649
|
},
|
|
@@ -6480,7 +6474,7 @@ var composeCommand = new Command7().name("compose").description("Create or updat
|
|
|
6480
6474
|
options.autoUpdate = false;
|
|
6481
6475
|
}
|
|
6482
6476
|
if (options.autoUpdate !== false) {
|
|
6483
|
-
await startSilentUpgrade("9.
|
|
6477
|
+
await startSilentUpgrade("9.38.1");
|
|
6484
6478
|
}
|
|
6485
6479
|
try {
|
|
6486
6480
|
let result;
|
|
@@ -8694,7 +8688,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
8694
8688
|
async (identifier, prompt, options) => {
|
|
8695
8689
|
try {
|
|
8696
8690
|
if (options.autoUpdate !== false) {
|
|
8697
|
-
await startSilentUpgrade("9.
|
|
8691
|
+
await startSilentUpgrade("9.38.1");
|
|
8698
8692
|
}
|
|
8699
8693
|
const { scope, name, version } = parseIdentifier(identifier);
|
|
8700
8694
|
if (scope && !options.experimentalSharedAgent) {
|
|
@@ -10270,7 +10264,7 @@ var cookAction = new Command27().name("cook").description("Quick start: prepare,
|
|
|
10270
10264
|
).option("-y, --yes", "Skip confirmation prompts").option("-v, --verbose", "Show full tool inputs and outputs").addOption(new Option5("--debug-no-mock-claude").hideHelp()).addOption(new Option5("--no-auto-update").hideHelp()).action(
|
|
10271
10265
|
async (prompt, options) => {
|
|
10272
10266
|
if (options.autoUpdate !== false) {
|
|
10273
|
-
const shouldExit = await checkAndUpgrade("9.
|
|
10267
|
+
const shouldExit = await checkAndUpgrade("9.38.1", prompt);
|
|
10274
10268
|
if (shouldExit) {
|
|
10275
10269
|
process.exit(0);
|
|
10276
10270
|
}
|
|
@@ -13774,8 +13768,183 @@ import { Command as Command71 } from "commander";
|
|
|
13774
13768
|
|
|
13775
13769
|
// src/commands/connector/connect.ts
|
|
13776
13770
|
import { Command as Command67 } from "commander";
|
|
13777
|
-
import
|
|
13771
|
+
import chalk68 from "chalk";
|
|
13778
13772
|
import { initClient as initClient13 } from "@ts-rest/core";
|
|
13773
|
+
|
|
13774
|
+
// src/commands/connector/lib/computer/start-services.ts
|
|
13775
|
+
import { spawn as spawn3 } from "child_process";
|
|
13776
|
+
import { access as access2, constants } from "fs/promises";
|
|
13777
|
+
import { createServer } from "net";
|
|
13778
|
+
import { homedir as homedir4 } from "os";
|
|
13779
|
+
import { join as join11 } from "path";
|
|
13780
|
+
import chalk67 from "chalk";
|
|
13781
|
+
|
|
13782
|
+
// src/commands/connector/lib/computer/ngrok.ts
|
|
13783
|
+
import ngrok from "@ngrok/ngrok";
|
|
13784
|
+
async function startNgrokTunnels(ngrokToken, endpointPrefix, webdavPort, cdpPort) {
|
|
13785
|
+
await ngrok.forward({
|
|
13786
|
+
addr: `localhost:${webdavPort}`,
|
|
13787
|
+
authtoken: ngrokToken,
|
|
13788
|
+
domain: `webdav.${endpointPrefix}.internal`
|
|
13789
|
+
});
|
|
13790
|
+
await ngrok.forward({
|
|
13791
|
+
addr: `localhost:${cdpPort}`,
|
|
13792
|
+
authtoken: ngrokToken,
|
|
13793
|
+
domain: `chrome.${endpointPrefix}.internal`
|
|
13794
|
+
});
|
|
13795
|
+
}
|
|
13796
|
+
async function stopNgrokTunnels() {
|
|
13797
|
+
await ngrok.kill();
|
|
13798
|
+
}
|
|
13799
|
+
|
|
13800
|
+
// src/commands/connector/lib/computer/start-services.ts
|
|
13801
|
+
var CHROME_CANDIDATES = [
|
|
13802
|
+
// macOS absolute paths
|
|
13803
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
13804
|
+
"/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",
|
|
13805
|
+
"/Applications/Chromium.app/Contents/MacOS/Chromium",
|
|
13806
|
+
// Linux / PATH-based
|
|
13807
|
+
"google-chrome",
|
|
13808
|
+
"google-chrome-stable",
|
|
13809
|
+
"chromium-browser",
|
|
13810
|
+
"chromium",
|
|
13811
|
+
"chrome"
|
|
13812
|
+
];
|
|
13813
|
+
async function getRandomPort() {
|
|
13814
|
+
return new Promise((resolve, reject) => {
|
|
13815
|
+
const server = createServer();
|
|
13816
|
+
server.listen(0, "127.0.0.1", () => {
|
|
13817
|
+
const { port } = server.address();
|
|
13818
|
+
server.close(() => resolve(port));
|
|
13819
|
+
});
|
|
13820
|
+
server.on("error", reject);
|
|
13821
|
+
});
|
|
13822
|
+
}
|
|
13823
|
+
async function findBinary(...candidates) {
|
|
13824
|
+
for (const candidate of candidates) {
|
|
13825
|
+
if (candidate.startsWith("/")) {
|
|
13826
|
+
try {
|
|
13827
|
+
await access2(candidate, constants.X_OK);
|
|
13828
|
+
return candidate;
|
|
13829
|
+
} catch {
|
|
13830
|
+
}
|
|
13831
|
+
} else {
|
|
13832
|
+
const found = await new Promise((resolve) => {
|
|
13833
|
+
const child = spawn3("which", [candidate]);
|
|
13834
|
+
child.on("close", (code) => resolve(code === 0));
|
|
13835
|
+
});
|
|
13836
|
+
if (found) return candidate;
|
|
13837
|
+
}
|
|
13838
|
+
}
|
|
13839
|
+
return null;
|
|
13840
|
+
}
|
|
13841
|
+
async function checkComputerDependencies() {
|
|
13842
|
+
const wsgidavBinary = await findBinary("wsgidav");
|
|
13843
|
+
if (!wsgidavBinary) {
|
|
13844
|
+
throw new Error(
|
|
13845
|
+
"wsgidav not found\n\nInstall with: pip install wsgidav[cheroot]"
|
|
13846
|
+
);
|
|
13847
|
+
}
|
|
13848
|
+
const chromeBinary = await findBinary(...CHROME_CANDIDATES);
|
|
13849
|
+
if (!chromeBinary) {
|
|
13850
|
+
throw new Error("Chrome not found\n\nInstall Google Chrome or Chromium");
|
|
13851
|
+
}
|
|
13852
|
+
}
|
|
13853
|
+
async function startComputerServices(credentials) {
|
|
13854
|
+
console.log(chalk67.cyan("Starting computer connector services..."));
|
|
13855
|
+
const wsgidavBinary = await findBinary("wsgidav");
|
|
13856
|
+
if (!wsgidavBinary) {
|
|
13857
|
+
throw new Error(
|
|
13858
|
+
"wsgidav not found\n\nInstall with: pip install wsgidav[cheroot]"
|
|
13859
|
+
);
|
|
13860
|
+
}
|
|
13861
|
+
const chromeBinary = await findBinary(...CHROME_CANDIDATES);
|
|
13862
|
+
if (!chromeBinary) {
|
|
13863
|
+
throw new Error("Chrome not found\n\nInstall Google Chrome or Chromium");
|
|
13864
|
+
}
|
|
13865
|
+
const webdavPort = await getRandomPort();
|
|
13866
|
+
const cdpPort = await getRandomPort();
|
|
13867
|
+
const downloadsPath = join11(homedir4(), "Downloads");
|
|
13868
|
+
const wsgidav = spawn3(
|
|
13869
|
+
wsgidavBinary,
|
|
13870
|
+
[
|
|
13871
|
+
"--host=127.0.0.1",
|
|
13872
|
+
`--port=${webdavPort}`,
|
|
13873
|
+
`--root=${downloadsPath}`,
|
|
13874
|
+
"--auth=anonymous",
|
|
13875
|
+
"--no-config"
|
|
13876
|
+
],
|
|
13877
|
+
{ stdio: ["ignore", "pipe", "pipe"] }
|
|
13878
|
+
);
|
|
13879
|
+
wsgidav.stdout?.on("data", (data) => process.stdout.write(data));
|
|
13880
|
+
wsgidav.stderr?.on("data", (data) => process.stderr.write(data));
|
|
13881
|
+
console.log(chalk67.green("\u2713 WebDAV server started"));
|
|
13882
|
+
const chrome = spawn3(
|
|
13883
|
+
chromeBinary,
|
|
13884
|
+
[
|
|
13885
|
+
`--remote-debugging-port=${cdpPort}`,
|
|
13886
|
+
"--remote-debugging-address=127.0.0.1",
|
|
13887
|
+
"--headless=new",
|
|
13888
|
+
"--no-sandbox",
|
|
13889
|
+
"--disable-gpu"
|
|
13890
|
+
],
|
|
13891
|
+
{ stdio: ["ignore", "pipe", "pipe"] }
|
|
13892
|
+
);
|
|
13893
|
+
chrome.stdout?.on("data", (data) => process.stdout.write(data));
|
|
13894
|
+
chrome.stderr?.on("data", (data) => process.stderr.write(data));
|
|
13895
|
+
console.log(chalk67.green("\u2713 Chrome started"));
|
|
13896
|
+
try {
|
|
13897
|
+
await startNgrokTunnels(
|
|
13898
|
+
credentials.ngrokToken,
|
|
13899
|
+
credentials.endpointPrefix,
|
|
13900
|
+
webdavPort,
|
|
13901
|
+
cdpPort
|
|
13902
|
+
);
|
|
13903
|
+
console.log(
|
|
13904
|
+
chalk67.green(
|
|
13905
|
+
`\u2713 ngrok tunnels: webdav.${credentials.domain}, chrome.${credentials.domain}`
|
|
13906
|
+
)
|
|
13907
|
+
);
|
|
13908
|
+
console.log();
|
|
13909
|
+
console.log(chalk67.green("\u2713 Computer connector active"));
|
|
13910
|
+
console.log(` WebDAV: ~/Downloads \u2192 webdav.${credentials.domain}`);
|
|
13911
|
+
console.log(
|
|
13912
|
+
` Chrome CDP: port ${cdpPort} \u2192 chrome.${credentials.domain}`
|
|
13913
|
+
);
|
|
13914
|
+
console.log();
|
|
13915
|
+
console.log(chalk67.dim("Press ^C twice to disconnect"));
|
|
13916
|
+
console.log();
|
|
13917
|
+
let sigintCount = 0;
|
|
13918
|
+
await new Promise((resolve) => {
|
|
13919
|
+
const keepAlive = setInterval(() => {
|
|
13920
|
+
}, 6e4);
|
|
13921
|
+
const done = () => {
|
|
13922
|
+
clearInterval(keepAlive);
|
|
13923
|
+
process.removeListener("SIGINT", onSigint);
|
|
13924
|
+
resolve();
|
|
13925
|
+
};
|
|
13926
|
+
const onSigint = () => {
|
|
13927
|
+
sigintCount++;
|
|
13928
|
+
if (sigintCount === 1) {
|
|
13929
|
+
console.log(chalk67.dim("\nPress ^C again to disconnect and exit..."));
|
|
13930
|
+
} else {
|
|
13931
|
+
done();
|
|
13932
|
+
}
|
|
13933
|
+
};
|
|
13934
|
+
process.on("SIGINT", onSigint);
|
|
13935
|
+
process.once("SIGTERM", done);
|
|
13936
|
+
});
|
|
13937
|
+
} finally {
|
|
13938
|
+
console.log();
|
|
13939
|
+
console.log(chalk67.cyan("Stopping services..."));
|
|
13940
|
+
wsgidav.kill("SIGTERM");
|
|
13941
|
+
chrome.kill("SIGTERM");
|
|
13942
|
+
await stopNgrokTunnels();
|
|
13943
|
+
console.log(chalk67.green("\u2713 Services stopped"));
|
|
13944
|
+
}
|
|
13945
|
+
}
|
|
13946
|
+
|
|
13947
|
+
// src/commands/connector/connect.ts
|
|
13779
13948
|
function delay2(ms) {
|
|
13780
13949
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
13781
13950
|
}
|
|
@@ -13797,14 +13966,41 @@ var connectCommand = new Command67().name("connect").description("Connect a thir
|
|
|
13797
13966
|
try {
|
|
13798
13967
|
const parseResult = connectorTypeSchema.safeParse(type2);
|
|
13799
13968
|
if (!parseResult.success) {
|
|
13800
|
-
console.error(
|
|
13969
|
+
console.error(chalk68.red(`\u2717 Unknown connector type: ${type2}`));
|
|
13801
13970
|
console.error("Available connectors: github");
|
|
13802
13971
|
process.exit(1);
|
|
13803
13972
|
}
|
|
13804
13973
|
const connectorType = parseResult.data;
|
|
13805
13974
|
const apiUrl = await getApiUrl();
|
|
13806
13975
|
const headers = await getHeaders2();
|
|
13807
|
-
|
|
13976
|
+
if (connectorType === "computer") {
|
|
13977
|
+
await checkComputerDependencies();
|
|
13978
|
+
console.log(chalk68.cyan("Setting up computer connector..."));
|
|
13979
|
+
const computerClient = initClient13(computerConnectorContract, {
|
|
13980
|
+
baseUrl: apiUrl,
|
|
13981
|
+
baseHeaders: headers,
|
|
13982
|
+
jsonQuery: false
|
|
13983
|
+
});
|
|
13984
|
+
const createResult2 = await computerClient.create({
|
|
13985
|
+
body: {}
|
|
13986
|
+
});
|
|
13987
|
+
if (createResult2.status !== 200) {
|
|
13988
|
+
const errorBody = createResult2.body;
|
|
13989
|
+
console.error(
|
|
13990
|
+
chalk68.red(
|
|
13991
|
+
`\u2717 Failed to create connector: ${errorBody.error?.message}`
|
|
13992
|
+
)
|
|
13993
|
+
);
|
|
13994
|
+
process.exit(1);
|
|
13995
|
+
}
|
|
13996
|
+
const credentials = createResult2.body;
|
|
13997
|
+
await startComputerServices(credentials);
|
|
13998
|
+
console.log(chalk68.cyan("Disconnecting computer connector..."));
|
|
13999
|
+
await deleteConnector("computer");
|
|
14000
|
+
console.log(chalk68.green("\u2713 Disconnected computer"));
|
|
14001
|
+
process.exit(0);
|
|
14002
|
+
}
|
|
14003
|
+
console.log(`Connecting ${chalk68.cyan(type2)}...`);
|
|
13808
14004
|
const sessionsClient = initClient13(connectorSessionsContract, {
|
|
13809
14005
|
baseUrl: apiUrl,
|
|
13810
14006
|
baseHeaders: headers,
|
|
@@ -13817,14 +14013,14 @@ var connectCommand = new Command67().name("connect").description("Connect a thir
|
|
|
13817
14013
|
if (createResult.status !== 200) {
|
|
13818
14014
|
const errorBody = createResult.body;
|
|
13819
14015
|
console.error(
|
|
13820
|
-
|
|
14016
|
+
chalk68.red(`\u2717 Failed to create session: ${errorBody.error?.message}`)
|
|
13821
14017
|
);
|
|
13822
14018
|
process.exit(1);
|
|
13823
14019
|
}
|
|
13824
14020
|
const session = createResult.body;
|
|
13825
14021
|
const verificationUrl = `${apiUrl}${session.verificationUrl}`;
|
|
13826
|
-
console.log(
|
|
13827
|
-
console.log(
|
|
14022
|
+
console.log(chalk68.green("\nSession created"));
|
|
14023
|
+
console.log(chalk68.cyan(`
|
|
13828
14024
|
To connect, visit: ${verificationUrl}`));
|
|
13829
14025
|
console.log(
|
|
13830
14026
|
`
|
|
@@ -13851,7 +14047,7 @@ The session expires in ${Math.floor(session.expiresIn / 60)} minutes.`
|
|
|
13851
14047
|
if (statusResult.status !== 200) {
|
|
13852
14048
|
const errorBody = statusResult.body;
|
|
13853
14049
|
console.error(
|
|
13854
|
-
|
|
14050
|
+
chalk68.red(
|
|
13855
14051
|
`
|
|
13856
14052
|
\u2717 Failed to check status: ${errorBody.error?.message}`
|
|
13857
14053
|
)
|
|
@@ -13861,17 +14057,17 @@ The session expires in ${Math.floor(session.expiresIn / 60)} minutes.`
|
|
|
13861
14057
|
const status = statusResult.body;
|
|
13862
14058
|
switch (status.status) {
|
|
13863
14059
|
case "complete":
|
|
13864
|
-
console.log(
|
|
14060
|
+
console.log(chalk68.green(`
|
|
13865
14061
|
|
|
13866
14062
|
${type2} connected successfully!`));
|
|
13867
14063
|
return;
|
|
13868
14064
|
case "expired":
|
|
13869
|
-
console.error(
|
|
14065
|
+
console.error(chalk68.red("\n\u2717 Session expired, please try again"));
|
|
13870
14066
|
process.exit(1);
|
|
13871
14067
|
break;
|
|
13872
14068
|
case "error":
|
|
13873
14069
|
console.error(
|
|
13874
|
-
|
|
14070
|
+
chalk68.red(
|
|
13875
14071
|
`
|
|
13876
14072
|
\u2717 Connection failed: ${status.errorMessage || "Unknown error"}`
|
|
13877
14073
|
)
|
|
@@ -13879,20 +14075,20 @@ ${type2} connected successfully!`));
|
|
|
13879
14075
|
process.exit(1);
|
|
13880
14076
|
break;
|
|
13881
14077
|
case "pending":
|
|
13882
|
-
process.stdout.write(
|
|
14078
|
+
process.stdout.write(chalk68.dim("."));
|
|
13883
14079
|
break;
|
|
13884
14080
|
}
|
|
13885
14081
|
}
|
|
13886
|
-
console.error(
|
|
14082
|
+
console.error(chalk68.red("\n\u2717 Session timed out, please try again"));
|
|
13887
14083
|
process.exit(1);
|
|
13888
14084
|
} catch (error) {
|
|
13889
14085
|
if (error instanceof Error) {
|
|
13890
|
-
console.error(
|
|
14086
|
+
console.error(chalk68.red(`\u2717 ${error.message}`));
|
|
13891
14087
|
if (error.cause instanceof Error) {
|
|
13892
|
-
console.error(
|
|
14088
|
+
console.error(chalk68.dim(` Cause: ${error.cause.message}`));
|
|
13893
14089
|
}
|
|
13894
14090
|
} else {
|
|
13895
|
-
console.error(
|
|
14091
|
+
console.error(chalk68.red("\u2717 An unexpected error occurred"));
|
|
13896
14092
|
}
|
|
13897
14093
|
process.exit(1);
|
|
13898
14094
|
}
|
|
@@ -13900,7 +14096,7 @@ ${type2} connected successfully!`));
|
|
|
13900
14096
|
|
|
13901
14097
|
// src/commands/connector/list.ts
|
|
13902
14098
|
import { Command as Command68 } from "commander";
|
|
13903
|
-
import
|
|
14099
|
+
import chalk69 from "chalk";
|
|
13904
14100
|
var listCommand9 = new Command68().name("list").alias("ls").description("List all connectors and their status").action(
|
|
13905
14101
|
withErrorHandler(async () => {
|
|
13906
14102
|
const result = await listConnectors();
|
|
@@ -13914,42 +14110,42 @@ var listCommand9 = new Command68().name("list").alias("ls").description("List al
|
|
|
13914
14110
|
statusText.padEnd(statusWidth),
|
|
13915
14111
|
"ACCOUNT"
|
|
13916
14112
|
].join(" ");
|
|
13917
|
-
console.log(
|
|
14113
|
+
console.log(chalk69.dim(header));
|
|
13918
14114
|
for (const type2 of allTypes) {
|
|
13919
14115
|
const connector = connectedMap.get(type2);
|
|
13920
|
-
const status = connector ?
|
|
13921
|
-
const account = connector?.externalUsername ? `@${connector.externalUsername}` :
|
|
14116
|
+
const status = connector ? chalk69.green("\u2713".padEnd(statusWidth)) : chalk69.dim("-".padEnd(statusWidth));
|
|
14117
|
+
const account = connector?.externalUsername ? `@${connector.externalUsername}` : chalk69.dim("-");
|
|
13922
14118
|
const row = [type2.padEnd(typeWidth), status, account].join(" ");
|
|
13923
14119
|
console.log(row);
|
|
13924
14120
|
}
|
|
13925
14121
|
console.log();
|
|
13926
|
-
console.log(
|
|
13927
|
-
console.log(
|
|
14122
|
+
console.log(chalk69.dim("To connect a service:"));
|
|
14123
|
+
console.log(chalk69.dim(" vm0 connector connect <type>"));
|
|
13928
14124
|
})
|
|
13929
14125
|
);
|
|
13930
14126
|
|
|
13931
14127
|
// src/commands/connector/status.ts
|
|
13932
14128
|
import { Command as Command69 } from "commander";
|
|
13933
|
-
import
|
|
14129
|
+
import chalk70 from "chalk";
|
|
13934
14130
|
var LABEL_WIDTH = 16;
|
|
13935
14131
|
var statusCommand7 = new Command69().name("status").description("Show detailed status of a connector").argument("<type>", "Connector type (e.g., github)").action(
|
|
13936
14132
|
withErrorHandler(async (type2) => {
|
|
13937
14133
|
const parseResult = connectorTypeSchema.safeParse(type2);
|
|
13938
14134
|
if (!parseResult.success) {
|
|
13939
|
-
console.error(
|
|
14135
|
+
console.error(chalk70.red(`\u2717 Unknown connector type: ${type2}`));
|
|
13940
14136
|
console.error();
|
|
13941
14137
|
console.error("Available connectors:");
|
|
13942
14138
|
for (const [t, config] of Object.entries(CONNECTOR_TYPES)) {
|
|
13943
|
-
console.error(` ${
|
|
14139
|
+
console.error(` ${chalk70.cyan(t)} - ${config.label}`);
|
|
13944
14140
|
}
|
|
13945
14141
|
process.exit(1);
|
|
13946
14142
|
}
|
|
13947
14143
|
const connector = await getConnector(parseResult.data);
|
|
13948
|
-
console.log(`Connector: ${
|
|
14144
|
+
console.log(`Connector: ${chalk70.cyan(type2)}`);
|
|
13949
14145
|
console.log();
|
|
13950
14146
|
if (connector) {
|
|
13951
14147
|
console.log(
|
|
13952
|
-
`${"Status:".padEnd(LABEL_WIDTH)}${
|
|
14148
|
+
`${"Status:".padEnd(LABEL_WIDTH)}${chalk70.green("connected")}`
|
|
13953
14149
|
);
|
|
13954
14150
|
console.log(
|
|
13955
14151
|
`${"Account:".padEnd(LABEL_WIDTH)}@${connector.externalUsername}`
|
|
@@ -13971,50 +14167,51 @@ var statusCommand7 = new Command69().name("status").description("Show detailed s
|
|
|
13971
14167
|
);
|
|
13972
14168
|
}
|
|
13973
14169
|
console.log();
|
|
13974
|
-
console.log(
|
|
13975
|
-
console.log(
|
|
14170
|
+
console.log(chalk70.dim("To disconnect:"));
|
|
14171
|
+
console.log(chalk70.dim(` vm0 connector disconnect ${type2}`));
|
|
13976
14172
|
} else {
|
|
13977
14173
|
console.log(
|
|
13978
|
-
`${"Status:".padEnd(LABEL_WIDTH)}${
|
|
14174
|
+
`${"Status:".padEnd(LABEL_WIDTH)}${chalk70.dim("not connected")}`
|
|
13979
14175
|
);
|
|
13980
14176
|
console.log();
|
|
13981
|
-
console.log(
|
|
13982
|
-
console.log(
|
|
14177
|
+
console.log(chalk70.dim("To connect:"));
|
|
14178
|
+
console.log(chalk70.dim(` vm0 connector connect ${type2}`));
|
|
13983
14179
|
}
|
|
13984
14180
|
})
|
|
13985
14181
|
);
|
|
13986
14182
|
|
|
13987
14183
|
// src/commands/connector/disconnect.ts
|
|
13988
14184
|
import { Command as Command70 } from "commander";
|
|
13989
|
-
import
|
|
14185
|
+
import chalk71 from "chalk";
|
|
13990
14186
|
var disconnectCommand = new Command70().name("disconnect").description("Disconnect a third-party service").argument("<type>", "Connector type to disconnect (e.g., github)").action(async (type2) => {
|
|
13991
14187
|
try {
|
|
13992
14188
|
const parseResult = connectorTypeSchema.safeParse(type2);
|
|
13993
14189
|
if (!parseResult.success) {
|
|
13994
|
-
console.error(
|
|
14190
|
+
console.error(chalk71.red(`\u2717 Unknown connector type: ${type2}`));
|
|
13995
14191
|
console.error();
|
|
13996
14192
|
console.error("Available connectors:");
|
|
13997
14193
|
for (const [t, config] of Object.entries(CONNECTOR_TYPES)) {
|
|
13998
|
-
console.error(` ${
|
|
14194
|
+
console.error(` ${chalk71.cyan(t)} - ${config.label}`);
|
|
13999
14195
|
}
|
|
14000
14196
|
process.exit(1);
|
|
14001
14197
|
}
|
|
14002
|
-
|
|
14003
|
-
|
|
14198
|
+
const connectorType = parseResult.data;
|
|
14199
|
+
await deleteConnector(connectorType);
|
|
14200
|
+
console.log(chalk71.green(`\u2713 Disconnected ${type2}`));
|
|
14004
14201
|
} catch (error) {
|
|
14005
14202
|
if (error instanceof Error) {
|
|
14006
14203
|
if (error.message.includes("not found")) {
|
|
14007
|
-
console.error(
|
|
14204
|
+
console.error(chalk71.red(`\u2717 Connector "${type2}" is not connected`));
|
|
14008
14205
|
} else if (error.message.includes("Not authenticated")) {
|
|
14009
|
-
console.error(
|
|
14206
|
+
console.error(chalk71.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
14010
14207
|
} else {
|
|
14011
|
-
console.error(
|
|
14208
|
+
console.error(chalk71.red(`\u2717 ${error.message}`));
|
|
14012
14209
|
if (error.cause instanceof Error) {
|
|
14013
|
-
console.error(
|
|
14210
|
+
console.error(chalk71.dim(` Cause: ${error.cause.message}`));
|
|
14014
14211
|
}
|
|
14015
14212
|
}
|
|
14016
14213
|
} else {
|
|
14017
|
-
console.error(
|
|
14214
|
+
console.error(chalk71.red("\u2717 An unexpected error occurred"));
|
|
14018
14215
|
}
|
|
14019
14216
|
process.exit(1);
|
|
14020
14217
|
}
|
|
@@ -14025,24 +14222,24 @@ var connectorCommand = new Command71().name("connector").description("Manage thi
|
|
|
14025
14222
|
|
|
14026
14223
|
// src/commands/onboard/index.ts
|
|
14027
14224
|
import { Command as Command72 } from "commander";
|
|
14028
|
-
import
|
|
14225
|
+
import chalk75 from "chalk";
|
|
14029
14226
|
import { mkdir as mkdir8 } from "fs/promises";
|
|
14030
14227
|
import { existsSync as existsSync12 } from "fs";
|
|
14031
14228
|
|
|
14032
14229
|
// src/lib/ui/welcome-box.ts
|
|
14033
|
-
import
|
|
14230
|
+
import chalk72 from "chalk";
|
|
14034
14231
|
var gradientColors = [
|
|
14035
|
-
|
|
14232
|
+
chalk72.hex("#FFAB5E"),
|
|
14036
14233
|
// Line 1 - lightest
|
|
14037
|
-
|
|
14234
|
+
chalk72.hex("#FF9642"),
|
|
14038
14235
|
// Line 2
|
|
14039
|
-
|
|
14236
|
+
chalk72.hex("#FF8228"),
|
|
14040
14237
|
// Line 3
|
|
14041
|
-
|
|
14238
|
+
chalk72.hex("#FF6D0A"),
|
|
14042
14239
|
// Line 4
|
|
14043
|
-
|
|
14240
|
+
chalk72.hex("#E85D00"),
|
|
14044
14241
|
// Line 5
|
|
14045
|
-
|
|
14242
|
+
chalk72.hex("#CC4E00")
|
|
14046
14243
|
// Line 6 - darkest
|
|
14047
14244
|
];
|
|
14048
14245
|
var vm0LogoLines = [
|
|
@@ -14064,15 +14261,15 @@ function renderVm0Banner() {
|
|
|
14064
14261
|
function renderOnboardWelcome() {
|
|
14065
14262
|
renderVm0Banner();
|
|
14066
14263
|
console.log(` Build agentic workflows using natural language.`);
|
|
14067
|
-
console.log(` ${
|
|
14264
|
+
console.log(` ${chalk72.dim("Currently in beta, enjoy it free")}`);
|
|
14068
14265
|
console.log(
|
|
14069
|
-
` ${
|
|
14266
|
+
` ${chalk72.dim("Star us on GitHub: https://github.com/vm0-ai/vm0")}`
|
|
14070
14267
|
);
|
|
14071
14268
|
console.log();
|
|
14072
14269
|
}
|
|
14073
14270
|
|
|
14074
14271
|
// src/lib/ui/step-runner.ts
|
|
14075
|
-
import
|
|
14272
|
+
import chalk73 from "chalk";
|
|
14076
14273
|
function createStepRunner(options = true) {
|
|
14077
14274
|
const opts = typeof options === "boolean" ? { interactive: options } : options;
|
|
14078
14275
|
const interactive = opts.interactive ?? true;
|
|
@@ -14087,25 +14284,25 @@ function createStepRunner(options = true) {
|
|
|
14087
14284
|
}
|
|
14088
14285
|
for (const [i, step] of completedSteps.entries()) {
|
|
14089
14286
|
if (step.failed) {
|
|
14090
|
-
console.log(
|
|
14287
|
+
console.log(chalk73.red(`\u2717 ${step.label}`));
|
|
14091
14288
|
} else {
|
|
14092
|
-
console.log(
|
|
14289
|
+
console.log(chalk73.green(`\u25CF ${step.label}`));
|
|
14093
14290
|
}
|
|
14094
14291
|
const isLastStep = i === completedSteps.length - 1;
|
|
14095
14292
|
if (!isLastStep || !isFinal) {
|
|
14096
|
-
console.log(
|
|
14293
|
+
console.log(chalk73.dim("\u2502"));
|
|
14097
14294
|
}
|
|
14098
14295
|
}
|
|
14099
14296
|
}
|
|
14100
14297
|
async function executeStep(label, fn, isFinal) {
|
|
14101
14298
|
let stepFailed = false;
|
|
14102
|
-
console.log(
|
|
14299
|
+
console.log(chalk73.yellow(`\u25CB ${label}`));
|
|
14103
14300
|
const ctx = {
|
|
14104
14301
|
connector() {
|
|
14105
|
-
console.log(
|
|
14302
|
+
console.log(chalk73.dim("\u2502"));
|
|
14106
14303
|
},
|
|
14107
14304
|
detail(message) {
|
|
14108
|
-
console.log(`${
|
|
14305
|
+
console.log(`${chalk73.dim("\u2502")} ${message}`);
|
|
14109
14306
|
},
|
|
14110
14307
|
async prompt(promptFn) {
|
|
14111
14308
|
return await promptFn();
|
|
@@ -14122,12 +14319,12 @@ function createStepRunner(options = true) {
|
|
|
14122
14319
|
redrawCompletedSteps(isFinal);
|
|
14123
14320
|
} else {
|
|
14124
14321
|
if (stepFailed) {
|
|
14125
|
-
console.log(
|
|
14322
|
+
console.log(chalk73.red(`\u2717 ${label}`));
|
|
14126
14323
|
} else {
|
|
14127
|
-
console.log(
|
|
14324
|
+
console.log(chalk73.green(`\u25CF ${label}`));
|
|
14128
14325
|
}
|
|
14129
14326
|
if (!isFinal) {
|
|
14130
|
-
console.log(
|
|
14327
|
+
console.log(chalk73.dim("\u2502"));
|
|
14131
14328
|
}
|
|
14132
14329
|
}
|
|
14133
14330
|
}
|
|
@@ -14286,15 +14483,15 @@ async function setupModelProvider(type2, secret, options) {
|
|
|
14286
14483
|
}
|
|
14287
14484
|
|
|
14288
14485
|
// src/lib/domain/onboard/claude-setup.ts
|
|
14289
|
-
import { spawn as
|
|
14290
|
-
import
|
|
14486
|
+
import { spawn as spawn4 } from "child_process";
|
|
14487
|
+
import chalk74 from "chalk";
|
|
14291
14488
|
var MARKETPLACE_NAME = "vm0-skills";
|
|
14292
14489
|
var MARKETPLACE_REPO = "vm0-ai/vm0-skills";
|
|
14293
14490
|
var PLUGIN_ID = "vm0@vm0-skills";
|
|
14294
14491
|
var PRIMARY_SKILL_NAME = "vm0-agent";
|
|
14295
14492
|
async function runClaudeCommand(args, cwd) {
|
|
14296
14493
|
return new Promise((resolve) => {
|
|
14297
|
-
const child =
|
|
14494
|
+
const child = spawn4("claude", args, {
|
|
14298
14495
|
stdio: ["inherit", "pipe", "pipe"],
|
|
14299
14496
|
cwd
|
|
14300
14497
|
});
|
|
@@ -14324,12 +14521,12 @@ async function runClaudeCommand(args, cwd) {
|
|
|
14324
14521
|
}
|
|
14325
14522
|
function handlePluginError(error, context) {
|
|
14326
14523
|
const displayContext = context ?? "Claude plugin";
|
|
14327
|
-
console.error(
|
|
14524
|
+
console.error(chalk74.red(`\u2717 Failed to install ${displayContext}`));
|
|
14328
14525
|
if (error instanceof Error) {
|
|
14329
|
-
console.error(
|
|
14526
|
+
console.error(chalk74.red(`\u2717 ${error.message}`));
|
|
14330
14527
|
}
|
|
14331
14528
|
console.error(
|
|
14332
|
-
|
|
14529
|
+
chalk74.dim("Please ensure Claude CLI is installed and accessible.")
|
|
14333
14530
|
);
|
|
14334
14531
|
process.exit(1);
|
|
14335
14532
|
}
|
|
@@ -14372,7 +14569,7 @@ async function updateMarketplace() {
|
|
|
14372
14569
|
]);
|
|
14373
14570
|
if (!result.success) {
|
|
14374
14571
|
console.warn(
|
|
14375
|
-
|
|
14572
|
+
chalk74.yellow(
|
|
14376
14573
|
`Warning: Could not update marketplace: ${result.error ?? "unknown error"}`
|
|
14377
14574
|
)
|
|
14378
14575
|
);
|
|
@@ -14410,7 +14607,7 @@ async function handleAuthentication(ctx) {
|
|
|
14410
14607
|
return;
|
|
14411
14608
|
}
|
|
14412
14609
|
if (!ctx.interactive) {
|
|
14413
|
-
console.error(
|
|
14610
|
+
console.error(chalk75.red("\u2717 Not authenticated"));
|
|
14414
14611
|
console.error("Run 'vm0 auth login' first or set VM0_TOKEN");
|
|
14415
14612
|
process.exit(1);
|
|
14416
14613
|
}
|
|
@@ -14418,19 +14615,19 @@ async function handleAuthentication(ctx) {
|
|
|
14418
14615
|
onInitiating: () => {
|
|
14419
14616
|
},
|
|
14420
14617
|
onDeviceCodeReady: (url, code, expiresIn) => {
|
|
14421
|
-
step.detail(`Copy code: ${
|
|
14422
|
-
step.detail(`Open: ${
|
|
14423
|
-
step.detail(
|
|
14618
|
+
step.detail(`Copy code: ${chalk75.cyan.bold(code)}`);
|
|
14619
|
+
step.detail(`Open: ${chalk75.cyan(url)}`);
|
|
14620
|
+
step.detail(chalk75.dim(`Expires in ${expiresIn} minutes`));
|
|
14424
14621
|
},
|
|
14425
14622
|
onPolling: () => {
|
|
14426
14623
|
},
|
|
14427
14624
|
onSuccess: () => {
|
|
14428
14625
|
},
|
|
14429
14626
|
onError: (error) => {
|
|
14430
|
-
console.error(
|
|
14627
|
+
console.error(chalk75.red(`
|
|
14431
14628
|
\u2717 ${error.message}`));
|
|
14432
14629
|
if (error.cause instanceof Error) {
|
|
14433
|
-
console.error(
|
|
14630
|
+
console.error(chalk75.dim(` Cause: ${error.cause.message}`));
|
|
14434
14631
|
}
|
|
14435
14632
|
process.exit(1);
|
|
14436
14633
|
}
|
|
@@ -14444,7 +14641,7 @@ async function handleModelProvider(ctx) {
|
|
|
14444
14641
|
return;
|
|
14445
14642
|
}
|
|
14446
14643
|
if (!ctx.interactive) {
|
|
14447
|
-
console.error(
|
|
14644
|
+
console.error(chalk75.red("\u2717 No model provider configured"));
|
|
14448
14645
|
console.error("Run 'vm0 model-provider setup' first");
|
|
14449
14646
|
process.exit(1);
|
|
14450
14647
|
}
|
|
@@ -14465,14 +14662,14 @@ async function handleModelProvider(ctx) {
|
|
|
14465
14662
|
const selectedChoice = choices.find((c25) => c25.type === providerType);
|
|
14466
14663
|
if (selectedChoice?.helpText) {
|
|
14467
14664
|
for (const line of selectedChoice.helpText.split("\n")) {
|
|
14468
|
-
step.detail(
|
|
14665
|
+
step.detail(chalk75.dim(line));
|
|
14469
14666
|
}
|
|
14470
14667
|
}
|
|
14471
14668
|
const secret = await step.prompt(
|
|
14472
14669
|
() => promptPassword(`Enter your ${selectedChoice?.secretLabel ?? "secret"}:`)
|
|
14473
14670
|
);
|
|
14474
14671
|
if (!secret) {
|
|
14475
|
-
console.log(
|
|
14672
|
+
console.log(chalk75.dim("Cancelled"));
|
|
14476
14673
|
process.exit(0);
|
|
14477
14674
|
}
|
|
14478
14675
|
let selectedModel;
|
|
@@ -14491,7 +14688,7 @@ async function handleModelProvider(ctx) {
|
|
|
14491
14688
|
() => promptSelect("Select model:", modelChoices)
|
|
14492
14689
|
);
|
|
14493
14690
|
if (modelSelection === void 0) {
|
|
14494
|
-
console.log(
|
|
14691
|
+
console.log(chalk75.dim("Cancelled"));
|
|
14495
14692
|
process.exit(0);
|
|
14496
14693
|
}
|
|
14497
14694
|
selectedModel = modelSelection === "" ? void 0 : modelSelection;
|
|
@@ -14501,7 +14698,7 @@ async function handleModelProvider(ctx) {
|
|
|
14501
14698
|
});
|
|
14502
14699
|
const modelNote = result.provider.selectedModel ? ` with model: ${result.provider.selectedModel}` : "";
|
|
14503
14700
|
step.detail(
|
|
14504
|
-
|
|
14701
|
+
chalk75.green(
|
|
14505
14702
|
`${providerType} ${result.created ? "created" : "updated"}${result.isDefault ? ` (default for ${result.framework})` : ""}${modelNote}`
|
|
14506
14703
|
)
|
|
14507
14704
|
);
|
|
@@ -14532,7 +14729,7 @@ async function handleAgentCreation(ctx) {
|
|
|
14532
14729
|
agentName = inputName;
|
|
14533
14730
|
if (existsSync12(agentName)) {
|
|
14534
14731
|
step.detail(
|
|
14535
|
-
|
|
14732
|
+
chalk75.yellow(`${agentName}/ already exists, choose another name`)
|
|
14536
14733
|
);
|
|
14537
14734
|
} else {
|
|
14538
14735
|
folderExists = false;
|
|
@@ -14541,22 +14738,22 @@ async function handleAgentCreation(ctx) {
|
|
|
14541
14738
|
} else {
|
|
14542
14739
|
if (!validateAgentName(agentName)) {
|
|
14543
14740
|
console.error(
|
|
14544
|
-
|
|
14741
|
+
chalk75.red(
|
|
14545
14742
|
"Invalid agent name: must be 3-64 chars, alphanumeric + hyphens"
|
|
14546
14743
|
)
|
|
14547
14744
|
);
|
|
14548
14745
|
process.exit(1);
|
|
14549
14746
|
}
|
|
14550
14747
|
if (existsSync12(agentName)) {
|
|
14551
|
-
console.error(
|
|
14748
|
+
console.error(chalk75.red(`\u2717 ${agentName}/ already exists`));
|
|
14552
14749
|
console.error();
|
|
14553
14750
|
console.error("Remove it first or choose a different name:");
|
|
14554
|
-
console.error(
|
|
14751
|
+
console.error(chalk75.cyan(` rm -rf ${agentName}`));
|
|
14555
14752
|
process.exit(1);
|
|
14556
14753
|
}
|
|
14557
14754
|
}
|
|
14558
14755
|
await mkdir8(agentName, { recursive: true });
|
|
14559
|
-
step.detail(
|
|
14756
|
+
step.detail(chalk75.green(`Created ${agentName}/`));
|
|
14560
14757
|
});
|
|
14561
14758
|
return agentName;
|
|
14562
14759
|
}
|
|
@@ -14572,7 +14769,7 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
14572
14769
|
shouldInstall = confirmed ?? true;
|
|
14573
14770
|
}
|
|
14574
14771
|
if (!shouldInstall) {
|
|
14575
|
-
step.detail(
|
|
14772
|
+
step.detail(chalk75.dim("Skipped"));
|
|
14576
14773
|
return;
|
|
14577
14774
|
}
|
|
14578
14775
|
const scope = "project";
|
|
@@ -14580,7 +14777,7 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
14580
14777
|
const agentDir = `${process.cwd()}/${agentName}`;
|
|
14581
14778
|
const result = await installVm0Plugin(scope, agentDir);
|
|
14582
14779
|
step.detail(
|
|
14583
|
-
|
|
14780
|
+
chalk75.green(`Installed ${result.pluginId} (scope: ${result.scope})`)
|
|
14584
14781
|
);
|
|
14585
14782
|
pluginInstalled = true;
|
|
14586
14783
|
} catch (error) {
|
|
@@ -14591,14 +14788,14 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
14591
14788
|
}
|
|
14592
14789
|
function printNextSteps(agentName, pluginInstalled) {
|
|
14593
14790
|
console.log();
|
|
14594
|
-
console.log(
|
|
14791
|
+
console.log(chalk75.bold("Next step:"));
|
|
14595
14792
|
console.log();
|
|
14596
14793
|
if (pluginInstalled) {
|
|
14597
14794
|
console.log(
|
|
14598
|
-
` ${
|
|
14795
|
+
` ${chalk75.cyan(`cd ${agentName} && claude "/${PRIMARY_SKILL_NAME} let's build an agent"`)}`
|
|
14599
14796
|
);
|
|
14600
14797
|
} else {
|
|
14601
|
-
console.log(` ${
|
|
14798
|
+
console.log(` ${chalk75.cyan(`cd ${agentName} && vm0 init`)}`);
|
|
14602
14799
|
}
|
|
14603
14800
|
console.log();
|
|
14604
14801
|
}
|
|
@@ -14625,12 +14822,12 @@ var onboardCommand = new Command72().name("onboard").description("Guided setup f
|
|
|
14625
14822
|
printNextSteps(agentName, pluginInstalled);
|
|
14626
14823
|
} catch (error) {
|
|
14627
14824
|
if (error instanceof Error) {
|
|
14628
|
-
console.error(
|
|
14825
|
+
console.error(chalk75.red(`\u2717 ${error.message}`));
|
|
14629
14826
|
if (error.cause instanceof Error) {
|
|
14630
|
-
console.error(
|
|
14827
|
+
console.error(chalk75.dim(` Cause: ${error.cause.message}`));
|
|
14631
14828
|
}
|
|
14632
14829
|
} else {
|
|
14633
|
-
console.error(
|
|
14830
|
+
console.error(chalk75.red("\u2717 An unexpected error occurred"));
|
|
14634
14831
|
}
|
|
14635
14832
|
process.exit(1);
|
|
14636
14833
|
}
|
|
@@ -14638,20 +14835,20 @@ var onboardCommand = new Command72().name("onboard").description("Guided setup f
|
|
|
14638
14835
|
|
|
14639
14836
|
// src/commands/setup-claude/index.ts
|
|
14640
14837
|
import { Command as Command73 } from "commander";
|
|
14641
|
-
import
|
|
14838
|
+
import chalk76 from "chalk";
|
|
14642
14839
|
var setupClaudeCommand = new Command73().name("setup-claude").description("Install VM0 Claude Plugin").option("--agent-dir <dir>", "Agent directory to run install in").option("--scope <scope>", "Installation scope (user or project)", "project").action(
|
|
14643
14840
|
withErrorHandler(async (options) => {
|
|
14644
|
-
console.log(
|
|
14841
|
+
console.log(chalk76.dim("Installing VM0 Claude Plugin..."));
|
|
14645
14842
|
const scope = options.scope === "user" ? "user" : "project";
|
|
14646
14843
|
const result = await installVm0Plugin(scope, options.agentDir);
|
|
14647
14844
|
console.log(
|
|
14648
|
-
|
|
14845
|
+
chalk76.green(`\u2713 Installed ${result.pluginId} (scope: ${result.scope})`)
|
|
14649
14846
|
);
|
|
14650
14847
|
console.log();
|
|
14651
14848
|
console.log("Next step:");
|
|
14652
14849
|
const cdPrefix = options.agentDir ? `cd ${options.agentDir} && ` : "";
|
|
14653
14850
|
console.log(
|
|
14654
|
-
|
|
14851
|
+
chalk76.cyan(
|
|
14655
14852
|
` ${cdPrefix}claude "/${PRIMARY_SKILL_NAME} let's build a workflow"`
|
|
14656
14853
|
)
|
|
14657
14854
|
);
|
|
@@ -14660,28 +14857,28 @@ var setupClaudeCommand = new Command73().name("setup-claude").description("Insta
|
|
|
14660
14857
|
|
|
14661
14858
|
// src/commands/dashboard/index.ts
|
|
14662
14859
|
import { Command as Command74 } from "commander";
|
|
14663
|
-
import
|
|
14860
|
+
import chalk77 from "chalk";
|
|
14664
14861
|
var dashboardCommand = new Command74().name("dashboard").description("Quick reference for common query commands").action(() => {
|
|
14665
14862
|
console.log();
|
|
14666
|
-
console.log(
|
|
14863
|
+
console.log(chalk77.bold("VM0 Dashboard"));
|
|
14667
14864
|
console.log();
|
|
14668
|
-
console.log(
|
|
14669
|
-
console.log(
|
|
14865
|
+
console.log(chalk77.bold("Agents"));
|
|
14866
|
+
console.log(chalk77.dim(" List agents: ") + "vm0 agent list");
|
|
14670
14867
|
console.log();
|
|
14671
|
-
console.log(
|
|
14672
|
-
console.log(
|
|
14673
|
-
console.log(
|
|
14868
|
+
console.log(chalk77.bold("Runs"));
|
|
14869
|
+
console.log(chalk77.dim(" Recent runs: ") + "vm0 run list");
|
|
14870
|
+
console.log(chalk77.dim(" View run logs: ") + "vm0 logs <run-id>");
|
|
14674
14871
|
console.log();
|
|
14675
|
-
console.log(
|
|
14676
|
-
console.log(
|
|
14872
|
+
console.log(chalk77.bold("Schedules"));
|
|
14873
|
+
console.log(chalk77.dim(" List schedules: ") + "vm0 schedule list");
|
|
14677
14874
|
console.log();
|
|
14678
|
-
console.log(
|
|
14679
|
-
console.log(
|
|
14680
|
-
console.log(
|
|
14681
|
-
console.log(
|
|
14875
|
+
console.log(chalk77.bold("Account"));
|
|
14876
|
+
console.log(chalk77.dim(" Usage stats: ") + "vm0 usage");
|
|
14877
|
+
console.log(chalk77.dim(" List secrets: ") + "vm0 secret list");
|
|
14878
|
+
console.log(chalk77.dim(" List variables: ") + "vm0 variable list");
|
|
14682
14879
|
console.log();
|
|
14683
14880
|
console.log(
|
|
14684
|
-
|
|
14881
|
+
chalk77.dim("Not logged in? Run: ") + chalk77.cyan("vm0 auth login")
|
|
14685
14882
|
);
|
|
14686
14883
|
console.log();
|
|
14687
14884
|
});
|
|
@@ -14691,7 +14888,7 @@ import { Command as Command76 } from "commander";
|
|
|
14691
14888
|
|
|
14692
14889
|
// src/commands/dev-tool/compose.ts
|
|
14693
14890
|
import { Command as Command75 } from "commander";
|
|
14694
|
-
import
|
|
14891
|
+
import chalk78 from "chalk";
|
|
14695
14892
|
import { initClient as initClient14 } from "@ts-rest/core";
|
|
14696
14893
|
function sleep2(ms) {
|
|
14697
14894
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -14743,7 +14940,7 @@ async function pollUntilComplete(jobId, intervalMs, timeoutMs, jsonMode) {
|
|
|
14743
14940
|
const job = await getComposeJobStatus(jobId);
|
|
14744
14941
|
if (!jsonMode) {
|
|
14745
14942
|
console.log(
|
|
14746
|
-
|
|
14943
|
+
chalk78.dim(`[${timestamp()}] Polling... status=${job.status}`)
|
|
14747
14944
|
);
|
|
14748
14945
|
}
|
|
14749
14946
|
if (job.status === "completed" || job.status === "failed") {
|
|
@@ -14802,7 +14999,7 @@ var composeCommand2 = new Command75().name("compose").description("Test server-s
|
|
|
14802
14999
|
githubUrl,
|
|
14803
15000
|
options.overwrite
|
|
14804
15001
|
);
|
|
14805
|
-
console.log(`Job ID: ${
|
|
15002
|
+
console.log(`Job ID: ${chalk78.cyan(jobId)}`);
|
|
14806
15003
|
console.log();
|
|
14807
15004
|
if (initialStatus === "completed" || initialStatus === "failed") {
|
|
14808
15005
|
const finalJob2 = await getComposeJobStatus(jobId);
|
|
@@ -14823,21 +15020,21 @@ var composeCommand2 = new Command75().name("compose").description("Test server-s
|
|
|
14823
15020
|
);
|
|
14824
15021
|
function displayResult(job) {
|
|
14825
15022
|
if (job.status === "completed" && job.result) {
|
|
14826
|
-
console.log(
|
|
14827
|
-
console.log(` Compose ID: ${
|
|
14828
|
-
console.log(` Name: ${
|
|
14829
|
-
console.log(` Version: ${
|
|
15023
|
+
console.log(chalk78.green("\u2713 Compose completed!"));
|
|
15024
|
+
console.log(` Compose ID: ${chalk78.cyan(job.result.composeId)}`);
|
|
15025
|
+
console.log(` Name: ${chalk78.cyan(job.result.composeName)}`);
|
|
15026
|
+
console.log(` Version: ${chalk78.cyan(job.result.versionId.slice(0, 8))}`);
|
|
14830
15027
|
if (job.result.warnings.length > 0) {
|
|
14831
15028
|
console.log();
|
|
14832
|
-
console.log(
|
|
15029
|
+
console.log(chalk78.yellow(" Warnings:"));
|
|
14833
15030
|
for (const warning of job.result.warnings) {
|
|
14834
|
-
console.log(
|
|
15031
|
+
console.log(chalk78.yellow(` - ${warning}`));
|
|
14835
15032
|
}
|
|
14836
15033
|
}
|
|
14837
15034
|
} else if (job.status === "failed") {
|
|
14838
|
-
console.error(
|
|
15035
|
+
console.error(chalk78.red("\u2717 Compose failed"));
|
|
14839
15036
|
if (job.error) {
|
|
14840
|
-
console.error(` Error: ${
|
|
15037
|
+
console.error(` Error: ${chalk78.red(job.error)}`);
|
|
14841
15038
|
}
|
|
14842
15039
|
} else {
|
|
14843
15040
|
console.log(`Status: ${job.status}`);
|
|
@@ -14849,7 +15046,7 @@ var devToolCommand = new Command76().name("dev-tool").description("Developer too
|
|
|
14849
15046
|
|
|
14850
15047
|
// src/commands/preference/index.ts
|
|
14851
15048
|
import { Command as Command77 } from "commander";
|
|
14852
|
-
import
|
|
15049
|
+
import chalk79 from "chalk";
|
|
14853
15050
|
function detectTimezone2() {
|
|
14854
15051
|
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
14855
15052
|
}
|
|
@@ -14870,15 +15067,15 @@ function parseOnOff(flag, value) {
|
|
|
14870
15067
|
);
|
|
14871
15068
|
}
|
|
14872
15069
|
function displayPreferences(prefs) {
|
|
14873
|
-
console.log(
|
|
15070
|
+
console.log(chalk79.bold("Current preferences:"));
|
|
14874
15071
|
console.log(
|
|
14875
|
-
` Timezone: ${prefs.timezone ?
|
|
15072
|
+
` Timezone: ${prefs.timezone ? chalk79.cyan(prefs.timezone) : chalk79.dim("not set")}`
|
|
14876
15073
|
);
|
|
14877
15074
|
console.log(
|
|
14878
|
-
` Email notify: ${prefs.notifyEmail ?
|
|
15075
|
+
` Email notify: ${prefs.notifyEmail ? chalk79.green("on") : chalk79.dim("off")}`
|
|
14879
15076
|
);
|
|
14880
15077
|
console.log(
|
|
14881
|
-
` Slack notify: ${prefs.notifySlack ?
|
|
15078
|
+
` Slack notify: ${prefs.notifySlack ? chalk79.green("on") : chalk79.dim("off")}`
|
|
14882
15079
|
);
|
|
14883
15080
|
}
|
|
14884
15081
|
function buildUpdates(opts) {
|
|
@@ -14889,9 +15086,9 @@ function buildUpdates(opts) {
|
|
|
14889
15086
|
const updates = {};
|
|
14890
15087
|
if (hasTimezone) {
|
|
14891
15088
|
if (!isValidTimezone(opts.timezone)) {
|
|
14892
|
-
console.error(
|
|
15089
|
+
console.error(chalk79.red(`Invalid timezone: ${opts.timezone}`));
|
|
14893
15090
|
console.error(
|
|
14894
|
-
|
|
15091
|
+
chalk79.dim(
|
|
14895
15092
|
" Use an IANA timezone identifier (e.g., America/New_York, Asia/Shanghai)"
|
|
14896
15093
|
)
|
|
14897
15094
|
);
|
|
@@ -14903,7 +15100,7 @@ function buildUpdates(opts) {
|
|
|
14903
15100
|
try {
|
|
14904
15101
|
updates.notifyEmail = parseOnOff("notify-email", opts.notifyEmail);
|
|
14905
15102
|
} catch (err) {
|
|
14906
|
-
console.error(
|
|
15103
|
+
console.error(chalk79.red(err.message));
|
|
14907
15104
|
process.exit(1);
|
|
14908
15105
|
}
|
|
14909
15106
|
}
|
|
@@ -14911,7 +15108,7 @@ function buildUpdates(opts) {
|
|
|
14911
15108
|
try {
|
|
14912
15109
|
updates.notifySlack = parseOnOff("notify-slack", opts.notifySlack);
|
|
14913
15110
|
} catch (err) {
|
|
14914
|
-
console.error(
|
|
15111
|
+
console.error(chalk79.red(err.message));
|
|
14915
15112
|
process.exit(1);
|
|
14916
15113
|
}
|
|
14917
15114
|
}
|
|
@@ -14920,21 +15117,21 @@ function buildUpdates(opts) {
|
|
|
14920
15117
|
function printUpdateResult(updates, result) {
|
|
14921
15118
|
if (updates.timezone !== void 0) {
|
|
14922
15119
|
console.log(
|
|
14923
|
-
|
|
14924
|
-
`Timezone set to ${
|
|
15120
|
+
chalk79.green(
|
|
15121
|
+
`Timezone set to ${chalk79.cyan(result.timezone ?? updates.timezone)}`
|
|
14925
15122
|
)
|
|
14926
15123
|
);
|
|
14927
15124
|
}
|
|
14928
15125
|
if (updates.notifyEmail !== void 0) {
|
|
14929
15126
|
console.log(
|
|
14930
|
-
|
|
15127
|
+
chalk79.green(
|
|
14931
15128
|
`Email notifications ${result.notifyEmail ? "enabled" : "disabled"}`
|
|
14932
15129
|
)
|
|
14933
15130
|
);
|
|
14934
15131
|
}
|
|
14935
15132
|
if (updates.notifySlack !== void 0) {
|
|
14936
15133
|
console.log(
|
|
14937
|
-
|
|
15134
|
+
chalk79.green(
|
|
14938
15135
|
`Slack notifications ${result.notifySlack ? "enabled" : "disabled"}`
|
|
14939
15136
|
)
|
|
14940
15137
|
);
|
|
@@ -14943,7 +15140,7 @@ function printUpdateResult(updates, result) {
|
|
|
14943
15140
|
async function interactiveSetup(prefs) {
|
|
14944
15141
|
if (!prefs.timezone) {
|
|
14945
15142
|
const detectedTz = detectTimezone2();
|
|
14946
|
-
console.log(
|
|
15143
|
+
console.log(chalk79.dim(`
|
|
14947
15144
|
System timezone detected: ${detectedTz}`));
|
|
14948
15145
|
const tz = await promptText(
|
|
14949
15146
|
"Set timezone? (enter timezone or leave empty to skip)",
|
|
@@ -14951,11 +15148,11 @@ System timezone detected: ${detectedTz}`));
|
|
|
14951
15148
|
);
|
|
14952
15149
|
if (tz?.trim()) {
|
|
14953
15150
|
if (!isValidTimezone(tz.trim())) {
|
|
14954
|
-
console.error(
|
|
15151
|
+
console.error(chalk79.red(`Invalid timezone: ${tz.trim()}`));
|
|
14955
15152
|
process.exit(1);
|
|
14956
15153
|
}
|
|
14957
15154
|
await updateUserPreferences({ timezone: tz.trim() });
|
|
14958
|
-
console.log(
|
|
15155
|
+
console.log(chalk79.green(`Timezone set to ${chalk79.cyan(tz.trim())}`));
|
|
14959
15156
|
}
|
|
14960
15157
|
}
|
|
14961
15158
|
if (!prefs.notifyEmail) {
|
|
@@ -14965,7 +15162,7 @@ System timezone detected: ${detectedTz}`));
|
|
|
14965
15162
|
);
|
|
14966
15163
|
if (enable) {
|
|
14967
15164
|
await updateUserPreferences({ notifyEmail: true });
|
|
14968
|
-
console.log(
|
|
15165
|
+
console.log(chalk79.green("Email notifications enabled"));
|
|
14969
15166
|
}
|
|
14970
15167
|
}
|
|
14971
15168
|
}
|
|
@@ -14984,10 +15181,10 @@ var preferenceCommand = new Command77().name("preference").description("View or
|
|
|
14984
15181
|
} else if (!prefs.timezone) {
|
|
14985
15182
|
console.log();
|
|
14986
15183
|
console.log(
|
|
14987
|
-
`To set timezone: ${
|
|
15184
|
+
`To set timezone: ${chalk79.cyan("vm0 preference --timezone <timezone>")}`
|
|
14988
15185
|
);
|
|
14989
15186
|
console.log(
|
|
14990
|
-
|
|
15187
|
+
chalk79.dim("Example: vm0 preference --timezone America/New_York")
|
|
14991
15188
|
);
|
|
14992
15189
|
}
|
|
14993
15190
|
})
|
|
@@ -14995,7 +15192,7 @@ var preferenceCommand = new Command77().name("preference").description("View or
|
|
|
14995
15192
|
|
|
14996
15193
|
// src/index.ts
|
|
14997
15194
|
var program = new Command78();
|
|
14998
|
-
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.
|
|
15195
|
+
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.38.1");
|
|
14999
15196
|
program.addCommand(authCommand);
|
|
15000
15197
|
program.addCommand(infoCommand);
|
|
15001
15198
|
program.addCommand(composeCommand);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vm0/cli",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.38.1",
|
|
4
4
|
"description": "CLI application",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"."
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
+
"@ngrok/ngrok": "^1.6.0",
|
|
18
19
|
"@sentry/node": "^10.38.0",
|
|
19
20
|
"@ts-rest/core": "3.53.0-rc.1",
|
|
20
21
|
"ably": "^2.17.0",
|