UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

428 lines (427 loc) 26 kB
import { w as parseStrictPositiveInteger } from "./number-coercion-CLj0HTDM.js"; import { r as defaultRuntime } from "./runtime-CF2WjnNZ.js"; import { r as setVerbose } from "./global-state-BAD7XgmL.js"; import { t as formatDocsLink } from "./links-ClIwBcy4.js"; import { r as theme } from "./theme-vjDs9tao.js"; import { n as inheritOptionFromParent } from "./command-options-BDuSHeWG.js"; import "./globals-CTaGxEqj.js"; import { t as ExpectedCliError } from "./failure-output-Dc5ce9_F.js"; import { t as TASK_FLOW_STATUSES } from "./task-flow-registry.types-BidrdCoB.js"; import { n as TASK_STATUS_FILTERS, t as TASK_RUNTIMES } from "./task-registry.types-73FJYVhP.js"; import { n as runCommandWithRuntime } from "./cli-utils-D1DAWB8d.js"; import { t as formatHelpExamples } from "./help-format-CAcwboTs.js"; import { n as TASK_SYSTEM_AUDIT_SEVERITIES, t as TASK_SYSTEM_AUDIT_CODES } from "./task-system-audit.types-EobzI_JT.js"; import { t as parseCliEnumFilter } from "./enum-filter-DPEFp-pf.js"; //#region src/cli/program/register.tasks.ts const TASKS_PARENT_OPTIONS = [ "json", "runtime", "status" ]; const TASKS_LEAF_OPTION_SUPPORT = { list: TASKS_PARENT_OPTIONS, audit: ["json"], maintenance: ["json"], show: ["json"], notify: [], cancel: [], retry: [], dismiss: [], "flow list": ["json"], "flow show": ["json"], "flow cancel": [] }; function createModuleLoader(load) { let promise; return () => promise ??= load(); } const loadTasksCommands = createModuleLoader(() => import("./tasks-BCgo7WbG.js")); const loadFlowsCommands = createModuleLoader(() => import("./flows-BmJfQolx.js")); async function runOwner(load, action) { await runCommandWithRuntime(defaultRuntime, async () => action(await load())); } function addTasksListOptions(command) { return command.option("--json", "Output as JSON", false).option("--runtime <name>", `Filter by kind (${TASK_RUNTIMES.join(", ")})`).option("--status <name>", `Filter by status (${TASK_STATUS_FILTERS.join(", ")})`); } function isTaskNotifyPolicy(value) { return value === "done_only" || value === "state_changes" || value === "silent"; } function throwTasksCliError(message) { throw new ExpectedCliError({ message, humanOutput: message, machineOutput: message }); } function resolveTasksLeafOptions(command, leaf) { const supported = TASKS_LEAF_OPTION_SUPPORT[leaf]; const flags = TASKS_PARENT_OPTIONS.filter((name) => !supported.includes(name) && inheritOptionFromParent(command, name, "cli") !== void 0).map((name) => `--${name}`); if (flags.length > 0) throwTasksCliError(`\`tasks ${leaf}\` does not support inherited ${flags.length === 1 ? "option" : "options"} ${flags.join(", ")}.`); const resolveLocal = (name) => { const source = command.getOptionValueSource(name); return source && source !== "default" ? command.getOptionValue(name) : void 0; }; const resolve = (name) => resolveLocal(name) ?? inheritOptionFromParent(command, name); const json = resolve("json"); const runtime = resolve("runtime"); const status = leaf === "flow list" ? resolveLocal("status") : resolve("status"); return { json: typeof json === "boolean" ? json : void 0, runtime: typeof runtime === "string" ? runtime : void 0, status: typeof status === "string" ? status : void 0 }; } function parseTasksAuditLimit(limit) { const parsed = parseStrictPositiveInteger(limit); if (limit !== void 0 && parsed === void 0) throwTasksCliError("--limit must be a positive integer, for example --limit 25."); return parsed; } function registerTasksCommand(program) { const tasksCmd = addTasksListOptions(program.command("tasks").description("Inspect durable background tasks and TaskFlow state")).action(async (opts) => { await runOwner(loadTasksCommands, ({ tasksListCommand }) => tasksListCommand({ json: Boolean(opts.json), runtime: typeof opts.runtime === "string" ? opts.runtime : void 0, status: typeof opts.status === "string" ? opts.status : void 0 }, defaultRuntime)); }); tasksCmd.enablePositionalOptions(); addTasksListOptions(tasksCmd.command("list").description("List tracked background tasks")).action(async (_opts, command) => { const resolved = resolveTasksLeafOptions(command, "list"); await runOwner(loadTasksCommands, ({ tasksListCommand }) => tasksListCommand({ json: Boolean(resolved.json), runtime: resolved.runtime, status: resolved.status }, defaultRuntime)); }); tasksCmd.command("audit").description("Show stale or broken background tasks and TaskFlows").option("--json", "Output as JSON", false).option("--severity <level>", `Filter by severity (${TASK_SYSTEM_AUDIT_SEVERITIES.join(", ")})`).option("--code <name>", `Filter by finding code (${TASK_SYSTEM_AUDIT_CODES.join(", ")})`).option("--limit <n>", "Limit displayed findings").action(async (opts, command) => { const resolved = resolveTasksLeafOptions(command, "audit"); const limit = parseTasksAuditLimit(opts.limit); await runOwner(loadTasksCommands, ({ tasksAuditCommand }) => tasksAuditCommand({ json: Boolean(resolved.json), severity: parseCliEnumFilter(opts.severity, "--severity", TASK_SYSTEM_AUDIT_SEVERITIES), code: parseCliEnumFilter(opts.code, "--code", TASK_SYSTEM_AUDIT_CODES), limit }, defaultRuntime)); }); tasksCmd.command("maintenance").description("Preview or apply tasks and TaskFlow maintenance").option("--json", "Output as JSON", false).option("--apply", "Apply reconciliation, cleanup stamping, and pruning", false).action(async (opts, command) => { const resolved = resolveTasksLeafOptions(command, "maintenance"); await runOwner(loadTasksCommands, ({ tasksMaintenanceCommand }) => tasksMaintenanceCommand({ json: Boolean(resolved.json), apply: Boolean(opts.apply) }, defaultRuntime)); }); tasksCmd.command("show").description("Show one background task by task id, run id, or session key").argument("<lookup>", "Task id, run id, or session key").option("--json", "Output as JSON", false).action(async (lookup, _opts, command) => { const resolved = resolveTasksLeafOptions(command, "show"); await runOwner(loadTasksCommands, ({ tasksShowCommand }) => tasksShowCommand({ lookup, json: Boolean(resolved.json) }, defaultRuntime)); }); tasksCmd.command("notify").description("Set task notify policy").argument("<lookup>", "Task id, run id, or session key").argument("<notify>", "Notify policy (done_only, state_changes, silent)").action(async (lookup, notify, _opts, command) => { resolveTasksLeafOptions(command, "notify"); if (!isTaskNotifyPolicy(notify)) throwTasksCliError("Notify policy must be done_only, state_changes, or silent."); await runOwner(loadTasksCommands, ({ tasksNotifyCommand }) => tasksNotifyCommand({ lookup, notify }, defaultRuntime)); }); tasksCmd.command("cancel").description("Cancel a running background task").argument("<lookup>", "Task id, run id, or session key").action(async (lookup, _opts, command) => { resolveTasksLeafOptions(command, "cancel"); await runOwner(loadTasksCommands, ({ tasksCancelCommand }) => tasksCancelCommand({ lookup }, defaultRuntime)); }); tasksCmd.command("retry <lookups...>").description("Retry delivery for up to 10 blocked subagent completions").action(async (lookups, _opts, command) => { resolveTasksLeafOptions(command, "retry"); await runOwner(loadTasksCommands, ({ tasksRetryCommand }) => tasksRetryCommand({ lookups }, defaultRuntime)); }); tasksCmd.command("dismiss <lookups...>").description("Dismiss delivery for up to 10 blocked subagent completions").action(async (lookups, _opts, command) => { resolveTasksLeafOptions(command, "dismiss"); await runOwner(loadTasksCommands, ({ tasksDismissCommand }) => tasksDismissCommand({ lookups }, defaultRuntime)); }); const tasksFlowCmd = tasksCmd.command("flow").description("Inspect durable TaskFlow state under tasks").option("--json", "Output as JSON", false); tasksFlowCmd.enablePositionalOptions(); tasksFlowCmd.command("list").description("List tracked TaskFlows").option("--json", "Output as JSON", false).option("--status <name>", `Filter by status (${TASK_FLOW_STATUSES.join(", ")})`).action(async (_opts, command) => { const resolved = resolveTasksLeafOptions(command, "flow list"); await runOwner(loadFlowsCommands, ({ flowsListCommand }) => flowsListCommand({ json: Boolean(resolved.json), status: resolved.status }, defaultRuntime)); }); tasksFlowCmd.command("show").description("Show one TaskFlow by flow id or owner key").argument("<lookup>", "Flow id or owner key").option("--json", "Output as JSON", false).action(async (lookup, _opts, command) => { const resolved = resolveTasksLeafOptions(command, "flow show"); await runOwner(loadFlowsCommands, ({ flowsShowCommand }) => flowsShowCommand({ lookup, json: Boolean(resolved.json) }, defaultRuntime)); }); tasksFlowCmd.command("cancel").description("Cancel a running TaskFlow").argument("<lookup>", "Flow id or owner key").action(async (lookup, _opts, command) => { resolveTasksLeafOptions(command, "flow cancel"); await runOwner(loadFlowsCommands, ({ flowsCancelCommand }) => flowsCancelCommand({ lookup }, defaultRuntime)); }); } //#endregion //#region src/cli/program/register.status-health-sessions.ts function resolveVerbose(opts) { return Boolean(opts.verbose || opts.debug); } const SESSIONS_PARENT_OPTION_FLAGS = { json: "--json", verbose: "--verbose", store: "--store", agent: "--agent", allAgents: "--all-agents", active: "--active", limit: "--limit" }; function throwSessionsCliError(message) { throw new ExpectedCliError({ message, humanOutput: message, machineOutput: message }); } function rejectUnsupportedSessionsParentOptions(subcommand, parentOpts, unsupportedOptions, reason) { const unsupportedFlags = unsupportedOptions.filter((option) => { const value = parentOpts?.[option]; return typeof value === "boolean" ? value : value !== void 0; }).map((option) => SESSIONS_PARENT_OPTION_FLAGS[option]); if (unsupportedFlags.length === 0) return; throwSessionsCliError(`\`sessions ${subcommand}\` does not support the parent \`sessions\` ${unsupportedFlags.length > 1 ? "options" : "option"} ${unsupportedFlags.join(", ")}; ${reason}.`); } function addSessionsListOptions(command) { return command.option("--json", "Output as JSON", false).option("--verbose", "Verbose logging", false).option("--store <path>", "Legacy session store selector path").option("--agent <id>", "Agent id to inspect (required for multiple explicit agents)").option("--all-agents", "Aggregate sessions across all configured agents", false).option("--active <minutes>", "Only show sessions updated within the past N minutes").option("--limit <count>", "Max sessions to show (default: 100; use \"all\" for full output)"); } function addSessionsGatewayOptions(command) { return command.option("--agent <id>", "Agent id that owns the session (required for global keys)").option("--url <url>", "Gateway WebSocket URL (defaults to gateway.remote.url when configured)").option("--token <token>", "Gateway token (if required)").option("--password <password>", "Gateway password (password auth)").option("--timeout <ms>", "RPC timeout in milliseconds").option("--json", "Output JSON", false); } function mergeSessionsListOptions(opts, parentOpts) { return { json: Boolean(opts.json || parentOpts?.json), verbose: Boolean(opts.verbose || parentOpts?.verbose), store: opts.store ?? parentOpts?.store, agent: opts.agent ?? parentOpts?.agent, allAgents: Boolean(opts.allAgents || parentOpts?.allAgents), active: opts.active ?? parentOpts?.active, limit: opts.limit ?? parentOpts?.limit }; } async function runSessionsListCli(opts) { setVerbose(Boolean(opts.verbose)); const { sessionsCommand } = await import("./sessions-TKqiPw8X.js"); await sessionsCommand({ json: Boolean(opts.json), store: opts.store, agent: opts.agent, allAgents: Boolean(opts.allAgents), active: opts.active, limit: opts.limit }, defaultRuntime); } function registerSessionsLifecycleCommand(sessionsCmd, operation) { const destructive = operation === "delete"; const examples = destructive ? [ ["openclaw sessions delete \"agent:main:scratch-1\"", "Delete with confirmation."], ["openclaw sessions delete \"agent:main:scratch-1\" \"agent:main:scratch-2\" --yes", "Delete several sessions non-interactively."], ["openclaw sessions delete \"agent:work:scratch-1\" --agent work --dry-run", "Preview an agent-scoped delete."] ] : [ ["openclaw sessions archive \"agent:main:scratch-1\"", "Archive one session."], ["openclaw sessions archive \"agent:main:scratch-1\" \"agent:main:scratch-2\"", "Archive several sessions."], ["openclaw sessions archive \"agent:work:scratch-1\" --agent work --dry-run", "Preview an agent-scoped archive."] ]; const command = sessionsCmd.command(`${operation} <keys...>`).description(destructive ? "Delete stored sessions and their live artifacts via the running gateway" : "Archive stored sessions via the running gateway").option(`--dry-run`, `Preview ${operation} actions without writing`, false); if (destructive) command.option("--yes", "Skip the destructive confirmation prompt", false); addSessionsGatewayOptions(command).addHelpText("after", () => `\n${theme.heading("Examples:")}\n${formatHelpExamples(examples)}${destructive ? `\n\n${theme.muted("Deletion uses the Control UI lifecycle operation, including transcript archival and runtime cleanup.")}` : ""}`).action(async (keys, opts, actionCommand) => { const parentOpts = actionCommand.parent?.opts(); rejectUnsupportedSessionsParentOptions(operation, parentOpts, [ "store", "allAgents", "active", "limit", "verbose" ], "the gateway resolves target stores from each key and --agent"); const timeoutMs = parseStrictPositiveInteger(opts.timeout); if (opts.timeout !== void 0 && timeoutMs === void 0) throwSessionsCliError("--timeout must be a positive integer (milliseconds)."); await runCommandWithRuntime(defaultRuntime, async () => { const lifecycleCommands = await import("./sessions-lifecycle-BrlTQsYQ.js"); await (destructive ? lifecycleCommands.sessionsDeleteCommand : lifecycleCommands.sessionsArchiveCommand)({ keys, agent: opts.agent ?? parentOpts?.agent, dryRun: Boolean(opts.dryRun), ...destructive ? { yes: Boolean(opts.yes) } : {}, timeout: timeoutMs !== void 0 ? String(timeoutMs) : void 0, url: opts.url, token: opts.token, password: opts.password, json: Boolean(opts.json || parentOpts?.json) }, defaultRuntime); }); }); } async function runWithVerboseAndTimeout(opts, action) { const verbose = resolveVerbose(opts); setVerbose(verbose); await runCommandWithRuntime(defaultRuntime, async () => { const timeoutMs = parseStrictPositiveInteger(opts.timeout); if (opts.timeout !== void 0 && timeoutMs === void 0) throw new Error("--timeout must be a positive integer (milliseconds)"); await action({ verbose, timeoutMs }); }); } /** Register status/health plus persistent session/task inspection command groups. */ function registerStatusHealthSessionsCommands(program) { program.command("status").description("Show channel health and recent session recipients").option("--json", "Output JSON instead of text", false).option("--all", "Full diagnosis (read-only, pasteable)", false).option("--usage", "Show model provider usage/quota snapshots", false).option("--agent <id>", "Agent id for --usage auth scope").option("--deep", "Probe channels (WhatsApp Web + Telegram + Discord + Slack + Signal)", false).option("--timeout <ms>", "Probe timeout in milliseconds", "10000").option("--verbose", "Verbose logging", false).option("--debug", "Alias for --verbose", false).addHelpText("after", () => `\n${theme.heading("Examples:")}\n${formatHelpExamples([ ["openclaw status", "Show channel health + session summary."], ["openclaw status --all", "Full diagnosis (read-only)."], ["openclaw status --json", "Machine-readable output."], ["openclaw status --usage", "Show model provider usage/quota snapshots."], ["openclaw status --deep", "Run channel probes (WA + Telegram + Discord + Slack + Signal)."], ["openclaw status --deep --timeout 5000", "Tighten probe timeout."] ])}`).addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/status", "docs.openclaw.ai/cli/status")}\n`).action(async (opts) => { await runWithVerboseAndTimeout(opts, async ({ verbose, timeoutMs }) => { const { statusCommand } = await import("./status-DSSE0Vmn.js"); await statusCommand({ json: Boolean(opts.json), all: Boolean(opts.all), deep: Boolean(opts.deep), usage: Boolean(opts.usage), ...opts.agent !== void 0 ? { agent: opts.agent } : {}, timeoutMs, verbose }, defaultRuntime); }); }); program.command("health").description("Fetch health from the running gateway").option("--json", "Output JSON instead of text", false).option("--timeout <ms>", "Connection timeout in milliseconds", "10000").option("--verbose", "Verbose logging", false).option("--debug", "Alias for --verbose", false).addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/health", "docs.openclaw.ai/cli/health")}\n`).action(async (opts) => { await runWithVerboseAndTimeout(opts, async ({ verbose, timeoutMs }) => { const { healthCommand } = await import("./health-YMSl1wN1.js"); await healthCommand({ json: Boolean(opts.json), timeoutMs, verbose }, defaultRuntime); }); }); const sessionsCmd = addSessionsListOptions(program.command("sessions").description("List stored conversation sessions")).addHelpText("after", () => `\n${theme.heading("Examples:")}\n${formatHelpExamples([ ["openclaw sessions", "List all sessions."], ["openclaw sessions --agent work", "List sessions for one agent."], ["openclaw sessions --all-agents", "Aggregate sessions across agents."], ["openclaw sessions --active 120", "Only last 2 hours."], ["openclaw sessions --limit 25", "Show the newest 25 sessions."], ["openclaw sessions --json", "Machine-readable output."], ["openclaw sessions --store ./tmp/sessions.sqlite", "Use a specific session store."] ])}\n\n${theme.muted("Shows token usage per session when the agent reports it; set the model entry's contextTokens to cap the window and show %.")}`).addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/sessions", "docs.openclaw.ai/cli/sessions")}\n`).action(async (opts) => { await runSessionsListCli(opts); }); sessionsCmd.enablePositionalOptions(); addSessionsListOptions(sessionsCmd.command("list").description("List stored conversation sessions")).action(async (opts, command) => { const parentOpts = command.parent?.opts(); await runSessionsListCli(mergeSessionsListOptions(opts, parentOpts)); }); sessionsCmd.command("cleanup").description("Run session-store maintenance now").option("--store <path>", "Legacy session store selector path").option("--agent <id>", "Agent id to maintain (required for multiple explicit agents)").option("--all-agents", "Run maintenance across all configured agents", false).option("--dry-run", "Preview maintenance actions without writing", false).option("--enforce", "Apply maintenance even when configured mode is warn", false).option("--fix-missing", "Remove store entries whose transcript files are missing (bypasses age/count retention)", false).option("--fix-dm-scope", "Retire stale direct-DM session rows that no longer match session.dmScope=main", false).option("--active-key <key>", "Protect this session key from budget-eviction").option("--json", "Output JSON", false).addHelpText("after", () => `\n${theme.heading("Examples:")}\n${formatHelpExamples([ ["openclaw sessions cleanup --dry-run", "Preview stale/cap cleanup."], ["openclaw sessions cleanup --dry-run --fix-missing", "Also preview pruning entries with missing transcript files."], ["openclaw sessions cleanup --dry-run --fix-dm-scope", "Preview stale direct-DM rows after returning dmScope to main."], ["openclaw sessions cleanup --enforce", "Apply maintenance now."], ["openclaw sessions cleanup --agent work --dry-run", "Preview one agent store."], ["openclaw sessions cleanup --all-agents --dry-run", "Preview all agent stores."], ["openclaw sessions cleanup --enforce --store ./tmp/sessions.sqlite", "Use a specific store."] ])}`).action(async (opts, command) => { const parentOpts = command.parent?.opts(); rejectUnsupportedSessionsParentOptions("cleanup", parentOpts, [ "active", "limit", "verbose" ], "session-list filters cannot scope session maintenance"); await runCommandWithRuntime(defaultRuntime, async () => { const { sessionsCleanupCommand } = await import("./sessions-cleanup-Bo78NwtM.js"); await sessionsCleanupCommand({ store: opts.store ?? parentOpts?.store, agent: opts.agent ?? parentOpts?.agent, allAgents: Boolean(opts.allAgents || parentOpts?.allAgents), dryRun: Boolean(opts.dryRun), enforce: Boolean(opts.enforce), fixMissing: Boolean(opts.fixMissing), fixDmScope: Boolean(opts.fixDmScope), activeKey: opts.activeKey, json: Boolean(opts.json || parentOpts?.json) }, defaultRuntime); }); }); sessionsCmd.command("tail").description("Tail human-readable session trajectory progress").option("--session-key <key>", "Session key to tail (default: active sessions or latest)").option("--tail <count>", "Number of existing trajectory events to show", "80").option("--follow", "Continue following for new trajectory events", false).option("--store <path>", "Legacy session store selector path").option("--agent <id>", "Agent id to inspect (required for multiple explicit agents)").option("--all-agents", "Aggregate sessions across all configured agents", false).action(async (opts, command) => { const parentOpts = command.parent?.opts(); rejectUnsupportedSessionsParentOptions("tail", parentOpts, [ "json", "active", "limit", "verbose" ], "trajectory tail emits human-readable progress and selects sessions separately"); await runCommandWithRuntime(defaultRuntime, async () => { const { sessionsTailCommand } = await import("./sessions-tail-BTxx4947.js"); await sessionsTailCommand({ sessionKey: opts.sessionKey, store: opts.store ?? parentOpts?.store, agent: opts.agent ?? parentOpts?.agent, allAgents: Boolean(opts.allAgents || parentOpts?.allAgents), follow: Boolean(opts.follow), tail: opts.tail }, defaultRuntime); }); }); sessionsCmd.command("export-trajectory").description("Export a redacted trajectory bundle for a stored session").option("--session-key <key>", "Session key to export").option("--output <path>", "Output directory name inside .openclaw/trajectory-exports").option("--workspace <path>", "Workspace root for the export (default: current directory)").option("--store <path>", "Legacy session store selector path").option("--agent <id>", "Agent id for resolving the default session store").option("--request-json-base64 <payload>", "Base64url-encoded export request").option("--json", "Output JSON", false).action(async (opts, command) => { const parentOpts = command.parent?.opts(); rejectUnsupportedSessionsParentOptions("export-trajectory", parentOpts, [ "allAgents", "active", "limit", "verbose" ], "trajectory export targets one session and cannot apply session-list filters"); await runCommandWithRuntime(defaultRuntime, async () => { const { exportTrajectoryCommand } = await import("./export-trajectory-D7lFOKt2.js"); await exportTrajectoryCommand({ sessionKey: opts.sessionKey, output: opts.output, workspace: opts.workspace, store: opts.store ?? parentOpts?.store, agent: opts.agent ?? parentOpts?.agent, requestJsonBase64: opts.requestJsonBase64, json: Boolean(opts.json || parentOpts?.json) }, defaultRuntime); }); }); registerSessionsLifecycleCommand(sessionsCmd, "archive"); registerSessionsLifecycleCommand(sessionsCmd, "delete"); addSessionsGatewayOptions(sessionsCmd.command("compact <key>")).description("Compact a stored session transcript via the running gateway").option("--max-lines <count>", "Truncate to the last N transcript lines instead of LLM summarization").addHelpText("after", () => `\n${theme.heading("Examples:")}\n${formatHelpExamples([ ["openclaw sessions compact \"agent:main:main\"", "LLM-summarize a session to reclaim context budget."], ["openclaw sessions compact \"agent:main:main\" --max-lines 200", "Truncate to the last 200 transcript lines instead."], ["openclaw sessions compact \"agent:work:main\" --agent work --json", "Target one agent's session and emit JSON."] ])}\n\n${theme.muted("Backed by the sessions.compact gateway RPC; exits non-zero when compaction fails.")}`).action(async (key, opts, command) => { const parentOpts = command.parent?.opts(); rejectUnsupportedSessionsParentOptions("compact", parentOpts, [ "store", "allAgents", "active", "limit", "verbose" ], "the gateway resolves the target store from <key> and --agent"); const maxLines = parseStrictPositiveInteger(opts.maxLines); if (opts.maxLines !== void 0 && maxLines === void 0) throwSessionsCliError("--max-lines must be a positive integer."); const timeoutMs = parseStrictPositiveInteger(opts.timeout); if (opts.timeout !== void 0 && timeoutMs === void 0) throwSessionsCliError("--timeout must be a positive integer (milliseconds)."); await runCommandWithRuntime(defaultRuntime, async () => { const { sessionsCompactCommand } = await import("./sessions-compact-tlp5c1br.js"); await sessionsCompactCommand({ key, agent: opts.agent ?? parentOpts?.agent, maxLines, timeout: timeoutMs !== void 0 ? String(timeoutMs) : void 0, url: opts.url, token: opts.token, password: opts.password, json: Boolean(opts.json || parentOpts?.json) }, defaultRuntime); }); }); registerTasksCommand(program); } //#endregion export { registerStatusHealthSessionsCommands };