@vm0/cli 4.28.0 → 4.29.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.
Files changed (2) hide show
  1. package/index.js +469 -6
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -6,8 +6,8 @@ var __export = (target, all) => {
6
6
  };
7
7
 
8
8
  // src/index.ts
9
- import { Command as Command24 } from "commander";
10
- import chalk25 from "chalk";
9
+ import { Command as Command25 } from "commander";
10
+ import chalk26 from "chalk";
11
11
 
12
12
  // src/lib/auth.ts
13
13
  import chalk from "chalk";
@@ -16814,7 +16814,7 @@ async function autoPullArtifact(runOutput, artifactDir) {
16814
16814
  }
16815
16815
  var cookCmd = new Command13().name("cook").description("One-click agent preparation and execution from vm0.yaml");
16816
16816
  cookCmd.argument("[prompt]", "Prompt for the agent").action(async (prompt) => {
16817
- const shouldExit = await checkAndUpgrade("4.28.0", prompt);
16817
+ const shouldExit = await checkAndUpgrade("4.29.0", prompt);
16818
16818
  if (shouldExit) {
16819
16819
  process.exit(0);
16820
16820
  }
@@ -17952,11 +17952,473 @@ var initCommand3 = new Command23().name("init").description("Initialize a new VM
17952
17952
  console.log(` 3. Run your agent: ${chalk24.cyan('vm0 cook "your prompt"')}`);
17953
17953
  });
17954
17954
 
17955
+ // src/commands/setup-github.ts
17956
+ import { Command as Command24 } from "commander";
17957
+ import chalk25 from "chalk";
17958
+ import * as readline3 from "readline";
17959
+ import { existsSync as existsSync10 } from "fs";
17960
+ import { mkdir as mkdir7, readFile as readFile8, writeFile as writeFile8 } from "fs/promises";
17961
+ import { execSync, spawnSync } from "child_process";
17962
+ import { parse as parseYaml4 } from "yaml";
17963
+ function isGhInstalled() {
17964
+ try {
17965
+ execSync("gh --version", { stdio: "ignore" });
17966
+ return true;
17967
+ } catch {
17968
+ return false;
17969
+ }
17970
+ }
17971
+ function isGhAuthenticated() {
17972
+ try {
17973
+ execSync("gh auth status", { stdio: "ignore" });
17974
+ return true;
17975
+ } catch {
17976
+ return false;
17977
+ }
17978
+ }
17979
+ async function checkPrerequisites() {
17980
+ console.log("Checking prerequisites...");
17981
+ if (!isGhInstalled()) {
17982
+ console.log(chalk25.red("\u2717 GitHub CLI (gh) is not installed"));
17983
+ console.log();
17984
+ console.log("GitHub CLI is required for this command.");
17985
+ console.log();
17986
+ console.log(` macOS: ${chalk25.cyan("brew install gh")}`);
17987
+ console.log(` Other: ${chalk25.cyan("https://cli.github.com/")}`);
17988
+ console.log();
17989
+ console.log("After installation, run:");
17990
+ console.log(` ${chalk25.cyan("gh auth login")}`);
17991
+ console.log();
17992
+ console.log("Then try again:");
17993
+ console.log(` ${chalk25.cyan("vm0 setup-github")}`);
17994
+ process.exit(1);
17995
+ }
17996
+ console.log(chalk25.green("\u2713 GitHub CLI (gh) is installed"));
17997
+ if (!isGhAuthenticated()) {
17998
+ console.log(chalk25.red("\u2717 GitHub CLI is not authenticated"));
17999
+ console.log();
18000
+ console.log("Please authenticate GitHub CLI first:");
18001
+ console.log(` ${chalk25.cyan("gh auth login")}`);
18002
+ console.log();
18003
+ console.log("Then try again:");
18004
+ console.log(` ${chalk25.cyan("vm0 setup-github")}`);
18005
+ process.exit(1);
18006
+ }
18007
+ console.log(chalk25.green("\u2713 GitHub CLI is authenticated"));
18008
+ const token = await getToken();
18009
+ if (!token) {
18010
+ console.log(chalk25.red("\u2717 VM0 not authenticated"));
18011
+ console.log();
18012
+ console.log("Please authenticate with VM0 first:");
18013
+ console.log(` ${chalk25.cyan("vm0 auth login")}`);
18014
+ console.log();
18015
+ console.log("Then try again:");
18016
+ console.log(` ${chalk25.cyan("vm0 setup-github")}`);
18017
+ process.exit(1);
18018
+ }
18019
+ console.log(chalk25.green("\u2713 VM0 authenticated"));
18020
+ if (!existsSync10("vm0.yaml")) {
18021
+ console.log(chalk25.red("\u2717 vm0.yaml not found"));
18022
+ console.log();
18023
+ console.log("This command requires a vm0.yaml configuration file.");
18024
+ console.log();
18025
+ console.log("To create one, run:");
18026
+ console.log(` ${chalk25.cyan("vm0 init")}`);
18027
+ console.log();
18028
+ console.log("Then try again:");
18029
+ console.log(` ${chalk25.cyan("vm0 setup-github")}`);
18030
+ process.exit(1);
18031
+ }
18032
+ console.log(chalk25.green("\u2713 vm0.yaml found"));
18033
+ return token;
18034
+ }
18035
+ function generatePublishYaml() {
18036
+ return `name: Publish Agent
18037
+
18038
+ on:
18039
+ push:
18040
+ branches: [main]
18041
+ paths:
18042
+ - 'vm0.yaml'
18043
+ - 'AGENTS.md'
18044
+
18045
+ jobs:
18046
+ publish:
18047
+ runs-on: ubuntu-latest
18048
+ steps:
18049
+ - uses: actions/checkout@v4
18050
+
18051
+ - name: Publish Agent
18052
+ uses: vm0-ai/compose-action@v1
18053
+ id: compose
18054
+ with:
18055
+ vm0-token: \${{ secrets.VM0_TOKEN }}
18056
+
18057
+ - name: Show Results
18058
+ run: |
18059
+ echo "Agent: \${{ steps.compose.outputs.name }}"
18060
+ echo "Compose ID: \${{ steps.compose.outputs.compose-id }}"
18061
+ echo "Version: \${{ steps.compose.outputs.version-id }}"
18062
+ echo "Action: \${{ steps.compose.outputs.action }}"
18063
+ `;
18064
+ }
18065
+ function generateRunYaml(agentName, secrets, vars) {
18066
+ const otherSecrets = secrets.filter((s) => s !== "VM0_TOKEN");
18067
+ const secretsLines = otherSecrets.map((s) => ` ${s}=\${{ secrets.${s} }}`).join("\n");
18068
+ const varsLines = vars.map((v) => ` ${v}=\${{ vars.${v} }}`).join("\n");
18069
+ let yaml = `name: Run Agent
18070
+
18071
+ on:
18072
+ # Uncomment to enable scheduled runs:
18073
+ # schedule:
18074
+ # - cron: '0 1 * * *' # Daily at 9:00 AM UTC+8
18075
+ workflow_dispatch:
18076
+ inputs:
18077
+ prompt:
18078
+ description: 'Prompt for the agent'
18079
+ required: false
18080
+ default: 'do the job'
18081
+
18082
+ jobs:
18083
+ run:
18084
+ runs-on: ubuntu-latest
18085
+ steps:
18086
+ - name: Run Agent
18087
+ uses: vm0-ai/run-action@v1
18088
+ with:
18089
+ agent: ${agentName}
18090
+ prompt: \${{ github.event.inputs.prompt || 'do the job' }}
18091
+ silent: true
18092
+ vm0-token: \${{ secrets.VM0_TOKEN }}`;
18093
+ if (secretsLines) {
18094
+ yaml += `
18095
+ secrets: |
18096
+ ${secretsLines}`;
18097
+ }
18098
+ if (varsLines) {
18099
+ yaml += `
18100
+ vars: |
18101
+ ${varsLines}`;
18102
+ }
18103
+ yaml += "\n";
18104
+ return yaml;
18105
+ }
18106
+ function extractSecretsAndVars(config2) {
18107
+ const secrets = /* @__PURE__ */ new Set();
18108
+ const vars = /* @__PURE__ */ new Set();
18109
+ const refs = extractVariableReferences(config2);
18110
+ const grouped = groupVariablesBySource(refs);
18111
+ for (const ref of grouped.secrets) {
18112
+ secrets.add(ref.name);
18113
+ }
18114
+ for (const ref of grouped.vars) {
18115
+ vars.add(ref.name);
18116
+ }
18117
+ const cfg = config2;
18118
+ const agents = cfg.agents;
18119
+ if (agents) {
18120
+ const agentConfig = Object.values(agents)[0];
18121
+ if (agentConfig) {
18122
+ const expSecrets = agentConfig.experimental_secrets;
18123
+ const expVars = agentConfig.experimental_vars;
18124
+ if (expSecrets) {
18125
+ for (const s of expSecrets) {
18126
+ secrets.add(s);
18127
+ }
18128
+ }
18129
+ if (expVars) {
18130
+ for (const v of expVars) {
18131
+ vars.add(v);
18132
+ }
18133
+ }
18134
+ }
18135
+ }
18136
+ secrets.add("VM0_TOKEN");
18137
+ return {
18138
+ secrets: Array.from(secrets).sort(),
18139
+ vars: Array.from(vars).sort()
18140
+ };
18141
+ }
18142
+ async function promptYesNo(question, defaultYes) {
18143
+ const hint = defaultYes ? "(Y/n)" : "(y/N)";
18144
+ const rl = readline3.createInterface({
18145
+ input: process.stdin,
18146
+ output: process.stdout
18147
+ });
18148
+ return new Promise((resolve2) => {
18149
+ rl.question(chalk25.cyan(`? ${question} ${hint} `), (answer) => {
18150
+ rl.close();
18151
+ const normalized = answer.trim().toLowerCase();
18152
+ if (normalized === "") {
18153
+ resolve2(defaultYes);
18154
+ } else {
18155
+ resolve2(normalized === "y" || normalized === "yes");
18156
+ }
18157
+ });
18158
+ });
18159
+ }
18160
+ function setGitHubSecret(name, value) {
18161
+ const result = spawnSync("gh", ["secret", "set", name], {
18162
+ input: value,
18163
+ stdio: ["pipe", "pipe", "pipe"]
18164
+ });
18165
+ return result.status === 0;
18166
+ }
18167
+ function setGitHubVariable(name, value) {
18168
+ const result = spawnSync("gh", ["variable", "set", name, "--body", value], {
18169
+ stdio: ["pipe", "pipe", "pipe"]
18170
+ });
18171
+ return result.status === 0;
18172
+ }
18173
+ async function detectSecretValues(secrets, vars, vm0Token) {
18174
+ const secretStatuses = secrets.map((name) => {
18175
+ if (name === "VM0_TOKEN") {
18176
+ return { name, found: true, source: "vm0 auth", value: vm0Token };
18177
+ }
18178
+ const envValue = process.env[name];
18179
+ if (envValue) {
18180
+ return { name, found: true, source: "environment", value: envValue };
18181
+ }
18182
+ return { name, found: false };
18183
+ });
18184
+ const varStatuses = vars.map((name) => {
18185
+ const envValue = process.env[name];
18186
+ if (envValue) {
18187
+ return { name, found: true, source: "environment", value: envValue };
18188
+ }
18189
+ return { name, found: false };
18190
+ });
18191
+ return { secretStatuses, varStatuses };
18192
+ }
18193
+ function displaySecretsTable(secretStatuses, varStatuses) {
18194
+ console.log("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
18195
+ console.log("\u2502 Detected secrets and variables: \u2502");
18196
+ console.log("\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524");
18197
+ if (secretStatuses.length > 0) {
18198
+ console.log("\u2502 Secrets: \u2502");
18199
+ for (const s of secretStatuses) {
18200
+ const status = s.found ? chalk25.green("\u2713") : chalk25.red("\u2717");
18201
+ const source = s.found ? `(from ${s.source})` : "not found";
18202
+ const paddedName = (s.name + " ").padEnd(23, ".");
18203
+ console.log(`\u2502 ${status} ${paddedName} ${source.padEnd(19)}\u2502`);
18204
+ }
18205
+ }
18206
+ if (varStatuses.length > 0) {
18207
+ console.log("\u2502 Variables: \u2502");
18208
+ for (const v of varStatuses) {
18209
+ const status = v.found ? chalk25.green("\u2713") : chalk25.red("\u2717");
18210
+ const source = v.found ? `(from ${v.source})` : "not found";
18211
+ const paddedName = (v.name + " ").padEnd(23, ".");
18212
+ console.log(`\u2502 ${status} ${paddedName} ${source.padEnd(19)}\u2502`);
18213
+ }
18214
+ }
18215
+ console.log("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
18216
+ }
18217
+ function showManualSetupInstructions(secrets, vars) {
18218
+ console.log("Skipped automatic setup. Configure secrets manually:");
18219
+ console.log();
18220
+ console.log(" Step 1: Get your VM0 token");
18221
+ console.log(` ${chalk25.cyan("vm0 auth setup-token")}`);
18222
+ console.log();
18223
+ console.log(" Step 2: Set GitHub secrets");
18224
+ for (const s of secrets) {
18225
+ console.log(` ${chalk25.cyan(`gh secret set ${s}`)}`);
18226
+ }
18227
+ if (vars.length > 0) {
18228
+ console.log();
18229
+ console.log(" Step 3: Set GitHub variables");
18230
+ for (const v of vars) {
18231
+ console.log(` ${chalk25.cyan(`gh variable set ${v}`)}`);
18232
+ }
18233
+ }
18234
+ }
18235
+ function showSuccessMessage() {
18236
+ console.log("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
18237
+ console.log("\u2502 \u2713 GitHub Actions setup complete! \u2502");
18238
+ console.log("\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524");
18239
+ console.log("\u2502 Workflows created: \u2502");
18240
+ console.log("\u2502 \u2022 .github/workflows/publish.yml \u2502");
18241
+ console.log("\u2502 \u2022 .github/workflows/run.yml \u2502");
18242
+ console.log("\u2502 \u2502");
18243
+ console.log("\u2502 Next steps: \u2502");
18244
+ console.log("\u2502 1. Commit and push the workflow files \u2502");
18245
+ console.log("\u2502 2. Push to main branch to trigger publish \u2502");
18246
+ console.log("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
18247
+ }
18248
+ function showPartialSuccessMessage(missingSecrets, missingVars) {
18249
+ console.log("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
18250
+ console.log("\u2502 \u26A0 Setup partially complete \u2502");
18251
+ console.log("\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524");
18252
+ console.log("\u2502 Missing secrets - set them manually: \u2502");
18253
+ for (const s of missingSecrets) {
18254
+ console.log(`\u2502 gh secret set ${s.padEnd(40)}\u2502`);
18255
+ }
18256
+ for (const v of missingVars) {
18257
+ console.log(`\u2502 gh variable set ${v.padEnd(38)}\u2502`);
18258
+ }
18259
+ console.log("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
18260
+ }
18261
+ function showWorkflowsCreatedMessage() {
18262
+ console.log("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
18263
+ console.log("\u2502 \u2713 Workflow files created! \u2502");
18264
+ console.log("\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524");
18265
+ console.log("\u2502 \u2022 .github/workflows/publish.yml \u2502");
18266
+ console.log("\u2502 \u2022 .github/workflows/run.yml \u2502");
18267
+ console.log("\u2502 \u2502");
18268
+ console.log("\u2502 Next steps: \u2502");
18269
+ console.log("\u2502 1. Set GitHub secrets (see commands above) \u2502");
18270
+ console.log("\u2502 2. Commit and push the workflow files \u2502");
18271
+ console.log("\u2502 3. Push to main branch to trigger publish \u2502");
18272
+ console.log("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
18273
+ }
18274
+ var setupGithubCommand = new Command24().name("setup-github").description("Initialize GitHub Actions workflows for agent deployment").option("-f, --force", "Overwrite existing workflow files").option("-y, --yes", "Auto-confirm all prompts").option("--skip-secrets", "Skip automatic secrets/variables setup").action(
18275
+ async (options) => {
18276
+ const vm0Token = await checkPrerequisites();
18277
+ if (!vm0Token) {
18278
+ process.exit(1);
18279
+ }
18280
+ console.log();
18281
+ console.log("Analyzing vm0.yaml...");
18282
+ const content = await readFile8("vm0.yaml", "utf8");
18283
+ const config2 = parseYaml4(content);
18284
+ const agents = config2.agents;
18285
+ const agentName = Object.keys(agents)[0];
18286
+ console.log(chalk25.green(`\u2713 Agent: ${agentName}`));
18287
+ const { secrets, vars } = extractSecretsAndVars(config2);
18288
+ console.log(
18289
+ chalk25.green(
18290
+ `\u2713 Found ${secrets.length} secrets, ${vars.length} variables`
18291
+ )
18292
+ );
18293
+ console.log();
18294
+ const publishPath = ".github/workflows/publish.yml";
18295
+ const runPath = ".github/workflows/run.yml";
18296
+ const existingFiles = [];
18297
+ if (existsSync10(publishPath)) existingFiles.push(publishPath);
18298
+ if (existsSync10(runPath)) existingFiles.push(runPath);
18299
+ if (existingFiles.length > 0 && !options.force) {
18300
+ console.log(chalk25.yellow("\u26A0 Existing workflow files detected:"));
18301
+ for (const file2 of existingFiles) {
18302
+ console.log(` \u2022 ${file2}`);
18303
+ }
18304
+ console.log();
18305
+ if (!options.yes) {
18306
+ const overwrite = await promptYesNo(
18307
+ "Overwrite existing files?",
18308
+ false
18309
+ );
18310
+ if (!overwrite) {
18311
+ console.log();
18312
+ console.log("Aborted. To force overwrite, run:");
18313
+ console.log(` ${chalk25.cyan("vm0 setup-github --force")}`);
18314
+ process.exit(0);
18315
+ }
18316
+ }
18317
+ console.log();
18318
+ }
18319
+ console.log("Creating workflow files...");
18320
+ await mkdir7(".github/workflows", { recursive: true });
18321
+ await writeFile8(publishPath, generatePublishYaml());
18322
+ const publishStatus = existingFiles.includes(publishPath) ? "Overwrote" : "Created";
18323
+ console.log(chalk25.green(`\u2713 ${publishStatus} ${publishPath}`));
18324
+ await writeFile8(runPath, generateRunYaml(agentName, secrets, vars));
18325
+ const runStatus = existingFiles.includes(runPath) ? "Overwrote" : "Created";
18326
+ console.log(chalk25.green(`\u2713 ${runStatus} ${runPath}`));
18327
+ console.log();
18328
+ if (options.skipSecrets) {
18329
+ console.log(chalk25.green("\u2713 Done (secrets setup skipped)"));
18330
+ return;
18331
+ }
18332
+ const { secretStatuses, varStatuses } = await detectSecretValues(
18333
+ secrets,
18334
+ vars,
18335
+ vm0Token
18336
+ );
18337
+ displaySecretsTable(secretStatuses, varStatuses);
18338
+ console.log();
18339
+ const hasFoundValues = secretStatuses.some((s) => s.found) || varStatuses.some((v) => v.found);
18340
+ if (!hasFoundValues) {
18341
+ console.log("No secret/variable values found in environment.");
18342
+ console.log();
18343
+ showManualSetupInstructions(secrets, vars);
18344
+ console.log();
18345
+ showWorkflowsCreatedMessage();
18346
+ return;
18347
+ }
18348
+ let shouldSetup = options.yes;
18349
+ if (!shouldSetup) {
18350
+ shouldSetup = await promptYesNo(
18351
+ "Set up GitHub secrets/variables automatically?",
18352
+ true
18353
+ );
18354
+ }
18355
+ if (!shouldSetup) {
18356
+ console.log();
18357
+ showManualSetupInstructions(secrets, vars);
18358
+ console.log();
18359
+ showWorkflowsCreatedMessage();
18360
+ return;
18361
+ }
18362
+ console.log();
18363
+ console.log("Setting secrets...");
18364
+ const failedSecrets = [];
18365
+ for (const s of secretStatuses) {
18366
+ if (s.found && s.value) {
18367
+ const success2 = setGitHubSecret(s.name, s.value);
18368
+ if (success2) {
18369
+ console.log(` ${chalk25.green("\u2713")} ${s.name}`);
18370
+ } else {
18371
+ console.log(` ${chalk25.red("\u2717")} ${s.name} (failed)`);
18372
+ failedSecrets.push(s.name);
18373
+ }
18374
+ } else {
18375
+ console.log(
18376
+ ` ${chalk25.yellow("\u26A0")} ${s.name} (skipped - not found)`
18377
+ );
18378
+ }
18379
+ }
18380
+ const failedVars = [];
18381
+ if (varStatuses.length > 0) {
18382
+ console.log();
18383
+ console.log("Setting variables...");
18384
+ for (const v of varStatuses) {
18385
+ if (v.found && v.value) {
18386
+ const success2 = setGitHubVariable(v.name, v.value);
18387
+ if (success2) {
18388
+ console.log(` ${chalk25.green("\u2713")} ${v.name}`);
18389
+ } else {
18390
+ console.log(` ${chalk25.red("\u2717")} ${v.name} (failed)`);
18391
+ failedVars.push(v.name);
18392
+ }
18393
+ } else {
18394
+ console.log(
18395
+ ` ${chalk25.yellow("\u26A0")} ${v.name} (skipped - not found)`
18396
+ );
18397
+ }
18398
+ }
18399
+ }
18400
+ console.log();
18401
+ const missingSecrets = [
18402
+ ...secretStatuses.filter((s) => !s.found).map((s) => s.name),
18403
+ ...failedSecrets
18404
+ ];
18405
+ const missingVars = [
18406
+ ...varStatuses.filter((v) => !v.found).map((v) => v.name),
18407
+ ...failedVars
18408
+ ];
18409
+ if (missingSecrets.length === 0 && missingVars.length === 0) {
18410
+ showSuccessMessage();
18411
+ } else {
18412
+ showPartialSuccessMessage(missingSecrets, missingVars);
18413
+ }
18414
+ }
18415
+ );
18416
+
17955
18417
  // src/index.ts
17956
- var program = new Command24();
17957
- program.name("vm0").description("VM0 CLI - A modern build tool").version("4.28.0");
18418
+ var program = new Command25();
18419
+ program.name("vm0").description("VM0 CLI - A modern build tool").version("4.29.0");
17958
18420
  program.command("info").description("Display environment information").action(async () => {
17959
- console.log(chalk25.bold("System Information:"));
18421
+ console.log(chalk26.bold("System Information:"));
17960
18422
  console.log(`Node Version: ${process.version}`);
17961
18423
  console.log(`Platform: ${process.platform}`);
17962
18424
  console.log(`Architecture: ${process.arch}`);
@@ -17985,6 +18447,7 @@ program.addCommand(imageCommand);
17985
18447
  program.addCommand(logsCommand);
17986
18448
  program.addCommand(scopeCommand);
17987
18449
  program.addCommand(initCommand3);
18450
+ program.addCommand(setupGithubCommand);
17988
18451
  if (process.argv[1]?.endsWith("index.js") || process.argv[1]?.endsWith("index.ts") || process.argv[1]?.endsWith("vm0")) {
17989
18452
  program.parse();
17990
18453
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "4.28.0",
3
+ "version": "4.29.0",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",