@mutagent/cli 0.1.282 → 0.1.284
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 +241 -111
- package/dist/bin/cli.js.map +7 -6
- package/package.json +2 -2
package/dist/bin/cli.js
CHANGED
|
@@ -884,7 +884,7 @@ var init_sdk_client = __esm(() => {
|
|
|
884
884
|
|
|
885
885
|
// src/bin/cli.ts
|
|
886
886
|
import { Command as Command15 } from "commander";
|
|
887
|
-
import
|
|
887
|
+
import chalk29 from "chalk";
|
|
888
888
|
import { readFileSync as readFileSync12 } from "fs";
|
|
889
889
|
import { join as join14, dirname as dirname4 } from "path";
|
|
890
890
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -6122,7 +6122,7 @@ If mutagent-cli is not installed: mutagent install helix`), isJson);
|
|
|
6122
6122
|
|
|
6123
6123
|
// src/commands/helix/index.ts
|
|
6124
6124
|
import { Command as Command14 } from "commander";
|
|
6125
|
-
import
|
|
6125
|
+
import chalk28 from "chalk";
|
|
6126
6126
|
|
|
6127
6127
|
// src/commands/helix/spawn.ts
|
|
6128
6128
|
import chalk21 from "chalk";
|
|
@@ -6415,6 +6415,13 @@ async function postInput(id, body) {
|
|
|
6415
6415
|
sandboxId: id
|
|
6416
6416
|
});
|
|
6417
6417
|
}
|
|
6418
|
+
async function postSignal(id, body) {
|
|
6419
|
+
return requestJson(`/api/sandbox/${encodeURIComponent(id)}/signal`, {
|
|
6420
|
+
method: "POST",
|
|
6421
|
+
body: JSON.stringify(body),
|
|
6422
|
+
sandboxId: id
|
|
6423
|
+
});
|
|
6424
|
+
}
|
|
6418
6425
|
async function startSession(id, body) {
|
|
6419
6426
|
return requestJson(`/api/sandbox/${encodeURIComponent(id)}/session`, {
|
|
6420
6427
|
method: "POST",
|
|
@@ -7582,22 +7589,112 @@ function readType(raw) {
|
|
|
7582
7589
|
return "raw";
|
|
7583
7590
|
}
|
|
7584
7591
|
|
|
7592
|
+
// src/commands/helix/signal.ts
|
|
7593
|
+
import chalk24 from "chalk";
|
|
7594
|
+
init_errors();
|
|
7595
|
+
var SIGNAL_TYPES = ["SIGINT", "SIGTERM"];
|
|
7596
|
+
var DEFAULT_SIGNAL = "SIGINT";
|
|
7597
|
+
function registerSignalCommand(parent) {
|
|
7598
|
+
parent.command("signal").description("Stop a running session, leaving its sandbox up").argument("<id>", "Sandbox ID").requiredOption("--session <id>", "Session ID inside the sandbox").option("--type <signal>", `${SIGNAL_TYPES.join(" | ")} (default: ${DEFAULT_SIGNAL})`).addHelpText("after", `
|
|
7599
|
+
Examples:
|
|
7600
|
+
${chalk24.dim("$")} mutagent helix signal sbx_123 --session s1 ${chalk24.dim("SIGINT — like Ctrl-C")}
|
|
7601
|
+
${chalk24.dim("$")} mutagent helix signal sbx_123 --session s1 --type SIGTERM ${chalk24.dim("Ask it to shut down")}
|
|
7602
|
+
${chalk24.dim("$")} mutagent helix signal sbx_123 --session s1 --json
|
|
7603
|
+
|
|
7604
|
+
THE SANDBOX SURVIVES. This stops the SESSION — the agent process — and leaves
|
|
7605
|
+
the box, its filesystem and its event log exactly where they are, so you can
|
|
7606
|
+
attach, exec against it, or read what the agent did before you stopped it.
|
|
7607
|
+
'mutagent helix rm <id>' is still the only thing that destroys a sandbox.
|
|
7608
|
+
|
|
7609
|
+
THREE WAYS TO STOP AN AGENT, WEAKEST FIRST:
|
|
7610
|
+
${chalk24.bold("send --type abort")} Asks the agent to end the turn. Needs a cooperating agent
|
|
7611
|
+
that is still reading its stdin. Try this first.
|
|
7612
|
+
${chalk24.bold("signal")} Does not ask. Reaches a wedged or looping process.
|
|
7613
|
+
The session ends; the box stays.
|
|
7614
|
+
${chalk24.bold("rm")} Destroys the sandbox and everything in it.
|
|
7615
|
+
|
|
7616
|
+
THE SIGNALS:
|
|
7617
|
+
SIGINT Interrupts the current turn, the way Ctrl-C does in a local terminal.
|
|
7618
|
+
SIGTERM Asks the process to shut down.
|
|
7619
|
+
SIGKILL is not accepted: it would end the session before it could flush the
|
|
7620
|
+
output you came back to read.
|
|
7621
|
+
|
|
7622
|
+
A 200 here means a LIVE process was signalled — not just that the request was
|
|
7623
|
+
understood. A session that had already finished is reported as such rather than
|
|
7624
|
+
being counted as a success, so this never tells you that you stopped an agent
|
|
7625
|
+
that had in fact been done for a while.
|
|
7626
|
+
|
|
7627
|
+
'mutagent helix ls' shows which sandboxes are up; 'mutagent helix attach <id>'
|
|
7628
|
+
shows what the session was doing.
|
|
7629
|
+
|
|
7630
|
+
AI Agent Directive:
|
|
7631
|
+
--json returns ONE object: { success, sandboxId, sessionId, signal, signalled,
|
|
7632
|
+
_links }. 'signalled' is an EFFECT, not an acknowledgement — it is true only
|
|
7633
|
+
when a running process was actually stopped.
|
|
7634
|
+
A session that has already ended exits non-zero rather than reporting success.
|
|
7635
|
+
Treat that as information, not as a failure to retry: the agent is already
|
|
7636
|
+
stopped, which is what you wanted.
|
|
7637
|
+
This does NOT destroy the sandbox. It stays billable until 'mutagent helix rm
|
|
7638
|
+
<id>'. Confirm with the user before that.
|
|
7639
|
+
`).action(async (id, options) => {
|
|
7640
|
+
const isJson = getJsonFlag(parent);
|
|
7641
|
+
const output = new OutputFormatter(isJson ? "json" : "table");
|
|
7642
|
+
try {
|
|
7643
|
+
const sessionId = options.session?.trim() ?? "";
|
|
7644
|
+
if (sessionId === "") {
|
|
7645
|
+
throw new MutagentError("MISSING_ARGUMENTS", "--session is required — a sandbox can hold more than one session.", `Run: mutagent helix signal ${id} --session <session-id>`);
|
|
7646
|
+
}
|
|
7647
|
+
const signal = resolveSignal(options.type);
|
|
7648
|
+
const result = await postSignal(id, { sessionId, signal });
|
|
7649
|
+
if (isJson) {
|
|
7650
|
+
output.output({
|
|
7651
|
+
success: true,
|
|
7652
|
+
sandboxId: id,
|
|
7653
|
+
sessionId,
|
|
7654
|
+
signal,
|
|
7655
|
+
signalled: result.signalled,
|
|
7656
|
+
_links: sandboxLinks(id),
|
|
7657
|
+
_directive: {
|
|
7658
|
+
instruction: "The session was stopped. The SANDBOX is still running and still billable — remove it explicitly when you are done with it.",
|
|
7659
|
+
next: [`mutagent helix attach ${id} --json`, `mutagent helix rm ${id}`]
|
|
7660
|
+
}
|
|
7661
|
+
});
|
|
7662
|
+
return;
|
|
7663
|
+
}
|
|
7664
|
+
output.success(`Sent ${signal} to session ${sessionId}`);
|
|
7665
|
+
console.error(chalk24.dim(` The sandbox is still up: mutagent helix attach ${id}`));
|
|
7666
|
+
console.error(chalk24.dim(` Destroy it with: mutagent helix rm ${id}`));
|
|
7667
|
+
} catch (error) {
|
|
7668
|
+
handleError(error, isJson);
|
|
7669
|
+
}
|
|
7670
|
+
});
|
|
7671
|
+
}
|
|
7672
|
+
function resolveSignal(raw) {
|
|
7673
|
+
if (raw === undefined)
|
|
7674
|
+
return DEFAULT_SIGNAL;
|
|
7675
|
+
const normalised = raw.trim().toUpperCase();
|
|
7676
|
+
if (!SIGNAL_TYPES.includes(normalised)) {
|
|
7677
|
+
throw new MutagentError("INVALID_ARGUMENTS", `Unknown signal "${raw}".`, `Use one of: ${SIGNAL_TYPES.join(", ")}. SIGKILL is not accepted — it would end the session before it could flush its output.`);
|
|
7678
|
+
}
|
|
7679
|
+
return normalised;
|
|
7680
|
+
}
|
|
7681
|
+
|
|
7585
7682
|
// src/commands/helix/session-start.ts
|
|
7586
7683
|
import { Command as Command13 } from "commander";
|
|
7587
|
-
import
|
|
7684
|
+
import chalk25 from "chalk";
|
|
7588
7685
|
init_errors();
|
|
7589
7686
|
function registerSessionCommand(parent) {
|
|
7590
7687
|
const session = new Command13("session").description("Start and inspect Helix sessions inside a sandbox").addHelpText("after", `
|
|
7591
7688
|
Examples:
|
|
7592
|
-
${
|
|
7593
|
-
${
|
|
7594
|
-
${
|
|
7689
|
+
${chalk25.dim("$")} mutagent helix session start sbx_123 --rpc
|
|
7690
|
+
${chalk25.dim("$")} mutagent helix session start sbx_123
|
|
7691
|
+
${chalk25.dim("$")} mutagent helix session start sbx_123 --rpc --json
|
|
7595
7692
|
|
|
7596
7693
|
A sandbox and a session are not the same thing:
|
|
7597
|
-
${
|
|
7598
|
-
${
|
|
7599
|
-
${
|
|
7600
|
-
${
|
|
7694
|
+
${chalk25.bold("spawn")} gives you a BOX — a machine with nothing running in it.
|
|
7695
|
+
${chalk25.bold("session start")} gives you an AGENT inside that box.
|
|
7696
|
+
${chalk25.bold("attach")} WATCHES that agent.
|
|
7697
|
+
${chalk25.bold("send")} TYPES INTO it.
|
|
7601
7698
|
A box with no session is a normal state — that is what 'exec' runs against.
|
|
7602
7699
|
|
|
7603
7700
|
AI Agent Directive:
|
|
@@ -7610,15 +7707,15 @@ AI Agent Directive:
|
|
|
7610
7707
|
function registerStart(session, root) {
|
|
7611
7708
|
session.command("start").description("Start a Helix session inside an existing sandbox").argument("<id>", "Sandbox ID").option("--rpc", "Long-lived session you can send into (default: one-shot)").addHelpText("after", `
|
|
7612
7709
|
Examples:
|
|
7613
|
-
${
|
|
7614
|
-
${
|
|
7615
|
-
${
|
|
7710
|
+
${chalk25.dim("$")} mutagent helix session start sbx_123 --rpc
|
|
7711
|
+
${chalk25.dim("$")} mutagent helix session start sbx_123
|
|
7712
|
+
${chalk25.dim("$")} mutagent helix session start sbx_123 --rpc --json
|
|
7616
7713
|
|
|
7617
7714
|
TWO MODES, AND ONLY ONE OF THEM LISTENS:
|
|
7618
|
-
${
|
|
7715
|
+
${chalk25.bold("--rpc")} A long-lived agent reading commands on its stdin. This is
|
|
7619
7716
|
the mode 'mutagent helix send' writes into; without it there
|
|
7620
7717
|
is nothing to write to and every send is refused.
|
|
7621
|
-
${
|
|
7718
|
+
${chalk25.dim("(default)")} One-shot. The session takes its turn and ends. Watchable
|
|
7622
7719
|
with 'attach', not steerable.
|
|
7623
7720
|
|
|
7624
7721
|
The box must already exist — 'mutagent helix spawn --image <ref>' makes one, and
|
|
@@ -7660,9 +7757,9 @@ AI Agent Directive:
|
|
|
7660
7757
|
return;
|
|
7661
7758
|
}
|
|
7662
7759
|
output.success(`Session ${sessionId} started in ${id} (${mode})`);
|
|
7663
|
-
console.error(
|
|
7760
|
+
console.error(chalk25.dim(` Watch it: mutagent helix attach ${id}`));
|
|
7664
7761
|
if (mode === "rpc") {
|
|
7665
|
-
console.error(
|
|
7762
|
+
console.error(chalk25.dim(` Talk to it: mutagent helix send ${id} --session ${sessionId} "<message>"`));
|
|
7666
7763
|
}
|
|
7667
7764
|
} catch (error) {
|
|
7668
7765
|
handleError(error, isJson);
|
|
@@ -7676,15 +7773,32 @@ function requireSessionId(result, sandboxId) {
|
|
|
7676
7773
|
}
|
|
7677
7774
|
|
|
7678
7775
|
// src/commands/helix/run.ts
|
|
7679
|
-
import
|
|
7776
|
+
import chalk26 from "chalk";
|
|
7680
7777
|
init_errors();
|
|
7681
7778
|
function registerRunCommand(parent) {
|
|
7682
|
-
parent.command("run").description("Run one Helix agent turn in a fresh sandbox").argument("<task...>", "WHAT to do this turn").requiredOption("--prompt <definition>", "WHO the agent is — the agent definition").option("--preset <name>", "Preset to run on (default: the backend default)").option("--keep", "Keep the sandbox afterwards instead of tearing it down").option("--timeout-ms <n>", "Per-command timeout in milliseconds").option("--no-stream", "Wait for the whole turn instead of watching it happen").addHelpText("after", `
|
|
7779
|
+
parent.command("run").alias("agent").description("Run one Helix agent turn in a fresh sandbox (alias: agent)").argument("<task...>", "WHAT to do this turn").requiredOption("--prompt <definition>", "WHO the agent is — the agent definition").option("--preset <name>", "Preset to run on (default: the backend default)").option("--keep", "Keep the sandbox afterwards instead of tearing it down").option("--timeout-ms <n>", "Per-command timeout in milliseconds").option("--no-stream", "Wait for the whole turn instead of watching it happen").option("--prime", "Run on the leaner ASPS-Prime scaffold (the binary's --prime)").addHelpText("after", `
|
|
7683
7780
|
Examples:
|
|
7684
|
-
${
|
|
7685
|
-
${
|
|
7686
|
-
${
|
|
7687
|
-
${
|
|
7781
|
+
${chalk26.dim("$")} mutagent helix run "summarise the failing tests" --prompt "You are a test triage agent."
|
|
7782
|
+
${chalk26.dim("$")} mutagent helix run fix the flaky login spec --prompt "$(cat agent.md)"
|
|
7783
|
+
${chalk26.dim("$")} mutagent helix run "list open PRs" --prompt "You are a release assistant." --json
|
|
7784
|
+
${chalk26.dim("$")} mutagent helix run "explore the repo" --prompt "$(cat agent.md)" --keep
|
|
7785
|
+
|
|
7786
|
+
--prime — THE SAME FLAG THE LOCAL BINARY TAKES:
|
|
7787
|
+
'helix agent --prime' locally and 'mutagent helix run --prime' in the cloud
|
|
7788
|
+
select the same thing: the ASPS-Prime scaffold, a leaner code-first arm with
|
|
7789
|
+
no orchestrator persona, no skills and no sub-agent crew. It is forwarded to
|
|
7790
|
+
the binary as argv rather than interpreted by the server, so it means exactly
|
|
7791
|
+
what the binary's own --help says it means. This is NOT a speed setting — it
|
|
7792
|
+
changes which agent takes the turn.
|
|
7793
|
+
|
|
7794
|
+
SAME COMMAND, TWO NAMES:
|
|
7795
|
+
'mutagent helix agent' is an ALIAS of 'mutagent helix run'. Not a variant, not
|
|
7796
|
+
a shorthand with different defaults — the same command, the same flags, the
|
|
7797
|
+
same behaviour. It exists so the verb that works against the local binary
|
|
7798
|
+
('helix agent --prompt "..." "task"') also works against the cloud.
|
|
7799
|
+
RUN is the canonical name: it is what the docs, the JSON output and the error
|
|
7800
|
+
messages use. 'agent' is there so a caller who learned the local CLI does not
|
|
7801
|
+
have to learn a second word for the same operation.
|
|
7688
7802
|
|
|
7689
7803
|
TWO PROMPTS, AND THEY ARE NOT THE SAME THING:
|
|
7690
7804
|
--prompt WHO the agent is — its definition, its standing instructions.
|
|
@@ -7719,6 +7833,11 @@ AI Agent Directive:
|
|
|
7719
7833
|
is a complete summary object, so '| tail -1' still yields one object. Same
|
|
7720
7834
|
convention as 'mutagent helix exec'.
|
|
7721
7835
|
Both --prompt and the task are required; do not fold one into the other.
|
|
7836
|
+
'mutagent helix agent' and 'mutagent helix run' are THE SAME COMMAND. Prefer
|
|
7837
|
+
'run' in anything you write down; 'agent' exists for parity with the local
|
|
7838
|
+
'helix agent' verb.
|
|
7839
|
+
--prime selects the binary's leaner scaffold. Omit it unless the user asked
|
|
7840
|
+
for it; it is not a performance flag, it changes which agent runs.
|
|
7722
7841
|
`).action(async (taskParts, options) => {
|
|
7723
7842
|
const isJson = getJsonFlag(parent);
|
|
7724
7843
|
const output = new OutputFormatter(isJson ? "json" : "table");
|
|
@@ -7735,6 +7854,7 @@ AI Agent Directive:
|
|
|
7735
7854
|
const body = {
|
|
7736
7855
|
prompt,
|
|
7737
7856
|
task,
|
|
7857
|
+
...options.prime === true ? { prime: true } : {},
|
|
7738
7858
|
...oneShotFields(options.preset, options.keep, options.timeoutMs)
|
|
7739
7859
|
};
|
|
7740
7860
|
if (options.stream === false) {
|
|
@@ -7791,17 +7911,17 @@ async function streamAgentTurn(body, isJson, keep) {
|
|
|
7791
7911
|
function registerExecCommand(parent) {
|
|
7792
7912
|
parent.command("exec").description("Run a command in a sandbox — an existing one, or a fresh one").argument("<argv...>", "Command and arguments (argv, not a shell string)").option("--sandbox <id>", "Run in this existing sandbox instead of a fresh one").option("--preset <name>", "Preset for the fresh sandbox (ignored with --sandbox)").option("--keep", "Keep the fresh sandbox afterwards (ignored with --sandbox)").option("--cwd <dir>", "Working directory inside the sandbox").option("--timeout-ms <n>", "Command timeout in milliseconds").option("--no-stream", "Wait for the full result instead of streaming it").addHelpText("after", `
|
|
7793
7913
|
Examples:
|
|
7794
|
-
${
|
|
7795
|
-
${
|
|
7796
|
-
${
|
|
7797
|
-
${
|
|
7914
|
+
${chalk26.dim("$")} mutagent helix exec -- ls -la /workspace
|
|
7915
|
+
${chalk26.dim("$")} mutagent helix exec --sandbox sbx_123 -- bun test
|
|
7916
|
+
${chalk26.dim("$")} mutagent helix exec --sandbox sbx_123 --cwd /src -- git status
|
|
7917
|
+
${chalk26.dim("$")} mutagent helix exec --preset default -- uname -m --json
|
|
7798
7918
|
|
|
7799
|
-
Put ${
|
|
7919
|
+
Put ${chalk26.bold("--")} before the command. Everything after it is argv and is passed through
|
|
7800
7920
|
untouched, so flags meant for your command are not read as flags for this one.
|
|
7801
7921
|
|
|
7802
7922
|
ARGV, NOT A SHELL STRING. There is no shell in the sandbox unless you name one:
|
|
7803
|
-
${
|
|
7804
|
-
${
|
|
7923
|
+
${chalk26.dim("$")} mutagent helix exec -- sh -c 'ls | wc -l' ${chalk26.dim("a shell, explicitly")}
|
|
7924
|
+
${chalk26.dim("$")} mutagent helix exec -- 'ls | wc -l' ${chalk26.dim("looks for a file called 'ls | wc -l'")}
|
|
7805
7925
|
|
|
7806
7926
|
WITH --sandbox runs in that box and streams as output is produced.
|
|
7807
7927
|
WITHOUT --sandbox spawns a fresh box from a preset, runs, tears it down. That
|
|
@@ -7933,17 +8053,17 @@ function reportResult(result, output, isJson, context) {
|
|
|
7933
8053
|
}
|
|
7934
8054
|
|
|
7935
8055
|
// src/commands/helix/inventory.ts
|
|
7936
|
-
import
|
|
8056
|
+
import chalk27 from "chalk";
|
|
7937
8057
|
init_errors();
|
|
7938
8058
|
function registerLsCommand(parent) {
|
|
7939
8059
|
parent.command("ls").description("List your sandboxes").addHelpText("after", `
|
|
7940
8060
|
Examples:
|
|
7941
|
-
${
|
|
7942
|
-
${
|
|
8061
|
+
${chalk27.dim("$")} mutagent helix ls
|
|
8062
|
+
${chalk27.dim("$")} mutagent helix ls --json
|
|
7943
8063
|
|
|
7944
8064
|
Listing is always workspace-scoped — these are the sandboxes in the workspace
|
|
7945
8065
|
you are configured for, not every sandbox on the account. Change it with:
|
|
7946
|
-
${
|
|
8066
|
+
${chalk27.dim("$")} mutagent config set workspace <workspace-id>
|
|
7947
8067
|
|
|
7948
8068
|
An empty list is a normal result, not an error: it means no sandbox is running.
|
|
7949
8069
|
|
|
@@ -7963,7 +8083,7 @@ AI Agent Directive:
|
|
|
7963
8083
|
return;
|
|
7964
8084
|
}
|
|
7965
8085
|
if (sandboxes.length === 0) {
|
|
7966
|
-
console.log(
|
|
8086
|
+
console.log(chalk27.gray("No sandboxes running."));
|
|
7967
8087
|
console.log("");
|
|
7968
8088
|
console.log(" Start one: mutagent helix spawn --image <ref>");
|
|
7969
8089
|
return;
|
|
@@ -7987,8 +8107,8 @@ function toRow(sandbox) {
|
|
|
7987
8107
|
function registerPresetsCommand(parent) {
|
|
7988
8108
|
parent.command("presets").description("List the presets a one-shot run can name").addHelpText("after", `
|
|
7989
8109
|
Examples:
|
|
7990
|
-
${
|
|
7991
|
-
${
|
|
8110
|
+
${chalk27.dim("$")} mutagent helix presets
|
|
8111
|
+
${chalk27.dim("$")} mutagent helix presets --json
|
|
7992
8112
|
|
|
7993
8113
|
A preset is a named definition on the backend. It is what lets 'helix run' and
|
|
7994
8114
|
'helix exec' start something without you knowing an image reference, a registry
|
|
@@ -8009,7 +8129,7 @@ AI Agent Directive:
|
|
|
8009
8129
|
return;
|
|
8010
8130
|
}
|
|
8011
8131
|
if (presets.length === 0) {
|
|
8012
|
-
console.log(
|
|
8132
|
+
console.log(chalk27.gray("No presets configured on this backend."));
|
|
8013
8133
|
console.log("");
|
|
8014
8134
|
console.log(" Spawn with an explicit image: mutagent helix spawn --image <ref>");
|
|
8015
8135
|
return;
|
|
@@ -8029,15 +8149,15 @@ AI Agent Directive:
|
|
|
8029
8149
|
function registerRmCommand(parent) {
|
|
8030
8150
|
parent.command("rm").description("Destroy a sandbox").argument("<id>", "Sandbox ID").option("-f, --force", "Skip confirmation").addHelpText("after", `
|
|
8031
8151
|
Examples:
|
|
8032
|
-
${
|
|
8033
|
-
${
|
|
8152
|
+
${chalk27.dim("$")} mutagent helix rm sbx_123 --force
|
|
8153
|
+
${chalk27.dim("$")} mutagent helix rm sbx_123 --json
|
|
8034
8154
|
|
|
8035
8155
|
This is the ONLY command that destroys a sandbox — detaching, Ctrl-C and a
|
|
8036
8156
|
closed terminal all leave it running. Removing a sandbox that is already gone
|
|
8037
8157
|
succeeds, so a retried teardown is safe.
|
|
8038
8158
|
|
|
8039
|
-
${
|
|
8040
|
-
${
|
|
8159
|
+
${chalk27.dim("Note: --force is required. The CLI is non-interactive — confirm with the user via your native flow, then pass --force. --json auto-confirms.")}
|
|
8160
|
+
${chalk27.dim("Warning: any session running in the sandbox ends immediately and cannot be recovered.")}
|
|
8041
8161
|
|
|
8042
8162
|
AI Agent Directive:
|
|
8043
8163
|
Destroying a sandbox ends any session running in it and cannot be undone.
|
|
@@ -8072,8 +8192,8 @@ Use --force to confirm: mutagent helix rm ${id} --force`);
|
|
|
8072
8192
|
function registerTracesCommand(parent) {
|
|
8073
8193
|
parent.command("traces").description("Show the spans captured for a sandbox").argument("<id>", "Sandbox ID").addHelpText("after", `
|
|
8074
8194
|
Examples:
|
|
8075
|
-
${
|
|
8076
|
-
${
|
|
8195
|
+
${chalk27.dim("$")} mutagent helix traces sbx_123
|
|
8196
|
+
${chalk27.dim("$")} mutagent helix traces sbx_123 --json
|
|
8077
8197
|
|
|
8078
8198
|
Spans are what the session actually did — the record to read when the output
|
|
8079
8199
|
alone does not explain the result. They are called spans, not traces, because
|
|
@@ -8097,7 +8217,7 @@ AI Agent Directive:
|
|
|
8097
8217
|
return;
|
|
8098
8218
|
}
|
|
8099
8219
|
if (spans.length === 0) {
|
|
8100
|
-
console.log(
|
|
8220
|
+
console.log(chalk27.gray(`No spans captured for sandbox ${id}.`));
|
|
8101
8221
|
return;
|
|
8102
8222
|
}
|
|
8103
8223
|
output.output(spans.map((span) => {
|
|
@@ -8119,43 +8239,49 @@ AI Agent Directive:
|
|
|
8119
8239
|
function createHelixCommand() {
|
|
8120
8240
|
const helix = new Command14("helix").description("Run Helix sessions in a cloud sandbox").addHelpText("after", `
|
|
8121
8241
|
Examples:
|
|
8122
|
-
${
|
|
8123
|
-
${
|
|
8124
|
-
${
|
|
8125
|
-
${
|
|
8126
|
-
${
|
|
8127
|
-
${
|
|
8128
|
-
${
|
|
8129
|
-
${
|
|
8130
|
-
${
|
|
8131
|
-
${
|
|
8132
|
-
${
|
|
8242
|
+
${chalk28.dim("$")} mutagent helix run "fix the failing test" --prompt "$(cat agent.md)"
|
|
8243
|
+
${chalk28.dim("$")} mutagent helix exec -- uname -m ${chalk28.dim("One command, fresh box")}
|
|
8244
|
+
${chalk28.dim("$")} mutagent helix presets ${chalk28.dim("What a one-shot can run on")}
|
|
8245
|
+
${chalk28.dim("$")} mutagent helix spawn --image alpine:3.20 ${chalk28.dim("Persistent box, then attach")}
|
|
8246
|
+
${chalk28.dim("$")} mutagent helix session start sbx_1 --rpc ${chalk28.dim("Start an agent inside that box")}
|
|
8247
|
+
${chalk28.dim("$")} mutagent helix ls ${chalk28.dim("What is running")}
|
|
8248
|
+
${chalk28.dim("$")} mutagent helix exec --sandbox sbx_1 -- bun test ${chalk28.dim("Command in that box")}
|
|
8249
|
+
${chalk28.dim("$")} mutagent helix attach sbx_1 --since 412 ${chalk28.dim("Resume after a sequence number")}
|
|
8250
|
+
${chalk28.dim("$")} mutagent helix send sbx_1 --session s1 "and now" ${chalk28.dim("Talk to a running session")}
|
|
8251
|
+
${chalk28.dim("$")} mutagent helix signal sbx_1 --session s1 ${chalk28.dim("Stop the agent, keep the box")}
|
|
8252
|
+
${chalk28.dim("$")} mutagent helix traces sbx_1 --json ${chalk28.dim("What the session actually did")}
|
|
8253
|
+
${chalk28.dim("$")} mutagent helix rm sbx_1 --force ${chalk28.dim("Destroy it")}
|
|
8133
8254
|
|
|
8134
8255
|
Subcommands:
|
|
8135
|
-
run, exec, spawn, session, ls, presets, attach, send,
|
|
8256
|
+
run (alias: agent), exec, spawn, session, ls, presets, attach, send, signal,
|
|
8257
|
+
traces, rm
|
|
8136
8258
|
|
|
8137
8259
|
One-shot vs persistent:
|
|
8138
|
-
${
|
|
8260
|
+
${chalk28.bold("run")} and ${chalk28.bold("exec")} (without --sandbox) start from a named PRESET, do one
|
|
8139
8261
|
thing and tear the sandbox down. Nothing to clean up, no image to know.
|
|
8140
|
-
${
|
|
8141
|
-
${
|
|
8262
|
+
${chalk28.bold("spawn")} takes an explicit --image and leaves a box running for you to
|
|
8263
|
+
${chalk28.bold("attach")} and ${chalk28.bold("exec --sandbox")} against until you ${chalk28.bold("rm")} it.
|
|
8142
8264
|
|
|
8143
8265
|
Boxes vs sessions vs watching vs steering:
|
|
8144
|
-
${
|
|
8145
|
-
${
|
|
8266
|
+
${chalk28.bold("spawn")} gives you a BOX. ${chalk28.bold("session start")} gives you an AGENT inside that box.
|
|
8267
|
+
${chalk28.bold("attach")} WATCHES that agent; it does not type into one. ${chalk28.bold("send")} TYPES INTO it,
|
|
8146
8268
|
from any terminal holding the id — so a session can be redirected without the
|
|
8147
8269
|
terminal that started it. A box with no session is normal: that is what
|
|
8148
|
-
${
|
|
8270
|
+
${chalk28.bold("exec")} runs against.
|
|
8271
|
+
${chalk28.bold("signal")} STOPS that agent and leaves the box standing — the remote Ctrl-C.
|
|
8272
|
+
Only ${chalk28.bold("rm")} destroys a sandbox.
|
|
8149
8273
|
|
|
8150
8274
|
Lifecycle:
|
|
8151
8275
|
A spawned sandbox outlives your terminal. Ctrl-C, a dropped connection and a
|
|
8152
8276
|
closed terminal all DETACH — the session keeps running and can be re-attached.
|
|
8277
|
+
Stopping the AGENT is a different thing from destroying the BOX: 'signal' does
|
|
8278
|
+
the first, 'rm' does the second.
|
|
8153
8279
|
Only 'mutagent helix rm <id>' destroys a sandbox, so remember to run it when
|
|
8154
8280
|
you are finished.
|
|
8155
8281
|
|
|
8156
8282
|
Access:
|
|
8157
8283
|
Sandbox access is minted per WORKSPACE, so a workspace must be configured:
|
|
8158
|
-
${
|
|
8284
|
+
${chalk28.dim("$")} mutagent config set workspace <workspace-id>
|
|
8159
8285
|
|
|
8160
8286
|
Output:
|
|
8161
8287
|
Sandbox stdout goes to stdout, sandbox stderr goes to stderr, and anything
|
|
@@ -8175,6 +8301,9 @@ AI Agent Directive:
|
|
|
8175
8301
|
single JSON document until it ends. Everything else returns one JSON object.
|
|
8176
8302
|
'run' is always blocking: it takes TWO strings, --prompt (WHO the agent is)
|
|
8177
8303
|
and the task (WHAT to do). Never fold one into the other.
|
|
8304
|
+
'run' and 'agent' are the same command; 'run' is the canonical name.
|
|
8305
|
+
To stop a running agent, prefer 'send --type abort' (asks it to stop), then
|
|
8306
|
+
'signal' (does not ask). Neither destroys the sandbox — only 'rm' does.
|
|
8178
8307
|
Spawning consumes resources until removed — confirm with the user before
|
|
8179
8308
|
'spawn' and before 'rm'.
|
|
8180
8309
|
`);
|
|
@@ -8185,6 +8314,7 @@ AI Agent Directive:
|
|
|
8185
8314
|
registerPresetsCommand(helix);
|
|
8186
8315
|
registerAttachCommand(helix);
|
|
8187
8316
|
registerSendCommand(helix);
|
|
8317
|
+
registerSignalCommand(helix);
|
|
8188
8318
|
registerSessionCommand(helix);
|
|
8189
8319
|
registerTracesCommand(helix);
|
|
8190
8320
|
registerRmCommand(helix);
|
|
@@ -8309,61 +8439,61 @@ program.name("mutagent").description(`Mutagent CLI - command-line client for the
|
|
|
8309
8439
|
});
|
|
8310
8440
|
program.addHelpText("beforeAll", () => renderBanner());
|
|
8311
8441
|
program.addHelpText("after", `
|
|
8312
|
-
${
|
|
8313
|
-
${
|
|
8314
|
-
${
|
|
8315
|
-
${
|
|
8442
|
+
${chalk29.bold.cyan("WORKFLOWS:")}
|
|
8443
|
+
${chalk29.bold("Setup")} mutagent login → mutagent init
|
|
8444
|
+
${chalk29.bold("Lifecycle Tools")} mutagent install helix ${chalk29.dim("(login-gated)")}
|
|
8445
|
+
${chalk29.bold("Feedback")} mutagent feedback send "<what happened>" --category <cli|helix|stage:<x>> ${chalk29.dim("[--session <id>] [--attach-transcript]")}
|
|
8316
8446
|
|
|
8317
|
-
${
|
|
8318
|
-
${
|
|
8447
|
+
${chalk29.dim("For CLI usage guidance for AI agents, see the Skill at")}
|
|
8448
|
+
${chalk29.cyan(".claude/skills/mutagent-cli/SKILL.md")}
|
|
8319
8449
|
|
|
8320
|
-
${
|
|
8321
|
-
-v, --version ${
|
|
8450
|
+
${chalk29.yellow("Global flags:")}
|
|
8451
|
+
-v, --version ${chalk29.dim("Print the CLI version")} ${chalk29.dim("(before a subcommand; after one it is the subcommand's)")}
|
|
8322
8452
|
--json --api-key <k> --endpoint <url> --non-interactive
|
|
8323
8453
|
|
|
8324
|
-
${
|
|
8325
|
-
export MUTAGENT_API_KEY=mt_... ${
|
|
8326
|
-
--json ${
|
|
8454
|
+
${chalk29.yellow("Non-Interactive Mode (CI/CD & Coding Agents):")}
|
|
8455
|
+
export MUTAGENT_API_KEY=mt_... ${chalk29.dim("or")} --api-key mt_...
|
|
8456
|
+
--json ${chalk29.dim("for structured output")} --non-interactive ${chalk29.dim("to disable prompts")}
|
|
8327
8457
|
|
|
8328
|
-
${
|
|
8329
|
-
mutagent login ${
|
|
8330
|
-
mutagent auth status ${
|
|
8331
|
-
mutagent init ${
|
|
8332
|
-
mutagent workspaces list --json ${
|
|
8333
|
-
mutagent config set workspace <id> ${
|
|
8334
|
-
mutagent usage --json ${
|
|
8458
|
+
${chalk29.yellow("Command Navigation:")}
|
|
8459
|
+
mutagent login ${chalk29.dim("Login (browser OAuth — recommended)")}
|
|
8460
|
+
mutagent auth status ${chalk29.dim("Check auth + workspace")}
|
|
8461
|
+
mutagent init ${chalk29.dim("Initialize project (.mutagentrc.json)")}
|
|
8462
|
+
mutagent workspaces list --json ${chalk29.dim("List workspaces (verify ID)")}
|
|
8463
|
+
mutagent config set workspace <id> ${chalk29.dim("Set active workspace")}
|
|
8464
|
+
mutagent usage --json ${chalk29.dim("Show account usage + provider status")}
|
|
8335
8465
|
|
|
8336
|
-
mutagent providers list --json ${
|
|
8337
|
-
mutagent providers list --models ${
|
|
8466
|
+
mutagent providers list --json ${chalk29.dim("List configured BYOK providers")}
|
|
8467
|
+
mutagent providers list --models ${chalk29.dim("See available models per provider")}
|
|
8338
8468
|
|
|
8339
|
-
mutagent helix run "<task>" --prompt "<who>" ${
|
|
8340
|
-
mutagent helix ls --json ${
|
|
8341
|
-
mutagent helix spawn --image <ref> ${
|
|
8342
|
-
mutagent helix rm <id> --force ${
|
|
8469
|
+
mutagent helix run "<task>" --prompt "<who>" ${chalk29.dim("One Helix agent turn in a cloud sandbox")}
|
|
8470
|
+
mutagent helix ls --json ${chalk29.dim("List running sandboxes")}
|
|
8471
|
+
mutagent helix spawn --image <ref> ${chalk29.dim("Persistent sandbox you attach to")}
|
|
8472
|
+
mutagent helix rm <id> --force ${chalk29.dim("Destroy a sandbox (the only thing that does)")}
|
|
8343
8473
|
|
|
8344
|
-
mutagent install helix ${
|
|
8345
|
-
mutagent install helix --version 1.2.3 ${
|
|
8346
|
-
mutagent install --help ${
|
|
8474
|
+
mutagent install helix ${chalk29.dim("Install the ADL lifecycle conductor locally (login-gated)")}
|
|
8475
|
+
mutagent install helix --version 1.2.3 ${chalk29.dim("Pin a version")}
|
|
8476
|
+
mutagent install --help ${chalk29.dim("helix")}
|
|
8347
8477
|
|
|
8348
|
-
mutagent hooks --help ${
|
|
8478
|
+
mutagent hooks --help ${chalk29.dim("Hook setup for Claude Code session telemetry upload")}
|
|
8349
8479
|
|
|
8350
|
-
${
|
|
8351
|
-
Hit a bug? Run: ${
|
|
8352
|
-
Lifecycle-stage feedback: ${
|
|
8353
|
-
Link to a session: ${
|
|
8354
|
-
Attach your coding-agent session transcript: ${
|
|
8355
|
-
${
|
|
8480
|
+
${chalk29.bold.red("Report Issues:")}
|
|
8481
|
+
Hit a bug? Run: ${chalk29.cyan('mutagent feedback send "describe what went wrong" --category cli')}
|
|
8482
|
+
Lifecycle-stage feedback: ${chalk29.cyan('mutagent feedback send "eval gate unclear" --category stage:evaluate')}
|
|
8483
|
+
Link to a session: ${chalk29.cyan('mutagent feedback send "..." --session <session-id>')}
|
|
8484
|
+
Attach your coding-agent session transcript: ${chalk29.cyan('mutagent feedback send "..." --attach-transcript')}
|
|
8485
|
+
${chalk29.dim("--category accepts: cli | helix | stage:<spec|build|evaluate|diagnose|optimize>")}
|
|
8356
8486
|
|
|
8357
|
-
${
|
|
8487
|
+
${chalk29.yellow("Directive System:")}
|
|
8358
8488
|
Every --json response may include:
|
|
8359
|
-
${
|
|
8360
|
-
${
|
|
8361
|
-
${
|
|
8362
|
-
${
|
|
8363
|
-
${
|
|
8364
|
-
${
|
|
8365
|
-
|
|
8366
|
-
${
|
|
8489
|
+
${chalk29.bold("_directive.display")} Type tag — 'status_card' for card-kind directives (drives test/docs guards)
|
|
8490
|
+
${chalk29.bold("_directive.renderedCard")} Pre-formatted card ${chalk29.red("(MUST echo verbatim in chat whenever this field exists — see SKILL.md Verbatim Card Display Protocol)")}
|
|
8491
|
+
${chalk29.bold("_directive.instruction")} Next step for the agent (self-sufficient, no Skill required)
|
|
8492
|
+
${chalk29.bold("_directive.next")} Array of suggested follow-up commands
|
|
8493
|
+
${chalk29.bold("_links")} Dashboard/API URLs (format as markdown links)
|
|
8494
|
+
${chalk29.bold("_compat")} Compat metadata: cliVersion, skillVersion, skillMinCliVersion
|
|
8495
|
+
|
|
8496
|
+
${chalk29.yellow("AI Agent Rules (MANDATORY for coding agents):")}
|
|
8367
8497
|
1. Login (two paths):
|
|
8368
8498
|
- CI / fully automated: export MUTAGENT_API_KEY=mt_... then mutagent login --json
|
|
8369
8499
|
- Helping a user onboard: mutagent login --browser --json
|
|
@@ -8373,13 +8503,13 @@ ${chalk28.yellow("AI Agent Rules (MANDATORY for coding agents):")}
|
|
|
8373
8503
|
2. EVERY command MUST include --json (no exceptions)
|
|
8374
8504
|
3. Run <command> --help BEFORE first use of any command
|
|
8375
8505
|
4. Parse _directive.renderedCard and copy it into your CHAT RESPONSE verbatim
|
|
8376
|
-
${
|
|
8506
|
+
${chalk29.red("HARD STOP")}: do NOT run further commands until the card is rendered in chat
|
|
8377
8507
|
5. After mutagent init, verify workspace: mutagent workspaces list --json
|
|
8378
8508
|
6. ALL user interaction via AskUserQuestion — CLI is non-interactive
|
|
8379
8509
|
${!hasCredentials() ? `
|
|
8380
|
-
` +
|
|
8510
|
+
` + chalk29.yellow(" Warning: Not authenticated. Run: mutagent login") + `
|
|
8381
8511
|
` : ""}${!hasRcConfig() ? `
|
|
8382
|
-
` +
|
|
8512
|
+
` + chalk29.green(" Get started: mutagent init") + `
|
|
8383
8513
|
` : ""}`);
|
|
8384
8514
|
var rawArgs = process.argv.slice(2);
|
|
8385
8515
|
if (isGlobalVersionFlag(rawArgs)) {
|
|
@@ -8420,5 +8550,5 @@ program.addCommand(createFeedbackCommand());
|
|
|
8420
8550
|
program.addCommand(createTraceCommand());
|
|
8421
8551
|
program.parse();
|
|
8422
8552
|
|
|
8423
|
-
//# debugId=
|
|
8553
|
+
//# debugId=B28A5231DE264E0C64756E2164756E21
|
|
8424
8554
|
//# sourceMappingURL=cli.js.map
|