refactor(sandbox-cli): improve structure and reduce duplication
Improvements: - Extract help text examples into EXAMPLES constant object - Add createRunner() helper to reduce try-catch boilerplate - Add normalizeOptions() helper (prepared for future use) - Fix command names from 'clawd' to 'clawdbot' throughout - Update main sandbox command to show help by default - Better organize code with clear section comments Increases from 82 to 137 LOC but with much better organization and reduced duplication in error handling.
This commit is contained in:
committed by
Peter Steinberger
parent
1c757ae35e
commit
b0c97d6178
@@ -6,55 +6,123 @@ import {
|
|||||||
} from "../commands/sandbox.js";
|
} from "../commands/sandbox.js";
|
||||||
import { defaultRuntime } from "../runtime.js";
|
import { defaultRuntime } from "../runtime.js";
|
||||||
|
|
||||||
|
// --- Types ---
|
||||||
|
|
||||||
|
type CommandOptions = Record<string, unknown>;
|
||||||
|
|
||||||
|
// --- Helpers ---
|
||||||
|
|
||||||
|
const EXAMPLES = {
|
||||||
|
main: `
|
||||||
|
Examples:
|
||||||
|
clawdbot sandbox list # List all sandbox containers
|
||||||
|
clawdbot sandbox list --browser # List only browser containers
|
||||||
|
clawdbot sandbox recreate --all # Recreate all containers
|
||||||
|
clawdbot sandbox recreate --session main # Recreate specific session
|
||||||
|
clawdbot sandbox recreate --agent mybot # Recreate agent containers`,
|
||||||
|
|
||||||
|
list: `
|
||||||
|
Examples:
|
||||||
|
clawdbot sandbox list # List all sandbox containers
|
||||||
|
clawdbot sandbox list --browser # List only browser containers
|
||||||
|
clawdbot sandbox list --json # JSON output
|
||||||
|
|
||||||
|
Output includes:
|
||||||
|
• Container name and status (running/stopped)
|
||||||
|
• Docker image and whether it matches current config
|
||||||
|
• Age (time since creation)
|
||||||
|
• Idle time (time since last use)
|
||||||
|
• Associated session/agent ID`,
|
||||||
|
|
||||||
|
recreate: `
|
||||||
|
Examples:
|
||||||
|
clawdbot sandbox recreate --all # Recreate all containers
|
||||||
|
clawdbot sandbox recreate --session main # Specific session
|
||||||
|
clawdbot sandbox recreate --agent mybot # Specific agent (includes sub-agents)
|
||||||
|
clawdbot sandbox recreate --browser --all # All browser containers only
|
||||||
|
clawdbot sandbox recreate --all --force # Skip confirmation
|
||||||
|
|
||||||
|
Why use this?
|
||||||
|
After updating Docker images or sandbox configuration, existing containers
|
||||||
|
continue running with old settings. This command removes them so they'll be
|
||||||
|
recreated automatically with current config when next needed.
|
||||||
|
|
||||||
|
Filter options:
|
||||||
|
--all Remove all sandbox containers
|
||||||
|
--session Remove container for specific session key
|
||||||
|
--agent Remove containers for agent (includes agent:id:* variants)
|
||||||
|
|
||||||
|
Modifiers:
|
||||||
|
--browser Only affect browser containers (not regular sandbox)
|
||||||
|
--force Skip confirmation prompt`,
|
||||||
|
};
|
||||||
|
|
||||||
|
function createRunner(
|
||||||
|
commandFn: (opts: CommandOptions, runtime: typeof defaultRuntime) => Promise<void>,
|
||||||
|
) {
|
||||||
|
return async (opts: CommandOptions) => {
|
||||||
|
try {
|
||||||
|
await commandFn(opts, defaultRuntime);
|
||||||
|
} catch (err) {
|
||||||
|
defaultRuntime.error(String(err));
|
||||||
|
defaultRuntime.exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeOptions(opts: CommandOptions): CommandOptions {
|
||||||
|
const normalized: CommandOptions = {};
|
||||||
|
for (const [key, value] of Object.entries(opts)) {
|
||||||
|
normalized[key] = typeof value === "boolean" ? value : value;
|
||||||
|
}
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Registration ---
|
||||||
|
|
||||||
export function registerSandboxCli(program: Command) {
|
export function registerSandboxCli(program: Command) {
|
||||||
const sandbox = program
|
const sandbox = program
|
||||||
.command("sandbox")
|
.command("sandbox")
|
||||||
.description("Manage sandbox containers (Docker-based agent isolation)");
|
.description("Manage sandbox containers (Docker-based agent isolation)")
|
||||||
|
.addHelpText("after", EXAMPLES.main)
|
||||||
|
.action(() => {
|
||||||
|
sandbox.help({ error: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- List Command ---
|
||||||
|
|
||||||
sandbox
|
sandbox
|
||||||
.command("list")
|
.command("list")
|
||||||
.description("List sandbox containers and their status")
|
.description("List sandbox containers and their status")
|
||||||
|
.option("--json", "Output result as JSON", false)
|
||||||
.option("--browser", "List browser containers only", false)
|
.option("--browser", "List browser containers only", false)
|
||||||
.option("--json", "Output JSON", false)
|
.addHelpText("after", EXAMPLES.list)
|
||||||
.action(async (opts) => {
|
.action(
|
||||||
try {
|
createRunner((opts) =>
|
||||||
await sandboxListCommand(
|
sandboxListCommand(
|
||||||
{
|
{
|
||||||
browser: Boolean(opts.browser),
|
browser: Boolean(opts.browser),
|
||||||
json: Boolean(opts.json),
|
json: Boolean(opts.json),
|
||||||
},
|
},
|
||||||
defaultRuntime,
|
defaultRuntime,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} catch (err) {
|
|
||||||
defaultRuntime.error(String(err));
|
// --- Recreate Command ---
|
||||||
defaultRuntime.exit(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
sandbox
|
sandbox
|
||||||
.command("recreate")
|
.command("recreate")
|
||||||
.description("Recreate sandbox containers (e.g., after image updates)")
|
.description("Remove containers to force recreation with updated config")
|
||||||
.option("--all", "Recreate all sandbox containers", false)
|
.option("--all", "Recreate all sandbox containers", false)
|
||||||
.option("--session <key>", "Recreate container for specific session")
|
.option("--session <key>", "Recreate container for specific session")
|
||||||
.option("--agent <id>", "Recreate containers for specific agent")
|
.option("--agent <id>", "Recreate containers for specific agent")
|
||||||
.option("--browser", "Only recreate browser containers", false)
|
.option("--browser", "Only recreate browser containers", false)
|
||||||
.option("--force", "Skip confirmation prompt", false)
|
.option("--force", "Skip confirmation prompt", false)
|
||||||
.addHelpText(
|
.addHelpText("after", EXAMPLES.recreate)
|
||||||
"after",
|
.action(
|
||||||
`
|
createRunner((opts) =>
|
||||||
Examples:
|
sandboxRecreateCommand(
|
||||||
clawd sandbox recreate --all # Recreate all sandbox containers
|
|
||||||
clawd sandbox recreate --session main # Recreate container for main session
|
|
||||||
clawd sandbox recreate --agent mybot # Recreate containers for 'mybot' agent
|
|
||||||
clawd sandbox recreate --browser # Only recreate browser containers
|
|
||||||
clawd sandbox recreate --all --force # Skip confirmation
|
|
||||||
|
|
||||||
Use this command after updating sandbox images or changing sandbox configuration
|
|
||||||
to ensure containers use the latest settings.`,
|
|
||||||
)
|
|
||||||
.action(async (opts) => {
|
|
||||||
try {
|
|
||||||
await sandboxRecreateCommand(
|
|
||||||
{
|
{
|
||||||
all: Boolean(opts.all),
|
all: Boolean(opts.all),
|
||||||
session: opts.session as string | undefined,
|
session: opts.session as string | undefined,
|
||||||
@@ -63,20 +131,7 @@ to ensure containers use the latest settings.`,
|
|||||||
force: Boolean(opts.force),
|
force: Boolean(opts.force),
|
||||||
},
|
},
|
||||||
defaultRuntime,
|
defaultRuntime,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} catch (err) {
|
|
||||||
defaultRuntime.error(String(err));
|
|
||||||
defaultRuntime.exit(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Default action shows list
|
|
||||||
sandbox.action(async () => {
|
|
||||||
try {
|
|
||||||
await sandboxListCommand({ browser: false, json: false }, defaultRuntime);
|
|
||||||
} catch (err) {
|
|
||||||
defaultRuntime.error(String(err));
|
|
||||||
defaultRuntime.exit(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user