@mutagent/cli 0.1.381 → 0.1.383

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/dist/bin/cli.js CHANGED
@@ -16696,6 +16696,7 @@ __export(exports_organization_scope, {
16696
16696
  fetchOrganizations: () => fetchOrganizations,
16697
16697
  fetchKeySelf: () => fetchKeySelf,
16698
16698
  envKeyHasNoSelection: () => envKeyHasNoSelection,
16699
+ endpointOf: () => endpointOf,
16699
16700
  deadKeyError: () => deadKeyError,
16700
16701
  configTenancyHeaders: () => configTenancyHeaders,
16701
16702
  TenancyError: () => TenancyError,
@@ -18324,7 +18325,7 @@ function handleAgentParseError(error3, json) {
18324
18325
  }
18325
18326
 
18326
18327
  // src/bin/cli.ts
18327
- import chalk37 from "chalk";
18328
+ import chalk38 from "chalk";
18328
18329
  import { readFileSync as readFileSync14 } from "fs";
18329
18330
  import { join as join21, dirname as dirname7 } from "path";
18330
18331
  import { fileURLToPath as fileURLToPath4 } from "url";
@@ -25044,6 +25045,10 @@ async function sandboxFetch(path, init, deps = {}) {
25044
25045
  throw toNetworkError(error3, endpoint);
25045
25046
  }
25046
25047
  }
25048
+ var CLOUD_NOT_ENABLED = "CLOUD_NOT_ENABLED";
25049
+ function cloudNotEnabledError() {
25050
+ return new MutagentError(CLOUD_NOT_ENABLED, "Cloud sandboxes are not enabled for your account yet.", undefined, 1);
25051
+ }
25047
25052
  async function toCliError(response, sandboxId) {
25048
25053
  const body = await response.text().catch(() => "");
25049
25054
  const message = extractMessage(body) || response.statusText || "Request failed";
@@ -25051,8 +25056,10 @@ async function toCliError(response, sandboxId) {
25051
25056
  return new AuthenticationError;
25052
25057
  if (response.status === 404 && sandboxId)
25053
25058
  return new NotFoundError("Sandbox", sandboxId);
25054
- const error3 = new ApiError(response.status, message);
25055
25059
  const code = parseRecord(body)?.code;
25060
+ if (response.status === 403 && code === CLOUD_NOT_ENABLED)
25061
+ return cloudNotEnabledError();
25062
+ const error3 = new ApiError(response.status, message);
25056
25063
  if (typeof code === "string" && /^[A-Za-z][A-Za-z0-9_]{0,63}$/.test(code))
25057
25064
  error3.code = code;
25058
25065
  return error3;
@@ -27788,7 +27795,7 @@ function createHelixCommand() {
27788
27795
 
27789
27796
  // src/commands/sandbox/index.ts
27790
27797
  import { Command as Command16 } from "commander";
27791
- import chalk35 from "chalk";
27798
+ import chalk36 from "chalk";
27792
27799
 
27793
27800
  // src/commands/sandbox/spawn.ts
27794
27801
  import chalk30 from "chalk";
@@ -28173,15 +28180,82 @@ AI Agent Directive:
28173
28180
  });
28174
28181
  }
28175
28182
 
28176
- // src/commands/sandbox/providers.ts
28183
+ // src/commands/sandbox/access.ts
28177
28184
  import chalk33 from "chalk";
28185
+
28186
+ // src/lib/sandbox-access.ts
28187
+ init_errors();
28188
+ init_config();
28189
+ init_organization_scope();
28190
+ async function getCloudAccess() {
28191
+ let body;
28192
+ try {
28193
+ body = await requestJson("/api/sandbox/access");
28194
+ } catch (error3) {
28195
+ if (error3 instanceof ApiError && error3.statusCode === 404)
28196
+ return { cloudSandboxes: true };
28197
+ if (error3 instanceof MutagentError && error3.code === "SANDBOX_UNREACHABLE") {
28198
+ throw unreachableServerError(endpointOf(loadConfig().endpoint));
28199
+ }
28200
+ throw error3;
28201
+ }
28202
+ if (typeof body.cloudSandboxes !== "boolean") {
28203
+ throw new MutagentError("INVALID_RESPONSE", "The server answered /api/sandbox/access without a cloudSandboxes flag.", 'Retry, and if it persists report it with: mutagent feedback send "<what happened>" --category cli');
28204
+ }
28205
+ return { cloudSandboxes: body.cloudSandboxes };
28206
+ }
28207
+
28208
+ // src/commands/sandbox/access.ts
28209
+ init_errors();
28210
+ function registerAccessCommand(parent) {
28211
+ parent.command("access").description("Check whether this account can create cloud sandboxes").addHelpText("after", `
28212
+ Examples:
28213
+ ${chalk33.dim("$")} mutagent sandbox access
28214
+ ${chalk33.dim("$")} mutagent sandbox access --json
28215
+
28216
+ Asks the server once (GET /api/sandbox/access) for the current workspace and the
28217
+ signed-in account. Until the public launch, cloud sandboxes are limited to an
28218
+ allowlist; everyone else gets "Cloud sandboxes are not enabled for your account yet"
28219
+ from spawn, exec, and helix launches.
28220
+
28221
+ Output:
28222
+ Human: "Cloud sandboxes: enabled" or "Cloud sandboxes: not enabled for your account yet".
28223
+ --json: {"cloudSandboxes": true|false}
28224
+ Exit 0 in both cases. A rejected API key exits 2 (code AUTH_EXPIRED); a server
28225
+ that cannot be reached exits 1 (code REQUEST_FAILED).
28226
+ A server older than this check answers 404; that is reported as
28227
+ {"cloudSandboxes": true}, because such a server has no allowlist.
28228
+
28229
+ AI Agent Directive:
28230
+ Run 'mutagent sandbox access --json' before offering a cloud launch. When
28231
+ cloudSandboxes is false, tell the user cloud sandboxes are not enabled for their
28232
+ account yet and do not attempt a launch; do not retry.
28233
+
28234
+ Requires a workspace: mutagent workspaces use <name> (or --workspace for one command)
28235
+ `).action(async () => {
28236
+ const isJson = getJsonFlag(parent);
28237
+ try {
28238
+ const access = await getCloudAccess();
28239
+ if (isJson) {
28240
+ console.log(JSON.stringify(access));
28241
+ return;
28242
+ }
28243
+ console.log(access.cloudSandboxes ? "Cloud sandboxes: enabled" : "Cloud sandboxes: not enabled for your account yet");
28244
+ } catch (error3) {
28245
+ handleError(error3, isJson);
28246
+ }
28247
+ });
28248
+ }
28249
+
28250
+ // src/commands/sandbox/providers.ts
28251
+ import chalk34 from "chalk";
28178
28252
  init_errors();
28179
28253
  function registerProvidersCommand(parent, registration) {
28180
28254
  const jsonSource = registration?.jsonSource ?? parent;
28181
28255
  parent.command("providers").description("List sandbox providers for mutagent helix --sandbox-provider").addHelpText("after", `
28182
28256
  Examples:
28183
- ${chalk33.dim("$")} mutagent sandbox providers
28184
- ${chalk33.dim("$")} mutagent sandbox providers --json
28257
+ ${chalk34.dim("$")} mutagent sandbox providers
28258
+ ${chalk34.dim("$")} mutagent sandbox providers --json
28185
28259
 
28186
28260
  A sandbox provider is where a sandbox runs (for example docker or agentcore). It is not an
28187
28261
  LLM provider (\`mutagent providers\`) and not an Environment (\`mutagent env\`).
@@ -28202,7 +28276,7 @@ AI Agent Directive:
28202
28276
  return;
28203
28277
  }
28204
28278
  if (list.names.length === 0) {
28205
- console.log(chalk33.gray("No sandbox providers configured on this backend."));
28279
+ console.log(chalk34.gray("No sandbox providers configured on this backend."));
28206
28280
  return;
28207
28281
  }
28208
28282
  output.output(list.names.map((name) => ({ name, default: name === list.default ? "yes" : "" })));
@@ -28215,9 +28289,9 @@ function registerPreflightCommand(parent, registration) {
28215
28289
  const jsonSource = registration?.jsonSource ?? parent;
28216
28290
  parent.command("preflight").description("Check whether a sandbox provider can run a definition, without creating anything").requiredOption("--image <ref>", "Image reference (repository:tag or @digest)").option("--arch <arch>", "Image architecture: x86_64 | arm64 (default: this host's)").option("--name <name>", "Definition name (default: derived from the image reference)").option("--provider <name>", "Sandbox provider to check against (default: the server's)").option("--env <name>", "Workspace Environment the definition would load").option("--egress <policy>", "Outbound network: deny | allowlist | allow (default: deny)").option("--egress-allow <rule>", "domain:, port: or cidr: rule for --egress allowlist (repeatable)", (value2, previous) => [...previous, value2], []).addHelpText("after", `
28217
28291
  Examples:
28218
- ${chalk33.dim("$")} mutagent sandbox preflight --image alpine:3.20
28219
- ${chalk33.dim("$")} mutagent sandbox preflight --image alpine:3.20 --provider agentcore --json
28220
- ${chalk33.dim("$")} mutagent sandbox preflight --image <ref> --egress allowlist --egress-allow domain:api.anthropic.com
28292
+ ${chalk34.dim("$")} mutagent sandbox preflight --image alpine:3.20
28293
+ ${chalk34.dim("$")} mutagent sandbox preflight --image alpine:3.20 --provider agentcore --json
28294
+ ${chalk34.dim("$")} mutagent sandbox preflight --image <ref> --egress allowlist --egress-allow domain:api.anthropic.com
28221
28295
 
28222
28296
  Takes the same flags as spawn and checks the definition spawn would send. Every
28223
28297
  violation is listed. An incompatible definition exits 0 with compatible: false;
@@ -28246,7 +28320,7 @@ AI Agent Directive:
28246
28320
  output.success(`${definition.name} is compatible with ${verdict.provider}`);
28247
28321
  return;
28248
28322
  }
28249
- console.log(chalk33.yellow(`${definition.name} is NOT compatible with ${verdict.provider}:`));
28323
+ console.log(chalk34.yellow(`${definition.name} is NOT compatible with ${verdict.provider}:`));
28250
28324
  for (const violation of verdict.violations)
28251
28325
  console.log(` - ${violation}`);
28252
28326
  } catch (error3) {
@@ -28256,14 +28330,14 @@ AI Agent Directive:
28256
28330
  }
28257
28331
 
28258
28332
  // src/commands/sandbox/inventory.ts
28259
- import chalk34 from "chalk";
28333
+ import chalk35 from "chalk";
28260
28334
  init_errors();
28261
28335
  function registerLsCommand(parent, registration) {
28262
28336
  const jsonSource = registration?.jsonSource ?? parent;
28263
28337
  parent.command("ls").description("List the workspace's live sandboxes").addHelpText("after", `
28264
28338
  Examples:
28265
- ${chalk34.dim("$")} mutagent sandbox ls
28266
- ${chalk34.dim("$")} mutagent sandbox ls --json
28339
+ ${chalk35.dim("$")} mutagent sandbox ls
28340
+ ${chalk35.dim("$")} mutagent sandbox ls --json
28267
28341
 
28268
28342
  Lists the sandboxes in the configured workspace
28269
28343
  (mutagent workspaces use <name>).
@@ -28285,7 +28359,7 @@ AI Agent Directive:
28285
28359
  return;
28286
28360
  }
28287
28361
  if (sandboxes.length === 0) {
28288
- console.log(chalk34.gray("No sandboxes running."));
28362
+ console.log(chalk35.gray("No sandboxes running."));
28289
28363
  console.log("");
28290
28364
  console.log(" Start one: mutagent sandbox spawn --image <ref>");
28291
28365
  return;
@@ -28310,8 +28384,8 @@ function registerPresetsCommand(parent, registration) {
28310
28384
  const jsonSource = registration?.jsonSource ?? parent;
28311
28385
  parent.command("presets").description("List presets for mutagent helix --preset").addHelpText("after", `
28312
28386
  Examples:
28313
- ${chalk34.dim("$")} mutagent sandbox presets
28314
- ${chalk34.dim("$")} mutagent sandbox presets --json
28387
+ ${chalk35.dim("$")} mutagent sandbox presets
28388
+ ${chalk35.dim("$")} mutagent sandbox presets --json
28315
28389
 
28316
28390
  A preset is a named sandbox definition kept on the server. \`mutagent helix --preset <name>\`
28317
28391
  and \`mutagent sandbox exec --preset <name>\` use it. Image references are not shown.
@@ -28331,7 +28405,7 @@ AI Agent Directive:
28331
28405
  return;
28332
28406
  }
28333
28407
  if (presets.length === 0) {
28334
- console.log(chalk34.gray("No presets configured on this backend."));
28408
+ console.log(chalk35.gray("No presets configured on this backend."));
28335
28409
  console.log("");
28336
28410
  console.log(" Spawn with an explicit image: mutagent sandbox spawn --image <ref>");
28337
28411
  return;
@@ -28352,8 +28426,8 @@ function registerRmCommand(parent, registration) {
28352
28426
  const jsonSource = registration?.jsonSource ?? parent;
28353
28427
  parent.command("rm").description("Destroy a sandbox now").argument("<id>", "Sandbox ID").option("-f, --force", "Confirm (required unless --json)").addHelpText("after", `
28354
28428
  Examples:
28355
- ${chalk34.dim("$")} mutagent sandbox rm sbx_123 --force
28356
- ${chalk34.dim("$")} mutagent sandbox rm sbx_123 --json
28429
+ ${chalk35.dim("$")} mutagent sandbox rm sbx_123 --force
28430
+ ${chalk35.dim("$")} mutagent sandbox rm sbx_123 --json
28357
28431
 
28358
28432
  Ends every session in the sandbox. The server first tries to capture a checkpoint,
28359
28433
  so a Helix session can be rebuilt with \`mutagent helix session restore <reference>\`.
@@ -28394,8 +28468,8 @@ function registerTracesCommand(parent, registration) {
28394
28468
  const jsonSource = registration?.jsonSource ?? parent;
28395
28469
  parent.command("traces").description("Show the spans recorded for a sandbox").argument("<id>", "Sandbox ID").addHelpText("after", `
28396
28470
  Examples:
28397
- ${chalk34.dim("$")} mutagent sandbox traces sbx_123
28398
- ${chalk34.dim("$")} mutagent sandbox traces sbx_123 --json
28471
+ ${chalk35.dim("$")} mutagent sandbox traces sbx_123
28472
+ ${chalk35.dim("$")} mutagent sandbox traces sbx_123 --json
28399
28473
 
28400
28474
  An empty list means no spans were recorded; telemetry must be configured on the
28401
28475
  server for spans to exist.
@@ -28415,7 +28489,7 @@ AI Agent Directive:
28415
28489
  return;
28416
28490
  }
28417
28491
  if (spans.length === 0) {
28418
- console.log(chalk34.gray(`No spans captured for sandbox ${id}.`));
28492
+ console.log(chalk35.gray(`No spans captured for sandbox ${id}.`));
28419
28493
  return;
28420
28494
  }
28421
28495
  output.output(spans.map((span) => {
@@ -28436,8 +28510,8 @@ function registerStatusCommand(parent, registration) {
28436
28510
  const jsonSource = registration?.jsonSource ?? parent;
28437
28511
  parent.command("status").description("Print one sandbox's state").argument("<id>", "Sandbox ID").addHelpText("after", `
28438
28512
  Examples:
28439
- ${chalk34.dim("$")} mutagent sandbox status sbx_123
28440
- ${chalk34.dim("$")} mutagent sandbox status sbx_123 --json
28513
+ ${chalk35.dim("$")} mutagent sandbox status sbx_123
28514
+ ${chalk35.dim("$")} mutagent sandbox status sbx_123 --json
28441
28515
 
28442
28516
  States: pending, starting, running, paused, stopping, stopped, failed.
28443
28517
  For sandbox provider, arch and creation time use \`mutagent sandbox ls --json\`.
@@ -28466,21 +28540,22 @@ AI Agent Directive:
28466
28540
  function createSandboxCommand() {
28467
28541
  const sandbox = new Command16("sandbox").description("Internal: sandbox management. Everyday use goes through `mutagent helix`.").addHelpText("after", `
28468
28542
  Examples:
28469
- ${chalk35.dim("$")} mutagent sandbox presets ${chalk35.dim("Presets `mutagent helix --preset` can name")}
28470
- ${chalk35.dim("$")} mutagent sandbox providers ${chalk35.dim("Sandbox providers `mutagent helix --sandbox-provider` can name")}
28471
- ${chalk35.dim("$")} mutagent sandbox preflight --image alpine:3.20 ${chalk35.dim("Would this definition run?")}
28472
- ${chalk35.dim("$")} mutagent sandbox spawn --image alpine:3.20 --detach
28473
- ${chalk35.dim("$")} mutagent sandbox ls
28474
- ${chalk35.dim("$")} mutagent sandbox status sbx_1
28475
- ${chalk35.dim("$")} mutagent sandbox exec --sandbox sbx_1 -- bun test
28476
- ${chalk35.dim("$")} mutagent sandbox attach sbx_1 --since 412
28477
- ${chalk35.dim("$")} mutagent sandbox traces sbx_1
28478
- ${chalk35.dim("$")} mutagent sandbox rm sbx_1 --force
28543
+ ${chalk36.dim("$")} mutagent sandbox access --json ${chalk36.dim("Can this account create cloud sandboxes?")}
28544
+ ${chalk36.dim("$")} mutagent sandbox presets ${chalk36.dim("Presets `mutagent helix --preset` can name")}
28545
+ ${chalk36.dim("$")} mutagent sandbox providers ${chalk36.dim("Sandbox providers `mutagent helix --sandbox-provider` can name")}
28546
+ ${chalk36.dim("$")} mutagent sandbox preflight --image alpine:3.20 ${chalk36.dim("Would this definition run?")}
28547
+ ${chalk36.dim("$")} mutagent sandbox spawn --image alpine:3.20 --detach
28548
+ ${chalk36.dim("$")} mutagent sandbox ls
28549
+ ${chalk36.dim("$")} mutagent sandbox status sbx_1
28550
+ ${chalk36.dim("$")} mutagent sandbox exec --sandbox sbx_1 -- bun test
28551
+ ${chalk36.dim("$")} mutagent sandbox attach sbx_1 --since 412
28552
+ ${chalk36.dim("$")} mutagent sandbox traces sbx_1
28553
+ ${chalk36.dim("$")} mutagent sandbox rm sbx_1 --force
28479
28554
 
28480
28555
  Single command vs kept sandbox:
28481
- ${chalk35.bold("exec")} without --sandbox starts a fresh sandbox from a preset, runs one command
28482
- and removes the sandbox. ${chalk35.bold("spawn")} starts a sandbox from an image and leaves it running
28483
- for ${chalk35.bold("attach")} and ${chalk35.bold("exec --sandbox")}.
28556
+ ${chalk36.bold("exec")} without --sandbox starts a fresh sandbox from a preset, runs one command
28557
+ and removes the sandbox. ${chalk36.bold("spawn")} starts a sandbox from an image and leaves it running
28558
+ for ${chalk36.bold("attach")} and ${chalk36.bold("exec --sandbox")}.
28484
28559
 
28485
28560
  Lifecycle:
28486
28561
  Ctrl-C, a dropped connection or a closed terminal detaches; the sandbox keeps running.
@@ -28510,12 +28585,13 @@ Requires a workspace: mutagent workspaces use <name> (or --workspace for one com
28510
28585
  registerExecCommand(sandbox);
28511
28586
  registerAttachCommand(sandbox);
28512
28587
  registerTracesCommand(sandbox);
28588
+ registerAccessCommand(sandbox);
28513
28589
  return sandbox;
28514
28590
  }
28515
28591
 
28516
28592
  // src/commands/env/index.ts
28517
28593
  import { Command as Command17 } from "commander";
28518
- import chalk36 from "chalk";
28594
+ import chalk37 from "chalk";
28519
28595
  import { readFileSync as readFileSync13 } from "fs";
28520
28596
  init_errors();
28521
28597
 
@@ -28617,13 +28693,13 @@ function describeWithoutValue(arg) {
28617
28693
  function createEnvCommand() {
28618
28694
  const env = new Command17("env").description("Workspace Environments: the variables and secrets an agent’s tools need").addHelpText("after", `
28619
28695
  Examples:
28620
- ${chalk36.dim("$")} mutagent env ls
28621
- ${chalk36.dim("$")} mutagent env set demo GREETING=hello --secret GITHUB_TOKEN=ghp_…
28622
- ${chalk36.dim("$")} mutagent env set staging --from-file .env.staging --secrets-from-file .env.staging.secrets
28623
- ${chalk36.dim("$")} mutagent env show demo
28624
- ${chalk36.dim("$")} mutagent env unset demo GREETING
28625
- ${chalk36.dim("$")} mutagent env rm demo --force
28626
- ${chalk36.dim("$")} mutagent helix --env demo -p "check the deploy" ${chalk36.dim("Load it into a Helix cloud run")}
28696
+ ${chalk37.dim("$")} mutagent env ls
28697
+ ${chalk37.dim("$")} mutagent env set demo GREETING=hello --secret GITHUB_TOKEN=ghp_…
28698
+ ${chalk37.dim("$")} mutagent env set staging --from-file .env.staging --secrets-from-file .env.staging.secrets
28699
+ ${chalk37.dim("$")} mutagent env show demo
28700
+ ${chalk37.dim("$")} mutagent env unset demo GREETING
28701
+ ${chalk37.dim("$")} mutagent env rm demo --force
28702
+ ${chalk37.dim("$")} mutagent helix --env demo -p "check the deploy" ${chalk37.dim("Load it into a Helix cloud run")}
28627
28703
 
28628
28704
  An Environment holds the variables and secrets an agent's tools need: a GitHub token,
28629
28705
  a Langfuse key, a database URL. LLM provider keys belong in \`mutagent providers\`; a
@@ -28653,8 +28729,8 @@ AI Agent Directive:
28653
28729
  function registerLs(parent) {
28654
28730
  parent.command("ls").description("List the workspace’s Environments").addHelpText("after", `
28655
28731
  Examples:
28656
- ${chalk36.dim("$")} mutagent env ls
28657
- ${chalk36.dim("$")} mutagent env ls --json
28732
+ ${chalk37.dim("$")} mutagent env ls
28733
+ ${chalk37.dim("$")} mutagent env ls --json
28658
28734
 
28659
28735
  An empty list means the workspace has no Environments yet.
28660
28736
 
@@ -28671,7 +28747,7 @@ AI Agent Directive:
28671
28747
  return;
28672
28748
  }
28673
28749
  if (environments.length === 0) {
28674
- console.log(chalk36.gray("No Environments in this workspace. Create one: mutagent env set <name> KEY=VALUE"));
28750
+ console.log(chalk37.gray("No Environments in this workspace. Create one: mutagent env set <name> KEY=VALUE"));
28675
28751
  return;
28676
28752
  }
28677
28753
  output.output(environments.map((e) => ({
@@ -28688,8 +28764,8 @@ AI Agent Directive:
28688
28764
  function registerShow(parent) {
28689
28765
  parent.command("show").description("Entry names and fingerprints of one Environment — never a value").argument("<name>", "Environment name").addHelpText("after", `
28690
28766
  Examples:
28691
- ${chalk36.dim("$")} mutagent env show demo
28692
- ${chalk36.dim("$")} mutagent env show demo --json
28767
+ ${chalk37.dim("$")} mutagent env show demo
28768
+ ${chalk37.dim("$")} mutagent env show demo --json
28693
28769
 
28694
28770
  Each line is NAME KIND FINGERPRINT. The fingerprint is sha256(value)[:8]; compare
28695
28771
  it with your own (printf %s "$VALUE" | shasum -a 256 | cut -c1-8) to check what is
@@ -28714,10 +28790,10 @@ AI Agent Directive:
28714
28790
  function registerSet(parent) {
28715
28791
  parent.command("set").description("Set variables (and --secret secrets) on an Environment; creates it when absent").argument("<name>", "Environment name").argument("[assignments...]", "KEY=VALUE variables (non-secret)").option("-s, --secret <KEY=VALUE...>", "Secret entries — encrypted at rest, never returned").option("--from-file <path>", "Read variables from a .env file (KEY=VALUE lines); argv wins on the same name").option("--secrets-from-file <path>", "Read secrets from a .env file").option("--replace", "Replace the whole Environment instead of merging into it").option("--allow-provider-key", "Permit a variable named like an LLM provider key").addHelpText("after", `
28716
28792
  Examples:
28717
- ${chalk36.dim("$")} mutagent env set demo GREETING=hello
28718
- ${chalk36.dim("$")} mutagent env set demo GREETING=hello --secret TOKEN=abc123
28719
- ${chalk36.dim("$")} mutagent env set staging --from-file .env.staging
28720
- ${chalk36.dim("$")} mutagent env set staging --replace --from-file .env.staging ${chalk36.dim("Drop everything not in the file")}
28793
+ ${chalk37.dim("$")} mutagent env set demo GREETING=hello
28794
+ ${chalk37.dim("$")} mutagent env set demo GREETING=hello --secret TOKEN=abc123
28795
+ ${chalk37.dim("$")} mutagent env set staging --from-file .env.staging
28796
+ ${chalk37.dim("$")} mutagent env set staging --replace --from-file .env.staging ${chalk37.dim("Drop everything not in the file")}
28721
28797
 
28722
28798
  Entries you name are set and the rest stay; the Environment is created if missing.
28723
28799
  --replace removes every entry you do not name, secrets included.
@@ -28725,7 +28801,7 @@ Positional KEY=VALUE and --from-file are variables; --secret and --secrets-from-
28725
28801
  secrets (encrypted at rest, never returned). Both are set as environment variables in
28726
28802
  the sandbox. A name cannot be both.
28727
28803
  --secret takes every KEY=VALUE after it, so put variables first:
28728
- ${chalk36.dim("$")} mutagent env set demo A=1 --secret TOKEN=x
28804
+ ${chalk37.dim("$")} mutagent env set demo A=1 --secret TOKEN=x
28729
28805
  A value may contain '=': TOKEN=a=b stores "a=b".
28730
28806
  Names: A-Z, 0-9 and _, not starting with a digit. An invalid name exits 2. A name that
28731
28807
  looks like an LLM provider key is refused by the server (exit 1) unless
@@ -28764,8 +28840,8 @@ AI Agent Directive:
28764
28840
  function registerUnset(parent) {
28765
28841
  parent.command("unset").description("Remove entries from an Environment").argument("<name>", "Environment name").argument("<keys...>", "Entry names to remove").option("-s, --secret", "The names are secrets (default: try both variables and secrets)").addHelpText("after", `
28766
28842
  Examples:
28767
- ${chalk36.dim("$")} mutagent env unset demo GREETING
28768
- ${chalk36.dim("$")} mutagent env unset demo TOKEN OTHER_TOKEN
28843
+ ${chalk37.dim("$")} mutagent env unset demo GREETING
28844
+ ${chalk37.dim("$")} mutagent env unset demo TOKEN OTHER_TOKEN
28769
28845
 
28770
28846
  A name is removed wherever it is, variable or secret. Unsetting a name that is not
28771
28847
  there succeeds.
@@ -28795,8 +28871,8 @@ AI Agent Directive:
28795
28871
  function registerRm(parent) {
28796
28872
  parent.command("rm").description("Delete an Environment and its secrets").argument("<name>", "Environment name").option("-f, --force", "Confirm (required unless --json)").addHelpText("after", `
28797
28873
  Examples:
28798
- ${chalk36.dim("$")} mutagent env rm demo --force
28799
- ${chalk36.dim("$")} mutagent env rm demo --json
28874
+ ${chalk37.dim("$")} mutagent env rm demo --force
28875
+ ${chalk37.dim("$")} mutagent env rm demo --json
28800
28876
 
28801
28877
  Deletes the Environment and its encrypted secrets. Sandboxes already running keep the
28802
28878
  values they were given; the next run naming this Environment fails.
@@ -28849,7 +28925,7 @@ function printEnvironment(environment, output, isJson) {
28849
28925
  output.output({ success: true, environment });
28850
28926
  return;
28851
28927
  }
28852
- console.log(`${chalk36.bold(environment.name)} ${chalk36.dim(environment.updatedAt ?? "")}`);
28928
+ console.log(`${chalk37.bold(environment.name)} ${chalk37.dim(environment.updatedAt ?? "")}`);
28853
28929
  printEntries(environment);
28854
28930
  }
28855
28931
  function printEntries(environment) {
@@ -28858,12 +28934,12 @@ function printEntries(environment) {
28858
28934
  ...environment.secrets.map((s) => ({ name: s.name, kind: "secret", fingerprint: s.fingerprint }))
28859
28935
  ];
28860
28936
  if (rows.length === 0) {
28861
- console.log(chalk36.gray(" (no entries)"));
28937
+ console.log(chalk37.gray(" (no entries)"));
28862
28938
  return;
28863
28939
  }
28864
28940
  const width = Math.max(...rows.map((r) => r.name.length));
28865
28941
  for (const row of rows) {
28866
- console.log(` ${row.name.padEnd(width)} ${row.kind === "secret" ? chalk36.yellow("secret") : chalk36.dim("var ")} ${chalk36.dim(row.fingerprint)}`);
28942
+ console.log(` ${row.name.padEnd(width)} ${row.kind === "secret" ? chalk37.yellow("secret") : chalk37.dim("var ")} ${chalk37.dim(row.fingerprint)}`);
28867
28943
  }
28868
28944
  }
28869
28945
 
@@ -29436,50 +29512,50 @@ program.name("mutagent").description(`Mutagent CLI - command-line client for the
29436
29512
  });
29437
29513
  program.addHelpText("beforeAll", () => renderBanner());
29438
29514
  program.addHelpText("after", `
29439
- ${chalk37.yellow("Get started:")}
29440
- mutagent login ${chalk37.dim("Sign in (browser or API key)")}
29441
- mutagent providers mirror ${chalk37.dim("Copy local Helix LLM provider keys into the workspace")}
29442
- mutagent helix -p "<task>" ${chalk37.dim("Run Helix in the cloud")}
29443
- mutagent install helix ${chalk37.dim("Install the standalone Helix binary on this machine")}
29444
-
29445
- ${chalk37.yellow("Managed agents:")}
29446
- mutagent agent deploy <agent.md> ${chalk37.dim("Check, upload and activate an agent.md folder (--env names the slot)")}
29447
- mutagent helix agent @<slug> -p "<task>" ${chalk37.dim("Run a managed agent in the cloud")}
29448
- mutagent agent --help ${chalk37.dim("check, pack, run, deploy, activate, list, inspect, retire")}
29449
-
29450
- ${chalk37.yellow("Workspace:")}
29451
- mutagent workspaces use <name> ${chalk37.dim("Choose the workspace every later command works in")}
29452
- mutagent workspaces current ${chalk37.dim("The key's scope, organization and the verified workspace")}
29453
- mutagent workspaces list ${chalk37.dim("Your workspaces in the key's organization")}
29454
- --workspace <name|id> ${chalk37.dim("One command in another workspace (then MUTAGENT_WORKSPACE_ID, then the selection)")}
29455
- mutagent login --org <slug> ${chalk37.dim("Sign in for another organization")}
29456
- mutagent providers list ${chalk37.dim("LLM providers in the workspace")}
29457
- mutagent helix models ${chalk37.dim("Models Helix can use in the cloud, and the workspace default model")}
29458
- mutagent env ls ${chalk37.dim("Environments: variables and secrets for tools")}
29459
- mutagent usage ${chalk37.dim("Count the workspace's LLM providers and your workspaces")}
29460
-
29461
- ${chalk37.yellow("Automation:")}
29462
- MUTAGENT_API_KEY=mt_... ${chalk37.dim("Sign in without a browser (or --api-key <key>)")}
29463
- --json ${chalk37.dim("Structured output")}
29464
- --non-interactive ${chalk37.dim("No sign-in method or consent prompts (also when CI=true or stdin is not a terminal); a first sign-in in a terminal ends with a menu unless --json")}
29465
- -v, --version ${chalk37.dim("CLI version (only before a subcommand)")}
29466
-
29467
- ${chalk37.yellow("Report a problem:")}
29515
+ ${chalk38.yellow("Get started:")}
29516
+ mutagent login ${chalk38.dim("Sign in (browser or API key)")}
29517
+ mutagent providers mirror ${chalk38.dim("Copy local Helix LLM provider keys into the workspace")}
29518
+ mutagent helix -p "<task>" ${chalk38.dim("Run Helix in the cloud")}
29519
+ mutagent install helix ${chalk38.dim("Install the standalone Helix binary on this machine")}
29520
+
29521
+ ${chalk38.yellow("Managed agents:")}
29522
+ mutagent agent deploy <agent.md> ${chalk38.dim("Check, upload and activate an agent.md folder (--env names the slot)")}
29523
+ mutagent helix agent @<slug> -p "<task>" ${chalk38.dim("Run a managed agent in the cloud")}
29524
+ mutagent agent --help ${chalk38.dim("check, pack, run, deploy, activate, list, inspect, retire")}
29525
+
29526
+ ${chalk38.yellow("Workspace:")}
29527
+ mutagent workspaces use <name> ${chalk38.dim("Choose the workspace every later command works in")}
29528
+ mutagent workspaces current ${chalk38.dim("The key's scope, organization and the verified workspace")}
29529
+ mutagent workspaces list ${chalk38.dim("Your workspaces in the key's organization")}
29530
+ --workspace <name|id> ${chalk38.dim("One command in another workspace (then MUTAGENT_WORKSPACE_ID, then the selection)")}
29531
+ mutagent login --org <slug> ${chalk38.dim("Sign in for another organization")}
29532
+ mutagent providers list ${chalk38.dim("LLM providers in the workspace")}
29533
+ mutagent helix models ${chalk38.dim("Models Helix can use in the cloud, and the workspace default model")}
29534
+ mutagent env ls ${chalk38.dim("Environments: variables and secrets for tools")}
29535
+ mutagent usage ${chalk38.dim("Count the workspace's LLM providers and your workspaces")}
29536
+
29537
+ ${chalk38.yellow("Automation:")}
29538
+ MUTAGENT_API_KEY=mt_... ${chalk38.dim("Sign in without a browser (or --api-key <key>)")}
29539
+ --json ${chalk38.dim("Structured output")}
29540
+ --non-interactive ${chalk38.dim("No sign-in method or consent prompts (also when CI=true or stdin is not a terminal); a first sign-in in a terminal ends with a menu unless --json")}
29541
+ -v, --version ${chalk38.dim("CLI version (only before a subcommand)")}
29542
+
29543
+ ${chalk38.yellow("Report a problem:")}
29468
29544
  mutagent feedback send "<what happened>" --category cli
29469
- ${chalk37.dim("--category accepts: cli | helix | stage:<spec|build|evaluate|diagnose|optimize>")}
29545
+ ${chalk38.dim("--category accepts: cli | helix | stage:<spec|build|evaluate|diagnose|optimize>")}
29470
29546
 
29471
- ${chalk37.dim("For CLI usage guidance for AI agents, see the Skill at")}
29472
- ${chalk37.cyan(".claude/skills/mutagent-cli/SKILL.md")}
29547
+ ${chalk38.dim("For CLI usage guidance for AI agents, see the Skill at")}
29548
+ ${chalk38.cyan(".claude/skills/mutagent-cli/SKILL.md")}
29473
29549
 
29474
- ${chalk37.yellow("Directive System:")}
29550
+ ${chalk38.yellow("Directive System:")}
29475
29551
  A --json response may include:
29476
- ${chalk37.bold("_directive.renderedCard")} A status card: copy it into your chat reply verbatim before running another command
29477
- ${chalk37.bold("_directive.instruction")} What to do next
29478
- ${chalk37.bold("_directive.next")} Suggested follow-up commands
29479
- ${chalk37.bold("_links")} Dashboard and API URLs
29480
- ${chalk37.bold("_compat")} cliVersion, skillVersion, skillMinCliVersion
29552
+ ${chalk38.bold("_directive.renderedCard")} A status card: copy it into your chat reply verbatim before running another command
29553
+ ${chalk38.bold("_directive.instruction")} What to do next
29554
+ ${chalk38.bold("_directive.next")} Suggested follow-up commands
29555
+ ${chalk38.bold("_links")} Dashboard and API URLs
29556
+ ${chalk38.bold("_compat")} cliVersion, skillVersion, skillMinCliVersion
29481
29557
 
29482
- ${chalk37.yellow("AI Agent Rules (MANDATORY for coding agents):")}
29558
+ ${chalk38.yellow("AI Agent Rules (MANDATORY for coding agents):")}
29483
29559
  1. Sign in: with MUTAGENT_API_KEY set, run mutagent login --json. To help a user sign in,
29484
29560
  run mutagent login --browser --json, show the printed URL to the user verbatim, and
29485
29561
  wait: the CLI polls for up to 5 minutes.
@@ -29490,9 +29566,9 @@ ${chalk37.yellow("AI Agent Rules (MANDATORY for coding agents):")}
29490
29566
  5. After mutagent init, check the workspace: mutagent workspaces list --json
29491
29567
  6. Ask the user through your own question tool. With --json only mutagent login can prompt, in a terminal; pass --browser or set MUTAGENT_API_KEY.
29492
29568
  ${!hasCredentials() ? `
29493
- ` + chalk37.yellow(" Warning: Not authenticated. Run: mutagent login") + `
29569
+ ` + chalk38.yellow(" Warning: Not authenticated. Run: mutagent login") + `
29494
29570
  ` : ""}${!hasRcConfig() ? `
29495
- ` + chalk37.green(" Get started: mutagent init") + `
29571
+ ` + chalk38.green(" Get started: mutagent init") + `
29496
29572
  ` : ""}`);
29497
29573
  var rawArgs = process.argv.slice(2);
29498
29574
  if (isGlobalVersionFlag(rawArgs)) {
@@ -29573,4 +29649,4 @@ if (isAgentInvocation(rawArgs)) {
29573
29649
  program.parse(argvForCommander, { from: "user" });
29574
29650
  }
29575
29651
 
29576
- //# debugId=22EA0CB4BCE602F064756E2164756E21
29652
+ //# debugId=6107DF45DB32A14A64756E2164756E21
package/dist/index.js CHANGED
@@ -621,6 +621,7 @@ __export(exports_organization_scope, {
621
621
  fetchOrganizations: () => fetchOrganizations,
622
622
  fetchKeySelf: () => fetchKeySelf,
623
623
  envKeyHasNoSelection: () => envKeyHasNoSelection,
624
+ endpointOf: () => endpointOf,
624
625
  deadKeyError: () => deadKeyError,
625
626
  configTenancyHeaders: () => configTenancyHeaders,
626
627
  TenancyError: () => TenancyError,
@@ -1691,4 +1692,4 @@ export {
1691
1692
  ApiError
1692
1693
  };
1693
1694
 
1694
- //# debugId=6C0EFE359421B56964756E2164756E21
1695
+ //# debugId=73D846829EED9BB964756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutagent/cli",
3
- "version": "0.1.381",
3
+ "version": "0.1.383",
4
4
  "description": "Bun-native CLI for the MutagenT AI platform - auth, provider config, and lifecycle-tool installer for AI-native workflows",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@inquirer/prompts": "^8.7.2",
45
- "@mutagent/sdk": "0.6.14",
45
+ "@mutagent/sdk": "0.6.15",
46
46
  "chalk": "^5.3.0",
47
47
  "commander": "^12.1.0",
48
48
  "cosmiconfig": "^9.0.0",