Skip to content

Workflow Runner Design

Design for the xcsh component that reads workflow YAML from this catalog and executes steps via Chrome DevTools Protocol.

packages/coding-agent/src/tools/catalog-workflow-runner.ts in the xcsh repo. Sits alongside browser.ts and delegates all browser interaction to BrowserTool.execute().

interface WorkflowDefinition {
schema: string;
id: string;
label: string;
resource: string;
operation: string;
preconditions?: string[];
params?: Record<string, WorkflowParam>;
steps: WorkflowStep[];
postconditions?: string[];
metadata?: WorkflowMetadata;
}
interface RunnerOptions {
params: Record<string, unknown>;
baseUrl: string;
observable?: boolean; // slow execution, screenshots per step
observableDelayMs?: number; // default 1500
screenshotDir?: string;
signal?: AbortSignal;
onStepStart?: (step: WorkflowStep, index: number) => void;
onStepComplete?: (result: StepResult) => void;
}
interface StepResult {
stepId: string;
action: string;
status: "pass" | "fail" | "skipped";
durationMs: number;
error?: string;
screenshotPath?: string;
}
interface WorkflowRunResult {
workflowId: string;
label: string;
status: "pass" | "fail";
totalDurationMs: number;
steps: StepResult[];
failedAtStep?: string;
}
Workflow ActionBrowser Tool ActionNotes
navigategoto + wait_for_selectorPrepend baseUrl to relative URL
clickclickDirect selector mapping
fillfillResolve {param} in value
fill-listLoop: fill + press Enter per itemResolve array param
selectclick (open) + click (option)Custom console dropdowns
assertget_text + string comparisonFail-fast if mismatch
screenshotscreenshotSave to screenshotDir
key-presspressDirect key mapping
waitwait_for_selectorSelector or time-based
  1. Explicit params from RunnerOptions (highest priority)
  2. F5XC environment variables ({namespace} maps to F5XC_NAMESPACE)
  3. Unresolved required params produce a WorkflowParamError
  • Fail-fast: first failed step stops execution
  • Capture failure screenshot (best-effort)
  • No retry logic — caller decides whether to retry full workflow
  • All errors extend ToolError for agent loop compatibility

When observable: true:

  • 1500ms delay between steps (configurable)
  • Screenshot after every step (named workflowId-stepIndex-stepId.png)
  • onStepStart/onStepComplete callbacks for live logging
  • Browser actions themselves run at full speed (delays are inter-step only)
class CatalogWorkflowRunner {
constructor(
private readonly browserTool: BrowserTool,
private readonly contextEnv: ContextEnv,
) {}
async run(
workflow: WorkflowDefinition,
options: RunnerOptions,
): Promise<WorkflowRunResult> { ... }
}

The runner calls browserTool.execute() directly. The browser must be open before run() is called (or the first workflow step must be navigate).