import { Schema } from "effect"; import type { NodeSpecCapabilitySummary, StepInputBinding, WorkflowOperationName, WrapperArtifactCapabilitySummary, } from "./generated/workflow-contract.js"; import { WorkflowHealthResultSchema, WorkflowSourcesListPayloadSchema, WorkflowSourcesListResultSchema, WorkflowCapabilitiesListPayloadSchema, WorkflowCapabilitiesListResultSchema, WorkflowCapabilitiesInspectPayloadSchema, WorkflowCapabilitiesInspectResultSchema, WorkflowCapabilitiesCallPayloadSchema, WorkflowCapabilitiesCallResultSchema, WorkflowDraftWorkspacesListResultSchema, WorkflowDraftWorkspacesGetPayloadSchema, WorkflowDraftWorkspacesGetResultSchema, WorkflowDraftWorkspacesCreateEmptyPayloadSchema, WorkflowDraftWorkspacesCreateEmptyResultSchema, WorkflowDraftWorkspacesCreateFromCapabilityPayloadSchema, WorkflowDraftWorkspacesCreateFromCapabilityResultSchema, WorkflowDraftWorkspacesAddStepFromCapabilityPayloadSchema, WorkflowDraftWorkspacesAddStepFromCapabilityResultSchema, WorkflowDraftWorkspacesUpdateCapabilityStepPayloadSchema, WorkflowDraftWorkspacesUpdateCapabilityStepResultSchema, WorkflowDraftWorkspacesSetRoutePayloadSchema, WorkflowDraftWorkspacesSetRouteResultSchema, WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema, WorkflowDraftWorkspacesSetStepInputBindingsResultSchema, WorkflowDraftWorkspacesSetStepOutputBindingsPayloadSchema, WorkflowDraftWorkspacesSetStepOutputBindingsResultSchema, WorkflowDraftWorkspacesValidatePayloadSchema, WorkflowDraftWorkspacesValidateResultSchema, WorkflowArtifactsListPayloadSchema, WorkflowArtifactsListResultSchema, WorkflowArtifactsInspectPayloadSchema, WorkflowArtifactsInspectResultSchema, WorkflowDeploymentsListResultSchema, WorkflowDeploymentsInspectPayloadSchema, WorkflowDeploymentsInspectResultSchema, WorkflowDeploymentsValidatePayloadSchema, WorkflowDeploymentsValidateResultSchema, WorkflowRunsListPayloadSchema, WorkflowRunsListResultSchema, WorkflowRunsInspectPayloadSchema, WorkflowRunsInspectResultSchema, WorkflowRunsStartPayloadSchema, WorkflowRunsStartResultSchema, WorkflowRunsResumePayloadSchema, WorkflowRunsResumeResultSchema, WorkflowRunsTracePayloadSchema, WorkflowRunsTraceResultSchema, } from "./rpcs.js"; export type OperationMeta = { readonly method: WorkflowOperationName; readonly label: string; readonly explanation: string; readonly idempotency: "read" | "write"; readonly equivalentCli: (params: unknown) => string; readonly interpret: (result: unknown) => unknown; }; export type WorkflowHealthInterpreted = { readonly status: "ok"; readonly storeRoot: string; }; export type WorkflowSourcesListInterpreted = { readonly sources: ReadonlyArray<{ readonly id: string; readonly kind: string; readonly enabled: boolean; readonly description: string | null; readonly counts: { readonly tools: number; readonly nodeSpecs: number; readonly reducers: number; readonly prompts: number; readonly resources: number; }; }>; readonly nextCursor: string | null; readonly total: number; }; export type CapabilitySummaryInterpreted = { readonly kind: "node_spec" | "wrapper_artifact"; readonly name: string; readonly sourceId: string; readonly description: string | null; readonly outcomes: ReadonlyArray; readonly isAsync: boolean; readonly inputFields: ReadonlyArray; readonly outputFields: ReadonlyArray; readonly artifactId?: string; readonly version?: number; readonly title?: string; }; export type CapabilityCallInterpreted = { readonly qualifiedName: string; readonly sourceId: string; readonly kind: "node_spec" | "wrapper_artifact"; readonly deploymentId: string | null; readonly outcome: string; readonly output: Record | null; readonly diagnostics: ReadonlyArray<{ readonly boundSource: string | null; readonly code: string; readonly logicalRef: string; readonly message: string; readonly repairHint: string | null; readonly severity: string; }>; }; export type DraftWorkspaceInterpreted = { readonly workspaceId: string; readonly revision: number; readonly title: string | null; readonly status: "valid" | "invalid" | "conflict"; readonly diagnostics: ReadonlyArray<{ readonly code: string; readonly path: string; readonly message: string; readonly stepId: string | null; readonly repairHint: string | null; readonly details: Readonly>; }>; readonly summary: { readonly name: unknown; readonly start: unknown; readonly stepCount: number; readonly routeCount: number; readonly steps: ReadonlyArray; }; readonly draft: Readonly> | null; }; const interpretNextActions = (nextActions: { readonly can_continue: boolean; readonly can_save_now: boolean | null; readonly recommended_next_tool: string | null; readonly reason: string; readonly patch_examples: ReadonlyArray; readonly warnings: ReadonlyArray; }) => ({ canContinue: nextActions.can_continue, canSaveNow: nextActions.can_save_now, recommendedNextTool: nextActions.recommended_next_tool, reason: nextActions.reason, patchExamples: nextActions.patch_examples, warnings: nextActions.warnings, }); const shellArg = (value: string | number): string => { const text = String(value); return /^[A-Za-z0-9._/@=:-]+$/.test(text) ? text : `'${text.replace(/'/g, "'\\''")}'`; }; const nonEquivalentCli = ( command: string, fields: readonly string[], ): string => fields.length === 0 ? command : `${command} [non-equivalent: unavailable CLI representation for ${fields.join(", ")}]`; const isRecord = (value: unknown): value is Record => typeof value === "object" && value !== null && !Array.isArray(value); const inputBindingCliArgs = ( bindings: readonly StepInputBinding[], pathFlag: "--input" | "--map" = "--input", ): { readonly args: readonly string[]; readonly unavailable: readonly string[] } => { const args: string[] = []; const unavailable: string[] = []; for (const binding of bindings) { if (typeof binding.target !== "string") { unavailable.push("input_bindings (use --bindings-file)"); continue; } if ("path" in binding) { if (typeof binding.path !== "string") { unavailable.push("input_bindings (use --bindings-file)"); continue; } args.push(pathFlag, shellArg(`${binding.path}=${binding.target}`)); continue; } if ("value" in binding) { const serialized = JSON.stringify(binding.value); if (serialized !== undefined) { args.push("--value", shellArg(`${binding.target}=${serialized}`)); } else { unavailable.push("input_bindings (use --bindings-file)"); } continue; } if ("expression" in binding) { // Composite expressions have no lossless inline CLI equivalent. unavailable.push("input_bindings (use --bindings-file)"); continue; } const exhaustive: never = binding; void exhaustive; unavailable.push("input_bindings (use --bindings-file)"); } return { args, unavailable }; }; const outputBindingCliArgs = ( bindings: readonly unknown[], ): { readonly args: readonly string[]; readonly unavailable: readonly string[] } => { const args: string[] = []; const unavailable: string[] = []; for (const binding of bindings) { if ( !isRecord(binding) || typeof binding.source !== "string" || typeof binding.target !== "string" ) { unavailable.push("output_bindings (use --bindings-file)"); continue; } args.push("--map", shellArg(`${binding.source}=${binding.target}`)); } return { args, unavailable }; }; const interpretCapabilitySummary = ( capability: NodeSpecCapabilitySummary | WrapperArtifactCapabilitySummary, ): CapabilitySummaryInterpreted => { const interpreted = { kind: capability.kind, name: capability.name, sourceId: capability.source_id, description: capability.description, outcomes: capability.outcomes, isAsync: capability.is_async, inputFields: capability.input_fields, outputFields: capability.output_fields, }; if (capability.kind === "wrapper_artifact") { return { ...interpreted, artifactId: capability.artifact_id, version: capability.version, title: capability.title, }; } return interpreted; }; const interpretDraftWorkspace = (decoded: { readonly diagnostics: ReadonlyArray<{ readonly code: string; readonly details?: Record; readonly message: string; readonly path: string; readonly repair_hint?: string | null; readonly step_id?: string | null; }>; readonly draft?: Record; readonly revision: number; readonly status: "valid" | "invalid" | "conflict"; readonly summary: { readonly name: unknown; readonly route_count: number; readonly start: unknown; readonly step_count: number; readonly steps: ReadonlyArray; }; readonly title: string | null; readonly workspace_id: string; }): DraftWorkspaceInterpreted => ({ workspaceId: decoded.workspace_id, revision: decoded.revision, title: decoded.title, status: decoded.status, diagnostics: decoded.diagnostics.map((diagnostic) => ({ code: diagnostic.code, path: diagnostic.path, message: diagnostic.message, stepId: diagnostic.step_id ?? null, repairHint: diagnostic.repair_hint ?? null, details: diagnostic.details ?? {}, })), summary: { name: decoded.summary.name, start: decoded.summary.start, stepCount: decoded.summary.step_count, routeCount: decoded.summary.route_count, steps: decoded.summary.steps, }, draft: decoded.draft ?? null, }); /** Adapts a snake_case run detail from the server into camelCase for the browser. */ const interpretRunDetail = (decoded: { readonly run_id: string | null; readonly deployment_id: string; readonly artifact_id: string; readonly artifact_version: number; readonly status: string; readonly resume_readiness: string | null; readonly interrupt: unknown; readonly outcome: string | null; readonly error: string | null; readonly output: Record | null; readonly diagnostics: ReadonlyArray; readonly trace_count: number; readonly next_actions: Parameters[0]; }) => ({ runId: decoded.run_id, deploymentId: decoded.deployment_id, artifactId: decoded.artifact_id, artifactVersion: decoded.artifact_version, status: decoded.status, resumeReadiness: decoded.resume_readiness, interrupt: decoded.interrupt, outcome: decoded.outcome, error: decoded.error, output: decoded.output, diagnostics: decoded.diagnostics, traceCount: decoded.trace_count, nextActions: interpretNextActions(decoded.next_actions), }); const defineOperationEntries = < const Entries extends ReadonlyArray, >(entries: Entries): Entries => entries; const operationEntries = defineOperationEntries([ { method: "workflow.health", label: "Health check", explanation: "Check if the workflow server is running", idempotency: "read", equivalentCli: () => "uv run wf status", interpret: (result): WorkflowHealthInterpreted => { const decoded = Schema.decodeUnknownSync(WorkflowHealthResultSchema)(result); return { status: decoded.status, storeRoot: decoded.store_root }; }, }, { method: "workflow.sources.list", label: "List sources", explanation: "List registered data sources with pagination", idempotency: "read", equivalentCli: (params) => { const p = Schema.decodeUnknownSync(WorkflowSourcesListPayloadSchema)( params, { onExcessProperty: "error" }, ); const parts = ["uv run wf source list"]; if (p.limit != null) parts.push(`--limit ${p.limit}`); if (p.cursor != null) parts.push(`--cursor ${shellArg(p.cursor)}`); return parts.join(" "); }, interpret: (result): WorkflowSourcesListInterpreted => { const decoded = Schema.decodeUnknownSync( WorkflowSourcesListResultSchema, )(result); return { sources: decoded.sources.map((source) => ({ id: source.id, kind: source.kind, enabled: source.enabled, description: source.description, counts: { tools: source.tool_count, nodeSpecs: source.node_spec_count, reducers: source.reducer_count, prompts: source.prompt_count, resources: source.resource_count, }, })), nextCursor: decoded.next_cursor, total: decoded.total, }; }, }, { method: "workflow.capabilities.list", label: "List capabilities", explanation: "List workflow-authorable capabilities with pagination", idempotency: "read", equivalentCli: (params) => { const p = Schema.decodeUnknownSync(WorkflowCapabilitiesListPayloadSchema)( params, { onExcessProperty: "error" }, ); const parts = ["uv run wf cap list"]; if (p.query != null) parts.push(`--query ${shellArg(p.query)}`); if (p.source_id != null) parts.push(`--source ${shellArg(p.source_id)}`); if (p.cursor != null) parts.push(`--cursor ${shellArg(p.cursor)}`); if (p.limit != null) parts.push(`--limit ${p.limit}`); return parts.join(" "); }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowCapabilitiesListResultSchema, )(result); return { capabilities: decoded.capabilities.map(interpretCapabilitySummary), nextCursor: decoded.next_cursor, total: decoded.total, }; }, }, { method: "workflow.capabilities.inspect", label: "Inspect capability", explanation: "Inspect one workflow-authorable capability", idempotency: "read", equivalentCli: (params) => { const p = Schema.decodeUnknownSync( WorkflowCapabilitiesInspectPayloadSchema, )(params, { onExcessProperty: "error" }); return `uv run wf cap inspect ${shellArg(p.qualified_name)}`; }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowCapabilitiesInspectResultSchema, )(result); const base = { kind: decoded.kind, name: decoded.name, sourceId: decoded.source_id, description: decoded.description, isAsync: decoded.is_async, outcomes: decoded.outcomes, inputSchema: decoded.input_schema, outputSchema: decoded.output_schema, wrapperHints: decoded.wrapper_hints, }; if (decoded.kind === "wrapper_artifact") { return { ...base, artifactId: decoded.artifact_id, title: decoded.title, version: decoded.version, requiredCapabilities: decoded.required_capabilities, }; } return { ...base, acceptsContext: decoded.accepts_context, }; }, }, { method: "workflow.capabilities.call", label: "Call capability", explanation: "Call one workflow-authorable capability directly", idempotency: "write", equivalentCli: (params) => { const p = Schema.decodeUnknownSync(WorkflowCapabilitiesCallPayloadSchema)( params, { onExcessProperty: "error" }, ); const parts = [ "uv run wf cap call", shellArg(p.qualified_name), "--input", shellArg(JSON.stringify(p.payload ?? {})), ]; if (p.deployment_id != null) { parts.push("--deployment", shellArg(p.deployment_id)); } return parts.join(" "); }, interpret: (result): CapabilityCallInterpreted => { const decoded = Schema.decodeUnknownSync( WorkflowCapabilitiesCallResultSchema, )(result); return { qualifiedName: decoded.qualified_name, sourceId: decoded.source_id, kind: decoded.kind, deploymentId: decoded.deployment_id, outcome: decoded.outcome, output: decoded.output, diagnostics: decoded.diagnostics.map((diagnostic) => ({ boundSource: diagnostic.bound_source, code: diagnostic.code, logicalRef: diagnostic.logical_ref, message: diagnostic.message, repairHint: diagnostic.repair_hint, severity: diagnostic.severity, })), }; }, }, { method: "workflow.draft_workspaces.list", label: "List draft workspaces", explanation: "List persisted workflow draft workspaces", idempotency: "read", equivalentCli: () => "uv run wf draft list", interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowDraftWorkspacesListResultSchema, )(result); return { items: decoded.workspaces.map(interpretDraftWorkspace), }; }, }, { method: "workflow.draft_workspaces.get", label: "Inspect draft workspace", explanation: "Inspect one persisted workflow draft workspace", idempotency: "read", equivalentCli: (params) => { const p = Schema.decodeUnknownSync( WorkflowDraftWorkspacesGetPayloadSchema, )(params, { onExcessProperty: "error" }); const parts = ["uv run wf draft inspect", shellArg(p.workspace_id)]; if (p.include_draft === true) parts.push("--include-draft"); return parts.join(" "); }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowDraftWorkspacesGetResultSchema, )(result); return interpretDraftWorkspace(decoded); }, }, { method: "workflow.draft_workspaces.create_empty", label: "Create empty draft workspace", explanation: "Create an empty persisted workflow draft workspace", idempotency: "write", equivalentCli: (params) => { const p = Schema.decodeUnknownSync( WorkflowDraftWorkspacesCreateEmptyPayloadSchema, )(params, { onExcessProperty: "error" }); const parts = ["uv run wf draft create", shellArg(p.workspace_id), "--name", shellArg(p.name)]; if (p.title != null) parts.push("--title", shellArg(p.title)); for (const outcome of p.outcomes ?? []) { parts.push("--outcome", shellArg(outcome)); } const unavailable = [ ...(p.input_schema != null ? ["input_schema (use --input-schema-file)"] : []), ...(p.state_schema != null ? ["state_schema (use --state-schema-file)"] : []), ...(p.output_schema != null ? ["output_schema (use --output-schema-file)"] : []), ]; return nonEquivalentCli(parts.join(" "), unavailable); }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowDraftWorkspacesCreateEmptyResultSchema, )(result); return interpretDraftWorkspace(decoded); }, }, { method: "workflow.draft_workspaces.create_from_capability", label: "Create draft from capability", explanation: "Create a capability-backed persisted workflow draft workspace", idempotency: "write", equivalentCli: (params) => { const p = Schema.decodeUnknownSync( WorkflowDraftWorkspacesCreateFromCapabilityPayloadSchema, )(params, { onExcessProperty: "error" }); const parts = [ "uv run wf draft create", shellArg(p.workspace_id), "--capability", shellArg(p.capability_name), ]; if (p.name != null) parts.push("--name", shellArg(p.name)); if (p.title != null) parts.push("--title", shellArg(p.title)); const unavailable = [ ...(p.input_schema != null ? ["input_schema"] : []), ...(p.state_schema != null ? ["state_schema"] : []), ...(p.output_schema != null ? ["output_schema"] : []), ...(p.input != null ? ["input"] : []), ...(p.output != null ? ["output"] : []), ...(p.input_map != null ? ["input_map"] : []), ...(p.output_map != null ? ["output_map"] : []), ...(p.error_message_source !== undefined ? ["error_message_source"] : []), ]; return nonEquivalentCli(parts.join(" "), unavailable); }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowDraftWorkspacesCreateFromCapabilityResultSchema, )(result); return interpretDraftWorkspace(decoded); }, }, { method: "workflow.draft_workspaces.add_step_from_capability", label: "Add capability draft step", explanation: "Add a capability-backed step to a persisted workflow draft", idempotency: "write", equivalentCli: (params) => { const p = Schema.decodeUnknownSync( WorkflowDraftWorkspacesAddStepFromCapabilityPayloadSchema, )(params, { onExcessProperty: "error" }); const parts = [ "uv run wf draft add capability", shellArg(p.workspace_id), "--revision", String(p.revision), "--step", shellArg(p.step_id), "--capability", shellArg(p.capability_name), ]; if (p.route_from_step != null) { parts.push("--from-step", shellArg(p.route_from_step)); if (p.route_from_outcome != null) { parts.push("--from-outcome", shellArg(p.route_from_outcome)); } } for (const [outcome, target] of Object.entries(p.routes ?? {})) { parts.push("--route", shellArg(`${outcome}=${target}`)); } for (const [source, target] of Object.entries(p.input_map ?? {})) { parts.push("--input", shellArg(`${source}=${target}`)); } for (const [source, target] of Object.entries(p.bind_outputs ?? {})) { parts.push("--bind-output", shellArg(`${source}=${target}`)); } if (p.desc != null) parts.push("--description", shellArg(p.desc)); if (p.retry != null) parts.push("--retry", String(p.retry)); if (p.timeout_seconds != null) { parts.push("--timeout-seconds", String(p.timeout_seconds)); } const unavailable: string[] = []; if (p.input_bindings != null) { if (p.input_map != null) { unavailable.push("input_map and input_bindings (mutually exclusive)"); } const rendered = inputBindingCliArgs(p.input_bindings); parts.push(...rendered.args); unavailable.push(...rendered.unavailable); } return nonEquivalentCli(parts.join(" "), unavailable); }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowDraftWorkspacesAddStepFromCapabilityResultSchema, )(result); return interpretDraftWorkspace(decoded); }, }, { method: "workflow.draft_workspaces.update_capability_step", label: "Update capability draft step", explanation: "Update metadata or input bindings on a capability-backed draft step", idempotency: "write", equivalentCli: (params) => { const p = Schema.decodeUnknownSync( WorkflowDraftWorkspacesUpdateCapabilityStepPayloadSchema, )(params, { onExcessProperty: "error" }); const parts = [ "uv run wf draft update capability", shellArg(p.workspace_id), "--revision", String(p.revision), "--step", shellArg(p.step_id), ]; if (p.update.desc != null) parts.push("--description", shellArg(p.update.desc)); else if (p.update.desc === null) parts.push("--clear-description"); if (p.update.retry != null) { if (p.update.retry === 0) parts.push("--retry", "0"); else parts.push("--retry", String(p.update.retry)); } else if (p.update.retry === null) parts.push("--clear-retry"); if (p.update.timeout_seconds != null) { parts.push("--timeout-seconds", String(p.update.timeout_seconds)); } else if (p.update.timeout_seconds === null) { parts.push("--clear-timeout"); } const unavailable: string[] = []; const updateInput = p.update.input; if (Array.isArray(updateInput)) { if (updateInput.length === 0) { parts.push("--clear-input"); } else { const rendered = inputBindingCliArgs(updateInput); parts.push(...rendered.args); unavailable.push(...rendered.unavailable); } } else if (updateInput === null) { unavailable.push("input: null (the service rejects null input updates)"); } return nonEquivalentCli(parts.join(" "), unavailable); }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowDraftWorkspacesUpdateCapabilityStepResultSchema, )(result); return interpretDraftWorkspace(decoded); }, }, { method: "workflow.draft_workspaces.set_route", label: "Set draft route", explanation: "Set one outcome route on a persisted workflow draft", idempotency: "write", equivalentCli: (params) => { const p = Schema.decodeUnknownSync( WorkflowDraftWorkspacesSetRoutePayloadSchema, )(params, { onExcessProperty: "error" }); return `uv run wf draft set-route ${shellArg(p.workspace_id)} --revision ${p.revision} --step ${shellArg(p.step_id)} --outcome ${shellArg(p.outcome)} --to ${shellArg(p.target)}`; }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowDraftWorkspacesSetRouteResultSchema, )(result); return interpretDraftWorkspace(decoded); }, }, { method: "workflow.draft_workspaces.set_step_input_bindings", label: "Set step input bindings", explanation: "Replace one capability-backed step's ordered input bindings", idempotency: "write", equivalentCli: (params) => { const p = Schema.decodeUnknownSync( WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema, )(params, { onExcessProperty: "error" }); const parts = [ "uv run wf draft set-input", shellArg(p.workspace_id), "--revision", String(p.revision), "--step", shellArg(p.step_id), ]; if (p.bindings.length === 0) { parts.push("--clear"); } else { const rendered = inputBindingCliArgs(p.bindings, "--map"); parts.push(...rendered.args); return nonEquivalentCli(parts.join(" "), rendered.unavailable); } return parts.join(" "); }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowDraftWorkspacesSetStepInputBindingsResultSchema, )(result); return interpretDraftWorkspace(decoded); }, }, { method: "workflow.draft_workspaces.set_step_output_bindings", label: "Set step output bindings", explanation: "Replace one capability-backed step's ordered output bindings", idempotency: "write", equivalentCli: (params) => { const p = Schema.decodeUnknownSync( WorkflowDraftWorkspacesSetStepOutputBindingsPayloadSchema, )(params, { onExcessProperty: "error" }); const parts = [ "uv run wf draft set-output", shellArg(p.workspace_id), "--revision", String(p.revision), "--step", shellArg(p.step_id), ]; if (p.bindings.length === 0) { parts.push("--clear"); } else { const rendered = outputBindingCliArgs(p.bindings); parts.push(...rendered.args); return nonEquivalentCli(parts.join(" "), rendered.unavailable); } return parts.join(" "); }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowDraftWorkspacesSetStepOutputBindingsResultSchema, )(result); return interpretDraftWorkspace(decoded); }, }, { method: "workflow.draft_workspaces.validate", label: "Validate draft workspace", explanation: "Validate a persisted workflow draft workspace", idempotency: "read", equivalentCli: (params) => { const p = Schema.decodeUnknownSync( WorkflowDraftWorkspacesValidatePayloadSchema, )(params, { onExcessProperty: "error" }); return `uv run wf draft validate ${shellArg(p.workspace_id)}`; }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowDraftWorkspacesValidateResultSchema, )(result); return interpretDraftWorkspace(decoded); }, }, { method: "workflow.artifacts.list", label: "List artifacts", explanation: "List workflow artifacts with pagination", idempotency: "read", equivalentCli: (params) => { const p = Schema.decodeUnknownSync(WorkflowArtifactsListPayloadSchema)( params, { onExcessProperty: "error" }, ); const parts = ["uv run wf artifact list"]; if (p.query != null) parts.push(`--query ${shellArg(p.query)}`); if (p.kind != null) parts.push(`--kind ${shellArg(p.kind)}`); if (p.cursor != null) parts.push(`--cursor ${shellArg(p.cursor)}`); if (p.limit != null) parts.push(`--limit ${p.limit}`); return parts.join(" "); }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowArtifactsListResultSchema, )(result); return { items: decoded.nodes.map((node) => ({ key: `${node.artifact_id}@${node.version}`, artifactId: node.artifact_id, version: node.version, kind: node.kind, displayName: node.display_name, description: node.description, outcomes: node.outcomes, requiredSources: node.required_sources, diagnosticCount: node.diagnostics.length, })), nextCursor: decoded.next_cursor, total: decoded.total, }; }, }, { method: "workflow.artifacts.inspect", label: "Inspect artifact", explanation: "Inspect a workflow artifact by id and version", idempotency: "read", equivalentCli: (params) => { const p = Schema.decodeUnknownSync(WorkflowArtifactsInspectPayloadSchema)( params, { onExcessProperty: "error" }, ); return `uv run wf artifact inspect ${shellArg(p.artifact_id)} --version ${p.version}`; }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowArtifactsInspectResultSchema, )(result); return { artifactId: decoded.id, version: decoded.version, title: decoded.title, kind: decoded.kind, description: decoded.description, outcomes: decoded.outcomes, plan: decoded.plan, requiredCapabilities: decoded.required_capabilities, workflowDependencies: decoded.workflow_dependencies, createdFromCatalogVersion: decoded.created_from_catalog_version, }; }, }, { method: "workflow.deployments.list", label: "List deployments", explanation: "List workflow deployments", idempotency: "read", equivalentCli: () => "uv run wf deploy list", interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowDeploymentsListResultSchema, )(result); return { items: decoded.deployments.map((d) => ({ id: d.id, artifactId: d.artifact_id, artifactVersion: d.artifact_version, bindingCount: d.binding_count, driftPolicy: d.drift_policy, })), }; }, }, { method: "workflow.deployments.inspect", label: "Inspect deployment", explanation: "Inspect a workflow deployment by id", idempotency: "read", equivalentCli: (params) => { const p = Schema.decodeUnknownSync( WorkflowDeploymentsInspectPayloadSchema, )(params, { onExcessProperty: "error" }); return `uv run wf deploy inspect ${shellArg(p.deployment_id)}`; }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowDeploymentsInspectResultSchema, )(result); return { id: decoded.id, artifactId: decoded.artifact_id, artifactVersion: decoded.artifact_version, bindings: decoded.bindings.map((b) => ({ logicalSource: b.logical_source, concreteSource: b.concrete_source, })), driftPolicy: decoded.drift_policy, }; }, }, { method: "workflow.deployments.validate", label: "Validate deployment", explanation: "Validate a workflow deployment", idempotency: "read", equivalentCli: (params) => { const p = Schema.decodeUnknownSync( WorkflowDeploymentsValidatePayloadSchema, )(params, { onExcessProperty: "error" }); return `uv run wf deploy validate ${shellArg(p.deployment_id)}`; }, interpret: (result) => { const decoded = Schema.decodeUnknownSync( WorkflowDeploymentsValidateResultSchema, )(result); return { deploymentId: decoded.deployment_id, artifactId: decoded.artifact_id, artifactVersion: decoded.artifact_version, status: decoded.status, diagnostics: decoded.diagnostics, nextActions: interpretNextActions(decoded.next_actions), }; }, }, { method: "workflow.runs.list", label: "List runs", explanation: "List workflow runs with pagination", idempotency: "read", equivalentCli: (params) => { const p = Schema.decodeUnknownSync(WorkflowRunsListPayloadSchema)( params, { onExcessProperty: "error" }, ); const parts = ["uv run wf run list"]; if (p.status != null) parts.push(`--status ${shellArg(p.status)}`); if (p.cursor != null) parts.push(`--cursor ${shellArg(p.cursor)}`); if (p.limit != null) parts.push(`--limit ${p.limit}`); return parts.join(" "); }, interpret: (result) => { const decoded = Schema.decodeUnknownSync(WorkflowRunsListResultSchema)( result, ); return { items: decoded.runs.map((run) => ({ runId: run.run_id, deploymentId: run.deployment_id, artifactId: run.artifact_id, artifactVersion: run.artifact_version, status: run.status, resumeReadiness: run.resume_readiness, diagnosticCount: run.diagnostic_count, createdAt: run.created_at, updatedAt: run.updated_at, })), nextCursor: decoded.next_cursor, total: decoded.total, }; }, }, { method: "workflow.runs.inspect", label: "Inspect run", explanation: "Inspect a workflow run by id", idempotency: "read", equivalentCli: (params) => { const p = Schema.decodeUnknownSync(WorkflowRunsInspectPayloadSchema)( params, { onExcessProperty: "error" }, ); return `uv run wf run inspect ${shellArg(p.run_id)}`; }, interpret: (result) => { const decoded = Schema.decodeUnknownSync(WorkflowRunsInspectResultSchema)( result, ); return interpretRunDetail(decoded); }, }, { method: "workflow.runs.start", label: "Start run", explanation: "Start a workflow deployment run", idempotency: "write", equivalentCli: (params) => { const p = Schema.decodeUnknownSync(WorkflowRunsStartPayloadSchema)( params, { onExcessProperty: "error" }, ); return `uv run wf run start ${shellArg(p.deployment_id)} --input ''`; }, interpret: (result) => { const decoded = Schema.decodeUnknownSync(WorkflowRunsStartResultSchema)( result, { onExcessProperty: "ignore" }, ); return interpretRunDetail(decoded); }, }, { method: "workflow.runs.resume", label: "Resume run", explanation: "Resume an interrupted workflow run", idempotency: "write", equivalentCli: (params) => { const p = Schema.decodeUnknownSync(WorkflowRunsResumePayloadSchema)( params, { onExcessProperty: "error" }, ); return `uv run wf run resume ${shellArg(p.run_id)} --payload ''`; }, interpret: (result) => { const decoded = Schema.decodeUnknownSync(WorkflowRunsResumeResultSchema)( result, { onExcessProperty: "ignore" }, ); return interpretRunDetail(decoded); }, }, { method: "workflow.runs.trace", label: "Read run trace", explanation: "Read trace frames for a workflow run", idempotency: "read", equivalentCli: (params) => { const p = Schema.decodeUnknownSync(WorkflowRunsTracePayloadSchema)( params, { onExcessProperty: "error" }, ); const parts = ["uv run wf run trace", shellArg(p.run_id)]; if (p.trace_range.start != null) { parts.push(`--from ${p.trace_range.start}`); } if (p.trace_range.limit != null) { parts.push(`--limit ${p.trace_range.limit}`); } return parts.join(" "); }, interpret: (result) => { const decoded = Schema.decodeUnknownSync(WorkflowRunsTraceResultSchema)(result); const trace = decoded.trace.map((entry) => ({ frameId: entry.frame_id, nodeId: entry.node_id, stepType: entry.step_type, outcome: entry.outcome, nextNodeId: entry.next_node_id, resolvedInput: entry.resolved_input, output: entry.output, stateChanges: entry.state_changes, })); return { runId: decoded.run_id, status: decoded.status, frames: trace, traceStart: decoded.trace_start, traceLimit: decoded.trace_limit, traceTruncated: decoded.trace_truncated, }; }, }, ]); export type OperationName = (typeof operationEntries)[number]["method"]; export const workflowRpcOperationNames: ReadonlyArray = Object.freeze(operationEntries.map(({ method }) => method)); const operationNameSet: ReadonlySet = new Set(workflowRpcOperationNames); export const isOperationName = (value: string): value is OperationName => operationNameSet.has(value); const registry: ReadonlyMap = new Map( operationEntries.map((entry) => [entry.method, entry]), ); export const getOperationMeta = (method: string): OperationMeta | undefined => registry.get(method); export const listOperations = (): ReadonlyArray => operationEntries;