@vm0/cli 4.26.1 → 4.28.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 +113 -22
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -12370,7 +12370,7 @@ var agentDefinitionSchema = external_exports.object({
12370
12370
  * is routed through mitmproxy -> VM0 Proxy for decryption.
12371
12371
  * Default: false (plaintext secrets in env vars)
12372
12372
  */
12373
- beta_network_security: external_exports.boolean().optional().default(false),
12373
+ experimental_network_security: external_exports.boolean().optional().default(false),
12374
12374
  /**
12375
12375
  * Path to instructions file (e.g., AGENTS.md).
12376
12376
  * Auto-uploaded as volume and mounted at /home/user/.claude/CLAUDE.md
@@ -12404,14 +12404,16 @@ var createComposeResponseSchema = external_exports.object({
12404
12404
  });
12405
12405
  var composesMainContract = c2.router({
12406
12406
  /**
12407
- * GET /api/agent/composes?name={name}
12407
+ * GET /api/agent/composes?name={name}&scope={scope}
12408
12408
  * Get agent compose by name with HEAD version content
12409
+ * If scope is not provided, uses the authenticated user's default scope
12409
12410
  */
12410
12411
  getByName: {
12411
12412
  method: "GET",
12412
12413
  path: "/api/agent/composes",
12413
12414
  query: external_exports.object({
12414
- name: external_exports.string().min(1, "Missing name query parameter")
12415
+ name: external_exports.string().min(1, "Missing name query parameter"),
12416
+ scope: external_exports.string().optional()
12415
12417
  }),
12416
12418
  responses: {
12417
12419
  200: composeResponseSchema,
@@ -13521,11 +13523,15 @@ var ApiClient = class {
13521
13523
  }
13522
13524
  return apiUrl;
13523
13525
  }
13524
- async getComposeByName(name) {
13526
+ async getComposeByName(name, scope) {
13525
13527
  const baseUrl = await this.getBaseUrl();
13526
13528
  const headers = await this.getHeaders();
13529
+ const params = new URLSearchParams({ name });
13530
+ if (scope) {
13531
+ params.append("scope", scope);
13532
+ }
13527
13533
  const response = await fetch(
13528
- `${baseUrl}/api/agent/composes?name=${encodeURIComponent(name)}`,
13534
+ `${baseUrl}/api/agent/composes?${params.toString()}`,
13529
13535
  {
13530
13536
  method: "GET",
13531
13537
  headers
@@ -14038,6 +14044,50 @@ function validateAgentCompose(config2) {
14038
14044
  }
14039
14045
  }
14040
14046
  }
14047
+ if (agent.experimental_secrets !== void 0) {
14048
+ if (!Array.isArray(agent.experimental_secrets)) {
14049
+ return {
14050
+ valid: false,
14051
+ error: "agent.experimental_secrets must be an array of strings"
14052
+ };
14053
+ }
14054
+ for (const item of agent.experimental_secrets) {
14055
+ if (typeof item !== "string") {
14056
+ return {
14057
+ valid: false,
14058
+ error: "Each entry in experimental_secrets must be a string"
14059
+ };
14060
+ }
14061
+ if (item.length === 0) {
14062
+ return {
14063
+ valid: false,
14064
+ error: "experimental_secrets entries cannot be empty strings"
14065
+ };
14066
+ }
14067
+ }
14068
+ }
14069
+ if (agent.experimental_vars !== void 0) {
14070
+ if (!Array.isArray(agent.experimental_vars)) {
14071
+ return {
14072
+ valid: false,
14073
+ error: "agent.experimental_vars must be an array of strings"
14074
+ };
14075
+ }
14076
+ for (const item of agent.experimental_vars) {
14077
+ if (typeof item !== "string") {
14078
+ return {
14079
+ valid: false,
14080
+ error: "Each entry in experimental_vars must be a string"
14081
+ };
14082
+ }
14083
+ if (item.length === 0) {
14084
+ return {
14085
+ valid: false,
14086
+ error: "experimental_vars entries cannot be empty strings"
14087
+ };
14088
+ }
14089
+ }
14090
+ }
14041
14091
  const agentVolumes = agent.volumes;
14042
14092
  if (agentVolumes && Array.isArray(agentVolumes) && agentVolumes.length > 0) {
14043
14093
  const volumesSection = cfg.volumes;
@@ -14482,6 +14532,33 @@ async function uploadSkill(skillUrl) {
14482
14532
  }
14483
14533
 
14484
14534
  // src/commands/compose.ts
14535
+ function transformExperimentalShorthand(agent) {
14536
+ const experimentalSecrets = agent.experimental_secrets;
14537
+ const experimentalVars = agent.experimental_vars;
14538
+ if (!experimentalSecrets && !experimentalVars) {
14539
+ return;
14540
+ }
14541
+ const environment = agent.environment || {};
14542
+ if (experimentalSecrets) {
14543
+ for (const secretName of experimentalSecrets) {
14544
+ if (!(secretName in environment)) {
14545
+ environment[secretName] = "${{ secrets." + secretName + " }}";
14546
+ }
14547
+ }
14548
+ delete agent.experimental_secrets;
14549
+ }
14550
+ if (experimentalVars) {
14551
+ for (const varName of experimentalVars) {
14552
+ if (!(varName in environment)) {
14553
+ environment[varName] = "${{ vars." + varName + " }}";
14554
+ }
14555
+ }
14556
+ delete agent.experimental_vars;
14557
+ }
14558
+ if (Object.keys(environment).length > 0) {
14559
+ agent.environment = environment;
14560
+ }
14561
+ }
14485
14562
  var composeCommand = new Command().name("compose").description("Create or update agent compose").argument("<config-file>", "Path to config YAML file").action(async (configFile) => {
14486
14563
  try {
14487
14564
  if (!existsSync3(configFile)) {
@@ -14506,6 +14583,9 @@ var composeCommand = new Command().name("compose").description("Create or update
14506
14583
  }
14507
14584
  const cfg = config2;
14508
14585
  const agentsConfig = cfg.agents;
14586
+ for (const agentConfig of Object.values(agentsConfig)) {
14587
+ transformExperimentalShorthand(agentConfig);
14588
+ }
14509
14589
  for (const [name, agentConfig] of Object.entries(agentsConfig)) {
14510
14590
  const image = agentConfig.image;
14511
14591
  if (image) {
@@ -14590,19 +14670,20 @@ var composeCommand = new Command().name("compose").description("Create or update
14590
14670
  const response = await apiClient.createOrUpdateCompose({
14591
14671
  content: config2
14592
14672
  });
14673
+ const scopeResponse = await apiClient.getScope();
14593
14674
  const shortVersionId = response.versionId.slice(0, 8);
14675
+ const displayName = `${scopeResponse.slug}/${response.name}`;
14594
14676
  if (response.action === "created") {
14595
- console.log(chalk2.green(`\u2713 Compose created: ${response.name}`));
14677
+ console.log(chalk2.green(`\u2713 Compose created: ${displayName}`));
14596
14678
  } else {
14597
- console.log(chalk2.green(`\u2713 Compose version exists: ${response.name}`));
14679
+ console.log(chalk2.green(`\u2713 Compose version exists: ${displayName}`));
14598
14680
  }
14599
- console.log(chalk2.dim(` Compose ID: ${response.composeId}`));
14600
- console.log(chalk2.dim(` Version: ${shortVersionId}`));
14681
+ console.log(chalk2.dim(` Version: ${shortVersionId}`));
14601
14682
  console.log();
14602
14683
  console.log(" Run your agent:");
14603
14684
  console.log(
14604
14685
  chalk2.cyan(
14605
- ` vm0 run ${response.name} --artifact-name <artifact> "your prompt"`
14686
+ ` vm0 run ${displayName}:${shortVersionId} --artifact-name <artifact> "your prompt"`
14606
14687
  )
14607
14688
  );
14608
14689
  } catch (error43) {
@@ -15316,14 +15397,22 @@ function parseIdentifier(identifier) {
15316
15397
  if (isUUID(identifier)) {
15317
15398
  return { name: identifier };
15318
15399
  }
15319
- const colonIndex = identifier.lastIndexOf(":");
15320
- if (colonIndex > 0 && colonIndex < identifier.length - 1) {
15400
+ let scope;
15401
+ let rest = identifier;
15402
+ const slashIndex = identifier.indexOf("/");
15403
+ if (slashIndex > 0) {
15404
+ scope = identifier.slice(0, slashIndex);
15405
+ rest = identifier.slice(slashIndex + 1);
15406
+ }
15407
+ const colonIndex = rest.indexOf(":");
15408
+ if (colonIndex > 0 && colonIndex < rest.length - 1) {
15321
15409
  return {
15322
- name: identifier.slice(0, colonIndex),
15323
- version: identifier.slice(colonIndex + 1)
15410
+ scope,
15411
+ name: rest.slice(0, colonIndex),
15412
+ version: rest.slice(colonIndex + 1)
15324
15413
  };
15325
15414
  }
15326
- return { name: identifier };
15415
+ return { scope, name: rest };
15327
15416
  }
15328
15417
  async function pollEvents(runId, options) {
15329
15418
  let nextSequence = 0;
@@ -15420,7 +15509,7 @@ function showNextSteps(result) {
15420
15509
  }
15421
15510
  var runCmd = new Command2().name("run").description("Execute an agent").argument(
15422
15511
  "<identifier>",
15423
- "Agent name, config ID, or name:version (e.g., 'my-agent', 'my-agent:abc123', 'my-agent:latest')"
15512
+ "Agent reference: [scope/]name[:version] (e.g., 'my-agent', 'lancy/my-agent:abc123', 'my-agent:latest')"
15424
15513
  ).argument("<prompt>", "Prompt for the agent").option(
15425
15514
  "--vars <KEY=value>",
15426
15515
  "Variables for ${{ vars.xxx }} (repeatable, falls back to env vars and .env)",
@@ -15447,7 +15536,7 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
15447
15536
  const startTimestamp = /* @__PURE__ */ new Date();
15448
15537
  const verbose = options.verbose;
15449
15538
  try {
15450
- const { name, version: version2 } = parseIdentifier(identifier);
15539
+ const { scope, name, version: version2 } = parseIdentifier(identifier);
15451
15540
  let composeId;
15452
15541
  let composeContent;
15453
15542
  if (isUUID(name)) {
@@ -15466,10 +15555,11 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
15466
15555
  }
15467
15556
  } else {
15468
15557
  if (verbose) {
15469
- console.log(chalk5.dim(` Resolving agent name: ${name}`));
15558
+ const displayRef = scope ? `${scope}/${name}` : name;
15559
+ console.log(chalk5.dim(` Resolving agent: ${displayRef}`));
15470
15560
  }
15471
15561
  try {
15472
- const compose = await apiClient.getComposeByName(name);
15562
+ const compose = await apiClient.getComposeByName(name, scope);
15473
15563
  composeId = compose.id;
15474
15564
  composeContent = compose.content;
15475
15565
  if (verbose) {
@@ -15477,7 +15567,8 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
15477
15567
  }
15478
15568
  } catch (error43) {
15479
15569
  if (error43 instanceof Error) {
15480
- console.error(chalk5.red(`\u2717 Agent not found: ${name}`));
15570
+ const displayRef = scope ? `${scope}/${name}` : name;
15571
+ console.error(chalk5.red(`\u2717 Agent not found: ${displayRef}`));
15481
15572
  console.error(
15482
15573
  chalk5.dim(
15483
15574
  " Make sure you've composed the agent with: vm0 compose"
@@ -16723,7 +16814,7 @@ async function autoPullArtifact(runOutput, artifactDir) {
16723
16814
  }
16724
16815
  var cookCmd = new Command13().name("cook").description("One-click agent preparation and execution from vm0.yaml");
16725
16816
  cookCmd.argument("[prompt]", "Prompt for the agent").action(async (prompt) => {
16726
- const shouldExit = await checkAndUpgrade("4.26.1", prompt);
16817
+ const shouldExit = await checkAndUpgrade("4.28.0", prompt);
16727
16818
  if (shouldExit) {
16728
16819
  process.exit(0);
16729
16820
  }
@@ -17863,7 +17954,7 @@ var initCommand3 = new Command23().name("init").description("Initialize a new VM
17863
17954
 
17864
17955
  // src/index.ts
17865
17956
  var program = new Command24();
17866
- program.name("vm0").description("VM0 CLI - A modern build tool").version("4.26.1");
17957
+ program.name("vm0").description("VM0 CLI - A modern build tool").version("4.28.0");
17867
17958
  program.command("info").description("Display environment information").action(async () => {
17868
17959
  console.log(chalk25.bold("System Information:"));
17869
17960
  console.log(`Node Version: ${process.version}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "4.26.1",
3
+ "version": "4.28.0",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",