import { type NeutralRule } from './rule-registry.js'; export type CollapsedSection = { /** Shared-section id whose heading collided with a neutral rule. */ id: string; /** Normalized heading key that collided. */ key: string; /** Which path won the collision. */ keptFrom: 'neutral' | 'compiled'; }; export type ComposeResult = { /** Neutral rules to emit for this profile after dedup, in stable order. */ rules: NeutralRule[]; /** Ids of neutral rules suppressed because they duplicate a compiled section already emitted. */ suppressedRuleIds: string[]; /** Compiled sections a surviving neutral rule overrides (for warning/reporting). */ collapsed: CollapsedSection[]; }; /** Normalizes a heading to a comparable dedup key (mirrors capabilities.ts `normalizeSignal`). */ export declare function normalizeHeading(value: string): string; /** * Composes the neutral rules to emit for a profile against the profile's compiled * section lines, deduping by normalized heading and applying `replacesSection` * precedence. * * @param profileId profile whose rules are being emitted * @param compiledSectionLines the compiled shared-section lines already baked into the profile rule body * @param neutralRules all loaded neutral rules (filtered to the profile internally) */ export declare function composeProfileRules(profileId: string, compiledSectionLines: readonly string[], neutralRules: readonly NeutralRule[]): ComposeResult; /** A profile with its compiled rule body — the shape emission sites can supply. */ export type ComposableProfile = { id: string; ruleContent(): string; }; /** * Project-level dedup for the emission sites (claude/cursor/codex/rules-inject). * * Neutral rules are emitted once per project, but each collapses against the * compiled sections of whichever selected profile(s) it applies to. A neutral rule * whose heading (or `replacesSection`) matches a compiled section for ANY profile it * targets is suppressed at emission — the compiled section already carries that * content in the profile rule body, so writing the neutral file too would duplicate it. * Rules with no compiled collision stay additive (backward-compatible). * * Returns the neutral rules that should still be written as separate files, plus the * suppressed ids and the collapsed sections for logging. */ export declare function composeProfileRulesForProfiles(profiles: readonly ComposableProfile[], neutralRules: readonly NeutralRule[]): ComposeResult;