mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-03 21:31:26 +00:00
ClawFlow: add linear flow control surface (#58227)
* ClawFlow: add linear flow control surface * Flows: clear blocked metadata on resume
This commit is contained in:
@@ -5,6 +5,9 @@ import { registerStatusHealthSessionsCommands } from "./register.status-health-s
|
||||
const mocks = vi.hoisted(() => ({
|
||||
statusCommand: vi.fn(),
|
||||
healthCommand: vi.fn(),
|
||||
flowsListCommand: vi.fn(),
|
||||
flowsShowCommand: vi.fn(),
|
||||
flowsCancelCommand: vi.fn(),
|
||||
sessionsCommand: vi.fn(),
|
||||
sessionsCleanupCommand: vi.fn(),
|
||||
tasksListCommand: vi.fn(),
|
||||
@@ -23,6 +26,9 @@ const mocks = vi.hoisted(() => ({
|
||||
|
||||
const statusCommand = mocks.statusCommand;
|
||||
const healthCommand = mocks.healthCommand;
|
||||
const flowsListCommand = mocks.flowsListCommand;
|
||||
const flowsShowCommand = mocks.flowsShowCommand;
|
||||
const flowsCancelCommand = mocks.flowsCancelCommand;
|
||||
const sessionsCommand = mocks.sessionsCommand;
|
||||
const sessionsCleanupCommand = mocks.sessionsCleanupCommand;
|
||||
const tasksListCommand = mocks.tasksListCommand;
|
||||
@@ -42,6 +48,12 @@ vi.mock("../../commands/health.js", () => ({
|
||||
healthCommand: mocks.healthCommand,
|
||||
}));
|
||||
|
||||
vi.mock("../../commands/flows.js", () => ({
|
||||
flowsListCommand: mocks.flowsListCommand,
|
||||
flowsShowCommand: mocks.flowsShowCommand,
|
||||
flowsCancelCommand: mocks.flowsCancelCommand,
|
||||
}));
|
||||
|
||||
vi.mock("../../commands/sessions.js", () => ({
|
||||
sessionsCommand: mocks.sessionsCommand,
|
||||
}));
|
||||
@@ -79,6 +91,9 @@ describe("registerStatusHealthSessionsCommands", () => {
|
||||
runtime.exit.mockImplementation(() => {});
|
||||
statusCommand.mockResolvedValue(undefined);
|
||||
healthCommand.mockResolvedValue(undefined);
|
||||
flowsListCommand.mockResolvedValue(undefined);
|
||||
flowsShowCommand.mockResolvedValue(undefined);
|
||||
flowsCancelCommand.mockResolvedValue(undefined);
|
||||
sessionsCommand.mockResolvedValue(undefined);
|
||||
sessionsCleanupCommand.mockResolvedValue(undefined);
|
||||
tasksListCommand.mockResolvedValue(undefined);
|
||||
@@ -317,4 +332,39 @@ describe("registerStatusHealthSessionsCommands", () => {
|
||||
runtime,
|
||||
);
|
||||
});
|
||||
|
||||
it("runs flows list from the parent command", async () => {
|
||||
await runCli(["flows", "--json", "--status", "blocked"]);
|
||||
|
||||
expect(flowsListCommand).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
json: true,
|
||||
status: "blocked",
|
||||
}),
|
||||
runtime,
|
||||
);
|
||||
});
|
||||
|
||||
it("runs flows show subcommand with lookup forwarding", async () => {
|
||||
await runCli(["flows", "show", "flow-123", "--json"]);
|
||||
|
||||
expect(flowsShowCommand).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
lookup: "flow-123",
|
||||
json: true,
|
||||
}),
|
||||
runtime,
|
||||
);
|
||||
});
|
||||
|
||||
it("runs flows cancel subcommand with lookup forwarding", async () => {
|
||||
await runCli(["flows", "cancel", "flow-123"]);
|
||||
|
||||
expect(flowsCancelCommand).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
lookup: "flow-123",
|
||||
}),
|
||||
runtime,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Command } from "commander";
|
||||
import { flowsCancelCommand, flowsListCommand, flowsShowCommand } from "../../commands/flows.js";
|
||||
import { healthCommand } from "../../commands/health.js";
|
||||
import { sessionsCleanupCommand } from "../../commands/sessions-cleanup.js";
|
||||
import { sessionsCommand } from "../../commands/sessions.js";
|
||||
@@ -373,4 +374,84 @@ export function registerStatusHealthSessionsCommands(program: Command) {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
const flowsCmd = program
|
||||
.command("flows")
|
||||
.description("Inspect ClawFlow state")
|
||||
.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,
|
||||
);
|
||||
});
|
||||
});
|
||||
flowsCmd.enablePositionalOptions();
|
||||
|
||||
flowsCmd
|
||||
.command("list")
|
||||
.description("List tracked ClawFlow runs")
|
||||
.option("--json", "Output as JSON", false)
|
||||
.option(
|
||||
"--status <name>",
|
||||
"Filter by status (queued, running, waiting, blocked, succeeded, failed, cancelled, lost)",
|
||||
)
|
||||
.action(async (opts, command) => {
|
||||
const parentOpts = command.parent?.opts() as
|
||||
| {
|
||||
json?: boolean;
|
||||
status?: string;
|
||||
}
|
||||
| undefined;
|
||||
await runCommandWithRuntime(defaultRuntime, async () => {
|
||||
await flowsListCommand(
|
||||
{
|
||||
json: Boolean(opts.json || parentOpts?.json),
|
||||
status: (opts.status as string | undefined) ?? parentOpts?.status,
|
||||
},
|
||||
defaultRuntime,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
flowsCmd
|
||||
.command("show")
|
||||
.description("Show one ClawFlow by flow id or owner session key")
|
||||
.argument("<lookup>", "Flow id or owner session key")
|
||||
.option("--json", "Output as JSON", false)
|
||||
.action(async (lookup, opts, command) => {
|
||||
const parentOpts = command.parent?.opts() as { json?: boolean } | undefined;
|
||||
await runCommandWithRuntime(defaultRuntime, async () => {
|
||||
await flowsShowCommand(
|
||||
{
|
||||
lookup,
|
||||
json: Boolean(opts.json || parentOpts?.json),
|
||||
},
|
||||
defaultRuntime,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
flowsCmd
|
||||
.command("cancel")
|
||||
.description("Cancel a ClawFlow and its active child tasks")
|
||||
.argument("<lookup>", "Flow id or owner session key")
|
||||
.action(async (lookup) => {
|
||||
await runCommandWithRuntime(defaultRuntime, async () => {
|
||||
await flowsCancelCommand(
|
||||
{
|
||||
lookup,
|
||||
},
|
||||
defaultRuntime,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user