import { type ImportState } from './import-state.js'; import { type MigrationReportData } from './migration-report.js'; import { type CommitSpec, type PushIdentity } from '../util/clone-and-stack-push.js'; import type { CoercedSentinelSummary, DroppedOverrideSummary, DuplicateResolution, DuplicateResolutionSummary, LegacyChange, MigrationSource, SkippedConfigSummary } from './source.js'; export interface ApplyLocalMigrationOptions { /** Commit author. Defaults to the migrator identity. */ author?: PushIdentity; /** Initial branch name when initializing a fresh repo. Defaults to `main`. */ branch?: string; changes: LegacyChange[]; /** Environments discovered from the source (slugified). Written to `quonfig.json` if missing. */ environments: string[]; /** * qfg-wbkj: when true, produce one git commit per change (audit-log mode) + * one final state-file commit on top. Requires `source.getCommitMeta` to be * defined. See pushMigrationToCloud's matching option. */ fullHistory?: boolean; importState: ImportState; localDir: string; /** * Base report data. The migrator overrides `counts` after writing files, * since counts must reflect what was actually written to disk (qfg-7eig). */ reportData: MigrationReportData; source: MigrationSource; /** qfg-6na9.3: `--strict-keys` — refuse to migrate if any key would be rewritten. */ strictKeys?: boolean; } export interface ApplyLocalMigrationResult { /** `'initialized'` if we had to `git init` the target, `'reused'` if it was already a repo. */ action: 'initialized' | 'reused'; /** Sentinel rule values coerced to typed defaults during translate. Null if none. */ coercedSentinels: CoercedSentinelSummary | null; commitSha: string | null; /** `false` if translate produced no net changes — nothing was committed. */ committed: boolean; /** Override sections dropped during translate because env.id was unknown. Null if none. */ droppedOverrides: DroppedOverrideSummary | null; /** Cross-type key collisions resolved by preferring the config side. Null if none. */ duplicateResolutions: DuplicateResolutionSummary | null; /** Configs soft-skipped during translate due to invalid source data. Null if none. */ skippedConfigs: SkippedConfigSummary | null; } export declare class MigratorKeyCollisionError extends Error { readonly destPath: string; readonly firstSourceKey: string; readonly secondSourceKey: string; constructor(destPath: string, firstSourceKey: string, secondSourceKey: string); } export declare const writeQuonfigFiles: (dir: string, changes: LegacyChange[], source: MigrationSource) => WriteQuonfigFilesResult; interface WriteQuonfigFilesResult { livePaths: string[]; resolutions: DuplicateResolution[]; } export declare const buildMigrationCounts: (livePaths: string[], environmentsMapped: number, itemsSkipped: number) => import("./migration-report.js").MigrationReportCounts; export declare const buildMigrationCommitMessage: (source: string, counts: import("./migration-report.js").MigrationReportCounts) => string; export declare const applyLocalMigration: (opts: ApplyLocalMigrationOptions) => Promise; /** * qfg-wbkj: accumulator for source-level summaries that the final state-file * commit collects from the source after all per-change commits have run. * Used by both push-to-cloud and local-write to surface back to callers. */ export interface AuditAccumulator { coercedSentinels: CoercedSentinelSummary | null; droppedOverrides: DroppedOverrideSummary | null; duplicateResolutions: DuplicateResolutionSummary | null; skippedConfigs: SkippedConfigSummary | null; } /** * qfg-wbkj: build one CommitSpec per change, each carrying the original * source-side author/date/message when `getCommitMeta` returns metadata. Used * by `--full-summary` from both the local-write and push-to-cloud paths. */ export declare const buildAuditPerChangeCommits: (changes: LegacyChange[], source: MigrationSource) => CommitSpec[]; export interface BuildAuditFinalCommitOptions { changes: LegacyChange[]; environments: string[]; importState: ImportState; /** Receives the accumulated summaries once the commit's apply() has run. */ onAccumulatorUpdate?: (acc: AuditAccumulator) => void; /** * Optional hook to run AFTER writeImportState + writeMigrationReport but before * the commit lands. Push-to-cloud uses this to run validateWorkspace (and to * merge source-side environments into the existing quonfig.json). Throwing here * aborts the commit cleanly. */ postWrite?: (dir: string) => Promise | void; /** * Optional hook to run BEFORE bookkeeping (state file + report). Push-to-cloud * uses this to merge source-side environments into the cloned quonfig.json. */ preWrite?: (dir: string) => Promise | void; reportData: MigrationReportData; source: MigrationSource; } /** * qfg-wbkj: build the final state-file commit for audit-log mode. Writes * `.qf/import-state.json` + `.qf/MIGRATION_REPORT.md` with cumulative counts read * from disk, and surfaces the source's accumulated dropped/skipped/coerced * summaries via `onAccumulatorUpdate`. The `preWrite` / `postWrite` hooks let * push-to-cloud merge environments and run server-side-equivalent validation * without local-write needing to know about either. */ export declare const buildAuditFinalCommit: (opts: BuildAuditFinalCommitOptions) => CommitSpec; /** * Walk the type-dir top-levels we care about, returning all `/*.json` * paths on disk. Used to recompute cumulative counts in audit-log mode where * `writeQuonfigFiles` runs per-change and its in-memory `livePaths` reflects * only the last slice. */ export declare const collectLivePathsOnDisk: (dir: string) => string[]; /** * qfg-hbuy.12: every key ALREADY present in the target workspace on disk — * used to seed the key rewriter so an import that case-collides with an * existing key (incoming `Foo`, workspace `foo`) renames deterministically * instead of aborting at the verify gate, while a byte-equal match keeps * today's silent-overwrite re-migration behavior. Scans every validated * content dir (uniqueness is pooled per workspace, so schemas-protected/ * counts too, even though the migrator never writes there). */ export declare const collectExistingWorkspaceKeys: (dir: string) => string[]; export {};