@vm0/cli 9.17.1 → 9.17.2
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 +146 -107
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -237,7 +237,7 @@ var infoCommand = new Command6().name("info").description("Display environment i
|
|
|
237
237
|
import { Command as Command7, Option } from "commander";
|
|
238
238
|
import chalk4 from "chalk";
|
|
239
239
|
import { readFile as readFile4 } from "fs/promises";
|
|
240
|
-
import { existsSync as
|
|
240
|
+
import { existsSync as existsSync4 } from "fs";
|
|
241
241
|
import { dirname as dirname2 } from "path";
|
|
242
242
|
import { parse as parseYaml2 } from "yaml";
|
|
243
243
|
|
|
@@ -2109,6 +2109,41 @@ var MODEL_PROVIDER_TYPES = {
|
|
|
2109
2109
|
models: ["GLM-4.7", "GLM-4.5-Air"],
|
|
2110
2110
|
defaultModel: "GLM-4.7"
|
|
2111
2111
|
},
|
|
2112
|
+
"azure-foundry": {
|
|
2113
|
+
framework: "claude-code",
|
|
2114
|
+
label: "Azure Foundry",
|
|
2115
|
+
helpText: "Run Claude on Microsoft Azure Foundry.\nSetup guide: https://code.claude.com/docs/en/microsoft-foundry",
|
|
2116
|
+
authMethods: {
|
|
2117
|
+
"api-key": {
|
|
2118
|
+
label: "API Key",
|
|
2119
|
+
helpText: "Use an Azure Foundry API key for authentication",
|
|
2120
|
+
credentials: {
|
|
2121
|
+
ANTHROPIC_FOUNDRY_API_KEY: {
|
|
2122
|
+
label: "ANTHROPIC_FOUNDRY_API_KEY",
|
|
2123
|
+
required: true,
|
|
2124
|
+
helpText: "API key from Azure Foundry portal (Endpoints and keys)"
|
|
2125
|
+
},
|
|
2126
|
+
ANTHROPIC_FOUNDRY_RESOURCE: {
|
|
2127
|
+
label: "ANTHROPIC_FOUNDRY_RESOURCE",
|
|
2128
|
+
required: true,
|
|
2129
|
+
placeholder: "my-resource",
|
|
2130
|
+
helpText: "Azure resource name (from portal URL)"
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
}
|
|
2134
|
+
},
|
|
2135
|
+
defaultAuthMethod: "api-key",
|
|
2136
|
+
environmentMapping: {
|
|
2137
|
+
CLAUDE_CODE_USE_FOUNDRY: "1",
|
|
2138
|
+
ANTHROPIC_FOUNDRY_API_KEY: "$credentials.ANTHROPIC_FOUNDRY_API_KEY",
|
|
2139
|
+
ANTHROPIC_FOUNDRY_RESOURCE: "$credentials.ANTHROPIC_FOUNDRY_RESOURCE",
|
|
2140
|
+
ANTHROPIC_MODEL: "$model"
|
|
2141
|
+
},
|
|
2142
|
+
models: [],
|
|
2143
|
+
defaultModel: "",
|
|
2144
|
+
allowCustomModel: true,
|
|
2145
|
+
customModelPlaceholder: "claude-sonnet-4-5"
|
|
2146
|
+
},
|
|
2112
2147
|
"aws-bedrock": {
|
|
2113
2148
|
framework: "claude-code",
|
|
2114
2149
|
label: "AWS Bedrock",
|
|
@@ -2183,6 +2218,7 @@ var modelProviderTypeSchema = z15.enum([
|
|
|
2183
2218
|
"minimax-api-key",
|
|
2184
2219
|
"deepseek-api-key",
|
|
2185
2220
|
"zai-api-key",
|
|
2221
|
+
"azure-foundry",
|
|
2186
2222
|
"aws-bedrock"
|
|
2187
2223
|
]);
|
|
2188
2224
|
var modelProviderFrameworkSchema = z15.enum(["claude-code", "codex"]);
|
|
@@ -3926,47 +3962,47 @@ async function listScheduleRuns(params) {
|
|
|
3926
3962
|
handleError(result, `Failed to list runs for schedule "${params.name}"`);
|
|
3927
3963
|
}
|
|
3928
3964
|
|
|
3929
|
-
// src/lib/api/domains/
|
|
3965
|
+
// src/lib/api/domains/secrets.ts
|
|
3930
3966
|
import { initClient as initClient7 } from "@ts-rest/core";
|
|
3931
|
-
async function
|
|
3967
|
+
async function listSecrets() {
|
|
3932
3968
|
const config = await getClientConfig();
|
|
3933
|
-
const client = initClient7(
|
|
3969
|
+
const client = initClient7(secretsMainContract, config);
|
|
3934
3970
|
const result = await client.list({ headers: {} });
|
|
3935
3971
|
if (result.status === 200) {
|
|
3936
3972
|
return result.body;
|
|
3937
3973
|
}
|
|
3938
|
-
handleError(result, "Failed to list
|
|
3974
|
+
handleError(result, "Failed to list secrets");
|
|
3939
3975
|
}
|
|
3940
|
-
async function
|
|
3976
|
+
async function getSecret(name) {
|
|
3941
3977
|
const config = await getClientConfig();
|
|
3942
|
-
const client = initClient7(
|
|
3978
|
+
const client = initClient7(secretsByNameContract, config);
|
|
3943
3979
|
const result = await client.get({
|
|
3944
3980
|
params: { name }
|
|
3945
3981
|
});
|
|
3946
3982
|
if (result.status === 200) {
|
|
3947
3983
|
return result.body;
|
|
3948
3984
|
}
|
|
3949
|
-
handleError(result, `
|
|
3985
|
+
handleError(result, `Secret "${name}" not found`);
|
|
3950
3986
|
}
|
|
3951
|
-
async function
|
|
3987
|
+
async function setSecret(body) {
|
|
3952
3988
|
const config = await getClientConfig();
|
|
3953
|
-
const client = initClient7(
|
|
3989
|
+
const client = initClient7(secretsMainContract, config);
|
|
3954
3990
|
const result = await client.set({ body });
|
|
3955
3991
|
if (result.status === 200 || result.status === 201) {
|
|
3956
3992
|
return result.body;
|
|
3957
3993
|
}
|
|
3958
|
-
handleError(result, "Failed to set
|
|
3994
|
+
handleError(result, "Failed to set secret");
|
|
3959
3995
|
}
|
|
3960
|
-
async function
|
|
3996
|
+
async function deleteSecret(name) {
|
|
3961
3997
|
const config = await getClientConfig();
|
|
3962
|
-
const client = initClient7(
|
|
3998
|
+
const client = initClient7(secretsByNameContract, config);
|
|
3963
3999
|
const result = await client.delete({
|
|
3964
4000
|
params: { name }
|
|
3965
4001
|
});
|
|
3966
4002
|
if (result.status === 204) {
|
|
3967
4003
|
return;
|
|
3968
4004
|
}
|
|
3969
|
-
handleError(result, `
|
|
4005
|
+
handleError(result, `Secret "${name}" not found`);
|
|
3970
4006
|
}
|
|
3971
4007
|
|
|
3972
4008
|
// src/lib/api/domains/model-providers.ts
|
|
@@ -4349,6 +4385,17 @@ import * as tar2 from "tar";
|
|
|
4349
4385
|
import * as fs2 from "fs";
|
|
4350
4386
|
import * as path2 from "path";
|
|
4351
4387
|
import * as tar from "tar";
|
|
4388
|
+
function checkDirectoryStatus(dirPath) {
|
|
4389
|
+
if (!fs2.existsSync(dirPath)) {
|
|
4390
|
+
return { exists: false, empty: true };
|
|
4391
|
+
}
|
|
4392
|
+
const stat = fs2.statSync(dirPath);
|
|
4393
|
+
if (!stat.isDirectory()) {
|
|
4394
|
+
return { exists: true, empty: false };
|
|
4395
|
+
}
|
|
4396
|
+
const entries = fs2.readdirSync(dirPath);
|
|
4397
|
+
return { exists: true, empty: entries.length === 0 };
|
|
4398
|
+
}
|
|
4352
4399
|
function formatBytes(bytes) {
|
|
4353
4400
|
if (bytes === 0) return "0 B";
|
|
4354
4401
|
const k = 1024;
|
|
@@ -4961,7 +5008,7 @@ function getSecretsFromComposeContent(content) {
|
|
|
4961
5008
|
return new Set(grouped.secrets.map((r) => r.name));
|
|
4962
5009
|
}
|
|
4963
5010
|
async function loadAndValidateConfig(configFile) {
|
|
4964
|
-
if (!
|
|
5011
|
+
if (!existsSync4(configFile)) {
|
|
4965
5012
|
console.error(chalk4.red(`\u2717 Config file not found: ${configFile}`));
|
|
4966
5013
|
process.exit(1);
|
|
4967
5014
|
}
|
|
@@ -5177,7 +5224,7 @@ var composeCommand = new Command7().name("compose").description("Create or updat
|
|
|
5177
5224
|
)
|
|
5178
5225
|
);
|
|
5179
5226
|
if (options.autoUpdate !== false) {
|
|
5180
|
-
await silentUpgradeAfterCommand("9.17.
|
|
5227
|
+
await silentUpgradeAfterCommand("9.17.2");
|
|
5181
5228
|
}
|
|
5182
5229
|
} catch (error) {
|
|
5183
5230
|
if (error instanceof Error) {
|
|
@@ -7408,7 +7455,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
7408
7455
|
}
|
|
7409
7456
|
showNextSteps(result);
|
|
7410
7457
|
if (options.autoUpdate !== false) {
|
|
7411
|
-
await silentUpgradeAfterCommand("9.17.
|
|
7458
|
+
await silentUpgradeAfterCommand("9.17.2");
|
|
7412
7459
|
}
|
|
7413
7460
|
} catch (error) {
|
|
7414
7461
|
handleRunError(error, identifier);
|
|
@@ -7685,7 +7732,7 @@ import path6 from "path";
|
|
|
7685
7732
|
|
|
7686
7733
|
// src/lib/storage/storage-utils.ts
|
|
7687
7734
|
import { readFile as readFile5, writeFile as writeFile4, mkdir as mkdir4 } from "fs/promises";
|
|
7688
|
-
import { existsSync as
|
|
7735
|
+
import { existsSync as existsSync6 } from "fs";
|
|
7689
7736
|
import { parse as parseYaml3, stringify as stringifyYaml } from "yaml";
|
|
7690
7737
|
import path5 from "path";
|
|
7691
7738
|
var CONFIG_DIR = ".vm0";
|
|
@@ -7701,9 +7748,9 @@ async function readStorageConfig(basePath = process.cwd()) {
|
|
|
7701
7748
|
const configPath = path5.join(basePath, CONFIG_DIR, CONFIG_FILE);
|
|
7702
7749
|
const legacyConfigPath = path5.join(basePath, CONFIG_DIR, "volume.yaml");
|
|
7703
7750
|
let actualPath = null;
|
|
7704
|
-
if (
|
|
7751
|
+
if (existsSync6(configPath)) {
|
|
7705
7752
|
actualPath = configPath;
|
|
7706
|
-
} else if (
|
|
7753
|
+
} else if (existsSync6(legacyConfigPath)) {
|
|
7707
7754
|
actualPath = legacyConfigPath;
|
|
7708
7755
|
}
|
|
7709
7756
|
if (!actualPath) {
|
|
@@ -7719,7 +7766,7 @@ async function readStorageConfig(basePath = process.cwd()) {
|
|
|
7719
7766
|
async function writeStorageConfig(storageName, basePath = process.cwd(), type = "volume") {
|
|
7720
7767
|
const configDir = path5.join(basePath, CONFIG_DIR);
|
|
7721
7768
|
const configPath = path5.join(configDir, CONFIG_FILE);
|
|
7722
|
-
if (!
|
|
7769
|
+
if (!existsSync6(configDir)) {
|
|
7723
7770
|
await mkdir4(configDir, { recursive: true });
|
|
7724
7771
|
}
|
|
7725
7772
|
const config = {
|
|
@@ -8058,8 +8105,9 @@ import * as os5 from "os";
|
|
|
8058
8105
|
import * as tar4 from "tar";
|
|
8059
8106
|
async function cloneStorage(name, type, destination, options = {}) {
|
|
8060
8107
|
const typeLabel = type === "artifact" ? "artifact" : "volume";
|
|
8061
|
-
|
|
8062
|
-
|
|
8108
|
+
const dirStatus = checkDirectoryStatus(destination);
|
|
8109
|
+
if (dirStatus.exists && !dirStatus.empty) {
|
|
8110
|
+
throw new Error(`Directory "${destination}" is not empty`);
|
|
8063
8111
|
}
|
|
8064
8112
|
console.log(chalk20.dim(`Checking remote ${typeLabel}...`));
|
|
8065
8113
|
const downloadInfo = await getStorageDownload({
|
|
@@ -8914,7 +8962,7 @@ var cookAction = new Command27().name("cook").description("Quick start: prepare,
|
|
|
8914
8962
|
).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(
|
|
8915
8963
|
async (prompt, options) => {
|
|
8916
8964
|
if (options.autoUpdate !== false) {
|
|
8917
|
-
const shouldExit = await checkAndUpgrade("9.17.
|
|
8965
|
+
const shouldExit = await checkAndUpgrade("9.17.2", prompt);
|
|
8918
8966
|
if (shouldExit) {
|
|
8919
8967
|
process.exit(0);
|
|
8920
8968
|
}
|
|
@@ -9494,7 +9542,7 @@ import { Command as Command38 } from "commander";
|
|
|
9494
9542
|
// src/commands/agent/clone.ts
|
|
9495
9543
|
import { Command as Command35 } from "commander";
|
|
9496
9544
|
import chalk36 from "chalk";
|
|
9497
|
-
import {
|
|
9545
|
+
import { mkdtempSync as mkdtempSync5 } from "fs";
|
|
9498
9546
|
import { mkdir as mkdir7, writeFile as writeFile6, readdir, copyFile, rm as rm3 } from "fs/promises";
|
|
9499
9547
|
import { join as join7, dirname as dirname3 } from "path";
|
|
9500
9548
|
import { tmpdir as tmpdir7 } from "os";
|
|
@@ -9552,8 +9600,9 @@ async function downloadInstructions(agentName, instructionsPath, destination) {
|
|
|
9552
9600
|
var cloneCommand3 = new Command35().name("clone").description("Clone agent compose to local directory (latest version)").argument("<name>", "Agent compose name to clone").argument("[destination]", "Destination directory (default: agent name)").action(async (name, destination) => {
|
|
9553
9601
|
try {
|
|
9554
9602
|
const targetDir = destination || name;
|
|
9555
|
-
|
|
9556
|
-
|
|
9603
|
+
const dirStatus = checkDirectoryStatus(targetDir);
|
|
9604
|
+
if (dirStatus.exists && !dirStatus.empty) {
|
|
9605
|
+
console.error(chalk36.red(`\u2717 Directory "${targetDir}" is not empty`));
|
|
9557
9606
|
process.exit(1);
|
|
9558
9607
|
}
|
|
9559
9608
|
console.log(`Cloning agent compose: ${name}`);
|
|
@@ -9915,7 +9964,7 @@ var agentCommand = new Command38().name("agent").description("Manage agent compo
|
|
|
9915
9964
|
import { Command as Command39 } from "commander";
|
|
9916
9965
|
import chalk39 from "chalk";
|
|
9917
9966
|
import path15 from "path";
|
|
9918
|
-
import { existsSync as
|
|
9967
|
+
import { existsSync as existsSync10 } from "fs";
|
|
9919
9968
|
import { writeFile as writeFile7 } from "fs/promises";
|
|
9920
9969
|
var VM0_YAML_FILE = "vm0.yaml";
|
|
9921
9970
|
var AGENTS_MD_FILE = "AGENTS.md";
|
|
@@ -9947,8 +9996,8 @@ You are a HackerNews AI content curator.
|
|
|
9947
9996
|
}
|
|
9948
9997
|
function checkExistingFiles() {
|
|
9949
9998
|
const existingFiles = [];
|
|
9950
|
-
if (
|
|
9951
|
-
if (
|
|
9999
|
+
if (existsSync10(VM0_YAML_FILE)) existingFiles.push(VM0_YAML_FILE);
|
|
10000
|
+
if (existsSync10(AGENTS_MD_FILE)) existingFiles.push(AGENTS_MD_FILE);
|
|
9952
10001
|
return existingFiles;
|
|
9953
10002
|
}
|
|
9954
10003
|
var initCommand3 = new Command39().name("init").description("Initialize a new VM0 project in the current directory").option("-f, --force", "Overwrite existing files").option("-n, --name <name>", "Agent name (required in non-interactive mode)").action(async (options) => {
|
|
@@ -10170,7 +10219,6 @@ import chalk40 from "chalk";
|
|
|
10170
10219
|
var defaultPromptDeps = {
|
|
10171
10220
|
isInteractive,
|
|
10172
10221
|
promptConfirm,
|
|
10173
|
-
promptPassword,
|
|
10174
10222
|
promptText
|
|
10175
10223
|
};
|
|
10176
10224
|
function parseKeyValuePairs(pairs) {
|
|
@@ -10185,25 +10233,23 @@ function parseKeyValuePairs(pairs) {
|
|
|
10185
10233
|
}
|
|
10186
10234
|
return result;
|
|
10187
10235
|
}
|
|
10188
|
-
async function
|
|
10189
|
-
if (optionSecrets.length > 0) {
|
|
10190
|
-
return {
|
|
10191
|
-
secrets: parseKeyValuePairs(optionSecrets),
|
|
10192
|
-
preserveExistingSecrets: false
|
|
10193
|
-
};
|
|
10194
|
-
}
|
|
10236
|
+
async function handleExistingSecrets(existingSecretNames, deps) {
|
|
10195
10237
|
if (existingSecretNames.length > 0 && deps.isInteractive()) {
|
|
10196
10238
|
const keepSecrets = await deps.promptConfirm(
|
|
10197
10239
|
`Keep existing secrets? (${existingSecretNames.join(", ")})`,
|
|
10198
10240
|
true
|
|
10199
10241
|
);
|
|
10200
10242
|
if (keepSecrets) {
|
|
10201
|
-
return
|
|
10243
|
+
return true;
|
|
10202
10244
|
}
|
|
10203
|
-
console.log(
|
|
10204
|
-
|
|
10245
|
+
console.log(
|
|
10246
|
+
chalk40.dim(
|
|
10247
|
+
" Note: Secrets will be cleared. Use 'vm0 secret set' to add platform secrets."
|
|
10248
|
+
)
|
|
10249
|
+
);
|
|
10250
|
+
return false;
|
|
10205
10251
|
}
|
|
10206
|
-
return
|
|
10252
|
+
return false;
|
|
10207
10253
|
}
|
|
10208
10254
|
async function handleVars(optionVars, existingVars, deps) {
|
|
10209
10255
|
if (optionVars.length > 0) {
|
|
@@ -10221,29 +10267,24 @@ async function handleVars(optionVars, existingVars, deps) {
|
|
|
10221
10267
|
return {};
|
|
10222
10268
|
}
|
|
10223
10269
|
function displayMissingRequirements(missingSecrets, missingVars) {
|
|
10224
|
-
console.log(chalk40.yellow("\nAgent requires the following configuration:"));
|
|
10225
10270
|
if (missingSecrets.length > 0) {
|
|
10226
|
-
console.log(chalk40.
|
|
10271
|
+
console.log(chalk40.yellow("\nAgent requires the following secrets:"));
|
|
10272
|
+
for (const name of missingSecrets) {
|
|
10273
|
+
console.log(chalk40.dim(` ${name}`));
|
|
10274
|
+
}
|
|
10275
|
+
console.log();
|
|
10276
|
+
console.log("Set secrets using the platform:");
|
|
10227
10277
|
for (const name of missingSecrets) {
|
|
10228
|
-
console.log(chalk40.
|
|
10278
|
+
console.log(chalk40.cyan(` vm0 secret set ${name} <value>`));
|
|
10229
10279
|
}
|
|
10280
|
+
console.log();
|
|
10230
10281
|
}
|
|
10231
10282
|
if (missingVars.length > 0) {
|
|
10232
|
-
console.log(chalk40.
|
|
10283
|
+
console.log(chalk40.yellow("\nAgent requires the following variables:"));
|
|
10233
10284
|
for (const name of missingVars) {
|
|
10234
|
-
console.log(chalk40.dim(`
|
|
10235
|
-
}
|
|
10236
|
-
}
|
|
10237
|
-
console.log("");
|
|
10238
|
-
}
|
|
10239
|
-
async function promptForMissingSecrets(missingSecrets, secrets, deps) {
|
|
10240
|
-
for (const name of missingSecrets) {
|
|
10241
|
-
const value = await deps.promptPassword(
|
|
10242
|
-
`Enter value for secret ${chalk40.cyan(name)}`
|
|
10243
|
-
);
|
|
10244
|
-
if (value) {
|
|
10245
|
-
secrets[name] = value;
|
|
10285
|
+
console.log(chalk40.dim(` ${name}`));
|
|
10246
10286
|
}
|
|
10287
|
+
console.log();
|
|
10247
10288
|
}
|
|
10248
10289
|
}
|
|
10249
10290
|
async function promptForMissingVars(missingVars, vars, deps) {
|
|
@@ -10258,32 +10299,30 @@ async function promptForMissingVars(missingVars, vars, deps) {
|
|
|
10258
10299
|
}
|
|
10259
10300
|
}
|
|
10260
10301
|
async function gatherConfiguration(params, deps = defaultPromptDeps) {
|
|
10261
|
-
const { required,
|
|
10302
|
+
const { required, optionVars, existingSchedule } = params;
|
|
10262
10303
|
const existingSecretNames = existingSchedule?.secretNames ?? [];
|
|
10263
10304
|
const existingVars = existingSchedule?.vars ?? null;
|
|
10264
|
-
const
|
|
10265
|
-
optionSecrets,
|
|
10305
|
+
const preserveExistingSecrets = await handleExistingSecrets(
|
|
10266
10306
|
existingSecretNames,
|
|
10267
10307
|
deps
|
|
10268
10308
|
);
|
|
10269
10309
|
const vars = await handleVars(optionVars, existingVars, deps);
|
|
10270
10310
|
const effectiveExistingSecrets = preserveExistingSecrets ? existingSecretNames : [];
|
|
10271
10311
|
const missingSecrets = required.secrets.filter(
|
|
10272
|
-
(name) => !
|
|
10312
|
+
(name) => !effectiveExistingSecrets.includes(name)
|
|
10273
10313
|
);
|
|
10274
10314
|
const missingVars = required.vars.filter(
|
|
10275
10315
|
(name) => !Object.keys(vars).includes(name)
|
|
10276
10316
|
);
|
|
10277
10317
|
if (missingSecrets.length === 0 && missingVars.length === 0) {
|
|
10278
|
-
return {
|
|
10318
|
+
return { vars, preserveExistingSecrets };
|
|
10279
10319
|
}
|
|
10280
10320
|
if (!deps.isInteractive()) {
|
|
10281
|
-
return {
|
|
10321
|
+
return { vars, preserveExistingSecrets };
|
|
10282
10322
|
}
|
|
10283
10323
|
displayMissingRequirements(missingSecrets, missingVars);
|
|
10284
|
-
await promptForMissingSecrets(missingSecrets, secrets, deps);
|
|
10285
10324
|
await promptForMissingVars(missingVars, vars, deps);
|
|
10286
|
-
return {
|
|
10325
|
+
return { vars, preserveExistingSecrets };
|
|
10287
10326
|
}
|
|
10288
10327
|
|
|
10289
10328
|
// src/commands/schedule/setup.ts
|
|
@@ -10688,7 +10727,7 @@ async function handleScheduleEnabling(params) {
|
|
|
10688
10727
|
showEnableHint(agentName);
|
|
10689
10728
|
}
|
|
10690
10729
|
}
|
|
10691
|
-
var setupCommand = new Command40().name("setup").description("Create or edit a schedule for an agent").argument("<agent-name>", "Agent name to configure schedule for").option("-f, --frequency <type>", "Frequency: daily|weekly|monthly|once").option("-t, --time <HH:MM>", "Time to run (24-hour format)").option("-d, --day <day>", "Day of week (mon-sun) or day of month (1-31)").option("-z, --timezone <tz>", "IANA timezone").option("-p, --prompt <text>", "Prompt to run").option("--var <name=value>", "Variable (can be repeated)", collect, []).option("--
|
|
10730
|
+
var setupCommand = new Command40().name("setup").description("Create or edit a schedule for an agent").argument("<agent-name>", "Agent name to configure schedule for").option("-f, --frequency <type>", "Frequency: daily|weekly|monthly|once").option("-t, --time <HH:MM>", "Time to run (24-hour format)").option("-d, --day <day>", "Day of week (mon-sun) or day of month (1-31)").option("-z, --timezone <tz>", "IANA timezone").option("-p, --prompt <text>", "Prompt to run").option("--var <name=value>", "Variable (can be repeated)", collect, []).option("--artifact-name <name>", "Artifact name", "artifact").option("-e, --enable", "Enable schedule immediately after creation").action(async (agentName, options) => {
|
|
10692
10731
|
try {
|
|
10693
10732
|
const { composeId, scheduleName, composeContent } = await resolveAgent(agentName);
|
|
10694
10733
|
const requiredConfig = extractRequiredConfiguration(composeContent);
|
|
@@ -10731,7 +10770,8 @@ var setupCommand = new Command40().name("setup").description("Create or edit a s
|
|
|
10731
10770
|
}
|
|
10732
10771
|
const config = await gatherConfiguration({
|
|
10733
10772
|
required: requiredConfig,
|
|
10734
|
-
optionSecrets:
|
|
10773
|
+
optionSecrets: [],
|
|
10774
|
+
// Secrets are no longer passed via CLI
|
|
10735
10775
|
optionVars: options.var || [],
|
|
10736
10776
|
existingSchedule
|
|
10737
10777
|
});
|
|
@@ -10746,7 +10786,8 @@ var setupCommand = new Command40().name("setup").description("Create or edit a s
|
|
|
10746
10786
|
timezone,
|
|
10747
10787
|
prompt: promptText_,
|
|
10748
10788
|
vars: Object.keys(config.vars).length > 0 ? config.vars : void 0,
|
|
10749
|
-
secrets:
|
|
10789
|
+
secrets: void 0,
|
|
10790
|
+
// Secrets managed via platform, not schedule
|
|
10750
10791
|
artifactName: options.artifactName
|
|
10751
10792
|
});
|
|
10752
10793
|
displayDeployResult(agentName, deployResult);
|
|
@@ -11246,38 +11287,36 @@ var usageCommand = new Command47().name("usage").description("View usage statist
|
|
|
11246
11287
|
}
|
|
11247
11288
|
});
|
|
11248
11289
|
|
|
11249
|
-
// src/commands/
|
|
11290
|
+
// src/commands/secret/index.ts
|
|
11250
11291
|
import { Command as Command51 } from "commander";
|
|
11251
11292
|
|
|
11252
|
-
// src/commands/
|
|
11293
|
+
// src/commands/secret/list.ts
|
|
11253
11294
|
import { Command as Command48 } from "commander";
|
|
11254
11295
|
import chalk48 from "chalk";
|
|
11255
|
-
var listCommand6 = new Command48().name("list").alias("ls").description("List all
|
|
11296
|
+
var listCommand6 = new Command48().name("list").alias("ls").description("List all secrets").action(async () => {
|
|
11256
11297
|
try {
|
|
11257
|
-
const result = await
|
|
11258
|
-
if (result.
|
|
11259
|
-
console.log(chalk48.dim("No
|
|
11298
|
+
const result = await listSecrets();
|
|
11299
|
+
if (result.secrets.length === 0) {
|
|
11300
|
+
console.log(chalk48.dim("No secrets found"));
|
|
11260
11301
|
console.log();
|
|
11261
|
-
console.log("To add a
|
|
11262
|
-
console.log(chalk48.cyan(" vm0
|
|
11302
|
+
console.log("To add a secret:");
|
|
11303
|
+
console.log(chalk48.cyan(" vm0 secret set MY_API_KEY <value>"));
|
|
11263
11304
|
return;
|
|
11264
11305
|
}
|
|
11265
|
-
console.log(chalk48.bold("
|
|
11306
|
+
console.log(chalk48.bold("Secrets:"));
|
|
11266
11307
|
console.log();
|
|
11267
|
-
for (const
|
|
11268
|
-
const typeIndicator =
|
|
11269
|
-
console.log(` ${chalk48.cyan(
|
|
11270
|
-
if (
|
|
11271
|
-
console.log(` ${chalk48.dim(
|
|
11308
|
+
for (const secret of result.secrets) {
|
|
11309
|
+
const typeIndicator = secret.type === "model-provider" ? chalk48.dim(" [model-provider]") : "";
|
|
11310
|
+
console.log(` ${chalk48.cyan(secret.name)}${typeIndicator}`);
|
|
11311
|
+
if (secret.description) {
|
|
11312
|
+
console.log(` ${chalk48.dim(secret.description)}`);
|
|
11272
11313
|
}
|
|
11273
11314
|
console.log(
|
|
11274
|
-
` ${chalk48.dim(`Updated: ${new Date(
|
|
11315
|
+
` ${chalk48.dim(`Updated: ${new Date(secret.updatedAt).toLocaleString()}`)}`
|
|
11275
11316
|
);
|
|
11276
11317
|
console.log();
|
|
11277
11318
|
}
|
|
11278
|
-
console.log(
|
|
11279
|
-
chalk48.dim(`Total: ${result.credentials.length} credential(s)`)
|
|
11280
|
-
);
|
|
11319
|
+
console.log(chalk48.dim(`Total: ${result.secrets.length} secret(s)`));
|
|
11281
11320
|
} catch (error) {
|
|
11282
11321
|
if (error instanceof Error) {
|
|
11283
11322
|
if (error.message.includes("Not authenticated")) {
|
|
@@ -11292,22 +11331,22 @@ var listCommand6 = new Command48().name("list").alias("ls").description("List al
|
|
|
11292
11331
|
}
|
|
11293
11332
|
});
|
|
11294
11333
|
|
|
11295
|
-
// src/commands/
|
|
11334
|
+
// src/commands/secret/set.ts
|
|
11296
11335
|
import { Command as Command49 } from "commander";
|
|
11297
11336
|
import chalk49 from "chalk";
|
|
11298
|
-
var setCommand2 = new Command49().name("set").description("Create or update a
|
|
11337
|
+
var setCommand2 = new Command49().name("set").description("Create or update a secret").argument("<name>", "Secret name (uppercase, e.g., MY_API_KEY)").argument("<value>", "Secret value").option("-d, --description <description>", "Optional description").action(
|
|
11299
11338
|
async (name, value, options) => {
|
|
11300
11339
|
try {
|
|
11301
|
-
const
|
|
11340
|
+
const secret = await setSecret({
|
|
11302
11341
|
name,
|
|
11303
11342
|
value,
|
|
11304
11343
|
description: options.description
|
|
11305
11344
|
});
|
|
11306
|
-
console.log(chalk49.green(`\u2713
|
|
11345
|
+
console.log(chalk49.green(`\u2713 Secret "${secret.name}" saved`));
|
|
11307
11346
|
console.log();
|
|
11308
11347
|
console.log("Use in vm0.yaml:");
|
|
11309
11348
|
console.log(chalk49.cyan(` environment:`));
|
|
11310
|
-
console.log(chalk49.cyan(` ${name}: \${{
|
|
11349
|
+
console.log(chalk49.cyan(` ${name}: \${{ secrets.${name} }}`));
|
|
11311
11350
|
} catch (error) {
|
|
11312
11351
|
if (error instanceof Error) {
|
|
11313
11352
|
if (error.message.includes("Not authenticated")) {
|
|
@@ -11317,7 +11356,7 @@ var setCommand2 = new Command49().name("set").description("Create or update a cr
|
|
|
11317
11356
|
} else if (error.message.includes("must contain only uppercase")) {
|
|
11318
11357
|
console.error(chalk49.red(`\u2717 ${error.message}`));
|
|
11319
11358
|
console.log();
|
|
11320
|
-
console.log("Examples of valid
|
|
11359
|
+
console.log("Examples of valid secret names:");
|
|
11321
11360
|
console.log(chalk49.dim(" MY_API_KEY"));
|
|
11322
11361
|
console.log(chalk49.dim(" GITHUB_TOKEN"));
|
|
11323
11362
|
console.log(chalk49.dim(" AWS_ACCESS_KEY_ID"));
|
|
@@ -11332,15 +11371,15 @@ var setCommand2 = new Command49().name("set").description("Create or update a cr
|
|
|
11332
11371
|
}
|
|
11333
11372
|
);
|
|
11334
11373
|
|
|
11335
|
-
// src/commands/
|
|
11374
|
+
// src/commands/secret/delete.ts
|
|
11336
11375
|
import { Command as Command50 } from "commander";
|
|
11337
11376
|
import chalk50 from "chalk";
|
|
11338
|
-
var deleteCommand2 = new Command50().name("delete").description("Delete a
|
|
11377
|
+
var deleteCommand2 = new Command50().name("delete").description("Delete a secret").argument("<name>", "Secret name to delete").option("-y, --yes", "Skip confirmation prompt").action(async (name, options) => {
|
|
11339
11378
|
try {
|
|
11340
11379
|
try {
|
|
11341
|
-
await
|
|
11380
|
+
await getSecret(name);
|
|
11342
11381
|
} catch {
|
|
11343
|
-
console.error(chalk50.red(`\u2717
|
|
11382
|
+
console.error(chalk50.red(`\u2717 Secret "${name}" not found`));
|
|
11344
11383
|
process.exit(1);
|
|
11345
11384
|
}
|
|
11346
11385
|
if (!options.yes) {
|
|
@@ -11351,7 +11390,7 @@ var deleteCommand2 = new Command50().name("delete").description("Delete a creden
|
|
|
11351
11390
|
process.exit(1);
|
|
11352
11391
|
}
|
|
11353
11392
|
const confirmed = await promptConfirm(
|
|
11354
|
-
`Are you sure you want to delete
|
|
11393
|
+
`Are you sure you want to delete secret "${name}"?`,
|
|
11355
11394
|
false
|
|
11356
11395
|
);
|
|
11357
11396
|
if (!confirmed) {
|
|
@@ -11359,8 +11398,8 @@ var deleteCommand2 = new Command50().name("delete").description("Delete a creden
|
|
|
11359
11398
|
return;
|
|
11360
11399
|
}
|
|
11361
11400
|
}
|
|
11362
|
-
await
|
|
11363
|
-
console.log(chalk50.green(`\u2713
|
|
11401
|
+
await deleteSecret(name);
|
|
11402
|
+
console.log(chalk50.green(`\u2713 Secret "${name}" deleted`));
|
|
11364
11403
|
} catch (error) {
|
|
11365
11404
|
if (error instanceof Error) {
|
|
11366
11405
|
if (error.message.includes("Not authenticated")) {
|
|
@@ -11375,8 +11414,8 @@ var deleteCommand2 = new Command50().name("delete").description("Delete a creden
|
|
|
11375
11414
|
}
|
|
11376
11415
|
});
|
|
11377
11416
|
|
|
11378
|
-
// src/commands/
|
|
11379
|
-
var
|
|
11417
|
+
// src/commands/secret/index.ts
|
|
11418
|
+
var secretCommand = new Command51().name("secret").description("Manage stored secrets for agent runs").addCommand(listCommand6).addCommand(setCommand2).addCommand(deleteCommand2);
|
|
11380
11419
|
|
|
11381
11420
|
// src/commands/model-provider/index.ts
|
|
11382
11421
|
import { Command as Command56 } from "commander";
|
|
@@ -12077,7 +12116,7 @@ var modelProviderCommand = new Command56().name("model-provider").description("M
|
|
|
12077
12116
|
import { Command as Command57 } from "commander";
|
|
12078
12117
|
import chalk58 from "chalk";
|
|
12079
12118
|
import { mkdir as mkdir8 } from "fs/promises";
|
|
12080
|
-
import { existsSync as
|
|
12119
|
+
import { existsSync as existsSync11 } from "fs";
|
|
12081
12120
|
|
|
12082
12121
|
// src/lib/ui/welcome-box.ts
|
|
12083
12122
|
import chalk55 from "chalk";
|
|
@@ -12577,7 +12616,7 @@ async function handleAgentCreation(ctx) {
|
|
|
12577
12616
|
process.exit(0);
|
|
12578
12617
|
}
|
|
12579
12618
|
agentName = inputName;
|
|
12580
|
-
if (
|
|
12619
|
+
if (existsSync11(agentName)) {
|
|
12581
12620
|
step.detail(
|
|
12582
12621
|
chalk58.yellow(`${agentName}/ already exists, choose another name`)
|
|
12583
12622
|
);
|
|
@@ -12594,7 +12633,7 @@ async function handleAgentCreation(ctx) {
|
|
|
12594
12633
|
);
|
|
12595
12634
|
process.exit(1);
|
|
12596
12635
|
}
|
|
12597
|
-
if (
|
|
12636
|
+
if (existsSync11(agentName)) {
|
|
12598
12637
|
console.error(chalk58.red(`${agentName}/ already exists`));
|
|
12599
12638
|
console.log();
|
|
12600
12639
|
console.log("Remove it first or choose a different name:");
|
|
@@ -12697,7 +12736,7 @@ var setupClaudeCommand = new Command58().name("setup-claude").description("Insta
|
|
|
12697
12736
|
|
|
12698
12737
|
// src/index.ts
|
|
12699
12738
|
var program = new Command59();
|
|
12700
|
-
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.17.
|
|
12739
|
+
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.17.2");
|
|
12701
12740
|
program.addCommand(authCommand);
|
|
12702
12741
|
program.addCommand(infoCommand);
|
|
12703
12742
|
program.addCommand(composeCommand);
|
|
@@ -12711,7 +12750,7 @@ program.addCommand(agentCommand);
|
|
|
12711
12750
|
program.addCommand(initCommand3);
|
|
12712
12751
|
program.addCommand(scheduleCommand);
|
|
12713
12752
|
program.addCommand(usageCommand);
|
|
12714
|
-
program.addCommand(
|
|
12753
|
+
program.addCommand(secretCommand);
|
|
12715
12754
|
program.addCommand(modelProviderCommand);
|
|
12716
12755
|
program.addCommand(onboardCommand);
|
|
12717
12756
|
program.addCommand(setupClaudeCommand);
|