import { BlockNodeAddress, BlockNodeType } from './base.js';
import { TextAddress, TrackedChangeAddress, SelectionTarget, DeleteBehavior } from './address.js';
import { TextSelector, NodeSelector } from './query.js';
import { InsertStylePolicy, StylePolicy } from './style-policy.types.js';
import { InlineRunPatch } from '../format/inline-run-patch.js';
import { SDFragment } from './fragment.js';
import { Placement, NestingPolicy } from './placement.js';
import { ChangeMode } from '../write/write.js';
import { StoryLocator } from './story.types.js';
export type SelectWhere = {
    by: 'select';
    select: TextSelector | NodeSelector;
    within?: BlockNodeAddress;
    require: 'first' | 'exactlyOne' | 'all';
};
export type RefWhere = {
    by: 'ref';
    ref: string;
    within?: BlockNodeAddress;
};
export type TargetWhere = {
    by: 'target';
    target: SelectionTarget;
};
export type BlockWhere = {
    by: 'block';
    nodeType: BlockNodeType;
    nodeId: string;
};
export type StepWhere = SelectWhere | RefWhere | TargetWhere | BlockWhere;
export type AssertWhere = {
    by: 'select';
    select: TextSelector | NodeSelector;
    within?: BlockNodeAddress;
};
/**
 * A single replacement block for structured multi-paragraph replacements.
 * In this workstream, per-block inline style overrides are not supported;
 * step-level `style` policy applies uniformly to all replacement blocks.
 */
export type ReplacementBlock = {
    text: string;
};
/**
 * Replacement payload for text.rewrite steps.
 *
 * - `{ text }`: flat string. For single-block (range) targets, used as-is.
 *   For cross-block (span) targets, normalized via deterministic paragraph
 *   boundary detection (\n\n+).
 * - `{ blocks }`: structured multi-paragraph payload, authoritative when provided.
 *   Use this for explicit control over paragraph structure.
 *
 * Exactly one of `text` or `blocks` must be provided.
 */
export type ReplacementPayload = {
    text: string;
    blocks?: undefined;
} | {
    text?: undefined;
    blocks: ReplacementBlock[];
};
export type TextRewriteStep = {
    id: string;
    op: 'text.rewrite';
    where: StepWhere;
    args: {
        replacement: ReplacementPayload;
        /**
         * Style policy for the replacement text.
         * When omitted, defaults to preserve mode:
         *   inline: { mode: 'preserve', onNonUniform: 'majority' }
         *   paragraph: { mode: 'preserve' }
         */
        style?: StylePolicy;
    };
};
export type TextInsertStep = {
    id: string;
    op: 'text.insert';
    where: StepWhere;
    args: {
        position: 'before' | 'after';
        content: {
            text: string;
        };
        style?: InsertStylePolicy;
    };
};
export type TextDeleteStep = {
    id: string;
    op: 'text.delete';
    where: StepWhere;
    args: {
        /** Controls block-edge expansion. Defaults to `'selection'`. */
        behavior?: DeleteBehavior;
    };
};
export type StyleApplyStep = {
    id: string;
    op: 'format.apply';
    where: StepWhere;
    args: {
        inline?: InlineRunPatch;
        alignment?: 'left' | 'center' | 'right' | 'justify';
        /** When "block", inline formatting expands to cover the entire parent textblock(s), not just the matched range. Default: "match". */
        scope?: 'match' | 'block';
    };
};
export type AssertStep = {
    id: string;
    op: 'assert';
    where: AssertWhere;
    args: {
        expectCount: number;
    };
};
export type StructuralInsertStep = {
    id: string;
    op: 'structural.insert';
    where: StepWhere;
    args: {
        content: SDFragment;
        placement?: Placement;
        nestingPolicy?: NestingPolicy;
    };
};
export type StructuralReplaceStep = {
    id: string;
    op: 'structural.replace';
    where: StepWhere;
    args: {
        content: SDFragment;
        nestingPolicy?: NestingPolicy;
    };
};
export type DomainStep = {
    id: string;
    op: string;
    where: StepWhere;
    args: Record<string, unknown>;
};
export type MutationStep = TextRewriteStep | TextInsertStep | TextDeleteStep | StyleApplyStep | StructuralInsertStep | StructuralReplaceStep | AssertStep | DomainStep;
export type { ChangeMode } from '../write/write.js';
export type MutationsApplyInput = {
    /** Target story for the mutation plan. Omit for body (backward compatible). */
    in?: StoryLocator;
    expectedRevision?: string;
    atomic: true;
    changeMode: ChangeMode;
    steps: MutationStep[];
};
export type MutationsPreviewInput = {
    /** Target story for the mutation preview. Omit for body (backward compatible). */
    in?: StoryLocator;
    expectedRevision?: string;
    atomic: true;
    changeMode: ChangeMode;
    steps: MutationStep[];
};
/** Maximum number of steps per mutation plan. */
export declare const MAX_PLAN_STEPS = 200;
/** Maximum total resolved targets across all steps in a plan. */
export declare const MAX_PLAN_RESOLVED_TARGETS = 500;
export type StepEffect = 'changed' | 'noop' | 'error' | 'assert_passed' | 'assert_failed';
/** Resolution for a single-block (range) target. */
export type TextStepResolution = {
    target: TextAddress;
    range: {
        from: number;
        to: number;
    };
    text: string;
};
/** Resolution for a cross-block (span) target. */
export type SpanStepResolution = {
    targets: TextAddress[];
    matchId: string;
    text: string;
};
/** Resolution for a selection-based target (may span multiple blocks). */
export type SelectionStepResolution = {
    selectionTarget: SelectionTarget;
    range: {
        from: number;
        to: number;
    };
    text: string;
};
export type TextStepData = {
    domain: 'text';
    resolutions: TextStepResolution[];
    spanResolutions?: SpanStepResolution[];
    selectionResolutions?: SelectionStepResolution[];
};
export type AssertStepData = {
    domain: 'assert';
    expectedCount: number;
    actualCount: number;
};
export type DomainStepData = {
    domain: 'command';
    commandDispatched: boolean;
};
export type TableStepData = {
    domain: 'table';
    tableId: string;
    affectedRows?: string[];
    affectedCells?: string[];
    affectedColumns?: number[];
};
export type StructuralStepData = {
    domain: 'structural';
    insertedBlockIds?: string[];
};
export type StepOutcomeData = TextStepData | AssertStepData | DomainStepData | TableStepData | StructuralStepData;
export type StepOutcome = {
    stepId: string;
    op: string;
    effect: StepEffect;
    matchCount: number;
    trackedChangeIds?: string[];
    data: StepOutcomeData;
};
export type PlanReceipt = {
    success: true;
    revision: {
        before: string;
        after: string;
    };
    steps: StepOutcome[];
    trackedChanges?: TrackedChangeAddress[];
    timing: {
        totalMs: number;
    };
};
export type PreviewFailurePhase = 'compile' | 'execute' | 'assert';
export type PreviewFailure = {
    code: string;
    stepId: string;
    phase: PreviewFailurePhase;
    message: string;
    details?: unknown;
};
export type StepPreview = {
    stepId: string;
    op: string;
    resolutions?: TextStepResolution[];
    spanResolutions?: SpanStepResolution[];
    selectionResolutions?: SelectionStepResolution[];
    style?: unknown;
};
export type MutationsPreviewOutput = {
    evaluatedRevision: string;
    steps: StepPreview[];
    valid: boolean;
    failures?: PreviewFailure[];
};
export type PlanExecutionError = {
    code: string;
    message: string;
    stepId?: string;
    details?: unknown;
};
export type { RevisionGuardOptions, MutationOptions } from '../write/write.js';
//# sourceMappingURL=mutation-plan.types.d.ts.map