/**
 * Plan step extraction and [DONE:n] progress tracking.
 *
 * The agent outputs [DONE:n] markers in its text to signal that step n
 * of the approved plan has been completed.  The UI parses these markers
 * and renders a progress widget.
 */
export interface PlanStep {
    /** 1-based step number */
    step: number;
    /** Short description extracted from the plan */
    text: string;
    completed: boolean;
}
/**
 * Extract numbered steps from a plan markdown string.
 *
 * Steps are ONLY read from a dedicated step-section heading (`## Steps` or a
 * close synonym — see STEP_SECTION_HEADING). If the plan has no such section,
 * this returns an empty array — progress tracking is opt-in.
 *
 * The previous behaviour scanned the entire document for any top-level
 * numbered list when no step section was present, which scraped phantom
 * "steps" out of unrelated prose (design decisions, Q&A bullets, rejected
 * alternatives). The post-approval prompt then pushed the model to march
 * through those non-tasks and emit `[DONE:n]` markers for them, deadlocking
 * a model that correctly refused to fabricate completion. Requiring an
 * explicit step-section heading keeps the progress contract honest.
 *
 * Looks for lines like:
 *   1. Do something
 *   2) Do something else
 *   3. **Bold step**
 */
export declare function extractPlanSteps(planContent: string): PlanStep[];
/**
 * Re-base a frozen step list onto a freshly extracted one.
 *
 * The progress widget captures `extractPlanSteps` once, at plan-approval time.
 * But the agent can rewrite or expand the approved plan while implementing it
 * (e.g. a 2-step plan becomes 12 steps). When that happens the frozen snapshot
 * goes stale: the total is wrong and `[DONE:n]` markers for the new steps can't
 * be matched. Re-extracting from the live plan and re-basing onto it keeps the
 * total in sync.
 *
 * Completion is carried over BY STEP NUMBER (not text), so a reworded step that
 * was already done stays done. New steps adopt the fresh text and start
 * incomplete. If the fresh plan has no steps (e.g. the step section was
 * temporarily removed mid-edit) the previous list is returned unchanged so we
 * never blow away real progress. The previous array reference is returned when
 * nothing meaningfully changed, so React state setters can no-op.
 */
export declare function rebasePlanSteps(previous: PlanStep[], fresh: PlanStep[]): PlanStep[];
/**
 * Strip [DONE:n] markers from text for display purposes.
 * These markers are machine-readable signals for the progress widget,
 * not meant to be shown to the user.
 */
export declare function stripDoneMarkers(text: string): string;
/**
 * Segment of an assistant turn's text after [DONE:N] markers are split
 * out for inline rendering. Used by the chat to render "✓ Step N: <desc>"
 * markers in the same temporal order the agent emitted them, instead of
 * stripping markers to invisible whitespace.
 */
export type DisplaySegment = {
    kind: "text";
    text: string;
} | {
    kind: "done";
    stepNum: number;
    description: string;
};
/**
 * Split text on [DONE:N] markers, returning an array of segments. Empty/
 * whitespace-only text segments are dropped. Step description is looked
 * up in `steps` (falls back to "" so the renderer can show just the step
 * number when the plan is no longer in scope, e.g. after onComplete
 * cleared planSteps).
 */
export declare function segmentDisplayText(text: string, steps: PlanStep[]): DisplaySegment[];
/**
 * Scan text for [DONE:n] markers and return the set of completed step numbers.
 */
export declare function findCompletedMarkers(text: string): Set<number>;
/**
 * Apply completed markers to a steps array (immutable — returns new array).
 */
export declare function markStepsCompleted(steps: PlanStep[], completed: Set<number>): PlanStep[];
//# sourceMappingURL=plan-steps.d.ts.map