/**
 * Living Docs Sync - Simplified sync mechanism
 *
 * Syncs increment specs to living docs structure:
 * - .specweave/docs/internal/specs/{project}/FS-XXX/FEATURE.md
 * - .specweave/docs/internal/specs/{project}/FS-XXX/us-*.md
 *
 * All features live directly under the project folder.
 * Archive: .specweave/docs/internal/specs/{project}/_archive/FS-XXX/
 *
 * Project folder is auto-detected from:
 * 1. multiProject.activeProject (config)
 * 2. Git remote (GitHub repo name)
 * 3. "default" (fallback)
 *
 * Uses FeatureIDManager for automatic feature ID assignment (greenfield vs brownfield)
 */
import { Logger } from '../../utils/logger.js';
import type { SyncOptions, SyncResult, ParsedSpec, UserStoryData, AcceptanceCriterionData } from './types.js';
export type { SyncOptions, SyncResult, ParsedSpec, UserStoryData, AcceptanceCriterionData };
export declare class LivingDocsSync {
    private static activeSyncs;
    private projectRoot;
    private featureIdManager;
    private boardMatcher;
    private crossProjectSync;
    private logger;
    private projectId;
    private projectResolution;
    constructor(projectRoot: string, options?: {
        logger?: Logger;
    });
    /**
     * Resolve increment directory from a short or full ID.
     * Handles "0421" → "0421-umbrella-docs-update" prefix matching.
     */
    private resolveIncrementDir;
    /**
     * Get current project ID
     *
     * Priority:
     * 1. Git remote (GitHub repo name)
     * 2. Sync configuration (JIRA/ADO project)
     * 3. "default" (fallback)
     */
    getProjectId(): string;
    /**
     * Sync an increment to living docs
     */
    syncIncrement(incrementId: string, options?: SyncOptions): Promise<SyncResult>;
    /**
     * Get feature ID for increment with EXTERNAL-ONLY collision detection
     *
     * SIMPLIFIED (v0.29.0): Feature ID is derived from increment number
     * No longer reads from metadata.json - derivation is the single source of truth
     *
     * CRITICAL FIX (2025-12-04): Collision detection was causing chain shifts!
     *
     * BUG: Old code checked for BOTH FS-XXX and FS-XXXE collisions.
     * This caused: increment 0103 sync → FS-103 exists → use FS-104 (WRONG!)
     * Result: FS-104 would contain 0103 content, FS-105 would contain 0104, etc.
     *
     * FIX: Internal features (FS-XXX) are DETERMINISTIC:
     * - Increment 0104 → ALWAYS FS-104 (derived, no collision check for internal)
     * - Only check for EXTERNAL collisions (FS-XXXE)
     * - If FS-XXXE exists → then use next available internal ID
     * - If FS-XXX already exists → REUSE (same increment re-syncing)
     *
     * CRITICAL (v0.33.0): External increments (0111E-...) MUST map to external
     * features (FS-111E), not internal ones. Uses canonical deriveFeatureId().
     *
     * @param incrementId - Increment ID (e.g., "0081-ado-repo-cloning" or "0111E-external")
     * @param resolvedProjectPath - Resolved project path (e.g., "acme/backend" or "my-project")
     * @returns Feature ID (e.g., "FS-081", "FS-111E", or "FS-082" if collision)
     * @see deriveFeatureId() in src/utils/feature-id-derivation.ts
     */
    private getFeatureIdForIncrement;
    /**
     * Find next available internal ID when external collision exists
     *
     * This is called ONLY when FS-XXXE (external) exists and we need to
     * find a non-colliding internal ID.
     *
     * @param baseNumber - Starting number (from increment ID)
     * @param projectSpecsPath - Path to project's specs folder
     * @returns Next available number that doesn't conflict
     */
    private findNextAvailableIdForExternal;
    /**
     * Extract project and board from increment spec.md YAML frontmatter
     *
     * Priority:
     * 1. YAML frontmatter `project:` field (v0.31.0+ - preferred)
     * 2. Legacy **Project**: field in body (backward compatibility)
     *
     * For 2-level structures, also extracts `board:` field.
     *
     * SECURITY: Validates both incrementId and extracted names to prevent path traversal
     *
     * @param incrementId - Increment ID (e.g., "0002-test-anton-monitor" or "0111E-external")
     * @returns Object with project and board (null if not specified or invalid)
     */
    private extractProjectBoardFromSpec;
    /**
     * Validate and normalize a project/board name
     *
     * SECURITY: Prevents path traversal and validates format
     */
    private validateAndNormalizeName;
    /**
     * Extract project name from increment spec.md (legacy method - delegates to new method)
     */
    private extractProjectFromSpec;
    /**
     * Resolve the project path for an increment (v0.31.0+ - SPEC.MD FRONTMATTER REQUIRED)
     *
     * For new increments (v0.31.0+), spec.md MUST have `project:` field in YAML frontmatter.
     * For 2-level structures, spec.md MUST have BOTH `project:` and `board:` fields.
     *
     * Priority:
     * 1. YAML frontmatter `project:` and `board:` fields (REQUIRED for v0.31.0+)
     * 2. Legacy **Project**: field in body (backward compatibility only)
     * 3. Fallback: intelligent board matching (deprecated - will warn)
     *
     * @param incrementId - Increment ID (e.g., "0002-test-anton-monitor")
     * @returns Project path (e.g., "my-project" or "acme-corp/digital-ops")
     * @throws Error if required fields are missing in spec.md
     */
    private resolveProjectPath;
    /**
     * Resolve project name through umbrella config.
     * When umbrella.enabled and the project matches umbrella.projectName or doesn't match
     * any child repo, return the umbrella project name for proper folder routing.
     */
    private resolveUmbrellaProject;
    /**
     * Get the raw spec.md content for an increment
     */
    private getIncrementSpecContent;
    /**
     * Ask user to select a board with intelligent match suggestions
     */
    private askUserForBoardSelection;
    /**
     * Ask user to select a project when sync is unsure
     */
    private askUserForProject;
    /**
     * Find the best matching project path in existing specs structure
     *
     * Searches for:
     * 1. Direct match: specs/{project}/
     * 2. Hierarchical match: specs/{org}/{project}/
     * 3. Fuzzy match: specs/{org}/{similar-project}/ (handles typos like "operation" vs "operations")
     *
     * @param specsBase - Base specs folder path
     * @param projectName - Project name to search for
     * @returns Full relative path (e.g., "acme/digital-operations-services") or null
     */
    private findBestProjectMatch;
    /**
     * Compare project names with fuzzy matching
     *
     * Handles common variations:
     * - "operation" vs "operations"
     * - "service" vs "services"
     * - Different separators (hyphen vs underscore)
     *
     * SECURITY: Requires minimum length to prevent false positive matches
     * NOTE: Uses standardization (singular form) instead of abbreviation to prevent
     *       false matches (e.g., "optical" should NOT match "operations")
     *
     * @param existing - Existing folder name
     * @param target - Target project name to match
     * @returns true if names match (exact or fuzzy)
     */
    private projectNamesMatch;
    /**
     * Parse increment spec.md
     */
    private parseIncrementSpec;
    /**
     * Sync tasks from increment to user story files
     *
     * Populates the ## Tasks section in each user story file with tasks from increment tasks.md
     */
    private syncTasksToUserStories;
    /**
     * Update ## Tasks section in user story file
     */
    private updateTasksSection;
    /**
     * Sync to external tools (GitHub, JIRA, ADO)
     *
     * AC-US5-01: Detect external tool configuration from metadata.json
     * AC-US5-02: When GitHub configured, trigger GitHub sync
     * AC-US5-03: When no external tools configured, skip
     * AC-US5-05: External tool failures don't break living docs sync
     *
     * v0.32.2+ (AC-US3-01 to AC-US3-05): Permission checks before syncing
     * - canUpsertInternalItems: Required for creating issues from SpecWeave increments
     * - canUpdateExternalItems: Required for updating externally-imported items
     * - canUpdateStatus: Required for updating issue status (open/closed)
     */
    private syncToExternalTools;
    /**
     * Detect external tool configuration from increment metadata.json
     *
     * AC-US5-01: Detect external tool configuration from metadata.json
     *
     * Returns: Array of tool names (['github'], ['github', 'jira'], or [])
     */
    /**
     * Detect external tools configured for this increment
     *
     * ADR-0134: Enhanced detection checks BOTH levels:
     * - Level 1 (metadata.json): Increment-specific configuration (cached links)
     * - Level 2 (config.json): Global project configuration (active profiles)
     *
     * Precedence: Level 1 > Level 2 (increment metadata takes priority)
     *
     * @param incrementId - Increment ID (e.g., "0056-auto-github-sync")
     * @returns Array of tool names (['github'], ['github', 'jira'], or [])
     */
    private detectExternalTools;
    /**
     * Sync to GitHub Issues
     *
     * AC-US5-02: When GitHub configured, trigger GitHub sync
     *
     * Uses GitHubFeatureSync.syncFeatureToGitHub() which is idempotent:
     * - Uses existing milestone if it exists
     * - Updates existing issues (triple idempotency check)
     * - Only creates new issues if they don't exist
     */
    private syncToGitHub;
    /**
     * Sync to JIRA Epics
     *
     * Uses JiraSpecSync.syncSpecToJira() which is idempotent:
     * - Uses existing epic if it exists
     * - Updates existing stories
     * - Only creates new stories if they don't exist
     *
     * Configuration priority:
     * 1. config.sync.jira (most common)
     * 2. config.sync.profiles[*] with provider='jira'
     * 3. Environment variables (JIRA_DOMAIN, JIRA_EMAIL, JIRA_API_TOKEN)
     */
    private syncToJira;
    /**
     * Sync to Azure DevOps Features
     *
     * Uses AdoSpecSync.syncSpecToAdo() which is idempotent:
     * - Uses existing feature if it exists
     * - Updates existing user stories
     * - Only creates new user stories if they don't exist
     *
     * Configuration priority:
     * 1. config.sync.ado (most common)
     * 2. config.sync.profiles[*] with provider='ado'
     * 3. Environment variables (AZURE_DEVOPS_ORG, AZURE_DEVOPS_PROJECT, AZURE_DEVOPS_PAT)
     */
    private syncToADO;
    /**
     * Backfill external links into increment metadata.json
     *
     * Mirrors GitHub's backfillIncrementMetadata() pattern:
     * writes sync results (JIRA epic keys, ADO work item IDs) to metadata.json
     * so the system can track which external items exist for each increment.
     *
     * Non-blocking — errors are logged but don't halt sync.
     */
    private backfillExternalLinks;
    /**
     * Generate feature illustration image and inject after TL;DR section
     *
     * Encapsulates SPECWEAVE_SKIP_IMAGE_GEN check, DocContext derivation,
     * generateLivingDocsImagesEnhanced() call, TL;DR regex replacement,
     * logging, and non-blocking error handling.
     *
     * @returns Modified content with image injected, or original content if skipped/failed
     */
    private generateAndInjectImage;
    /**
     * Validate feature folder consistency
     *
     * Verifies that the feature folder was created correctly:
     * - FEATURE.md exists in {project}/FS-XXX/
     * - Logs warning if missing
     *
     * @param featureId - Feature ID that was just synced (e.g., "FS-062")
     * @param resolvedProjectPath - Resolved project path (may be hierarchical like "org/project")
     */
    private validateAndRepairConsistency;
}
//# sourceMappingURL=living-docs-sync.d.ts.map