/** * OpenSpec Writer * * Takes generated specifications and writes them to the OpenSpec directory structure. * Handles initialization, merging with existing specs, and output tracking. */ import type { GeneratedSpec } from './openspec-format-generator.js'; import type { ProjectSurveyResult } from './spec-pipeline.js'; /** * Write mode for handling existing specs */ export type WriteMode = 'replace' | 'merge' | 'skip'; /** * Options for OpenSpec writer */ export interface OpenSpecWriterOptions { /** Root path of the project */ rootPath: string; /** How to handle existing specs */ writeMode?: WriteMode; /** Version string for generated specs */ version?: string; /** Whether to create backups */ createBackups?: boolean; /** Whether to update config.yaml */ updateConfig?: boolean; /** Whether to validate specs before writing */ validateBeforeWrite?: boolean; /** Remove existing domain directories not present in the new generation (used with --force) */ cleanBeforeWrite?: boolean; } /** * Result of writing a single spec */ export interface WriteResult { path: string; action: 'written' | 'skipped' | 'merged' | 'backed_up'; success: boolean; error?: string; backupPath?: string; } /** * Generation report */ export interface GenerationReport { timestamp: string; openspecVersion: string; openloreVersion: string; filesWritten: string[]; filesSkipped: string[]; filesBackedUp: string[]; filesMerged: string[]; domainsRemoved: string[]; configUpdated: boolean; validationErrors: string[]; warnings: string[]; nextSteps: string[]; } /** * Stale-domain cleanup is destructive, so it is authorized only by an unfiltered * full regeneration. A domain filter scopes what is written; it is not a delete list. * (change: harden-openspec-writer-fidelity) */ export declare function shouldCleanStaleDomains(force: boolean | undefined, domains: readonly string[] | undefined, adrOnly: boolean | undefined): boolean; /** * OpenSpec Writer - writes generated specs to the OpenSpec directory structure */ export declare class OpenSpecWriter { private rootPath; private options; private configManager; constructor(options: OpenSpecWriterOptions); /** * Initialize OpenSpec directory structure */ initialize(): Promise; /** * Write all generated specs */ writeSpecs(specs: GeneratedSpec[], survey: ProjectSurveyResult, metadataSpecs?: GeneratedSpec[]): Promise; /** * Write a single spec file */ private writeSpec; /** * Merge spec with existing content */ private mergeSpec; /** * Extract generated content for merge (skip headers) */ private extractGeneratedSection; /** * Boundary tokens can appear in LLM output or human documentation. Store those * occurrences as visible Markdown text so only writer-authored tokens delimit a * replaceable block. */ private escapeGeneratedBoundaryTokens; /** * Backup an existing file */ private backupFile; /** * Update config.yaml with openlore metadata */ private updateConfig; /** * Detect OpenSpec version if installed */ private detectOpenSpecVersion; /** * Generate next steps based on results */ private generateNextSteps; /** * Save generation report to .openlore/outputs/ */ private saveReport; /** * Log summary to console */ private logSummary; /** * Ensure directory exists for file */ private ensureDir; /** * Get list of existing spec domains */ getExistingDomains(): Promise; } /** * Write generated specs to OpenSpec directory */ export declare function writeOpenSpecs(specs: GeneratedSpec[], survey: ProjectSurveyResult, options: OpenSpecWriterOptions): Promise; /** * Initialize OpenSpec directory structure without writing specs */ export declare function initializeOpenSpec(rootPath: string): Promise; //# sourceMappingURL=openspec-writer.d.ts.map