/** * Plan `## Files` manifest parser (Phase 2). * * Every plan must carry a `## Files` section with a markdown table, one row * per file the plan touches: * * ## Files * * | path | layer | action | reason | * | --- | --- | --- | --- | * | src/foo.ts | commands | create | new command handler | * * Validation is deterministic: path must be non-empty and project-relative * (no absolute paths, no `..` escaping the project root), layer must be * non-empty, action must be one of create / edit / delete, and duplicate * paths are rejected. Errors carry the 1-based line number in the plan * document so the approve gate can list them file:line-style. * * Layer validation against the architecture's layer map is Phase 3 — the * optional `layers` parameter exists so a layer map can be passed in later * without changing call sites. */ export type ManifestAction = "create" | "edit" | "delete"; export declare const MANIFEST_ACTIONS: readonly ManifestAction[]; export interface ManifestEntry { /** Project-relative path exactly as written in the plan. */ path: string; layer: string; action: ManifestAction; reason: string; /** 1-based line number of the row in the plan document. */ line: number; } export interface ManifestError { /** 1-based line number in the plan document; 0 for section-level errors. */ line: number; message: string; } export interface FilesManifestResult { /** True when the plan has no `## Files` section at all. */ missingSection: boolean; entries: ManifestEntry[]; errors: ManifestError[]; } /** Parse the `## Files` manifest from a plan markdown body. * * `options.layers` is the future hook for architecture layer-map validation * (Phase 3): when provided, each row's layer must be one of the listed * layer names. */ export declare function parseFilesManifest(planContent: string, options?: { layers?: readonly string[]; }): FilesManifestResult; export interface FrameworkFieldResult { /** True when the plan carries a `## Framework` section. */ found: boolean; /** Normalized value (lowercased single token): a framework id or `none`. * Null when the section is missing or empty. */ value: string | null; /** 1-based line of the value in the plan document (heading line when the * section is empty); 0 when the section is missing. */ line: number; /** Validation error, or null when the value is `none` or a known * framework-library id. */ error: string | null; } export declare const FRAMEWORK_NONE = "none"; /** Parse the optional `## Framework` field from a plan markdown body. The * value is a single framework id from the chirpi framework-library, or * `none` when the project has no framework. The id is validated against the * installed @adi-mudi/pi-chirpi library (bundled maps plus the project's * `.pi/framework-library/` overrides); an unknown id is a parse error. */ export declare function parseFrameworkField(planContent: string, cwd: string): FrameworkFieldResult; export interface ManifestDiff { /** Planned `create` files that do not exist on disk. */ missing: string[]; /** Files on disk inside the manifest's target folders that no planned * `create` entry covers. */ unexpected: string[]; } /** Compare planned create-files against the actual disk state under `cwd`. * Exported in Phase 2, wired into the implement gate in Phase 3. * * `unexpected` lists files inside the manifest's target folders that no * manifest entry (any action) covers. When `options.since` (epoch ms) is * given, only files modified at or after that timestamp count — this scopes * the check to files the current run actually touched, so pre-existing * project files never false-positive. */ export declare function diffFilesManifest(entries: readonly ManifestEntry[], cwd: string, options?: { since?: number; }): ManifestDiff;