/** * One-off, explicit migration of the retired v1 task files * (`.crewly/tasks//{open,in_progress}/*.md`) into project tickets * (specs/2026-09-28-project-tickets.md §8). * * - Only unfinished files are imported (open / in_progress); done/ and * blocked/ are left alone. * - Every import becomes a `backlog` ticket — nobody is working on it now, and * a person decides what is still wanted. * - The original file is never modified, moved or deleted; its repo-relative * path is recorded as `migratedFrom`, which also makes re-runs no-ops. * - Dry-run unless `apply: true`. * * @module services/project-tickets/v1-task-migration */ import { type ProjectTicketCriterion, type ProjectTicketPriority } from '../../types/project-ticket.types.js'; import type { ProjectTicketService } from './project-ticket.service.js'; /** Options for {@link migrateV1Tasks}. */ export interface V1MigrationOptions { /** Write the tickets (default false = dry-run) */ apply?: boolean; /** Only these milestone folders (default: all) */ milestones?: string[]; } /** What happens to one v1 file. */ export interface V1MigrationItem { /** Repo-relative path of the v1 file */ source: string; milestone: string; /** The v1 status folder it sits in */ v1Status: string; title: string; priority: ProjectTicketPriority; action: 'create' | 'skip-existing' | 'skip-invalid' | 'skip-milestone'; /** Id of the created ticket (apply) or the existing one */ ticketId?: string; reason?: string; } /** Report of a run. */ export interface V1MigrationReport { projectPath: string; apply: boolean; /** v1 files found in open/in_progress folders */ scanned: number; /** Tickets created (apply) or that would be created (dry-run) */ toCreate: number; created: number; skipped: number; byMilestone: Record; items: V1MigrationItem[]; } /** A v1 file read into ticket content. */ interface V1Parsed { title: string; priority: ProjectTicketPriority; labels: string[]; description: string; acceptance: ProjectTicketCriterion[]; } /** * Push markdown headings two levels down (outside code fences) so an imported * body cannot open sections of its own inside the ticket. * * @param text - Markdown * @returns Markdown with `#` → `###`, `##` → `####`, … */ export declare function demoteHeadings(text: string): string; /** * Read a v1 task file. * * @param content - File content * @param fileBase - File name without `.md` * @param milestone - Milestone folder * @returns Ticket content */ export declare function parseV1Task(content: string, fileBase: string, milestone: string): V1Parsed; /** * Import unfinished v1 task files as backlog tickets. * * @param tickets - Ticket store * @param projectPath - Project root * @param projectName - Project name (id prefix on first allocation) * @param options - `apply` (default false), `milestones` * @returns What was / would be done * * @example * ```typescript * const dry = await migrateV1Tasks(svc, '/repo', 'repo'); // report only * const run = await migrateV1Tasks(svc, '/repo', 'repo', { apply: true }); * ``` */ export declare function migrateV1Tasks(tickets: ProjectTicketService, projectPath: string, projectName: string, options?: V1MigrationOptions): Promise; export {}; //# sourceMappingURL=v1-task-migration.d.ts.map