@vm0/cli 9.37.6 → 9.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +327 -158
- 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.0",
|
|
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.0",
|
|
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.0"}`));
|
|
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
|
},
|
|
@@ -3854,7 +3848,7 @@ var connectorSessionByIdContract = c19.router({
|
|
|
3854
3848
|
});
|
|
3855
3849
|
var computerConnectorCreateResponseSchema = z23.object({
|
|
3856
3850
|
id: z23.string().uuid(),
|
|
3857
|
-
|
|
3851
|
+
ngrokToken: z23.string(),
|
|
3858
3852
|
bridgeToken: z23.string(),
|
|
3859
3853
|
endpointPrefix: z23.string(),
|
|
3860
3854
|
domain: z23.string()
|
|
@@ -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.0");
|
|
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.0");
|
|
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.0", prompt);
|
|
10274
10268
|
if (shouldExit) {
|
|
10275
10269
|
process.exit(0);
|
|
10276
10270
|
}
|
|
@@ -13774,8 +13768,156 @@ 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 { createServer } from "net";
|
|
13777
|
+
import { homedir as homedir4 } from "os";
|
|
13778
|
+
import { join as join11 } from "path";
|
|
13779
|
+
import chalk67 from "chalk";
|
|
13780
|
+
|
|
13781
|
+
// src/commands/connector/lib/computer/ngrok.ts
|
|
13782
|
+
import ngrok from "@ngrok/ngrok";
|
|
13783
|
+
async function startNgrokTunnels(ngrokToken, endpointPrefix, webdavPort, cdpPort) {
|
|
13784
|
+
await ngrok.forward({
|
|
13785
|
+
addr: `localhost:${webdavPort}`,
|
|
13786
|
+
authtoken: ngrokToken,
|
|
13787
|
+
domain: `webdav.${endpointPrefix}.internal`
|
|
13788
|
+
});
|
|
13789
|
+
await ngrok.forward({
|
|
13790
|
+
addr: `localhost:${cdpPort}`,
|
|
13791
|
+
authtoken: ngrokToken,
|
|
13792
|
+
domain: `chrome.${endpointPrefix}.internal`
|
|
13793
|
+
});
|
|
13794
|
+
}
|
|
13795
|
+
async function stopNgrokTunnels() {
|
|
13796
|
+
await ngrok.kill();
|
|
13797
|
+
}
|
|
13798
|
+
|
|
13799
|
+
// src/commands/connector/lib/computer/start-services.ts
|
|
13800
|
+
async function getRandomPort() {
|
|
13801
|
+
return new Promise((resolve, reject) => {
|
|
13802
|
+
const server = createServer();
|
|
13803
|
+
server.listen(0, "127.0.0.1", () => {
|
|
13804
|
+
const { port } = server.address();
|
|
13805
|
+
server.close(() => resolve(port));
|
|
13806
|
+
});
|
|
13807
|
+
server.on("error", reject);
|
|
13808
|
+
});
|
|
13809
|
+
}
|
|
13810
|
+
async function findCommand(...candidates) {
|
|
13811
|
+
for (const binary of candidates) {
|
|
13812
|
+
const found = await new Promise((resolve) => {
|
|
13813
|
+
const child = spawn3("which", [binary]);
|
|
13814
|
+
child.on("close", (code) => resolve(code === 0));
|
|
13815
|
+
});
|
|
13816
|
+
if (found) return binary;
|
|
13817
|
+
}
|
|
13818
|
+
return null;
|
|
13819
|
+
}
|
|
13820
|
+
async function startComputerServices(credentials) {
|
|
13821
|
+
console.log(chalk67.cyan("Starting computer connector services..."));
|
|
13822
|
+
const wsgidavBinary = await findCommand("wsgidav");
|
|
13823
|
+
if (!wsgidavBinary) {
|
|
13824
|
+
throw new Error(
|
|
13825
|
+
"wsgidav not found\n\nInstall with: pip install wsgidav[cheroot]"
|
|
13826
|
+
);
|
|
13827
|
+
}
|
|
13828
|
+
const chromeBinary = await findCommand(
|
|
13829
|
+
"google-chrome",
|
|
13830
|
+
"google-chrome-stable",
|
|
13831
|
+
"chromium",
|
|
13832
|
+
"chromium-browser",
|
|
13833
|
+
"chrome"
|
|
13834
|
+
);
|
|
13835
|
+
if (!chromeBinary) {
|
|
13836
|
+
throw new Error("Chrome not found\n\nInstall Google Chrome or Chromium");
|
|
13837
|
+
}
|
|
13838
|
+
const webdavPort = await getRandomPort();
|
|
13839
|
+
const cdpPort = await getRandomPort();
|
|
13840
|
+
const downloadsPath = join11(homedir4(), "Downloads");
|
|
13841
|
+
const wsgidav = spawn3(
|
|
13842
|
+
wsgidavBinary,
|
|
13843
|
+
[
|
|
13844
|
+
"--host=127.0.0.1",
|
|
13845
|
+
`--port=${webdavPort}`,
|
|
13846
|
+
`--root=${downloadsPath}`,
|
|
13847
|
+
"--auth=anonymous",
|
|
13848
|
+
"--no-config"
|
|
13849
|
+
],
|
|
13850
|
+
{ stdio: ["ignore", "pipe", "pipe"] }
|
|
13851
|
+
);
|
|
13852
|
+
wsgidav.stdout?.on("data", (data) => process.stdout.write(data));
|
|
13853
|
+
wsgidav.stderr?.on("data", (data) => process.stderr.write(data));
|
|
13854
|
+
console.log(chalk67.green("\u2713 WebDAV server started"));
|
|
13855
|
+
const chrome = spawn3(
|
|
13856
|
+
chromeBinary,
|
|
13857
|
+
[
|
|
13858
|
+
`--remote-debugging-port=${cdpPort}`,
|
|
13859
|
+
"--remote-debugging-address=127.0.0.1",
|
|
13860
|
+
"--headless=new",
|
|
13861
|
+
"--no-sandbox",
|
|
13862
|
+
"--disable-gpu"
|
|
13863
|
+
],
|
|
13864
|
+
{ stdio: ["ignore", "pipe", "pipe"] }
|
|
13865
|
+
);
|
|
13866
|
+
chrome.stdout?.on("data", (data) => process.stdout.write(data));
|
|
13867
|
+
chrome.stderr?.on("data", (data) => process.stderr.write(data));
|
|
13868
|
+
console.log(chalk67.green("\u2713 Chrome started"));
|
|
13869
|
+
try {
|
|
13870
|
+
await startNgrokTunnels(
|
|
13871
|
+
credentials.ngrokToken,
|
|
13872
|
+
credentials.endpointPrefix,
|
|
13873
|
+
webdavPort,
|
|
13874
|
+
cdpPort
|
|
13875
|
+
);
|
|
13876
|
+
console.log(
|
|
13877
|
+
chalk67.green(
|
|
13878
|
+
`\u2713 ngrok tunnels: webdav.${credentials.domain}, chrome.${credentials.domain}`
|
|
13879
|
+
)
|
|
13880
|
+
);
|
|
13881
|
+
console.log();
|
|
13882
|
+
console.log(chalk67.green("\u2713 Computer connector active"));
|
|
13883
|
+
console.log(` WebDAV: ~/Downloads \u2192 webdav.${credentials.domain}`);
|
|
13884
|
+
console.log(
|
|
13885
|
+
` Chrome CDP: port ${cdpPort} \u2192 chrome.${credentials.domain}`
|
|
13886
|
+
);
|
|
13887
|
+
console.log();
|
|
13888
|
+
console.log(chalk67.dim("Press ^C twice to disconnect"));
|
|
13889
|
+
console.log();
|
|
13890
|
+
let sigintCount = 0;
|
|
13891
|
+
await new Promise((resolve) => {
|
|
13892
|
+
const keepAlive = setInterval(() => {
|
|
13893
|
+
}, 6e4);
|
|
13894
|
+
const done = () => {
|
|
13895
|
+
clearInterval(keepAlive);
|
|
13896
|
+
process.removeListener("SIGINT", onSigint);
|
|
13897
|
+
resolve();
|
|
13898
|
+
};
|
|
13899
|
+
const onSigint = () => {
|
|
13900
|
+
sigintCount++;
|
|
13901
|
+
if (sigintCount === 1) {
|
|
13902
|
+
console.log(chalk67.dim("\nPress ^C again to disconnect and exit..."));
|
|
13903
|
+
} else {
|
|
13904
|
+
done();
|
|
13905
|
+
}
|
|
13906
|
+
};
|
|
13907
|
+
process.on("SIGINT", onSigint);
|
|
13908
|
+
process.once("SIGTERM", done);
|
|
13909
|
+
});
|
|
13910
|
+
} finally {
|
|
13911
|
+
console.log();
|
|
13912
|
+
console.log(chalk67.cyan("Stopping services..."));
|
|
13913
|
+
wsgidav.kill("SIGTERM");
|
|
13914
|
+
chrome.kill("SIGTERM");
|
|
13915
|
+
await stopNgrokTunnels();
|
|
13916
|
+
console.log(chalk67.green("\u2713 Services stopped"));
|
|
13917
|
+
}
|
|
13918
|
+
}
|
|
13919
|
+
|
|
13920
|
+
// src/commands/connector/connect.ts
|
|
13779
13921
|
function delay2(ms) {
|
|
13780
13922
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
13781
13923
|
}
|
|
@@ -13797,14 +13939,40 @@ var connectCommand = new Command67().name("connect").description("Connect a thir
|
|
|
13797
13939
|
try {
|
|
13798
13940
|
const parseResult = connectorTypeSchema.safeParse(type2);
|
|
13799
13941
|
if (!parseResult.success) {
|
|
13800
|
-
console.error(
|
|
13942
|
+
console.error(chalk68.red(`\u2717 Unknown connector type: ${type2}`));
|
|
13801
13943
|
console.error("Available connectors: github");
|
|
13802
13944
|
process.exit(1);
|
|
13803
13945
|
}
|
|
13804
13946
|
const connectorType = parseResult.data;
|
|
13805
13947
|
const apiUrl = await getApiUrl();
|
|
13806
13948
|
const headers = await getHeaders2();
|
|
13807
|
-
|
|
13949
|
+
if (connectorType === "computer") {
|
|
13950
|
+
console.log(chalk68.cyan("Setting up computer connector..."));
|
|
13951
|
+
const computerClient = initClient13(computerConnectorContract, {
|
|
13952
|
+
baseUrl: apiUrl,
|
|
13953
|
+
baseHeaders: headers,
|
|
13954
|
+
jsonQuery: false
|
|
13955
|
+
});
|
|
13956
|
+
const createResult2 = await computerClient.create({
|
|
13957
|
+
body: {}
|
|
13958
|
+
});
|
|
13959
|
+
if (createResult2.status !== 200) {
|
|
13960
|
+
const errorBody = createResult2.body;
|
|
13961
|
+
console.error(
|
|
13962
|
+
chalk68.red(
|
|
13963
|
+
`\u2717 Failed to create connector: ${errorBody.error?.message}`
|
|
13964
|
+
)
|
|
13965
|
+
);
|
|
13966
|
+
process.exit(1);
|
|
13967
|
+
}
|
|
13968
|
+
const credentials = createResult2.body;
|
|
13969
|
+
await startComputerServices(credentials);
|
|
13970
|
+
console.log(chalk68.cyan("Disconnecting computer connector..."));
|
|
13971
|
+
await deleteConnector("computer");
|
|
13972
|
+
console.log(chalk68.green("\u2713 Disconnected computer"));
|
|
13973
|
+
process.exit(0);
|
|
13974
|
+
}
|
|
13975
|
+
console.log(`Connecting ${chalk68.cyan(type2)}...`);
|
|
13808
13976
|
const sessionsClient = initClient13(connectorSessionsContract, {
|
|
13809
13977
|
baseUrl: apiUrl,
|
|
13810
13978
|
baseHeaders: headers,
|
|
@@ -13817,14 +13985,14 @@ var connectCommand = new Command67().name("connect").description("Connect a thir
|
|
|
13817
13985
|
if (createResult.status !== 200) {
|
|
13818
13986
|
const errorBody = createResult.body;
|
|
13819
13987
|
console.error(
|
|
13820
|
-
|
|
13988
|
+
chalk68.red(`\u2717 Failed to create session: ${errorBody.error?.message}`)
|
|
13821
13989
|
);
|
|
13822
13990
|
process.exit(1);
|
|
13823
13991
|
}
|
|
13824
13992
|
const session = createResult.body;
|
|
13825
13993
|
const verificationUrl = `${apiUrl}${session.verificationUrl}`;
|
|
13826
|
-
console.log(
|
|
13827
|
-
console.log(
|
|
13994
|
+
console.log(chalk68.green("\nSession created"));
|
|
13995
|
+
console.log(chalk68.cyan(`
|
|
13828
13996
|
To connect, visit: ${verificationUrl}`));
|
|
13829
13997
|
console.log(
|
|
13830
13998
|
`
|
|
@@ -13851,7 +14019,7 @@ The session expires in ${Math.floor(session.expiresIn / 60)} minutes.`
|
|
|
13851
14019
|
if (statusResult.status !== 200) {
|
|
13852
14020
|
const errorBody = statusResult.body;
|
|
13853
14021
|
console.error(
|
|
13854
|
-
|
|
14022
|
+
chalk68.red(
|
|
13855
14023
|
`
|
|
13856
14024
|
\u2717 Failed to check status: ${errorBody.error?.message}`
|
|
13857
14025
|
)
|
|
@@ -13861,17 +14029,17 @@ The session expires in ${Math.floor(session.expiresIn / 60)} minutes.`
|
|
|
13861
14029
|
const status = statusResult.body;
|
|
13862
14030
|
switch (status.status) {
|
|
13863
14031
|
case "complete":
|
|
13864
|
-
console.log(
|
|
14032
|
+
console.log(chalk68.green(`
|
|
13865
14033
|
|
|
13866
14034
|
${type2} connected successfully!`));
|
|
13867
14035
|
return;
|
|
13868
14036
|
case "expired":
|
|
13869
|
-
console.error(
|
|
14037
|
+
console.error(chalk68.red("\n\u2717 Session expired, please try again"));
|
|
13870
14038
|
process.exit(1);
|
|
13871
14039
|
break;
|
|
13872
14040
|
case "error":
|
|
13873
14041
|
console.error(
|
|
13874
|
-
|
|
14042
|
+
chalk68.red(
|
|
13875
14043
|
`
|
|
13876
14044
|
\u2717 Connection failed: ${status.errorMessage || "Unknown error"}`
|
|
13877
14045
|
)
|
|
@@ -13879,20 +14047,20 @@ ${type2} connected successfully!`));
|
|
|
13879
14047
|
process.exit(1);
|
|
13880
14048
|
break;
|
|
13881
14049
|
case "pending":
|
|
13882
|
-
process.stdout.write(
|
|
14050
|
+
process.stdout.write(chalk68.dim("."));
|
|
13883
14051
|
break;
|
|
13884
14052
|
}
|
|
13885
14053
|
}
|
|
13886
|
-
console.error(
|
|
14054
|
+
console.error(chalk68.red("\n\u2717 Session timed out, please try again"));
|
|
13887
14055
|
process.exit(1);
|
|
13888
14056
|
} catch (error) {
|
|
13889
14057
|
if (error instanceof Error) {
|
|
13890
|
-
console.error(
|
|
14058
|
+
console.error(chalk68.red(`\u2717 ${error.message}`));
|
|
13891
14059
|
if (error.cause instanceof Error) {
|
|
13892
|
-
console.error(
|
|
14060
|
+
console.error(chalk68.dim(` Cause: ${error.cause.message}`));
|
|
13893
14061
|
}
|
|
13894
14062
|
} else {
|
|
13895
|
-
console.error(
|
|
14063
|
+
console.error(chalk68.red("\u2717 An unexpected error occurred"));
|
|
13896
14064
|
}
|
|
13897
14065
|
process.exit(1);
|
|
13898
14066
|
}
|
|
@@ -13900,7 +14068,7 @@ ${type2} connected successfully!`));
|
|
|
13900
14068
|
|
|
13901
14069
|
// src/commands/connector/list.ts
|
|
13902
14070
|
import { Command as Command68 } from "commander";
|
|
13903
|
-
import
|
|
14071
|
+
import chalk69 from "chalk";
|
|
13904
14072
|
var listCommand9 = new Command68().name("list").alias("ls").description("List all connectors and their status").action(
|
|
13905
14073
|
withErrorHandler(async () => {
|
|
13906
14074
|
const result = await listConnectors();
|
|
@@ -13914,42 +14082,42 @@ var listCommand9 = new Command68().name("list").alias("ls").description("List al
|
|
|
13914
14082
|
statusText.padEnd(statusWidth),
|
|
13915
14083
|
"ACCOUNT"
|
|
13916
14084
|
].join(" ");
|
|
13917
|
-
console.log(
|
|
14085
|
+
console.log(chalk69.dim(header));
|
|
13918
14086
|
for (const type2 of allTypes) {
|
|
13919
14087
|
const connector = connectedMap.get(type2);
|
|
13920
|
-
const status = connector ?
|
|
13921
|
-
const account = connector?.externalUsername ? `@${connector.externalUsername}` :
|
|
14088
|
+
const status = connector ? chalk69.green("\u2713".padEnd(statusWidth)) : chalk69.dim("-".padEnd(statusWidth));
|
|
14089
|
+
const account = connector?.externalUsername ? `@${connector.externalUsername}` : chalk69.dim("-");
|
|
13922
14090
|
const row = [type2.padEnd(typeWidth), status, account].join(" ");
|
|
13923
14091
|
console.log(row);
|
|
13924
14092
|
}
|
|
13925
14093
|
console.log();
|
|
13926
|
-
console.log(
|
|
13927
|
-
console.log(
|
|
14094
|
+
console.log(chalk69.dim("To connect a service:"));
|
|
14095
|
+
console.log(chalk69.dim(" vm0 connector connect <type>"));
|
|
13928
14096
|
})
|
|
13929
14097
|
);
|
|
13930
14098
|
|
|
13931
14099
|
// src/commands/connector/status.ts
|
|
13932
14100
|
import { Command as Command69 } from "commander";
|
|
13933
|
-
import
|
|
14101
|
+
import chalk70 from "chalk";
|
|
13934
14102
|
var LABEL_WIDTH = 16;
|
|
13935
14103
|
var statusCommand7 = new Command69().name("status").description("Show detailed status of a connector").argument("<type>", "Connector type (e.g., github)").action(
|
|
13936
14104
|
withErrorHandler(async (type2) => {
|
|
13937
14105
|
const parseResult = connectorTypeSchema.safeParse(type2);
|
|
13938
14106
|
if (!parseResult.success) {
|
|
13939
|
-
console.error(
|
|
14107
|
+
console.error(chalk70.red(`\u2717 Unknown connector type: ${type2}`));
|
|
13940
14108
|
console.error();
|
|
13941
14109
|
console.error("Available connectors:");
|
|
13942
14110
|
for (const [t, config] of Object.entries(CONNECTOR_TYPES)) {
|
|
13943
|
-
console.error(` ${
|
|
14111
|
+
console.error(` ${chalk70.cyan(t)} - ${config.label}`);
|
|
13944
14112
|
}
|
|
13945
14113
|
process.exit(1);
|
|
13946
14114
|
}
|
|
13947
14115
|
const connector = await getConnector(parseResult.data);
|
|
13948
|
-
console.log(`Connector: ${
|
|
14116
|
+
console.log(`Connector: ${chalk70.cyan(type2)}`);
|
|
13949
14117
|
console.log();
|
|
13950
14118
|
if (connector) {
|
|
13951
14119
|
console.log(
|
|
13952
|
-
`${"Status:".padEnd(LABEL_WIDTH)}${
|
|
14120
|
+
`${"Status:".padEnd(LABEL_WIDTH)}${chalk70.green("connected")}`
|
|
13953
14121
|
);
|
|
13954
14122
|
console.log(
|
|
13955
14123
|
`${"Account:".padEnd(LABEL_WIDTH)}@${connector.externalUsername}`
|
|
@@ -13971,50 +14139,51 @@ var statusCommand7 = new Command69().name("status").description("Show detailed s
|
|
|
13971
14139
|
);
|
|
13972
14140
|
}
|
|
13973
14141
|
console.log();
|
|
13974
|
-
console.log(
|
|
13975
|
-
console.log(
|
|
14142
|
+
console.log(chalk70.dim("To disconnect:"));
|
|
14143
|
+
console.log(chalk70.dim(` vm0 connector disconnect ${type2}`));
|
|
13976
14144
|
} else {
|
|
13977
14145
|
console.log(
|
|
13978
|
-
`${"Status:".padEnd(LABEL_WIDTH)}${
|
|
14146
|
+
`${"Status:".padEnd(LABEL_WIDTH)}${chalk70.dim("not connected")}`
|
|
13979
14147
|
);
|
|
13980
14148
|
console.log();
|
|
13981
|
-
console.log(
|
|
13982
|
-
console.log(
|
|
14149
|
+
console.log(chalk70.dim("To connect:"));
|
|
14150
|
+
console.log(chalk70.dim(` vm0 connector connect ${type2}`));
|
|
13983
14151
|
}
|
|
13984
14152
|
})
|
|
13985
14153
|
);
|
|
13986
14154
|
|
|
13987
14155
|
// src/commands/connector/disconnect.ts
|
|
13988
14156
|
import { Command as Command70 } from "commander";
|
|
13989
|
-
import
|
|
14157
|
+
import chalk71 from "chalk";
|
|
13990
14158
|
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
14159
|
try {
|
|
13992
14160
|
const parseResult = connectorTypeSchema.safeParse(type2);
|
|
13993
14161
|
if (!parseResult.success) {
|
|
13994
|
-
console.error(
|
|
14162
|
+
console.error(chalk71.red(`\u2717 Unknown connector type: ${type2}`));
|
|
13995
14163
|
console.error();
|
|
13996
14164
|
console.error("Available connectors:");
|
|
13997
14165
|
for (const [t, config] of Object.entries(CONNECTOR_TYPES)) {
|
|
13998
|
-
console.error(` ${
|
|
14166
|
+
console.error(` ${chalk71.cyan(t)} - ${config.label}`);
|
|
13999
14167
|
}
|
|
14000
14168
|
process.exit(1);
|
|
14001
14169
|
}
|
|
14002
|
-
|
|
14003
|
-
|
|
14170
|
+
const connectorType = parseResult.data;
|
|
14171
|
+
await deleteConnector(connectorType);
|
|
14172
|
+
console.log(chalk71.green(`\u2713 Disconnected ${type2}`));
|
|
14004
14173
|
} catch (error) {
|
|
14005
14174
|
if (error instanceof Error) {
|
|
14006
14175
|
if (error.message.includes("not found")) {
|
|
14007
|
-
console.error(
|
|
14176
|
+
console.error(chalk71.red(`\u2717 Connector "${type2}" is not connected`));
|
|
14008
14177
|
} else if (error.message.includes("Not authenticated")) {
|
|
14009
|
-
console.error(
|
|
14178
|
+
console.error(chalk71.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
14010
14179
|
} else {
|
|
14011
|
-
console.error(
|
|
14180
|
+
console.error(chalk71.red(`\u2717 ${error.message}`));
|
|
14012
14181
|
if (error.cause instanceof Error) {
|
|
14013
|
-
console.error(
|
|
14182
|
+
console.error(chalk71.dim(` Cause: ${error.cause.message}`));
|
|
14014
14183
|
}
|
|
14015
14184
|
}
|
|
14016
14185
|
} else {
|
|
14017
|
-
console.error(
|
|
14186
|
+
console.error(chalk71.red("\u2717 An unexpected error occurred"));
|
|
14018
14187
|
}
|
|
14019
14188
|
process.exit(1);
|
|
14020
14189
|
}
|
|
@@ -14025,24 +14194,24 @@ var connectorCommand = new Command71().name("connector").description("Manage thi
|
|
|
14025
14194
|
|
|
14026
14195
|
// src/commands/onboard/index.ts
|
|
14027
14196
|
import { Command as Command72 } from "commander";
|
|
14028
|
-
import
|
|
14197
|
+
import chalk75 from "chalk";
|
|
14029
14198
|
import { mkdir as mkdir8 } from "fs/promises";
|
|
14030
14199
|
import { existsSync as existsSync12 } from "fs";
|
|
14031
14200
|
|
|
14032
14201
|
// src/lib/ui/welcome-box.ts
|
|
14033
|
-
import
|
|
14202
|
+
import chalk72 from "chalk";
|
|
14034
14203
|
var gradientColors = [
|
|
14035
|
-
|
|
14204
|
+
chalk72.hex("#FFAB5E"),
|
|
14036
14205
|
// Line 1 - lightest
|
|
14037
|
-
|
|
14206
|
+
chalk72.hex("#FF9642"),
|
|
14038
14207
|
// Line 2
|
|
14039
|
-
|
|
14208
|
+
chalk72.hex("#FF8228"),
|
|
14040
14209
|
// Line 3
|
|
14041
|
-
|
|
14210
|
+
chalk72.hex("#FF6D0A"),
|
|
14042
14211
|
// Line 4
|
|
14043
|
-
|
|
14212
|
+
chalk72.hex("#E85D00"),
|
|
14044
14213
|
// Line 5
|
|
14045
|
-
|
|
14214
|
+
chalk72.hex("#CC4E00")
|
|
14046
14215
|
// Line 6 - darkest
|
|
14047
14216
|
];
|
|
14048
14217
|
var vm0LogoLines = [
|
|
@@ -14064,15 +14233,15 @@ function renderVm0Banner() {
|
|
|
14064
14233
|
function renderOnboardWelcome() {
|
|
14065
14234
|
renderVm0Banner();
|
|
14066
14235
|
console.log(` Build agentic workflows using natural language.`);
|
|
14067
|
-
console.log(` ${
|
|
14236
|
+
console.log(` ${chalk72.dim("Currently in beta, enjoy it free")}`);
|
|
14068
14237
|
console.log(
|
|
14069
|
-
` ${
|
|
14238
|
+
` ${chalk72.dim("Star us on GitHub: https://github.com/vm0-ai/vm0")}`
|
|
14070
14239
|
);
|
|
14071
14240
|
console.log();
|
|
14072
14241
|
}
|
|
14073
14242
|
|
|
14074
14243
|
// src/lib/ui/step-runner.ts
|
|
14075
|
-
import
|
|
14244
|
+
import chalk73 from "chalk";
|
|
14076
14245
|
function createStepRunner(options = true) {
|
|
14077
14246
|
const opts = typeof options === "boolean" ? { interactive: options } : options;
|
|
14078
14247
|
const interactive = opts.interactive ?? true;
|
|
@@ -14087,25 +14256,25 @@ function createStepRunner(options = true) {
|
|
|
14087
14256
|
}
|
|
14088
14257
|
for (const [i, step] of completedSteps.entries()) {
|
|
14089
14258
|
if (step.failed) {
|
|
14090
|
-
console.log(
|
|
14259
|
+
console.log(chalk73.red(`\u2717 ${step.label}`));
|
|
14091
14260
|
} else {
|
|
14092
|
-
console.log(
|
|
14261
|
+
console.log(chalk73.green(`\u25CF ${step.label}`));
|
|
14093
14262
|
}
|
|
14094
14263
|
const isLastStep = i === completedSteps.length - 1;
|
|
14095
14264
|
if (!isLastStep || !isFinal) {
|
|
14096
|
-
console.log(
|
|
14265
|
+
console.log(chalk73.dim("\u2502"));
|
|
14097
14266
|
}
|
|
14098
14267
|
}
|
|
14099
14268
|
}
|
|
14100
14269
|
async function executeStep(label, fn, isFinal) {
|
|
14101
14270
|
let stepFailed = false;
|
|
14102
|
-
console.log(
|
|
14271
|
+
console.log(chalk73.yellow(`\u25CB ${label}`));
|
|
14103
14272
|
const ctx = {
|
|
14104
14273
|
connector() {
|
|
14105
|
-
console.log(
|
|
14274
|
+
console.log(chalk73.dim("\u2502"));
|
|
14106
14275
|
},
|
|
14107
14276
|
detail(message) {
|
|
14108
|
-
console.log(`${
|
|
14277
|
+
console.log(`${chalk73.dim("\u2502")} ${message}`);
|
|
14109
14278
|
},
|
|
14110
14279
|
async prompt(promptFn) {
|
|
14111
14280
|
return await promptFn();
|
|
@@ -14122,12 +14291,12 @@ function createStepRunner(options = true) {
|
|
|
14122
14291
|
redrawCompletedSteps(isFinal);
|
|
14123
14292
|
} else {
|
|
14124
14293
|
if (stepFailed) {
|
|
14125
|
-
console.log(
|
|
14294
|
+
console.log(chalk73.red(`\u2717 ${label}`));
|
|
14126
14295
|
} else {
|
|
14127
|
-
console.log(
|
|
14296
|
+
console.log(chalk73.green(`\u25CF ${label}`));
|
|
14128
14297
|
}
|
|
14129
14298
|
if (!isFinal) {
|
|
14130
|
-
console.log(
|
|
14299
|
+
console.log(chalk73.dim("\u2502"));
|
|
14131
14300
|
}
|
|
14132
14301
|
}
|
|
14133
14302
|
}
|
|
@@ -14286,15 +14455,15 @@ async function setupModelProvider(type2, secret, options) {
|
|
|
14286
14455
|
}
|
|
14287
14456
|
|
|
14288
14457
|
// src/lib/domain/onboard/claude-setup.ts
|
|
14289
|
-
import { spawn as
|
|
14290
|
-
import
|
|
14458
|
+
import { spawn as spawn4 } from "child_process";
|
|
14459
|
+
import chalk74 from "chalk";
|
|
14291
14460
|
var MARKETPLACE_NAME = "vm0-skills";
|
|
14292
14461
|
var MARKETPLACE_REPO = "vm0-ai/vm0-skills";
|
|
14293
14462
|
var PLUGIN_ID = "vm0@vm0-skills";
|
|
14294
14463
|
var PRIMARY_SKILL_NAME = "vm0-agent";
|
|
14295
14464
|
async function runClaudeCommand(args, cwd) {
|
|
14296
14465
|
return new Promise((resolve) => {
|
|
14297
|
-
const child =
|
|
14466
|
+
const child = spawn4("claude", args, {
|
|
14298
14467
|
stdio: ["inherit", "pipe", "pipe"],
|
|
14299
14468
|
cwd
|
|
14300
14469
|
});
|
|
@@ -14324,12 +14493,12 @@ async function runClaudeCommand(args, cwd) {
|
|
|
14324
14493
|
}
|
|
14325
14494
|
function handlePluginError(error, context) {
|
|
14326
14495
|
const displayContext = context ?? "Claude plugin";
|
|
14327
|
-
console.error(
|
|
14496
|
+
console.error(chalk74.red(`\u2717 Failed to install ${displayContext}`));
|
|
14328
14497
|
if (error instanceof Error) {
|
|
14329
|
-
console.error(
|
|
14498
|
+
console.error(chalk74.red(`\u2717 ${error.message}`));
|
|
14330
14499
|
}
|
|
14331
14500
|
console.error(
|
|
14332
|
-
|
|
14501
|
+
chalk74.dim("Please ensure Claude CLI is installed and accessible.")
|
|
14333
14502
|
);
|
|
14334
14503
|
process.exit(1);
|
|
14335
14504
|
}
|
|
@@ -14372,7 +14541,7 @@ async function updateMarketplace() {
|
|
|
14372
14541
|
]);
|
|
14373
14542
|
if (!result.success) {
|
|
14374
14543
|
console.warn(
|
|
14375
|
-
|
|
14544
|
+
chalk74.yellow(
|
|
14376
14545
|
`Warning: Could not update marketplace: ${result.error ?? "unknown error"}`
|
|
14377
14546
|
)
|
|
14378
14547
|
);
|
|
@@ -14410,7 +14579,7 @@ async function handleAuthentication(ctx) {
|
|
|
14410
14579
|
return;
|
|
14411
14580
|
}
|
|
14412
14581
|
if (!ctx.interactive) {
|
|
14413
|
-
console.error(
|
|
14582
|
+
console.error(chalk75.red("\u2717 Not authenticated"));
|
|
14414
14583
|
console.error("Run 'vm0 auth login' first or set VM0_TOKEN");
|
|
14415
14584
|
process.exit(1);
|
|
14416
14585
|
}
|
|
@@ -14418,19 +14587,19 @@ async function handleAuthentication(ctx) {
|
|
|
14418
14587
|
onInitiating: () => {
|
|
14419
14588
|
},
|
|
14420
14589
|
onDeviceCodeReady: (url, code, expiresIn) => {
|
|
14421
|
-
step.detail(`Copy code: ${
|
|
14422
|
-
step.detail(`Open: ${
|
|
14423
|
-
step.detail(
|
|
14590
|
+
step.detail(`Copy code: ${chalk75.cyan.bold(code)}`);
|
|
14591
|
+
step.detail(`Open: ${chalk75.cyan(url)}`);
|
|
14592
|
+
step.detail(chalk75.dim(`Expires in ${expiresIn} minutes`));
|
|
14424
14593
|
},
|
|
14425
14594
|
onPolling: () => {
|
|
14426
14595
|
},
|
|
14427
14596
|
onSuccess: () => {
|
|
14428
14597
|
},
|
|
14429
14598
|
onError: (error) => {
|
|
14430
|
-
console.error(
|
|
14599
|
+
console.error(chalk75.red(`
|
|
14431
14600
|
\u2717 ${error.message}`));
|
|
14432
14601
|
if (error.cause instanceof Error) {
|
|
14433
|
-
console.error(
|
|
14602
|
+
console.error(chalk75.dim(` Cause: ${error.cause.message}`));
|
|
14434
14603
|
}
|
|
14435
14604
|
process.exit(1);
|
|
14436
14605
|
}
|
|
@@ -14444,7 +14613,7 @@ async function handleModelProvider(ctx) {
|
|
|
14444
14613
|
return;
|
|
14445
14614
|
}
|
|
14446
14615
|
if (!ctx.interactive) {
|
|
14447
|
-
console.error(
|
|
14616
|
+
console.error(chalk75.red("\u2717 No model provider configured"));
|
|
14448
14617
|
console.error("Run 'vm0 model-provider setup' first");
|
|
14449
14618
|
process.exit(1);
|
|
14450
14619
|
}
|
|
@@ -14465,14 +14634,14 @@ async function handleModelProvider(ctx) {
|
|
|
14465
14634
|
const selectedChoice = choices.find((c25) => c25.type === providerType);
|
|
14466
14635
|
if (selectedChoice?.helpText) {
|
|
14467
14636
|
for (const line of selectedChoice.helpText.split("\n")) {
|
|
14468
|
-
step.detail(
|
|
14637
|
+
step.detail(chalk75.dim(line));
|
|
14469
14638
|
}
|
|
14470
14639
|
}
|
|
14471
14640
|
const secret = await step.prompt(
|
|
14472
14641
|
() => promptPassword(`Enter your ${selectedChoice?.secretLabel ?? "secret"}:`)
|
|
14473
14642
|
);
|
|
14474
14643
|
if (!secret) {
|
|
14475
|
-
console.log(
|
|
14644
|
+
console.log(chalk75.dim("Cancelled"));
|
|
14476
14645
|
process.exit(0);
|
|
14477
14646
|
}
|
|
14478
14647
|
let selectedModel;
|
|
@@ -14491,7 +14660,7 @@ async function handleModelProvider(ctx) {
|
|
|
14491
14660
|
() => promptSelect("Select model:", modelChoices)
|
|
14492
14661
|
);
|
|
14493
14662
|
if (modelSelection === void 0) {
|
|
14494
|
-
console.log(
|
|
14663
|
+
console.log(chalk75.dim("Cancelled"));
|
|
14495
14664
|
process.exit(0);
|
|
14496
14665
|
}
|
|
14497
14666
|
selectedModel = modelSelection === "" ? void 0 : modelSelection;
|
|
@@ -14501,7 +14670,7 @@ async function handleModelProvider(ctx) {
|
|
|
14501
14670
|
});
|
|
14502
14671
|
const modelNote = result.provider.selectedModel ? ` with model: ${result.provider.selectedModel}` : "";
|
|
14503
14672
|
step.detail(
|
|
14504
|
-
|
|
14673
|
+
chalk75.green(
|
|
14505
14674
|
`${providerType} ${result.created ? "created" : "updated"}${result.isDefault ? ` (default for ${result.framework})` : ""}${modelNote}`
|
|
14506
14675
|
)
|
|
14507
14676
|
);
|
|
@@ -14532,7 +14701,7 @@ async function handleAgentCreation(ctx) {
|
|
|
14532
14701
|
agentName = inputName;
|
|
14533
14702
|
if (existsSync12(agentName)) {
|
|
14534
14703
|
step.detail(
|
|
14535
|
-
|
|
14704
|
+
chalk75.yellow(`${agentName}/ already exists, choose another name`)
|
|
14536
14705
|
);
|
|
14537
14706
|
} else {
|
|
14538
14707
|
folderExists = false;
|
|
@@ -14541,22 +14710,22 @@ async function handleAgentCreation(ctx) {
|
|
|
14541
14710
|
} else {
|
|
14542
14711
|
if (!validateAgentName(agentName)) {
|
|
14543
14712
|
console.error(
|
|
14544
|
-
|
|
14713
|
+
chalk75.red(
|
|
14545
14714
|
"Invalid agent name: must be 3-64 chars, alphanumeric + hyphens"
|
|
14546
14715
|
)
|
|
14547
14716
|
);
|
|
14548
14717
|
process.exit(1);
|
|
14549
14718
|
}
|
|
14550
14719
|
if (existsSync12(agentName)) {
|
|
14551
|
-
console.error(
|
|
14720
|
+
console.error(chalk75.red(`\u2717 ${agentName}/ already exists`));
|
|
14552
14721
|
console.error();
|
|
14553
14722
|
console.error("Remove it first or choose a different name:");
|
|
14554
|
-
console.error(
|
|
14723
|
+
console.error(chalk75.cyan(` rm -rf ${agentName}`));
|
|
14555
14724
|
process.exit(1);
|
|
14556
14725
|
}
|
|
14557
14726
|
}
|
|
14558
14727
|
await mkdir8(agentName, { recursive: true });
|
|
14559
|
-
step.detail(
|
|
14728
|
+
step.detail(chalk75.green(`Created ${agentName}/`));
|
|
14560
14729
|
});
|
|
14561
14730
|
return agentName;
|
|
14562
14731
|
}
|
|
@@ -14572,7 +14741,7 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
14572
14741
|
shouldInstall = confirmed ?? true;
|
|
14573
14742
|
}
|
|
14574
14743
|
if (!shouldInstall) {
|
|
14575
|
-
step.detail(
|
|
14744
|
+
step.detail(chalk75.dim("Skipped"));
|
|
14576
14745
|
return;
|
|
14577
14746
|
}
|
|
14578
14747
|
const scope = "project";
|
|
@@ -14580,7 +14749,7 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
14580
14749
|
const agentDir = `${process.cwd()}/${agentName}`;
|
|
14581
14750
|
const result = await installVm0Plugin(scope, agentDir);
|
|
14582
14751
|
step.detail(
|
|
14583
|
-
|
|
14752
|
+
chalk75.green(`Installed ${result.pluginId} (scope: ${result.scope})`)
|
|
14584
14753
|
);
|
|
14585
14754
|
pluginInstalled = true;
|
|
14586
14755
|
} catch (error) {
|
|
@@ -14591,14 +14760,14 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
14591
14760
|
}
|
|
14592
14761
|
function printNextSteps(agentName, pluginInstalled) {
|
|
14593
14762
|
console.log();
|
|
14594
|
-
console.log(
|
|
14763
|
+
console.log(chalk75.bold("Next step:"));
|
|
14595
14764
|
console.log();
|
|
14596
14765
|
if (pluginInstalled) {
|
|
14597
14766
|
console.log(
|
|
14598
|
-
` ${
|
|
14767
|
+
` ${chalk75.cyan(`cd ${agentName} && claude "/${PRIMARY_SKILL_NAME} let's build an agent"`)}`
|
|
14599
14768
|
);
|
|
14600
14769
|
} else {
|
|
14601
|
-
console.log(` ${
|
|
14770
|
+
console.log(` ${chalk75.cyan(`cd ${agentName} && vm0 init`)}`);
|
|
14602
14771
|
}
|
|
14603
14772
|
console.log();
|
|
14604
14773
|
}
|
|
@@ -14625,12 +14794,12 @@ var onboardCommand = new Command72().name("onboard").description("Guided setup f
|
|
|
14625
14794
|
printNextSteps(agentName, pluginInstalled);
|
|
14626
14795
|
} catch (error) {
|
|
14627
14796
|
if (error instanceof Error) {
|
|
14628
|
-
console.error(
|
|
14797
|
+
console.error(chalk75.red(`\u2717 ${error.message}`));
|
|
14629
14798
|
if (error.cause instanceof Error) {
|
|
14630
|
-
console.error(
|
|
14799
|
+
console.error(chalk75.dim(` Cause: ${error.cause.message}`));
|
|
14631
14800
|
}
|
|
14632
14801
|
} else {
|
|
14633
|
-
console.error(
|
|
14802
|
+
console.error(chalk75.red("\u2717 An unexpected error occurred"));
|
|
14634
14803
|
}
|
|
14635
14804
|
process.exit(1);
|
|
14636
14805
|
}
|
|
@@ -14638,20 +14807,20 @@ var onboardCommand = new Command72().name("onboard").description("Guided setup f
|
|
|
14638
14807
|
|
|
14639
14808
|
// src/commands/setup-claude/index.ts
|
|
14640
14809
|
import { Command as Command73 } from "commander";
|
|
14641
|
-
import
|
|
14810
|
+
import chalk76 from "chalk";
|
|
14642
14811
|
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
14812
|
withErrorHandler(async (options) => {
|
|
14644
|
-
console.log(
|
|
14813
|
+
console.log(chalk76.dim("Installing VM0 Claude Plugin..."));
|
|
14645
14814
|
const scope = options.scope === "user" ? "user" : "project";
|
|
14646
14815
|
const result = await installVm0Plugin(scope, options.agentDir);
|
|
14647
14816
|
console.log(
|
|
14648
|
-
|
|
14817
|
+
chalk76.green(`\u2713 Installed ${result.pluginId} (scope: ${result.scope})`)
|
|
14649
14818
|
);
|
|
14650
14819
|
console.log();
|
|
14651
14820
|
console.log("Next step:");
|
|
14652
14821
|
const cdPrefix = options.agentDir ? `cd ${options.agentDir} && ` : "";
|
|
14653
14822
|
console.log(
|
|
14654
|
-
|
|
14823
|
+
chalk76.cyan(
|
|
14655
14824
|
` ${cdPrefix}claude "/${PRIMARY_SKILL_NAME} let's build a workflow"`
|
|
14656
14825
|
)
|
|
14657
14826
|
);
|
|
@@ -14660,28 +14829,28 @@ var setupClaudeCommand = new Command73().name("setup-claude").description("Insta
|
|
|
14660
14829
|
|
|
14661
14830
|
// src/commands/dashboard/index.ts
|
|
14662
14831
|
import { Command as Command74 } from "commander";
|
|
14663
|
-
import
|
|
14832
|
+
import chalk77 from "chalk";
|
|
14664
14833
|
var dashboardCommand = new Command74().name("dashboard").description("Quick reference for common query commands").action(() => {
|
|
14665
14834
|
console.log();
|
|
14666
|
-
console.log(
|
|
14835
|
+
console.log(chalk77.bold("VM0 Dashboard"));
|
|
14667
14836
|
console.log();
|
|
14668
|
-
console.log(
|
|
14669
|
-
console.log(
|
|
14837
|
+
console.log(chalk77.bold("Agents"));
|
|
14838
|
+
console.log(chalk77.dim(" List agents: ") + "vm0 agent list");
|
|
14670
14839
|
console.log();
|
|
14671
|
-
console.log(
|
|
14672
|
-
console.log(
|
|
14673
|
-
console.log(
|
|
14840
|
+
console.log(chalk77.bold("Runs"));
|
|
14841
|
+
console.log(chalk77.dim(" Recent runs: ") + "vm0 run list");
|
|
14842
|
+
console.log(chalk77.dim(" View run logs: ") + "vm0 logs <run-id>");
|
|
14674
14843
|
console.log();
|
|
14675
|
-
console.log(
|
|
14676
|
-
console.log(
|
|
14844
|
+
console.log(chalk77.bold("Schedules"));
|
|
14845
|
+
console.log(chalk77.dim(" List schedules: ") + "vm0 schedule list");
|
|
14677
14846
|
console.log();
|
|
14678
|
-
console.log(
|
|
14679
|
-
console.log(
|
|
14680
|
-
console.log(
|
|
14681
|
-
console.log(
|
|
14847
|
+
console.log(chalk77.bold("Account"));
|
|
14848
|
+
console.log(chalk77.dim(" Usage stats: ") + "vm0 usage");
|
|
14849
|
+
console.log(chalk77.dim(" List secrets: ") + "vm0 secret list");
|
|
14850
|
+
console.log(chalk77.dim(" List variables: ") + "vm0 variable list");
|
|
14682
14851
|
console.log();
|
|
14683
14852
|
console.log(
|
|
14684
|
-
|
|
14853
|
+
chalk77.dim("Not logged in? Run: ") + chalk77.cyan("vm0 auth login")
|
|
14685
14854
|
);
|
|
14686
14855
|
console.log();
|
|
14687
14856
|
});
|
|
@@ -14691,7 +14860,7 @@ import { Command as Command76 } from "commander";
|
|
|
14691
14860
|
|
|
14692
14861
|
// src/commands/dev-tool/compose.ts
|
|
14693
14862
|
import { Command as Command75 } from "commander";
|
|
14694
|
-
import
|
|
14863
|
+
import chalk78 from "chalk";
|
|
14695
14864
|
import { initClient as initClient14 } from "@ts-rest/core";
|
|
14696
14865
|
function sleep2(ms) {
|
|
14697
14866
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -14743,7 +14912,7 @@ async function pollUntilComplete(jobId, intervalMs, timeoutMs, jsonMode) {
|
|
|
14743
14912
|
const job = await getComposeJobStatus(jobId);
|
|
14744
14913
|
if (!jsonMode) {
|
|
14745
14914
|
console.log(
|
|
14746
|
-
|
|
14915
|
+
chalk78.dim(`[${timestamp()}] Polling... status=${job.status}`)
|
|
14747
14916
|
);
|
|
14748
14917
|
}
|
|
14749
14918
|
if (job.status === "completed" || job.status === "failed") {
|
|
@@ -14802,7 +14971,7 @@ var composeCommand2 = new Command75().name("compose").description("Test server-s
|
|
|
14802
14971
|
githubUrl,
|
|
14803
14972
|
options.overwrite
|
|
14804
14973
|
);
|
|
14805
|
-
console.log(`Job ID: ${
|
|
14974
|
+
console.log(`Job ID: ${chalk78.cyan(jobId)}`);
|
|
14806
14975
|
console.log();
|
|
14807
14976
|
if (initialStatus === "completed" || initialStatus === "failed") {
|
|
14808
14977
|
const finalJob2 = await getComposeJobStatus(jobId);
|
|
@@ -14823,21 +14992,21 @@ var composeCommand2 = new Command75().name("compose").description("Test server-s
|
|
|
14823
14992
|
);
|
|
14824
14993
|
function displayResult(job) {
|
|
14825
14994
|
if (job.status === "completed" && job.result) {
|
|
14826
|
-
console.log(
|
|
14827
|
-
console.log(` Compose ID: ${
|
|
14828
|
-
console.log(` Name: ${
|
|
14829
|
-
console.log(` Version: ${
|
|
14995
|
+
console.log(chalk78.green("\u2713 Compose completed!"));
|
|
14996
|
+
console.log(` Compose ID: ${chalk78.cyan(job.result.composeId)}`);
|
|
14997
|
+
console.log(` Name: ${chalk78.cyan(job.result.composeName)}`);
|
|
14998
|
+
console.log(` Version: ${chalk78.cyan(job.result.versionId.slice(0, 8))}`);
|
|
14830
14999
|
if (job.result.warnings.length > 0) {
|
|
14831
15000
|
console.log();
|
|
14832
|
-
console.log(
|
|
15001
|
+
console.log(chalk78.yellow(" Warnings:"));
|
|
14833
15002
|
for (const warning of job.result.warnings) {
|
|
14834
|
-
console.log(
|
|
15003
|
+
console.log(chalk78.yellow(` - ${warning}`));
|
|
14835
15004
|
}
|
|
14836
15005
|
}
|
|
14837
15006
|
} else if (job.status === "failed") {
|
|
14838
|
-
console.error(
|
|
15007
|
+
console.error(chalk78.red("\u2717 Compose failed"));
|
|
14839
15008
|
if (job.error) {
|
|
14840
|
-
console.error(` Error: ${
|
|
15009
|
+
console.error(` Error: ${chalk78.red(job.error)}`);
|
|
14841
15010
|
}
|
|
14842
15011
|
} else {
|
|
14843
15012
|
console.log(`Status: ${job.status}`);
|
|
@@ -14849,7 +15018,7 @@ var devToolCommand = new Command76().name("dev-tool").description("Developer too
|
|
|
14849
15018
|
|
|
14850
15019
|
// src/commands/preference/index.ts
|
|
14851
15020
|
import { Command as Command77 } from "commander";
|
|
14852
|
-
import
|
|
15021
|
+
import chalk79 from "chalk";
|
|
14853
15022
|
function detectTimezone2() {
|
|
14854
15023
|
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
14855
15024
|
}
|
|
@@ -14870,15 +15039,15 @@ function parseOnOff(flag, value) {
|
|
|
14870
15039
|
);
|
|
14871
15040
|
}
|
|
14872
15041
|
function displayPreferences(prefs) {
|
|
14873
|
-
console.log(
|
|
15042
|
+
console.log(chalk79.bold("Current preferences:"));
|
|
14874
15043
|
console.log(
|
|
14875
|
-
` Timezone: ${prefs.timezone ?
|
|
15044
|
+
` Timezone: ${prefs.timezone ? chalk79.cyan(prefs.timezone) : chalk79.dim("not set")}`
|
|
14876
15045
|
);
|
|
14877
15046
|
console.log(
|
|
14878
|
-
` Email notify: ${prefs.notifyEmail ?
|
|
15047
|
+
` Email notify: ${prefs.notifyEmail ? chalk79.green("on") : chalk79.dim("off")}`
|
|
14879
15048
|
);
|
|
14880
15049
|
console.log(
|
|
14881
|
-
` Slack notify: ${prefs.notifySlack ?
|
|
15050
|
+
` Slack notify: ${prefs.notifySlack ? chalk79.green("on") : chalk79.dim("off")}`
|
|
14882
15051
|
);
|
|
14883
15052
|
}
|
|
14884
15053
|
function buildUpdates(opts) {
|
|
@@ -14889,9 +15058,9 @@ function buildUpdates(opts) {
|
|
|
14889
15058
|
const updates = {};
|
|
14890
15059
|
if (hasTimezone) {
|
|
14891
15060
|
if (!isValidTimezone(opts.timezone)) {
|
|
14892
|
-
console.error(
|
|
15061
|
+
console.error(chalk79.red(`Invalid timezone: ${opts.timezone}`));
|
|
14893
15062
|
console.error(
|
|
14894
|
-
|
|
15063
|
+
chalk79.dim(
|
|
14895
15064
|
" Use an IANA timezone identifier (e.g., America/New_York, Asia/Shanghai)"
|
|
14896
15065
|
)
|
|
14897
15066
|
);
|
|
@@ -14903,7 +15072,7 @@ function buildUpdates(opts) {
|
|
|
14903
15072
|
try {
|
|
14904
15073
|
updates.notifyEmail = parseOnOff("notify-email", opts.notifyEmail);
|
|
14905
15074
|
} catch (err) {
|
|
14906
|
-
console.error(
|
|
15075
|
+
console.error(chalk79.red(err.message));
|
|
14907
15076
|
process.exit(1);
|
|
14908
15077
|
}
|
|
14909
15078
|
}
|
|
@@ -14911,7 +15080,7 @@ function buildUpdates(opts) {
|
|
|
14911
15080
|
try {
|
|
14912
15081
|
updates.notifySlack = parseOnOff("notify-slack", opts.notifySlack);
|
|
14913
15082
|
} catch (err) {
|
|
14914
|
-
console.error(
|
|
15083
|
+
console.error(chalk79.red(err.message));
|
|
14915
15084
|
process.exit(1);
|
|
14916
15085
|
}
|
|
14917
15086
|
}
|
|
@@ -14920,21 +15089,21 @@ function buildUpdates(opts) {
|
|
|
14920
15089
|
function printUpdateResult(updates, result) {
|
|
14921
15090
|
if (updates.timezone !== void 0) {
|
|
14922
15091
|
console.log(
|
|
14923
|
-
|
|
14924
|
-
`Timezone set to ${
|
|
15092
|
+
chalk79.green(
|
|
15093
|
+
`Timezone set to ${chalk79.cyan(result.timezone ?? updates.timezone)}`
|
|
14925
15094
|
)
|
|
14926
15095
|
);
|
|
14927
15096
|
}
|
|
14928
15097
|
if (updates.notifyEmail !== void 0) {
|
|
14929
15098
|
console.log(
|
|
14930
|
-
|
|
15099
|
+
chalk79.green(
|
|
14931
15100
|
`Email notifications ${result.notifyEmail ? "enabled" : "disabled"}`
|
|
14932
15101
|
)
|
|
14933
15102
|
);
|
|
14934
15103
|
}
|
|
14935
15104
|
if (updates.notifySlack !== void 0) {
|
|
14936
15105
|
console.log(
|
|
14937
|
-
|
|
15106
|
+
chalk79.green(
|
|
14938
15107
|
`Slack notifications ${result.notifySlack ? "enabled" : "disabled"}`
|
|
14939
15108
|
)
|
|
14940
15109
|
);
|
|
@@ -14943,7 +15112,7 @@ function printUpdateResult(updates, result) {
|
|
|
14943
15112
|
async function interactiveSetup(prefs) {
|
|
14944
15113
|
if (!prefs.timezone) {
|
|
14945
15114
|
const detectedTz = detectTimezone2();
|
|
14946
|
-
console.log(
|
|
15115
|
+
console.log(chalk79.dim(`
|
|
14947
15116
|
System timezone detected: ${detectedTz}`));
|
|
14948
15117
|
const tz = await promptText(
|
|
14949
15118
|
"Set timezone? (enter timezone or leave empty to skip)",
|
|
@@ -14951,11 +15120,11 @@ System timezone detected: ${detectedTz}`));
|
|
|
14951
15120
|
);
|
|
14952
15121
|
if (tz?.trim()) {
|
|
14953
15122
|
if (!isValidTimezone(tz.trim())) {
|
|
14954
|
-
console.error(
|
|
15123
|
+
console.error(chalk79.red(`Invalid timezone: ${tz.trim()}`));
|
|
14955
15124
|
process.exit(1);
|
|
14956
15125
|
}
|
|
14957
15126
|
await updateUserPreferences({ timezone: tz.trim() });
|
|
14958
|
-
console.log(
|
|
15127
|
+
console.log(chalk79.green(`Timezone set to ${chalk79.cyan(tz.trim())}`));
|
|
14959
15128
|
}
|
|
14960
15129
|
}
|
|
14961
15130
|
if (!prefs.notifyEmail) {
|
|
@@ -14965,7 +15134,7 @@ System timezone detected: ${detectedTz}`));
|
|
|
14965
15134
|
);
|
|
14966
15135
|
if (enable) {
|
|
14967
15136
|
await updateUserPreferences({ notifyEmail: true });
|
|
14968
|
-
console.log(
|
|
15137
|
+
console.log(chalk79.green("Email notifications enabled"));
|
|
14969
15138
|
}
|
|
14970
15139
|
}
|
|
14971
15140
|
}
|
|
@@ -14984,10 +15153,10 @@ var preferenceCommand = new Command77().name("preference").description("View or
|
|
|
14984
15153
|
} else if (!prefs.timezone) {
|
|
14985
15154
|
console.log();
|
|
14986
15155
|
console.log(
|
|
14987
|
-
`To set timezone: ${
|
|
15156
|
+
`To set timezone: ${chalk79.cyan("vm0 preference --timezone <timezone>")}`
|
|
14988
15157
|
);
|
|
14989
15158
|
console.log(
|
|
14990
|
-
|
|
15159
|
+
chalk79.dim("Example: vm0 preference --timezone America/New_York")
|
|
14991
15160
|
);
|
|
14992
15161
|
}
|
|
14993
15162
|
})
|
|
@@ -14995,7 +15164,7 @@ var preferenceCommand = new Command77().name("preference").description("View or
|
|
|
14995
15164
|
|
|
14996
15165
|
// src/index.ts
|
|
14997
15166
|
var program = new Command78();
|
|
14998
|
-
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.
|
|
15167
|
+
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.38.0");
|
|
14999
15168
|
program.addCommand(authCommand);
|
|
15000
15169
|
program.addCommand(infoCommand);
|
|
15001
15170
|
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.0",
|
|
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",
|