/** * Markdown Serialization Utilities * * Convert between ADO work items and local markdown files. * * Files use YAML frontmatter (scalar fields — ADO refnames or friendly * aliases) + body sections (long text fields tagged with * `` comments). The sync engine is generic: * any field named in the file is pushed to ADO, any field not named is * left alone. * * Legacy files (pre-annotation) are detected and parsed via a * legacy-mappings fallback table. They auto-upgrade to the annotated * format on the next pull. */ import { type LocalOnlySection } from './annotation-parser.js'; /** * Subset of frontmatter values used by downstream services (sync-service, * file-utils) via stable friendly names. Always populated on parse by * pulling the corresponding refname out of `fieldMap`. */ export interface WorkItemFrontmatter { id: number; title: string; type: string; state: string; url: string; assignedTo?: string; storyPoints?: number; parent?: number; moscow?: string; tags?: string[]; areaPath?: string; iterationPath?: string; lastSyncedRevision: number; lastSyncedAt: string; } /** * Legacy slot for the four historically-supported custom fields. Retained * so that pre-annotation callers (and reports) keep working. New-style * consumers should read `bodyFieldMap` instead. */ export interface AdditionalFields { howToTest?: string; deploymentInformation?: string; predeploymentSteps?: string; postdeploymentSteps?: string; } export interface ParsedWorkItemFile { /** Friendly-name frontmatter view for back-compat. */ frontmatter: WorkItemFrontmatter; /** All scalar ADO fields from frontmatter, keyed by refname. */ fieldMap: Record; /** All body text fields (from annotated sections OR legacy headings), keyed by refname. */ bodyFieldMap: Record; /** Sections with no ADO-field annotation — preserved in the file but not pushed. */ localOnlySections: LocalOnlySection[]; /** Work item type (mirrors frontmatter.type). */ workItemType: string; description: string; reproSteps: string; acceptanceCriteria: string; additionalFields: AdditionalFields; rawContent: string; } export type FieldValue = string | number | boolean | string[]; export interface CommentsFrontmatter { id: number; title: string; commentCount: number; lastSyncedAt: string; } export interface ParsedComment { author: string; date: string; content: string; } export interface WorkItemToMarkdownResult { content: string; skippedFields: string[]; } /** * Serialize an ADO work item to an annotated markdown file. * * Follows the template for `fields['System.WorkItemType']`. Frontmatter * order and body-section order come from the template. Fields the ADO * response carries but the template doesn't mention are appended to the * frontmatter with a discovery comment (see D4 in the design plan). */ export declare function workItemToMarkdown(workItem: any, revision: number): WorkItemToMarkdownResult; export declare function parseWorkItemMarkdown(content: string): ParsedWorkItemFile; export declare function buildPatchOperations(parsed: ParsedWorkItemFile, currentWorkItem: any, skipAutoConvert?: boolean): { operations: any[]; skippedFields: string[]; convertedFields: string[]; }; export interface NewWorkItemFrontmatter { title: string; type: string; state: string; parent?: number; assignedTo?: string; storyPoints?: number; moscow?: string; tags?: string[]; areaPath?: string; iterationPath?: string; } export interface ParsedNewWorkItemFile { frontmatter: NewWorkItemFrontmatter; fieldMap: Record; bodyFieldMap: Record; localOnlySections: LocalOnlySection[]; workItemType: string; description: string; reproSteps: string; acceptanceCriteria: string; additionalFields: AdditionalFields; rawContent: string; } export declare function isNewWorkItem(frontmatter: Record): boolean; export declare function parseNewWorkItemMarkdown(content: string): ParsedNewWorkItemFile; /** * Split new-work-item fields into standard (safe for creation) and custom * (must be set via a follow-up update because ADO rejects custom fields * during creation). * * Standard = refname starts with `System.*` or `Microsoft.VSTS.*`. * Custom = everything else (conventionally `Custom.*`). */ export interface NewWorkItemFieldSplit { standardFields: Record; customFields: Record; } export declare function buildNewWorkItemFields(parsed: ParsedNewWorkItemFile, parentWorkItem?: any): NewWorkItemFieldSplit; export declare function generateNewWorkItemTemplate(parentId: number | undefined, parentTitle: string, project: string, workItemType?: string): string; export declare function commentsToMarkdown(workItem: any, comments: any[]): string; export declare function updateSyncRevision(content: string, newRevision: number): string; export declare function convertNewFileToSynced(content: string, workItemId: number, revision: number, url: string): string; /** * Return the list of large-text (body) refnames that should be HTML-checked * for a given work-item type. Driven by the loaded template. */ export declare function templateBodyRefnamesForType(workItemType: string): string[]; //# sourceMappingURL=markdown-serializer.d.ts.map