/**
 * Pure logic behind `forest workflow apply`: strict parsing of the JSON spec
 * (which `forest-layout.json` deliberately does NOT get — that file is a
 * machine round-trip, this one is hand-authored), upsert matching against the
 * remote workflows document, and the metadata `replace` plan for updates.
 * Kept free of IO so it is unit-testable; the command provides the glue.
 */
import type { JsonPatchOp } from './types';
import type { WorkflowSpec } from './workflow-bpmn';
/** The hand-authored apply spec: a {@link WorkflowSpec} plus upsert extras. */
export type WorkflowApplySpec = Partial<WorkflowSpec> & {
    id?: string;
    position?: number;
    version?: number;
};
/** A workflow as returned by `GET /api/workflows/...` (patchable document). */
export type RemoteWorkflow = {
    bpmnAwsS3Identifier?: string;
    collectionId: string;
    id: string;
    name: string;
    position?: number;
    segmentIds?: string[];
};
/** One planned metadata change on an existing workflow (`replace` + display label). */
export type ShellChange = {
    field: 'name' | 'position' | 'segments';
    label: string;
    op: JsonPatchOp;
};
/**
 * Parse the raw JSON of a `workflow apply` spec, strictly: clean JSON errors,
 * top-level/step/branch fields are whitelisted (typo-safe: "did you mean?")
 * and type-checked, `version` is absent-or-1 and `id`/`position` are
 * format-checked. Semantic
 * validation of the step graph stays in `validateWorkflowSpec` (shared with
 * the layout path, which must remain lenient about extra keys).
 */
export declare function parseWorkflowSpec(raw: string): WorkflowApplySpec;
/**
 * The workflows the spec designates, in remote order: all of them by explicit
 * `id`, else by name + collection. More than one match means the environment
 * holds duplicates — the caller warns and updates the first.
 */
export declare function findWorkflowMatches(existing: RemoteWorkflow[], spec: WorkflowApplySpec): RemoteWorkflow[];
/**
 * The metadata `replace` ops an update needs so the spec stays the source of
 * truth: `name` and `segments` are always converged (an omitted `segments`
 * means "no segments"); `position` only when the spec pins one — the remote
 * ordering is otherwise left alone.
 */
export declare function planShellUpdate(current: RemoteWorkflow, spec: WorkflowApplySpec): ShellChange[];
//# sourceMappingURL=workflow-apply.d.ts.map