/**
 * Kanban bridge — maps taskStore tasks to a 3-column Kanban view
 * (triage / doing / done) and promotes any task that lands in the
 * triage column into the autonomy loop's IMPLEMENTATION_PLAN.md so
 * the next loop iteration picks it up.
 *
 * Mapping convention:
 *   Column "triage" → tag "kanban:triage" OR status "pending"
 *   Column "doing"  → tag "kanban:doing"  OR status in {assigned, in_progress, review}
 *   Column "done"   → tag "kanban:done"   OR status in {done, cancelled, failed}
 *
 * An explicit "kanban:*" tag always wins over the status-based default.
 * That lets the UI move a card without touching its lifecycle state.
 *
 * Promotion contract (triage → plan):
 *   - Idempotent: a task whose id already appears in the plan is not
 *     duplicated.
 *   - The resulting plan task uses the same id as the source task
 *     (slugified for safety), the task title verbatim, and a `kind:`
 *     inferred from task tags ("kind:code"/"kind:research"/"kind:external"
 *     wins; otherwise default code).
 */
import type { Task } from './taskStore';
import { type PlanTask, type TaskKind } from './goalExpander';
export type KanbanColumn = 'triage' | 'doing' | 'done';
export declare const KANBAN_TAGS: Record<KanbanColumn, string>;
/**
 * Decide which Kanban column a task belongs to. Explicit `kanban:*`
 * tags always win — that's how the UI moves a card without touching
 * the task's lifecycle state.
 */
export declare function taskToColumn(task: Task): KanbanColumn;
/**
 * Group an arbitrary list of tasks into the 3-column board view.
 * Order within each column preserves caller order.
 */
export declare function groupTasksByColumn(tasks: Task[]): Record<KanbanColumn, Task[]>;
/**
 * Replace the kanban:* tag on a task. Returns the new tag set with at
 * most one kanban tag. Other tags (including `kind:*`) are preserved.
 */
export declare function withKanbanTag(currentTags: string[] | undefined, column: KanbanColumn): string[];
/**
 * Extract a TaskKind from tag list (`kind:code`, `kind:research`,
 * `kind:external`). Returns undefined when no recognised tag is set.
 */
export declare function inferKindFromTags(tags: string[] | undefined): TaskKind | undefined;
/**
 * Map a taskStore Task into a plan-shaped task. Uses the task id when
 * it's already slug-shaped; otherwise slugifies the title.
 */
export declare function taskToPlanTask(task: Task): PlanTask;
export interface PlanIoHooks {
    readFile: (p: string) => Promise<string>;
    writeFile: (p: string, data: string) => Promise<void>;
    appendFile: (p: string, data: string) => Promise<void>;
    access: (p: string) => Promise<void>;
}
export interface PromoteResult {
    /** Tasks actually appended (skips ids already present). */
    appended: PlanTask[];
    /** Tasks skipped because their id was already in the plan. */
    skipped: PlanTask[];
    /** True if the plan file was modified. */
    mutated: boolean;
}
/**
 * Append any "triage"-column tasks that aren't already in the plan.
 * Idempotent — running twice is a no-op for the second call.
 */
export declare function promoteTriageToPlan(tasks: Task[], options: {
    projectDir: string;
    planPath?: string;
    io?: PlanIoHooks;
}): Promise<PromoteResult>;
//# sourceMappingURL=kanbanBridge.d.ts.map