import { type SeedArgsT, type SeedResponse } from "../mcp/tools/seed.ts"; import type { UserMaskFields } from "../seed/mask/resolve.ts"; /** * The CLI seed orchestrator. * * Drives the SAME multi-step engine the MCP `seed` tool uses — * start → analyze → select → dry_run → run — in a single process, so * every safety gate (sandbox-only target, mandatory dry run, plan-hash * verification, confirm-before-run, validation-rule recovery guard) * applies identically to CLI seeds. There is deliberately no second * code path to the inserts. * * Confirmation is injected (`deps.confirm`) so the flow is testable and * so the oclif shell can prompt on a TTY / refuse without `--yes` in CI. */ export type SeedFlowOptions = { sourceOrg: string; targetOrg: string; object: string; where: string; limit?: number; sampleSize?: number; /** Optional parents to include at the select step (must match analyze output). */ includeParents: string[]; /** Optional children to include at the select step. */ includeChildren: string[]; includeManagedPackages: boolean; includeSystemChildren: boolean; childLookups?: Record; disableValidationRules: boolean; isolateIdMap: boolean; upsertKeyOverrides?: Record; mask: boolean; maskFields?: UserMaskFields; /** Stop after the dry run; print how to resume. */ dryRunOnly: boolean; }; export type ConfirmRequest = { totalRecords: number; targetOrg: string; reportPath: string; sessionId: string; }; export type SeedFlowDeps = { /** The engine. Injected for tests; defaults to the real one. */ seedFn?: (args: SeedArgsT) => Promise; /** Step-by-step progress lines. */ log: (message: string) => void; /** * Asked exactly once, between dry_run and run. Return false to abort * (the session stays resumable). Never asked when `dryRunOnly` is set. */ confirm: (req: ConfirmRequest) => Promise; }; export type SeedFlowResult = { sessionId: string; outcome: "ran" | "dry-run-only" | "declined"; start: Record; analyze: Record; select: Record; dryRun: Record; run?: Record; }; export declare function runSeedFlow(opts: SeedFlowOptions, deps: SeedFlowDeps): Promise; /** * Resume a previously dry-run session: optionally refresh the dry run, * confirm, run. The engine's freshness + plan-hash gates decide whether * the existing dry run is still valid — we don't second-guess them here. */ export declare function runResumeFlow(opts: { sessionId: string; refreshDryRun: boolean; }, deps: SeedFlowDeps): Promise<{ sessionId: string; outcome: "ran" | "declined"; dryRun?: Record; run?: Record; }>; /** "Contact:ReportsToId,OtherId" (repeatable) → { Contact: [ReportsToId, OtherId] } */ export declare function parseChildLookups(values: string[] | undefined): Record | undefined; /** "Account=External_Id__c" (repeatable) → { Account: "External_Id__c" } */ export declare function parseUpsertKeys(values: string[] | undefined): Record | undefined; /** * "Contact.Email" | "Contact.SSN__c:generic-text" | "Contact.Notes__c:copy" * (repeatable) → UserMaskFields. Field NAMES only, mirroring the MCP arg. */ export declare function parseMaskFields(values: string[] | undefined): UserMaskFields | undefined; /** "Account,Contact" or repeated flags → flat trimmed list. */ export declare function parseObjectList(values: string[] | undefined): string[];