@mutagent/cli 0.1.351 → 0.1.353

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
@@ -16783,7 +16783,7 @@ var init_sdk_debug = __esm(() => {
16783
16783
  });
16784
16784
 
16785
16785
  // src/lib/sdk-mappers.ts
16786
- import { Provider as SDKProviderEnum } from "@mutagent/sdk/models";
16786
+ import { LlmProviderType as SDKProviderEnum } from "@mutagent/sdk/models";
16787
16787
  function isProviderType(value2) {
16788
16788
  return PROVIDER_TYPES.includes(value2);
16789
16789
  }
@@ -17096,7 +17096,7 @@ class SDKClientWrapper {
17096
17096
  }
17097
17097
  async listProviders(filters) {
17098
17098
  try {
17099
- const response = await this.sdk.providerConfigs.listProviders({
17099
+ const response = await this.sdk.llmProviders.listProviderConfigs({
17100
17100
  provider: filters?.type,
17101
17101
  includeInactive: true
17102
17102
  });
@@ -17114,7 +17114,7 @@ class SDKClientWrapper {
17114
17114
  }
17115
17115
  async getProvider(id) {
17116
17116
  try {
17117
- const response = await this.sdk.providerConfigs.getProvider({
17117
+ const response = await this.sdk.llmProviders.getProviderConfig({
17118
17118
  id
17119
17119
  });
17120
17120
  return toProvider(response);
@@ -17190,7 +17190,7 @@ class SDKClientWrapper {
17190
17190
  }
17191
17191
  async testProvider(id) {
17192
17192
  try {
17193
- const response = await this.sdk.providerConfigs.testProvider({
17193
+ const response = await this.sdk.llmProviders.testProviderConfig({
17194
17194
  id
17195
17195
  });
17196
17196
  return toProviderTestResult(response);
@@ -17236,7 +17236,7 @@ class SDKClientWrapper {
17236
17236
  });
17237
17237
  return scrubKnownSuccessDeep({ ...response2, workspaceId });
17238
17238
  }
17239
- const response = await this.sdk.providerConfigs.updateProvider({
17239
+ const response = await this.sdk.llmProviders.updateProviderConfig({
17240
17240
  id,
17241
17241
  body: {
17242
17242
  name: data.name,
@@ -17255,7 +17255,7 @@ class SDKClientWrapper {
17255
17255
  async deleteProvider(id) {
17256
17256
  const workspaceId = this.requireUnambiguousWorkspace();
17257
17257
  try {
17258
- await this.sdk.providerConfigs.deleteProvider({ id });
17258
+ await this.sdk.llmProviders.deleteProviderConfig({ id });
17259
17259
  return { workspaceId };
17260
17260
  } catch (error3) {
17261
17261
  this.handleError(error3);
@@ -17403,7 +17403,7 @@ function sessionView(row) {
17403
17403
  return { ...row, revision: nullableInteger(row.revision) };
17404
17404
  }
17405
17405
  function bindAgentDeploymentSDK(sdk, endpoint, workspaceId) {
17406
- const client = sdk.helixAgentDeployments;
17406
+ const client = sdk.managedAgents;
17407
17407
  return {
17408
17408
  endpoint,
17409
17409
  workspaceId,
@@ -17540,8 +17540,8 @@ Run a managed agent with: mutagent helix agent @slug[:vN|:latest] [--env X] -p "
17540
17540
 
17541
17541
  The compiler needs Bun 1.3.14 (on PATH, or MUTAGENT_BUN_BIN). agent run needs a
17542
17542
  local Helix binary (mutagent install helix puts one at ~/.mutagent/bin/helix;
17543
- MUTAGENT_HELIX_BIN selects another) and the LLM provider key for
17544
- model on this machine.
17543
+ MUTAGENT_HELIX_BIN selects another) and, on this machine, the key of the
17544
+ LLM provider that model names.
17545
17545
 
17546
17546
  JSON: --json prints one result object on stdout. Revisions are numbers in JSON
17547
17547
  and vN in messages.
@@ -17565,7 +17565,7 @@ uploaded. The archive must be outside the agent folder; an existing file needs
17565
17565
  --force.
17566
17566
  Example: mutagent agent pack invoice/agent.md --output invoice.tgz --json`,
17567
17567
  run: `Compiles the folder and runs the task with the local Helix binary, in a
17568
- temporary copy of the package on this machine; it is not isolated in a box. It
17568
+ temporary copy of the package on this machine; it is not isolated in a sandbox. It
17569
17569
  creates nothing in the workspace. The task is the positional text (or the words
17570
17570
  after --). A slug is refused: a managed agent runs with mutagent helix agent @slug.
17571
17571
  Example: mutagent agent run invoice/agent.md "Price three widget units."`,
@@ -19231,7 +19231,7 @@ init_sdk_client();
19231
19231
  import { Command as Command6 } from "commander";
19232
19232
  import chalk12 from "chalk";
19233
19233
  init_errors();
19234
- import { Provider as ProviderCatalogId } from "@mutagent/sdk/models";
19234
+ import { LlmProviderType as ProviderCatalogId } from "@mutagent/sdk/models";
19235
19235
 
19236
19236
  // src/commands/providers/add.ts
19237
19237
  init_sdk_client();
@@ -19744,7 +19744,7 @@ AI Agent Directive:
19744
19744
  const isGateway = allowedFamilies !== undefined;
19745
19745
  if (options.hostedFamily) {
19746
19746
  if (!isGateway) {
19747
- throw new MutagentError("HOSTED_FAMILY_NOT_APPLICABLE", `'${providerType}' serves its own models, so it has no hosted family.`, `Drop --hosted-family, or pick a gateway provider: ${[...GATEWAY_PROVIDERS].join(", ")}`);
19747
+ throw new MutagentError("HOSTED_FAMILY_NOT_APPLICABLE", `'${providerType}' serves its own models, so it has no hosted family.`, `Drop --hosted-family, or pick a gateway LLM provider: ${[...GATEWAY_PROVIDERS].join(", ")}`);
19748
19748
  }
19749
19749
  if (!allowedFamilies.includes(options.hostedFamily)) {
19750
19750
  throw new MutagentError("INVALID_HOSTED_FAMILY", `'${providerType}' does not host '${options.hostedFamily}'.`, `${providerType} hosts: ${allowedFamilies.join(", ")}`);
@@ -19780,7 +19780,7 @@ AI Agent Directive:
19780
19780
  _directive: directive
19781
19781
  });
19782
19782
  } else {
19783
- output.success(`Provider created: ${created.name}`);
19783
+ output.success(`LLM provider created: ${created.name}`);
19784
19784
  console.log(` ID: ${created.id}`);
19785
19785
  console.log(` Type: ${providerType}`);
19786
19786
  if (options.hostedFamily) {
@@ -19792,7 +19792,7 @@ AI Agent Directive:
19792
19792
  console.log(` Workspace: ${workspaceId}`);
19793
19793
  console.log(` URL: ${providerLink(created.id)}`);
19794
19794
  if (options.setDefault) {
19795
- console.log(chalk8.green(" Set as default provider"));
19795
+ console.log(chalk8.green(" Set as the default LLM provider"));
19796
19796
  }
19797
19797
  console.log("");
19798
19798
  console.log(chalk8.dim("API key is encrypted server-side. Use `providers get` to see masked key."));
@@ -19803,12 +19803,12 @@ AI Agent Directive:
19803
19803
  });
19804
19804
  }
19805
19805
  function buildProviderCreatedDirective(provider, workspaceId) {
19806
- const title = `Provider Created — ${provider.name ?? "Unknown"}`;
19806
+ const title = `LLM provider created: ${provider.name ?? "Unknown"}`;
19807
19807
  const dashboardUrl = providerLink(provider.id);
19808
19808
  const apiUrl = `/api/providers/${String(provider.id)}`;
19809
19809
  const rows = [
19810
19810
  { label: "Name", value: provider.name ?? "Unknown" },
19811
- { label: "Provider ID", value: String(provider.id) },
19811
+ { label: "LLM provider ID", value: String(provider.id) },
19812
19812
  { label: "Workspace", value: workspaceId }
19813
19813
  ];
19814
19814
  const links = [
@@ -19888,7 +19888,7 @@ Only the fields you pass change. An update never sets the workspace default mode
19888
19888
  _directive: directive
19889
19889
  });
19890
19890
  } else {
19891
- output.success(`Provider updated: ${updated.name}`);
19891
+ output.success(`LLM provider updated: ${updated.name}`);
19892
19892
  console.log(` ID: ${updated.id}`);
19893
19893
  if (updated.workspaceId) {
19894
19894
  console.log(` Workspace: ${updated.workspaceId}`);
@@ -19905,11 +19905,11 @@ Only the fields you pass change. An update never sets the workspace default mode
19905
19905
  }
19906
19906
  function buildProviderUpdatedDirective(provider, requestId) {
19907
19907
  const id = provider.id ?? requestId;
19908
- const title = `Provider Updated — ${provider.name ?? String(id)}`;
19908
+ const title = `LLM provider updated: ${provider.name ?? String(id)}`;
19909
19909
  const dashboardUrl = providerLink(id);
19910
19910
  const apiUrl = `/api/providers/${String(id)}`;
19911
19911
  const rows = [
19912
- { label: "Provider ID", value: String(id) },
19912
+ { label: "LLM provider ID", value: String(id) },
19913
19913
  ...provider.name ? [{ label: "Name", value: provider.name }] : []
19914
19914
  ];
19915
19915
  const links = [
@@ -19952,7 +19952,7 @@ AI Agent Directive:
19952
19952
  const output = new OutputFormatter(isJson ? "json" : "table");
19953
19953
  try {
19954
19954
  if (!options.force && !isJson) {
19955
- throw new MutagentError("CONFIRMATION_REQUIRED", `Deleting provider ${id} requires confirmation. ` + "Warning: encrypted API keys are irrecoverable after deletion.", `Run: mutagent providers delete --help
19955
+ throw new MutagentError("CONFIRMATION_REQUIRED", `Deleting LLM provider ${id} requires confirmation. ` + "Warning: encrypted API keys are irrecoverable after deletion.", `Run: mutagent providers delete --help
19956
19956
  ` + `[Agent: Ask the user to confirm via MultiChoice, then pass --force]
19957
19957
  ` + `Use --force to confirm: mutagent providers delete ${id} --force`);
19958
19958
  }
@@ -19972,7 +19972,7 @@ AI Agent Directive:
19972
19972
  });
19973
19973
  echoDirectiveToStderr(directive);
19974
19974
  } else {
19975
- output.success(`Provider ${id} already deleted (idempotent)`);
19975
+ output.success(`LLM provider ${id} already deleted (idempotent)`);
19976
19976
  }
19977
19977
  return;
19978
19978
  }
@@ -19988,7 +19988,7 @@ AI Agent Directive:
19988
19988
  _directive: directive
19989
19989
  });
19990
19990
  } else {
19991
- output.success(`Deleted provider: ${id}`);
19991
+ output.success(`Deleted LLM provider: ${id}`);
19992
19992
  if (deletedFrom) {
19993
19993
  console.log(` Workspace: ${deletedFrom}`);
19994
19994
  }
@@ -20000,9 +20000,9 @@ AI Agent Directive:
20000
20000
  });
20001
20001
  }
20002
20002
  function buildProviderDeletedDirective(id) {
20003
- const title = `Provider Deleted — ${id}`;
20003
+ const title = `LLM provider deleted: ${id}`;
20004
20004
  const settingsUrl = providerSettingsLink();
20005
- const rows = [{ label: "Provider ID", value: id }];
20005
+ const rows = [{ label: "LLM provider ID", value: id }];
20006
20006
  const links = [{ label: "Settings", url: settingsUrl }];
20007
20007
  const next = [`mutagent providers list --json`];
20008
20008
  return {
@@ -20784,7 +20784,7 @@ Plan:`));
20784
20784
  output.output({
20785
20785
  success: failed.length === 0,
20786
20786
  cloudExecution: "not-verified",
20787
- modelRoster: "Explicit lists are authoritative; recognized native identities use the service-pinned catalogue when no list is declared. Other custom providers require declarations.",
20787
+ modelRoster: "Explicit lists are authoritative; recognized native identities use the service-pinned catalogue when no list is declared. Other custom LLM providers require declarations.",
20788
20788
  workspaceId: target,
20789
20789
  endpoint: config.endpoint ?? "https://api.mutagent.io",
20790
20790
  agentDir,
@@ -20825,7 +20825,7 @@ var VALID_PROVIDER_TYPES = Object.values(ProviderCatalogId);
20825
20825
  function validateProviderType(type4) {
20826
20826
  const match = VALID_PROVIDER_TYPES.find((entry) => entry === type4);
20827
20827
  if (!match) {
20828
- throw new MutagentError("INVALID_PROVIDER_TYPE", `Invalid provider type: ${type4}`, `Valid types: ${VALID_PROVIDER_TYPES.join(", ")}`);
20828
+ throw new MutagentError("INVALID_PROVIDER_TYPE", `Invalid LLM provider type: ${type4}`, `Valid types: ${VALID_PROVIDER_TYPES.join(", ")}`);
20829
20829
  }
20830
20830
  return match;
20831
20831
  }
@@ -20903,7 +20903,7 @@ Examples:
20903
20903
  output.output({ ...result, data: withLinks });
20904
20904
  } else {
20905
20905
  if (result.data.length === 0) {
20906
- output.info("No providers configured.");
20906
+ output.info("No LLM providers configured.");
20907
20907
  output.info(`Configure at: ${providerSettingsLink()}`);
20908
20908
  } else {
20909
20909
  const formatted = result.data.map((p) => ({
@@ -20966,7 +20966,7 @@ ${chalk12.dim("Tests the connection and lists the models the LLM provider report
20966
20966
  try {
20967
20967
  const client = await getSDKClient();
20968
20968
  if (!isJson) {
20969
- output.info(`Testing provider ${id}...`);
20969
+ output.info(`Testing LLM provider ${id}...`);
20970
20970
  }
20971
20971
  const result = scrubKnownSuccessDeep(await client.testProvider(id));
20972
20972
  if (isJson) {
@@ -20974,7 +20974,7 @@ ${chalk12.dim("Tests the connection and lists the models the LLM provider report
20974
20974
  } else {
20975
20975
  if (result.success) {
20976
20976
  const latency = typeof result.latencyMs === "number" ? ` (${String(result.latencyMs)}ms)` : "";
20977
- output.success(`Provider test passed${latency}`);
20977
+ output.success(`LLM provider test passed${latency}`);
20978
20978
  console.log(chalk12.green(`Message: ${result.message}`));
20979
20979
  if (result.models && result.models.length > 0) {
20980
20980
  console.log(chalk12.bold(`
@@ -20984,7 +20984,7 @@ Available Models:`));
20984
20984
  });
20985
20985
  }
20986
20986
  } else {
20987
- output.error(`Provider test failed: ${result.message}`);
20987
+ output.error(`LLM provider test failed: ${result.message}`);
20988
20988
  if (result.error) {
20989
20989
  console.log(chalk12.red(`Error: ${result.error}`));
20990
20990
  }
@@ -23868,13 +23868,13 @@ var TRANSPORT_TABLE = [
23868
23868
  takesValue: false,
23869
23869
  class: "cross",
23870
23870
  via: "args",
23871
- note: "The box runs the same launcher, so its diagnostics flag means the same there."
23871
+ note: "The sandbox runs the same launcher, so its diagnostics flag means the same there."
23872
23872
  },
23873
23873
  {
23874
23874
  token: "--refresh-runtime",
23875
23875
  takesValue: false,
23876
23876
  class: "reject",
23877
- reason: "the box does not extract a runtime — its harness is baked into the image",
23877
+ reason: "the sandbox image already contains Helix",
23878
23878
  alternative: "The image pins its own Helix build; see `mutagent sandbox presets`."
23879
23879
  },
23880
23880
  {
@@ -23895,7 +23895,7 @@ var TRANSPORT_TABLE = [
23895
23895
  takesValue: true,
23896
23896
  class: "translate",
23897
23897
  launcherClass: "cross",
23898
- note: "On `helix agent`, the definition selector: resolved against the LOCAL agent dirs when this machine has it — the definition body travels, because the box would resolve the same name to its BUNDLED agent first. A name not found here crosses as `--name <name>` in args and the box resolves it (bundled roster, then its agent dirs); the box refuses an unknown name rather than running a different one. See agent-argv.ts. On the launcher arms (bare `helix`, `helix --prime`), pi’s session label, forwarded as typed like `-n`."
23898
+ note: "On `helix agent`, the definition selector: resolved against the LOCAL agent dirs when this machine has it, and the definition body is sent, because the sandbox would resolve the same name to its BUNDLED agent first. A name not found here is sent as `--name <name>` in args and the sandbox resolves it (bundled roster, then its agent dirs); the sandbox refuses an unknown name rather than running a different one. See agent-argv.ts. On the launcher arms (bare `helix`, `helix --prime`), pi’s session label, forwarded as typed like `-n`."
23899
23899
  },
23900
23900
  {
23901
23901
  token: "--agent",
@@ -23920,21 +23920,21 @@ var TRANSPORT_TABLE = [
23920
23920
  token: "--api-key",
23921
23921
  takesValue: true,
23922
23922
  class: "reject",
23923
- reason: "it would put a provider secret on the wire and in the box’s process table",
23923
+ reason: "it would send an LLM provider key over the network and show it in the sandbox’s process list",
23924
23924
  alternative: "An LLM key for a cloud run belongs in the workspace’s LLM providers: `mutagent providers add -k <key> …`, or `mutagent providers mirror` to copy your local Helix logins."
23925
23925
  },
23926
23926
  {
23927
23927
  token: "--list-models",
23928
23928
  takesValue: true,
23929
23929
  class: "reject",
23930
- reason: "it prints a catalogue and exits without taking a turn, so a whole sandbox is spawned to answer a question the box cannot be asked interactively",
23931
- alternative: "Run it against a box you already hold: `mutagent sandbox exec --sandbox <id> -- helix --list-models`."
23930
+ reason: "it prints the model list and exits; a cloud run would start a sandbox for it",
23931
+ alternative: "Run: mutagent helix models"
23932
23932
  },
23933
23933
  {
23934
23934
  token: "--system-prompt",
23935
23935
  takesValue: true,
23936
23936
  class: "translate",
23937
- note: "pi reads the value as a FILE when the path exists (`resolvePromptInput`), so a value naming a local file is inlined here; anything else is text and crosses as it is. It was CROSS, so a local path crossed as a path the box does not have (DR-11)."
23937
+ note: "A value that names a local file is read here and sent as text; any other value is sent as it is."
23938
23938
  },
23939
23939
  {
23940
23940
  token: "--append-system-prompt",
@@ -23958,7 +23958,7 @@ var TRANSPORT_TABLE = [
23958
23958
  takesValue: false,
23959
23959
  class: "cross",
23960
23960
  via: "args",
23961
- note: "Same flag as --no-skills. The box HAS skills, so switching them off there is a real and honourable request."
23961
+ note: "Same flag as --no-skills. Turns off the skills in the sandbox image."
23962
23962
  },
23963
23963
  { token: "--no-prompt-templates", takesValue: false, class: "cross", via: "args" },
23964
23964
  { token: "-np", takesValue: false, class: "cross", via: "args" },
@@ -24011,7 +24011,7 @@ var TRANSPORT_TABLE = [
24011
24011
  token: "--tui-mode",
24012
24012
  takesValue: true,
24013
24013
  class: "reject",
24014
- reason: "there is no TUI in the box — the turn is non-interactive by construction",
24014
+ reason: "a cloud run has no terminal",
24015
24015
  alternative: "Drop it."
24016
24016
  },
24017
24017
  {
@@ -24026,14 +24026,14 @@ var TRANSPORT_TABLE = [
24026
24026
  takesValue: true,
24027
24027
  class: "reject",
24028
24028
  reason: HOST_PATH,
24029
- alternative: "Capture the session you want to fork with `mutagent helix session checkpoint`, then restore it into a new box."
24029
+ alternative: "Capture the session you want to fork with `mutagent helix session checkpoint`, then restore it into a new sandbox."
24030
24030
  },
24031
24031
  {
24032
24032
  token: "--session-dir",
24033
24033
  takesValue: true,
24034
24034
  class: "reject",
24035
24035
  reason: HOST_PATH,
24036
- alternative: "Sessions live inside the box; read them with `mutagent sandbox exec --sandbox <id>`."
24036
+ alternative: "Sessions are stored inside the sandbox; read them with `mutagent sandbox exec --sandbox <id>`."
24037
24037
  },
24038
24038
  { token: "--no-session", takesValue: false, class: "cross", via: "args" },
24039
24039
  { token: "--session-id", takesValue: true, class: "cross", via: "args" },
@@ -24048,15 +24048,15 @@ var TRANSPORT_TABLE = [
24048
24048
  token: "--continue",
24049
24049
  takesValue: false,
24050
24050
  class: "reject",
24051
- reason: "there is no previous session in a fresh box to continue",
24052
- alternative: "Run against a box you kept: `mutagent helix agent --sandbox <id> …`, or restore a checkpoint."
24051
+ reason: "there is no previous session in a new sandbox to continue",
24052
+ alternative: "Run against a sandbox you kept: `mutagent helix agent --sandbox <id> …`, or restore a checkpoint."
24053
24053
  },
24054
24054
  {
24055
24055
  token: "-c",
24056
24056
  takesValue: false,
24057
24057
  class: "reject",
24058
- reason: "there is no previous session in a fresh box to continue",
24059
- alternative: "Run against a box you kept: `mutagent helix agent --sandbox <id> …`, or restore a checkpoint."
24058
+ reason: "there is no previous session in a new sandbox to continue",
24059
+ alternative: "Run against a sandbox you kept: `mutagent helix agent --sandbox <id> …`, or restore a checkpoint."
24060
24060
  },
24061
24061
  {
24062
24062
  token: "--resume",
@@ -24076,7 +24076,7 @@ var TRANSPORT_TABLE = [
24076
24076
  token: "--export",
24077
24077
  takesValue: true,
24078
24078
  class: "reject",
24079
- reason: "it writes a file on the machine the harness runs on, which is the box — the file would be destroyed with it",
24079
+ reason: "it writes a file on the machine the harness runs on, which is the sandbox; the file is deleted with it",
24080
24080
  alternative: "Capture the stream instead: `mutagent helix agent … --json > run.ndjson`."
24081
24081
  },
24082
24082
  { token: "--verbose", takesValue: false, class: "cross", via: "args" },
@@ -24085,26 +24085,26 @@ var TRANSPORT_TABLE = [
24085
24085
  token: "--approve",
24086
24086
  takesValue: false,
24087
24087
  class: "drop",
24088
- notice: "--approve is dropped: a sandbox has no interactive trust prompt to pre-answer, and the box grants project trust by construction."
24088
+ notice: "--approve is ignored: a cloud sandbox always trusts the project."
24089
24089
  },
24090
24090
  {
24091
24091
  token: "-a",
24092
24092
  takesValue: false,
24093
24093
  class: "drop",
24094
- notice: "-a is dropped: a sandbox has no interactive trust prompt to pre-answer, and the box grants project trust by construction."
24094
+ notice: "-a is ignored: a cloud sandbox always trusts the project."
24095
24095
  },
24096
24096
  {
24097
24097
  token: "--no-approve",
24098
24098
  takesValue: false,
24099
24099
  class: "reject",
24100
- reason: "withholding project trust in a non-interactive box leaves the agent unable to read the workspace and unable to ask",
24100
+ reason: "without project trust the agent cannot read the workspace, and a cloud run cannot ask you for it",
24101
24101
  alternative: "Drop it, or restrict the agent with --tools / --exclude-tools instead."
24102
24102
  },
24103
24103
  {
24104
24104
  token: "-na",
24105
24105
  takesValue: false,
24106
24106
  class: "reject",
24107
- reason: "withholding project trust in a non-interactive box leaves the agent unable to read the workspace and unable to ask",
24107
+ reason: "without project trust the agent cannot read the workspace, and a cloud run cannot ask you for it",
24108
24108
  alternative: "Drop it, or restrict the agent with --tools / --exclude-tools instead."
24109
24109
  },
24110
24110
  {
@@ -24239,13 +24239,13 @@ function argumentLabel(args, i, files) {
24239
24239
  function checkArgsForRoute(args, files = []) {
24240
24240
  args.forEach((arg, i) => {
24241
24241
  if (arg === "") {
24242
- throw new MutagentError("INVALID_ARGUMENTS", `${argumentLabel(args, i, files)} is empty, and a session in a box refuses an empty argument.`, "Give it a value, or drop the flag.", 2);
24242
+ throw new MutagentError("INVALID_ARGUMENTS", `${argumentLabel(args, i, files)} is empty, and a cloud session refuses an empty argument.`, "Give it a value, or drop the flag.", 2);
24243
24243
  }
24244
24244
  });
24245
24245
  }
24246
24246
  function checkSandboxId(value2) {
24247
24247
  if (value2?.trim().startsWith("-") === true) {
24248
- throw new MutagentError("INVALID_ARGUMENTS", `--sandbox needs a sandbox id, and got a flag instead: ${redactToken(value2.trim())}`, "Name the box: --sandbox <id>. 'mutagent sandbox ls' shows the running ones.", 2);
24248
+ throw new MutagentError("INVALID_ARGUMENTS", `--sandbox needs a sandbox id, and got a flag instead: ${redactToken(value2.trim())}`, "Name the sandbox: --sandbox <id>. 'mutagent sandbox ls' shows the running ones.", 2);
24249
24249
  }
24250
24250
  }
24251
24251
 
@@ -24321,7 +24321,7 @@ function planAgentArgv(argv, deps, flags = {}) {
24321
24321
  continue;
24322
24322
  }
24323
24323
  if (token.startsWith("@")) {
24324
- throw rejection(redactToken(token), "an @file argument is read from the machine the harness runs on, and the box has no copy of it", "Inline the file’s contents into the task, or `mutagent sandbox exec` it into a box you kept. File upload does not exist yet.");
24324
+ throw rejection(redactToken(token), "an @file argument is read from the machine the harness runs on, and the sandbox has no copy of it", "Inline the file’s contents into the task, or `mutagent sandbox exec` it into a sandbox you kept. File upload does not exist yet.");
24325
24325
  }
24326
24326
  if (token.startsWith("--")) {
24327
24327
  forwardFlag(token);
@@ -24333,7 +24333,7 @@ function planAgentArgv(argv, deps, flags = {}) {
24333
24333
  continue;
24334
24334
  }
24335
24335
  if (token.startsWith("-")) {
24336
- throw rejection(redactToken(token), "the harness rejects unknown short options outright, so forwarding it would fail inside the box instead of here", "Check the spelling against `helix agent --help`, or use the long form.");
24336
+ throw rejection(redactToken(token), "the harness rejects unknown short options outright, so forwarding it would fail inside the sandbox instead of here", "Check the spelling against `helix agent --help`, or use the long form.");
24337
24337
  }
24338
24338
  if (i === 0 && source2 === undefined) {
24339
24339
  source2 = { kind: "prompt", value: token };
@@ -24405,7 +24405,7 @@ function planAgentArgv(argv, deps, flags = {}) {
24405
24405
  };
24406
24406
  }
24407
24407
  function rejection(token, reason, alternative) {
24408
- return new MutagentError("INVALID_ARGUMENTS", `${token} cannot cross to a cloud sandbox: ${reason}.`, alternative, 2);
24408
+ return new MutagentError("INVALID_ARGUMENTS", `${token} is not supported in a cloud run: ${reason}.`, alternative, 2);
24409
24409
  }
24410
24410
  function resolveDefinition(source2, deps) {
24411
24411
  if (source2 === undefined) {
@@ -24435,7 +24435,7 @@ function resolveDefinition(source2, deps) {
24435
24435
  const path = findAgentFile(source2.value, roots, deps);
24436
24436
  if (path === undefined) {
24437
24437
  return {
24438
- origin: `--name ${source2.value} (not on this machine; resolved by the box — searched: ${roots.join(", ")})`,
24438
+ origin: `--name ${source2.value} (not on this machine; resolved in the sandbox; searched: ${roots.join(", ")})`,
24439
24439
  forwardName: source2.value
24440
24440
  };
24441
24441
  }
@@ -24521,14 +24521,14 @@ function nativeMode(args, print, rpc = false) {
24521
24521
  return "json";
24522
24522
  if (print)
24523
24523
  return "text";
24524
- throw new MutagentError("NOT_SUPPORTED", "The Cloud CLI does not provide a terminal chat UI.", 'Use -p "<task>" for a complete run, --mode json "<task>" for events, or --mode rpc with a JSONL client.', 2);
24524
+ throw new MutagentError("NOT_SUPPORTED", "mutagent helix has no terminal chat UI.", 'Use -p "<task>" for a complete run, --mode json "<task>" for events, or --mode rpc with a JSONL client.', 2);
24525
24525
  }
24526
24526
  function nativeTaskNotices(mode, messages) {
24527
24527
  if (mode === "rpc") {
24528
- return messages.length === 0 ? [] : ["Native RPC ignores positional messages; send prompt commands on JSONL stdin."];
24528
+ return messages.length === 0 ? [] : ["An interactive session ignores positional messages; send the task as a prompt command on stdin."];
24529
24529
  }
24530
24530
  if (!messages.some((message) => message.trim() !== "")) {
24531
- throw new MutagentError("MISSING_ARGUMENTS", "A noninteractive Cloud run needs a task.", 'Add -p "<task>" or use --mode json "<task>".', 2);
24531
+ throw new MutagentError("MISSING_ARGUMENTS", "A headless cloud run needs a task.", 'Add -p "<task>" or use --mode json "<task>".', 2);
24532
24532
  }
24533
24533
  return [];
24534
24534
  }
@@ -24947,7 +24947,7 @@ function parseSessionPayload(data) {
24947
24947
  const record3 = parseRecord(data);
24948
24948
  if (!record3)
24949
24949
  return null;
24950
- const { seq, ts: ts2, sessionId, status, exitCode, lastSeq, generation } = record3;
24950
+ const { seq, ts: ts2, sessionId, status, exitCode, lastSeq, generation, mode } = record3;
24951
24951
  if (typeof seq !== "number" || typeof sessionId !== "string" || typeof status !== "string") {
24952
24952
  return null;
24953
24953
  }
@@ -24958,7 +24958,8 @@ function parseSessionPayload(data) {
24958
24958
  status,
24959
24959
  exitCode: typeof exitCode === "number" ? exitCode : null,
24960
24960
  lastSeq: typeof lastSeq === "number" ? lastSeq : -1,
24961
- generation: typeof generation === "number" ? generation : 0
24961
+ generation: typeof generation === "number" ? generation : 0,
24962
+ ...typeof mode === "string" ? { mode } : {}
24962
24963
  };
24963
24964
  }
24964
24965
  function parseLivePayload(data) {
@@ -25315,7 +25316,7 @@ async function runStreamSession(options) {
25315
25316
  break;
25316
25317
  }
25317
25318
  if (!alreadyDelivered(payload2.seq)) {
25318
- sink.notice(`Session ${payload2.sessionId} started.`);
25319
+ sink.notice(`Session ${payload2.sessionId} started${payload2.mode === undefined ? "" : ` (${payload2.mode})`}.`);
25319
25320
  }
25320
25321
  continue;
25321
25322
  }
@@ -25409,7 +25410,7 @@ function gapNotice(lastSeq, nextSeq) {
25409
25410
  }
25410
25411
  function exhausted(lastSeq, cause, onDisconnect) {
25411
25412
  const detail = cause instanceof Error ? ` (${cause.message})` : "";
25412
- const guidance = onDisconnect === "released" ? "This was a one-shot run: the server releases the sandbox as soon as the connection drops, so nothing is left running and there is nothing to re-attach to. Run the turn again, or use --no-stream to wait for the whole result in one reply." : `The sandbox is still running — nothing was destroyed. Resume with: mutagent sandbox attach <id> --since ${String(lastSeq)}`;
25413
+ const guidance = onDisconnect === "released" ? "This was a single-command run: the server deletes the sandbox when the connection drops, so nothing is left running and there is nothing to re-attach to. Run the turn again, or use --no-stream to wait for the whole result in one reply." : `The sandbox is still running — nothing was destroyed. Resume with: mutagent sandbox attach <id> --since ${String(lastSeq)}`;
25413
25414
  return new MutagentError("STREAM_DISCONNECTED", `Lost the sandbox stream and could not reconnect${detail}.`, guidance, 5);
25414
25415
  }
25415
25416
  function isGapError(payload) {
@@ -25526,11 +25527,11 @@ async function runNativeSession(options) {
25526
25527
  }
25527
25528
  const closed = await options.closeInput(inputController.signal);
25528
25529
  if (!closed.closed) {
25529
- throw new MutagentError("RPC_INPUT_REJECTED", "The session did not confirm stdin closure.", "Inspect the live execution; no signal was sent as a substitute for EOF.", 1);
25530
+ throw new MutagentError("RPC_INPUT_REJECTED", "The session did not confirm stdin closure.", "Check the session: mutagent helix session ls. No signal was sent in place of EOF.", 1);
25530
25531
  }
25531
25532
  };
25532
25533
  try {
25533
- notice("Session " + options.reference + (options.interrupt === undefined ? ". Ctrl-C detaches." : ". Ctrl-C sends SIGINT to this execution."));
25534
+ notice("Session " + options.reference + (options.interrupt === undefined ? ". Ctrl-C detaches." : ". Ctrl-C stops the session (SIGINT)."));
25534
25535
  if (options.interruptRequested)
25535
25536
  onSigint();
25536
25537
  const result = await runStreamSession({
@@ -25610,15 +25611,15 @@ async function runCloudLaunch(plan, mode) {
25610
25611
  checkArgsForRoute(plan.args);
25611
25612
  const sandbox = plan.sandbox?.trim();
25612
25613
  if (sandbox && plan.preset !== undefined) {
25613
- throw new MutagentError("INVALID_ARGUMENTS", "--preset cannot select an existing --sandbox.", "Drop --sandbox for automatic placement, or drop --preset to use the existing box.", 2);
25614
+ throw new MutagentError("INVALID_ARGUMENTS", "--preset cannot select an existing --sandbox.", "Drop --sandbox for automatic placement, or drop --preset to use that sandbox.", 2);
25614
25615
  }
25615
25616
  if (sandbox && plan.sandboxProvider !== undefined) {
25616
- throw new MutagentError("INVALID_ARGUMENTS", "--sandbox-provider cannot select an existing --sandbox.", "Drop --sandbox to place a fresh box on the named provider, or drop --sandbox-provider to use the existing box.", 2);
25617
+ throw new MutagentError("INVALID_ARGUMENTS", "--sandbox-provider cannot select an existing --sandbox.", "Drop --sandbox to start a new sandbox on that sandbox provider, or drop --sandbox-provider to use that sandbox.", 2);
25617
25618
  }
25618
25619
  const args = plan.args;
25619
25620
  const body = {
25620
25621
  arm: plan.arm,
25621
- mode: mode === "rpc" ? "rpc" : "oneshot",
25622
+ mode: mode === "rpc" ? "interactive" : "headless",
25622
25623
  ...args.length === 0 ? {} : { args },
25623
25624
  ...plan.environment === undefined ? {} : { environment: plan.environment },
25624
25625
  ...plan.cwd === undefined ? {} : { cwd: plan.cwd }
@@ -25635,10 +25636,10 @@ async function runCloudLaunch(plan, mode) {
25635
25636
  ...plan.sandboxProvider === undefined ? {} : { sandboxProvider: plan.sandboxProvider }
25636
25637
  });
25637
25638
  if (!session.reference) {
25638
- throw new MutagentError("INVALID_RESPONSE", "The server started a session without a live execution reference.", "Check that the server supports the Helix session API before launching again.", 1);
25639
+ throw new MutagentError("INVALID_RESPONSE", "The server did not return a session reference.", "Run: mutagent helix doctor", 1);
25639
25640
  }
25640
25641
  if (session.arm !== plan.arm || session.mode !== body.mode) {
25641
- throw new MutagentError("INVALID_RESPONSE", "The server started a different harness arm or I/O mode.", "Inspect live session " + session.reference + " before retrying; it may still be running.", 1);
25642
+ throw new MutagentError("INVALID_RESPONSE", "The server started the session with a different arm or mode than requested.", "Session " + session.reference + " may still be running. Check: mutagent helix session ls", 1);
25642
25643
  }
25643
25644
  process.removeListener("SIGINT", queueInterrupt);
25644
25645
  await attachLaunched({ reference: session.reference, sessionId: session.sessionId }, mode === "rpc", interruptRequested);
@@ -25665,16 +25666,15 @@ async function runManagedAgentLaunch(launch, write = (line) => {
25665
25666
  ...launch.sandboxProvider === undefined ? {} : { sandboxProvider: launch.sandboxProvider }
25666
25667
  });
25667
25668
  if (!session.reference || session.agent === undefined) {
25668
- throw new MutagentError("INVALID_RESPONSE", "The server did not return a managed agent session with a live execution reference.", "Check that the server supports managed agents (mutagent agent --help) before running again.", 1);
25669
+ throw new MutagentError("INVALID_RESPONSE", "The server did not return a session reference for the managed agent run.", "Check that the server supports managed agents (mutagent agent --help) before running again.", 1);
25669
25670
  }
25670
25671
  if (session.arm !== "agent" || plan.mode !== undefined && session.mode !== plan.mode) {
25671
- throw new MutagentError("INVALID_RESPONSE", "The server started a different harness arm or I/O mode.", "Inspect live session " + session.reference + " before retrying; it may still be running.", 1);
25672
+ throw new MutagentError("INVALID_RESPONSE", "The server started the session with a different arm or mode than requested.", "Session " + session.reference + " may still be running. Check: mutagent helix session ls", 1);
25672
25673
  }
25673
- const mode = session.mode === "rpc" ? "interactive" : "headless";
25674
- write("[mutagent] " + JSON.stringify({ reference: session.reference, sandboxId: session.sandboxId, agent: session.agent, mode }) + `
25674
+ write("[mutagent] " + JSON.stringify({ reference: session.reference, sandboxId: session.sandboxId, agent: session.agent, mode: session.mode }) + `
25675
25675
  `);
25676
25676
  process.removeListener("SIGINT", queueInterrupt);
25677
- await attachLaunched(session, session.mode === "rpc", interruptRequested);
25677
+ await attachLaunched(session, session.mode === "interactive", interruptRequested);
25678
25678
  return session;
25679
25679
  } finally {
25680
25680
  process.removeListener("SIGINT", queueInterrupt);
@@ -25749,14 +25749,14 @@ function planManagedAgentRun(argv, flags) {
25749
25749
  throw usage("-p runs headless and --rpc runs interactive, so pass one of them", `Run: ${example} or mutagent helix agent @${address.slug} --rpc`);
25750
25750
  }
25751
25751
  if (task !== undefined)
25752
- return { address, mode: "oneshot", task };
25752
+ return { address, mode: "headless", task };
25753
25753
  if (flags.rpc === true)
25754
- return { address, mode: "rpc" };
25754
+ return { address, mode: "interactive" };
25755
25755
  return { address };
25756
25756
  }
25757
25757
 
25758
25758
  // src/commands/helix/agent.ts
25759
- var MISSING_TASK_MESSAGE = 'cloud runs are non-interactive: pass the task with -p "<task>"';
25759
+ var MISSING_TASK_MESSAGE = 'a cloud run needs a task: pass -p "<task>", or --rpc for an interactive session';
25760
25760
  function registerAgentCommand(parent, registration, deps = defaultPlanDeps()) {
25761
25761
  const jsonSource = registration?.jsonSource ?? parent;
25762
25762
  parent.command("agent").description("Run a Helix agent in the cloud, or a managed agent by @slug").argument("[argv...]", "Agent definition, then the task and Helix flags; or @slug[:vN|:latest] for a managed agent").allowUnknownOption(true).allowExcessArguments(true).option("--sandbox <id>", "(internal) Run in an existing sandbox, by sandbox id").option("--preset <name>", "Sandbox preset (not with --sandbox)").option("--sandbox-provider <name>", "Run on this configured sandbox provider").option("--env <name>", "Workspace Environment to load for this run (see mutagent env ls)").option("--rpc", "Read JSON commands on stdin; write events on stdout").option("--cwd <path>", "Working directory in the sandbox").addHelpText("after", [
@@ -25791,12 +25791,12 @@ function registerAgentCommand(parent, registration, deps = defaultPlanDeps()) {
25791
25791
  " With --mode rpc, closing stdin ends the session's input; a dropped connection only detaches.",
25792
25792
  " Output is Helix's own, even with --json.",
25793
25793
  " Ctrl-C on a native launch sends SIGINT to the session, which stops it; the exit status is reported.",
25794
- " A sandbox idle for 15 minutes is checkpointed and stopped.",
25794
+ " A sandbox idle for 15 minutes is stopped; an interactive session in it is checkpointed first.",
25795
25795
  "",
25796
25796
  "AI Agent Directive:",
25797
25797
  ' For a managed agent, run mutagent helix agent @slug --env <slot> -p "<task>" and keep the',
25798
25798
  " reference from the stderr receipt; session attach, send and signal take it.",
25799
- " Preserve the definition/task distinction and select an explicit headless mode.",
25799
+ " Keep the definition and the task separate, and pass -p, --mode json or --mode rpc explicitly.",
25800
25800
  " Local paths that cannot travel are refused; read the recovery message."
25801
25801
  ].join(`
25802
25802
  `)).action(async (argv, options) => {
@@ -25876,7 +25876,7 @@ function withPlannedFlags(options, own) {
25876
25876
  init_errors();
25877
25877
  var LAUNCHER_OWN_FLAGS = ["--sandbox", "--preset", "--sandbox-provider", "--cwd", "--env", "--rpc"];
25878
25878
  function rejection2(token, reason, alternative) {
25879
- return new MutagentError("NOT_SUPPORTED", `${token} cannot cross to a cloud sandbox: ${reason}`, alternative, 2);
25879
+ return new MutagentError("NOT_SUPPORTED", `${token} is not supported in a cloud run: ${reason}`, alternative, 2);
25880
25880
  }
25881
25881
  function planLauncherArgv(argv, deps = defaultPlanDeps()) {
25882
25882
  let arm = "classic";
@@ -25941,7 +25941,7 @@ function planLauncherArgv(argv, deps = defaultPlanDeps()) {
25941
25941
  continue;
25942
25942
  }
25943
25943
  if (token.startsWith("@")) {
25944
- throw rejection2(redactToken(token), "an @file argument is read from the machine the harness runs on, and the box has no copy of it", "Inline the file’s contents into the task, or `mutagent sandbox exec` it into a box you kept. File upload does not exist yet.");
25944
+ throw rejection2(redactToken(token), "an @file argument is read from the machine the harness runs on, and the sandbox has no copy of it", "Inline the file’s contents into the task, or `mutagent sandbox exec` it into a sandbox you kept. File upload does not exist yet.");
25945
25945
  }
25946
25946
  if (token.startsWith("--")) {
25947
25947
  forwardFlag(token);
@@ -25953,7 +25953,7 @@ function planLauncherArgv(argv, deps = defaultPlanDeps()) {
25953
25953
  continue;
25954
25954
  }
25955
25955
  if (token.startsWith("-")) {
25956
- throw rejection2(redactToken(token), "the harness rejects unknown short options outright, so forwarding it would fail inside the box instead of here", "Check the spelling against `helix --help`, or use the long form.");
25956
+ throw rejection2(redactToken(token), "the harness rejects unknown short options outright, so forwarding it would fail inside the sandbox instead of here", "Check the spelling against `helix --help`, or use the long form.");
25957
25957
  }
25958
25958
  task ??= token;
25959
25959
  messages.push(token);
@@ -26638,7 +26638,7 @@ Types:
26638
26638
  --line sends one JSON object as written, for a command the four types do not
26639
26639
  cover. It cannot be combined with --type or a message.
26640
26640
 
26641
- Only rpc sessions (started with --mode rpc or --rpc) accept input, and a session
26641
+ Only interactive sessions (started with --mode rpc or --rpc) accept input, and a session
26642
26642
  that has ended refuses it; 'mutagent helix session ls' shows which are live.
26643
26643
  With a sandbox id and --session, if the sandbox is being stopped for idling, send
26644
26644
  waits the time the server asks and retries once. If the session's sandbox was stopped for idling,
@@ -26662,7 +26662,7 @@ AI Agent Directive:
26662
26662
  const built2 = buildLine(messageParts.join(" ").trim(), options);
26663
26663
  const result2 = await sendHelixInput(id, built2.line);
26664
26664
  if (!result2.accepted) {
26665
- throw new MutagentError("RPC_INPUT_REJECTED", "The session did not accept the command.", "Inspect the live execution before retrying; no reply is promised.", 1);
26665
+ throw new MutagentError("RPC_INPUT_REJECTED", "The session did not accept the command.", "Check the session: mutagent helix session ls", 1);
26666
26666
  }
26667
26667
  if (isJson)
26668
26668
  output.output({ success: result2.accepted, reference: id, ...built2, ...result2, _links: { api: liveSessionPath(id) } });
@@ -26777,7 +26777,7 @@ when the agent has stopped reading its input.
26777
26777
  Exits non-zero if the session had already ended.
26778
26778
  The sandbox is not deleted: its files and event log stay, and
26779
26779
  'mutagent helix session attach <reference>' shows what the session did. A sandbox
26780
- idle for 15 minutes is checkpointed and stopped.
26780
+ idle for 15 minutes is stopped; an interactive session in it is checkpointed first.
26781
26781
 
26782
26782
  AI Agent Directive:
26783
26783
  --json returns ONE object: { success, reference, signal, signalled, _links }.
@@ -26792,7 +26792,7 @@ AI Agent Directive:
26792
26792
  const signal2 = resolveSignal(options.type);
26793
26793
  const result2 = await signalHelixSession(id, signal2);
26794
26794
  if (!result2.signalled) {
26795
- throw new MutagentError("SESSION_SIGNAL_REJECTED", "The session was not signalled.", "Inspect the live execution before retrying.", 1);
26795
+ throw new MutagentError("SESSION_SIGNAL_REJECTED", "The session was not signalled.", "Check the session: mutagent helix session ls", 1);
26796
26796
  }
26797
26797
  if (isJson)
26798
26798
  output.output({ success: result2.signalled, reference: id, signal: signal2, ...result2, _links: { api: liveSessionPath(id) } });
@@ -26853,7 +26853,7 @@ A session reference (hs1_...) is printed when a run starts and listed by 'sessio
26853
26853
  attach, send, signal, close-input, checkpoint, checkpoints and restore take it.
26854
26854
  start and 'ls <sandbox-id>' are internal and take a sandbox id.
26855
26855
  checkpoint saves a session's conversation; restore continues it in a rebuilt sandbox.
26856
- A sandbox idle for 15 minutes is checkpointed and stopped; restore rebuilds it.
26856
+ A sandbox idle for 15 minutes is stopped; an interactive session in it is checkpointed first.
26857
26857
 
26858
26858
  AI Agent Directive:
26859
26859
  Start work with 'mutagent helix --mode rpc' and keep the session reference it
@@ -26885,7 +26885,7 @@ function withSessionFlags(options, own) {
26885
26885
  };
26886
26886
  }
26887
26887
  function registerStart(session, root) {
26888
- session.command("start").description("(internal) Start a Helix session in an existing sandbox, by sandbox id").argument("<sandbox-id>", "Sandbox to start the session in").argument("[args...]", "Helix flags (put -- before them)").allowUnknownOption(true).allowExcessArguments(true).option("--rpc", "Keep the session open for 'session send' (default: run once and end)").option("--cwd <path>", "Working directory (default: $HOME for an rpc session)").option("--env <name>", "Workspace Environment to load (see mutagent env ls)").addHelpText("after", `
26888
+ session.command("start").description("(internal) Start a Helix session in an existing sandbox, by sandbox id").argument("<sandbox-id>", "Sandbox to start the session in").argument("[args...]", "Helix flags (put -- before them)").allowUnknownOption(true).allowExcessArguments(true).option("--rpc", "Start an interactive session that accepts 'session send' (default: headless, runs once and ends)").option("--cwd <path>", "Working directory (default: $HOME for an interactive session)").option("--env <name>", "Workspace Environment to load (see mutagent env ls)").addHelpText("after", `
26889
26889
  Examples:
26890
26890
  ${chalk27.dim("$")} mutagent helix session start sbx_123 --rpc
26891
26891
  ${chalk27.dim("$")} mutagent helix session start sbx_123 --rpc --env staging
@@ -26894,7 +26894,7 @@ Examples:
26894
26894
 
26895
26895
  Prints the session id. Address the session as <sandbox-id> --session <session-id>
26896
26896
  for send, signal and checkpoint, and watch it with 'mutagent sandbox attach <sandbox-id>'.
26897
- Only an --rpc session accepts 'session send'; a one-shot session runs and ends.
26897
+ Only an interactive session (--rpc) accepts 'session send'; a headless session runs its task and ends.
26898
26898
  Flags after -- go to Helix. A flag that names a file on this machine is refused,
26899
26899
  because the sandbox cannot read it. A leading positional, --prompt, --file or
26900
26900
  --name is the agent definition, resolved on this machine first.
@@ -26913,7 +26913,7 @@ AI Agent Directive:
26913
26913
  process.stderr.write(`[mutagent] ${notice}
26914
26914
  `);
26915
26915
  const opts = withSessionFlags(options, planned.own);
26916
- const mode = opts.rpc === true ? "rpc" : "oneshot";
26916
+ const mode = opts.rpc === true ? "interactive" : "headless";
26917
26917
  const args = planned.args;
26918
26918
  const result = await startSession(id, {
26919
26919
  mode,
@@ -26933,8 +26933,8 @@ AI Agent Directive:
26933
26933
  ...opts.env === undefined ? {} : { environment: opts.env },
26934
26934
  _links: sandboxLinks(id),
26935
26935
  _directive: {
26936
- instruction: mode === "rpc" ? "The session is live and reading its stdin. Attach to watch it; send to steer it." : "The session takes one turn and ends. Attach to watch it; it does not accept input.",
26937
- next: mode === "rpc" ? [
26936
+ instruction: mode === "interactive" ? "The session is live and reading its stdin. Attach to watch it; send to steer it." : "The session runs its task to completion and ends. Attach to watch it; it does not accept input.",
26937
+ next: mode === "interactive" ? [
26938
26938
  `mutagent sandbox attach ${id} --json`,
26939
26939
  `mutagent helix session send ${id} --session ${sessionId} "<message>" --json`
26940
26940
  ] : [`mutagent sandbox attach ${id} --json`]
@@ -26944,7 +26944,7 @@ AI Agent Directive:
26944
26944
  }
26945
26945
  output.success(`Session ${sessionId} started in ${id} (${mode})`);
26946
26946
  console.error(chalk27.dim(` Watch it: mutagent sandbox attach ${id}`));
26947
- if (mode === "rpc") {
26947
+ if (mode === "interactive") {
26948
26948
  console.error(chalk27.dim(` Talk to it: mutagent helix session send ${id} --session ${sessionId} "<message>"`));
26949
26949
  }
26950
26950
  } catch (error3) {
@@ -26965,7 +26965,7 @@ Examples:
26965
26965
 
26966
26966
  Every session in the workspace, live and ended, newest activity first.
26967
26967
  STATUS is live (running now), ended (finished; exitCode in --json), stopped-for-idling
26968
- (its sandbox was idle for 15 minutes, then checkpointed and stopped) or restored
26968
+ (its sandbox was idle for 15 minutes and was stopped) or restored
26969
26969
  (running in a sandbox rebuilt from a checkpoint). AGENT is slug:vN for a session
26970
26970
  run from a managed agent (mutagent helix agent @slug) and blank otherwise. MODE is
26971
26971
  interactive or headless. ARM and MODE are blank for sessions older than those fields.
@@ -27000,7 +27000,7 @@ AI Agent Directive:
27000
27000
  if (isJson) {
27001
27001
  output.output({
27002
27002
  workspaceId,
27003
- sessions: sessions.map((row) => row.mode === undefined ? row : { ...row, mode: publicMode(row.mode) }),
27003
+ sessions,
27004
27004
  count: sessions.length,
27005
27005
  ...nextCursor === undefined ? {} : { nextCursor }
27006
27006
  });
@@ -27009,7 +27009,7 @@ AI Agent Directive:
27009
27009
  if (sessions.length === 0) {
27010
27010
  console.log(chalk27.gray("No Helix sessions in this workspace yet."));
27011
27011
  console.log("");
27012
- console.log(' Launch one: mutagent helix launch --task "..." (or session start <box>)');
27012
+ console.log(' Start one: mutagent helix -p "<task>" or mutagent helix --rpc');
27013
27013
  return;
27014
27014
  }
27015
27015
  output.output(sessions.map((s) => ({
@@ -27017,7 +27017,7 @@ AI Agent Directive:
27017
27017
  SANDBOX: s.sandboxId,
27018
27018
  AGENT: s.agent ?? "",
27019
27019
  ARM: s.arm ?? "",
27020
- MODE: publicMode(s.mode),
27020
+ MODE: s.mode ?? "",
27021
27021
  STATUS: s.status,
27022
27022
  "LAST ACTIVITY": s.lastActivityAt
27023
27023
  })));
@@ -27121,18 +27121,13 @@ function requireSession(raw, example) {
27121
27121
  return sessionId;
27122
27122
  throw new MutagentError("MISSING_ARGUMENTS", "--session is required — a sandbox can hold more than one session.", `Run: ${example} --session <session-id>`, 2);
27123
27123
  }
27124
- function publicMode(mode) {
27125
- if (mode === undefined)
27126
- return "";
27127
- return mode === "rpc" ? "interactive" : "headless";
27128
- }
27129
27124
 
27130
27125
  // src/commands/helix/models.ts
27131
27126
  import chalk28 from "chalk";
27132
27127
  init_errors();
27133
27128
  function printView(view, output) {
27134
27129
  if (view.models.length === 0) {
27135
- console.log(chalk28.gray("No Helix Cloud models: this workspace has no active LLM provider the box can use."));
27130
+ console.log(chalk28.gray("No Helix Cloud models: this workspace has no active LLM provider that Helix can use."));
27136
27131
  console.log("");
27137
27132
  console.log(" Add one: mutagent providers add --provider <id> --name <name> --api-key <key>");
27138
27133
  } else {
@@ -27145,7 +27140,7 @@ function printView(view, output) {
27145
27140
  console.log(view.default === null ? chalk28.yellow("No default set — a run without --model answers 428. Set one: mutagent helix models default <provider/model>") : `Default: ${view.default}`);
27146
27141
  }
27147
27142
  if (view.unmapped.length > 0) {
27148
- console.log(chalk28.yellow(`Not usable in a box (no harness credential mapping): ${view.unmapped.join(", ")}`));
27143
+ console.log(chalk28.yellow(`Not usable by Helix Cloud (Helix cannot load this LLM provider's key): ${view.unmapped.join(", ")}`));
27149
27144
  }
27150
27145
  }
27151
27146
  function registerModelsCommand(helix) {
@@ -27428,9 +27423,10 @@ function createHelixCommand() {
27428
27423
  "Each run prints its session reference (hs1_...) on stderr. Use it with",
27429
27424
  "mutagent helix session attach, send, signal and checkpoint.",
27430
27425
  "Ctrl-C sends SIGINT to the session, which stops it; the exit status is reported.",
27431
- "There is no interactive chat UI: choose -p, --mode json or --mode rpc.",
27426
+ "There is no terminal chat UI: choose -p, --mode json or --mode rpc.",
27432
27427
  "With --mode rpc, closing stdin ends the session's input; a dropped connection only detaches.",
27433
- "A sandbox idle for 15 minutes is checkpointed and stopped; mutagent helix session restore rebuilds it.",
27428
+ "A sandbox idle for 15 minutes is stopped; an interactive session in it is checkpointed first.",
27429
+ "mutagent helix session restore continues a checkpointed session in a new sandbox.",
27434
27430
  "",
27435
27431
  "AI Agent Directive:",
27436
27432
  " Choose -p, --mode json or --mode rpc explicitly.",
@@ -27564,7 +27560,7 @@ function resolveNetwork(requested, rules) {
27564
27560
  }
27565
27561
  const policy2 = requested.trim();
27566
27562
  if (!EGRESS_POLICIES.includes(policy2)) {
27567
- throw new MutagentError("INVALID_ARGUMENTS", `--egress must be one of ${EGRESS_POLICIES.join(", ")}, got "${requested}".`, "Use --egress allow to drive a Helix session; the default, deny, leaves the box with no network at all.");
27563
+ throw new MutagentError("INVALID_ARGUMENTS", `--egress must be one of ${EGRESS_POLICIES.join(", ")}, got "${requested}".`, "Use --egress allow to drive a Helix session; the default, deny, leaves the sandbox without network access.");
27568
27564
  }
27569
27565
  if (policy2 !== "allowlist") {
27570
27566
  if (rules.length > 0) {
@@ -27676,7 +27672,7 @@ command and is removed unless --keep. With --sandbox, output streams as it is pr
27676
27672
  --preset and --keep are refused there. The sandbox command's exit code is this command's.
27677
27673
 
27678
27674
  AI Agent Directive:
27679
- Use --no-stream --json (or the one-shot form, which is always blocking) for a
27675
+ Use --no-stream --json (or the single-command form, which is always blocking) for a
27680
27676
  result you intend to parse: one object, no NDJSON to reassemble.
27681
27677
  Run 'mutagent sandbox ls --json' first to confirm a --sandbox id is running.
27682
27678
  `).action(async (argv, options) => {
@@ -27741,7 +27737,7 @@ function rejectOneShotOnlyFlags(options) {
27741
27737
  offenders.push("--keep");
27742
27738
  if (offenders.length === 0)
27743
27739
  return;
27744
- throw new MutagentError("INVALID_ARGUMENTS", `${offenders.join(" and ")} ${offenders.length === 1 ? "applies" : "apply"} only to a fresh sandbox, but --sandbox names an existing one.`, "Drop --sandbox to run one-shot in a fresh box, or drop these flags to run in the existing one.");
27740
+ throw new MutagentError("INVALID_ARGUMENTS", `${offenders.join(" and ")} ${offenders.length === 1 ? "applies" : "apply"} only to a fresh sandbox, but --sandbox names an existing one.`, "Drop --sandbox to run the command in a new sandbox, or drop these flags to run in the existing one.");
27745
27741
  }
27746
27742
  function createExecOpener(id, body) {
27747
27743
  let submitted = false;
@@ -28155,15 +28151,15 @@ Examples:
28155
28151
  ${chalk35.dim("$")} mutagent sandbox traces sbx_1
28156
28152
  ${chalk35.dim("$")} mutagent sandbox rm sbx_1 --force
28157
28153
 
28158
- One-shot vs persistent:
28154
+ Single command vs kept sandbox:
28159
28155
  ${chalk35.bold("exec")} without --sandbox starts a fresh sandbox from a preset, runs one command
28160
28156
  and removes the sandbox. ${chalk35.bold("spawn")} starts a sandbox from an image and leaves it running
28161
28157
  for ${chalk35.bold("attach")} and ${chalk35.bold("exec --sandbox")}.
28162
28158
 
28163
28159
  Lifecycle:
28164
28160
  Ctrl-C, a dropped connection or a closed terminal detaches; the sandbox keeps running.
28165
- After 15 minutes with no input, attach, exec or agent turn, the server checkpoints
28166
- and stops it. A Helix session in it can be rebuilt with
28161
+ After 15 minutes with no input, attach, exec or agent turn, the server stops it;
28162
+ an interactive Helix session in it is checkpointed first and can be restored with
28167
28163
  \`mutagent helix session restore <reference>\`. \`sandbox rm\` destroys a sandbox now.
28168
28164
 
28169
28165
  Output:
@@ -28400,8 +28396,8 @@ Examples:
28400
28396
  Entries you name are set and the rest stay; the Environment is created if missing.
28401
28397
  --replace removes every entry you do not name, secrets included.
28402
28398
  Positional KEY=VALUE and --from-file are variables; --secret and --secrets-from-file are
28403
- secrets (encrypted at rest, never returned). Both reach the box as env vars. A name
28404
- cannot be both.
28399
+ secrets (encrypted at rest, never returned). Both are set as environment variables in
28400
+ the sandbox. A name cannot be both.
28405
28401
  --secret takes every KEY=VALUE after it, so put variables first:
28406
28402
  ${chalk36.dim("$")} mutagent env set demo A=1 --secret TOKEN=x
28407
28403
  A value may contain '=': TOKEN=a=b stores "a=b".
@@ -28476,8 +28472,8 @@ Examples:
28476
28472
  ${chalk36.dim("$")} mutagent env rm demo --force
28477
28473
  ${chalk36.dim("$")} mutagent env rm demo --json
28478
28474
 
28479
- Deletes the Environment and its encrypted secrets. Boxes already running keep what
28480
- they were handed; the next run naming this Environment fails.
28475
+ Deletes the Environment and its encrypted secrets. Sandboxes already running keep the
28476
+ values they were given; the next run naming this Environment fails.
28481
28477
  Without --force (and without --json) the command refuses; it never prompts.
28482
28478
  An unknown name is an error.
28483
28479
 
@@ -28708,8 +28704,8 @@ function helixKeyRefusal() {
28708
28704
  To pass the Mutagent platform key instead, put it before the command (mutagent --api-key <mutagent-key> helix …) or export MUTAGENT_API_KEY.`, 2);
28709
28705
  }
28710
28706
  function sandboxExecKeyRefusal() {
28711
- return new MutagentError("NOT_SUPPORTED", "--api-key after 'mutagent sandbox exec' and before a -- is refused: it reads as a flag of the command in the box, but the mutagent CLI would take it as its own platform key and send it to the Mutagent platform.", `${keyAlternative()}
28712
- Arguments for the command in the box go after --: mutagent sandbox exec --sandbox <id> -- <command> [args…].
28707
+ return new MutagentError("NOT_SUPPORTED", "--api-key after 'mutagent sandbox exec' and before a -- is refused: it reads as a flag of the command in the sandbox, but the mutagent CLI would take it as its own platform key and send it to the Mutagent platform.", `${keyAlternative()}
28708
+ Arguments for the command in the sandbox go after --: mutagent sandbox exec --sandbox <id> -- <command> [args…].
28713
28709
  To pass the Mutagent platform key instead, put it before the command (mutagent --api-key <mutagent-key> sandbox exec …) or export MUTAGENT_API_KEY.`, 2);
28714
28710
  }
28715
28711
  function rootValueOptionRefusal(option, label) {
@@ -29241,4 +29237,4 @@ if (isAgentInvocation(rawArgs)) {
29241
29237
  program.parse(argvForCommander, { from: "user" });
29242
29238
  }
29243
29239
 
29244
- //# debugId=093DD78045AEB58864756E2164756E21
29240
+ //# debugId=EBAEE05DDF8C12AA64756E2164756E21
package/dist/index.js CHANGED
@@ -708,7 +708,7 @@ var init_sdk_debug = __esm(() => {
708
708
  });
709
709
 
710
710
  // src/lib/sdk-mappers.ts
711
- import { Provider as SDKProviderEnum } from "@mutagent/sdk/models";
711
+ import { LlmProviderType as SDKProviderEnum } from "@mutagent/sdk/models";
712
712
  function isProviderType(value) {
713
713
  return PROVIDER_TYPES.includes(value);
714
714
  }
@@ -1021,7 +1021,7 @@ class SDKClientWrapper {
1021
1021
  }
1022
1022
  async listProviders(filters) {
1023
1023
  try {
1024
- const response = await this.sdk.providerConfigs.listProviders({
1024
+ const response = await this.sdk.llmProviders.listProviderConfigs({
1025
1025
  provider: filters?.type,
1026
1026
  includeInactive: true
1027
1027
  });
@@ -1039,7 +1039,7 @@ class SDKClientWrapper {
1039
1039
  }
1040
1040
  async getProvider(id) {
1041
1041
  try {
1042
- const response = await this.sdk.providerConfigs.getProvider({
1042
+ const response = await this.sdk.llmProviders.getProviderConfig({
1043
1043
  id
1044
1044
  });
1045
1045
  return toProvider(response);
@@ -1115,7 +1115,7 @@ class SDKClientWrapper {
1115
1115
  }
1116
1116
  async testProvider(id) {
1117
1117
  try {
1118
- const response = await this.sdk.providerConfigs.testProvider({
1118
+ const response = await this.sdk.llmProviders.testProviderConfig({
1119
1119
  id
1120
1120
  });
1121
1121
  return toProviderTestResult(response);
@@ -1161,7 +1161,7 @@ class SDKClientWrapper {
1161
1161
  });
1162
1162
  return scrubKnownSuccessDeep({ ...response2, workspaceId });
1163
1163
  }
1164
- const response = await this.sdk.providerConfigs.updateProvider({
1164
+ const response = await this.sdk.llmProviders.updateProviderConfig({
1165
1165
  id,
1166
1166
  body: {
1167
1167
  name: data.name,
@@ -1180,7 +1180,7 @@ class SDKClientWrapper {
1180
1180
  async deleteProvider(id) {
1181
1181
  const workspaceId = this.requireUnambiguousWorkspace();
1182
1182
  try {
1183
- await this.sdk.providerConfigs.deleteProvider({ id });
1183
+ await this.sdk.llmProviders.deleteProviderConfig({ id });
1184
1184
  return { workspaceId };
1185
1185
  } catch (error) {
1186
1186
  this.handleError(error);
@@ -1480,4 +1480,4 @@ export {
1480
1480
  ApiError
1481
1481
  };
1482
1482
 
1483
- //# debugId=F50D31F7C1A84A2764756E2164756E21
1483
+ //# debugId=0E9FCC198FD63F3C64756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutagent/cli",
3
- "version": "0.1.351",
3
+ "version": "0.1.353",
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.5.11",
45
+ "@mutagent/sdk": "0.6.0",
46
46
  "chalk": "^5.3.0",
47
47
  "commander": "^12.1.0",
48
48
  "cosmiconfig": "^9.0.0",