refactor(tasks): move task-flow ownership under tasks

This commit is contained in:
Vincent Koc
2026-04-02 21:36:56 +09:00
parent 0f45630d19
commit 6f91f87f3b
8 changed files with 139 additions and 44 deletions

View File

@@ -338,6 +338,27 @@ describe("registerStatusHealthSessionsCommands", () => {
);
});
it("routes tasks flow commands through the TaskFlow handlers", async () => {
await runCli(["tasks", "flow", "list", "--json", "--status", "blocked"]);
expect(flowsListCommand).toHaveBeenCalledWith(expect.any(Object), runtime);
await runCli(["tasks", "flow", "show", "flow-123", "--json"]);
expect(flowsShowCommand).toHaveBeenCalledWith(
expect.objectContaining({
lookup: "flow-123",
}),
runtime,
);
await runCli(["tasks", "flow", "cancel", "flow-123"]);
expect(flowsCancelCommand).toHaveBeenCalledWith(
expect.objectContaining({
lookup: "flow-123",
}),
runtime,
);
});
it("runs tasks notify subcommand with lookup and policy forwarding", async () => {
await runCli(["tasks", "notify", "run-123", "state_changes"]);

View File

@@ -225,7 +225,7 @@ export function registerStatusHealthSessionsCommands(program: Command) {
const tasksCmd = program
.command("tasks")
.description("Inspect durable background task state")
.description("Inspect durable background tasks and TaskFlow state")
.option("--json", "Output as JSON", false)
.option("--runtime <name>", "Filter by kind (subagent, acp, cron, cli)")
.option(
@@ -277,12 +277,12 @@ export function registerStatusHealthSessionsCommands(program: Command) {
tasksCmd
.command("audit")
.description("Show stale or broken background task runs")
.description("Show stale or broken background tasks and TaskFlows")
.option("--json", "Output as JSON", false)
.option("--severity <level>", "Filter by severity (warn, error)")
.option(
"--code <name>",
"Filter by finding code (stale_queued, stale_running, lost, delivery_failed, missing_cleanup, inconsistent_timestamps)",
"Filter by finding code (stale_queued, stale_running, lost, delivery_failed, missing_cleanup, inconsistent_timestamps, restore_failed, stale_waiting, stale_blocked, cancel_stuck, missing_linked_tasks, blocked_task_missing)",
)
.option("--limit <n>", "Limit displayed findings")
.action(async (opts, command) => {
@@ -299,6 +299,12 @@ export function registerStatusHealthSessionsCommands(program: Command) {
| "delivery_failed"
| "missing_cleanup"
| "inconsistent_timestamps"
| "restore_failed"
| "stale_waiting"
| "stale_blocked"
| "cancel_stuck"
| "missing_linked_tasks"
| "blocked_task_missing"
| undefined,
limit: parsePositiveIntOrUndefined(opts.limit),
},
@@ -309,7 +315,7 @@ export function registerStatusHealthSessionsCommands(program: Command) {
tasksCmd
.command("maintenance")
.description("Preview or apply task ledger 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) => {
@@ -375,9 +381,65 @@ export function registerStatusHealthSessionsCommands(program: Command) {
});
});
const tasksFlowCmd = tasksCmd
.command("flow")
.description("Inspect durable TaskFlow state under tasks");
tasksFlowCmd
.command("list")
.description("List tracked TaskFlows")
.option("--json", "Output as JSON", false)
.option(
"--status <name>",
"Filter by status (queued, running, waiting, blocked, succeeded, failed, cancelled, lost)",
)
.action(async (opts) => {
await runCommandWithRuntime(defaultRuntime, async () => {
await flowsListCommand(
{
json: Boolean(opts.json),
status: opts.status as string | undefined,
},
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) => {
await runCommandWithRuntime(defaultRuntime, async () => {
await flowsShowCommand(
{
lookup,
json: Boolean(opts.json),
},
defaultRuntime,
);
});
});
tasksFlowCmd
.command("cancel")
.description("Cancel a running TaskFlow")
.argument("<lookup>", "Flow id or owner key")
.action(async (lookup) => {
await runCommandWithRuntime(defaultRuntime, async () => {
await flowsCancelCommand(
{
lookup,
},
defaultRuntime,
);
});
});
const flowsCmd = program
.command("flows")
.description("Inspect durable background flow state")
.description("Inspect durable TaskFlow state (alias for `openclaw tasks flow`)")
.option("--json", "Output as JSON", false)
.option(
"--status <name>",