UNPKG

nx

Version:

The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.

181 lines (180 loc) 8.05 kB
/** * Presentation layer for `nx migrate --run-migrations`. Pure helpers — every * function maps (state) → (terminal output or string lines). Shared visual * vocabulary across the migrate run: * `→` start · `✓` success · `✗` failure · `↷` skipped · `ℹ` info · `─` boundary * * Inputs are typed structurally (e.g. `{ name: string }[]`) so this module * stays decoupled from `ExecutableMigration` and the executor in migrate.ts. */ /** * Some agent TUIs (codex, opencode) don't fully reset their cursor / SGR state * when they exit, which corrupts subsequent orchestrator output. Emit an SGR * reset + newline so our log lines land on a clean row instead of being * overlaid by leftover status bars. */ export declare function resetSgrAfterAgent(): void; /** * Per-migration boundary header. Anchors the orchestrator log at the start of * each migration with the migration index and identity. */ export declare function logMigrationBoundary(index: number, total: number, pkg: string, name: string): void; /** * Logs the outcome line that closes an agentic phase. Vocabulary: * ✓ <label>[ (<sha>)]: <summary> */ export declare function logAgenticSuccessOutcome(label: string, sha: string | null, summary: string): void; /** * Per-migration outcome record consumed by the failure recap. One entry is * appended per iteration that returned without throwing; the failing migration * has no record. * * - `applied`: ran fully to completion, including any agentic step. * - `no-changes`: generator ran but produced no diff (counts as applied work). * - `deferred`: prompt half was not applied (agent disabled or inside-agent * mode hands it off). For hybrid migrations the deterministic half still ran. * * `committedAsPartOf` is set when this migration's own commit attempt failed * but its diff was later absorbed into a successor migration's commit (which * stages the working tree's accumulated state via `git add -A`). The recap * uses this to anchor "last applied" honestly when the last-named commit * landed multiple migrations' contributions. */ export type MigrationOutcomeKind = 'applied' | 'no-changes' | 'deferred'; /** * The state of a migration's commit attempt. Tagged union so consumers don't * have to re-derive legal combinations from nullable fields. * * - `none` — no commit was attempted (`--no-create-commits` or no diff to * commit). * - `landed` — a commit was actually created. `sha: null` only when * `git rev-parse HEAD` failed transiently right after the * commit landed; by contract the diff did clear. * - `failed` — commit was attempted and errored (signing, hook rejection, * lock, install error mid-attempt, etc.). The diff stays in * the working tree until a later migration's commit absorbs * it (then transitions to `absorbed`) or until the run ends * (then surfaces as retained state). * - `absorbed` — own commit failed but a later migration's commit absorbed * this diff via `git add -A`. `into.sha: null` means that * absorbing commit itself hit a HEAD-resolve race; the recap * renders an anchor without a sha. */ export type CommitState = { kind: 'none'; } | { kind: 'landed'; sha: string | null; } | { kind: 'failed'; } | { kind: 'absorbed'; into: { name: string; sha: string | null; }; }; /** * Per-migration record produced by the executor loop. `status: 'completed'` * carries the kind (applied / no-changes / deferred); `status: 'aborted'` * means the migration threw before completing — the executor's catch block * records it so the recap can list it under retained-state alongside any * other migrations whose commits never landed. */ export type MigrationOutcome = { migration: { package: string; name: string; }; status: 'completed'; kind: MigrationOutcomeKind; commit: CommitState; } | { migration: { package: string; name: string; }; status: 'aborted'; commit: CommitState; }; /** * Counts the migrations whose own commit actually landed — including the * HEAD-resolve-race case (`commit: { kind: 'landed', sha: null }`). Used by * the end-of-run "<K> commits created" tally and by the success-path * accounting in `executeMigrations`. Counts landed-commit *records* rather * than distinct shas; absorbed predecessors (`kind: 'absorbed'`) are not * counted because the absorbing commit's record already contributes one. */ export declare function countLandedCommits(outcomes: ReadonlyArray<MigrationOutcome>): number; /** * Migrations whose own commit attempt failed and whose diff was never * absorbed by a later commit. Surfaces what the user has to commit or * revert after the run. Filters on `commit.kind === 'failed'` exactly — * `'absorbed'` means the diff cleared into a later commit, `'none'` means * no commit was attempted (intentional `--no-create-commits` or no-op). */ export declare function retainedMigrations(outcomes: ReadonlyArray<MigrationOutcome>): Array<{ package: string; name: string; }>; /** * Logs a structured recap when a migration throws mid-loop. Inserted between * the "Failed to run X" error block and the re-throw so the user (or AI agent * driving the run) can see what completed before the failure without scrolling * back through the per-migration log to count shas. * * Counts-based rather than full migration lists so a 24-migration run that * fails at #12 doesn't dump 24 names into the recap — readers scroll up to * see specifics in the per-migration log. The "last applied" anchor pairs the * most recent fully-applied migration with the sha its commit actually * produced, so a skipped/deferred step trailing an applied one can't borrow * the earlier sha. */ export declare function logFailureRecap(opts: { migrationIndex: number; totalMigrations: number; outcomes: ReadonlyArray<MigrationOutcome>; migrationEmittedNextSteps: string[]; insideAgent: boolean; }): void; /** * Builds the tally body line shown under the top end-of-run NX block. Returns * `null` when there is nothing meaningful to tally (e.g. an empty * migrations.json), so the caller can omit the body entirely instead of * emitting a misleading `0 prompt migrations skipped.` line. * * Rule (kept coherent across every scenario): * - When at least one migration was applied: `<N> migrations applied, <K> commits created[, <D> prompt migrations <skipped|deferred>]`. * The `<K> commits created` part stays even at 0 — it tells the reader work * was applied but not committed (the J4/J8 information made explicit). * - When zero migrations were applied but some prompt halves were * skipped/deferred: `<D> prompt migrations <skipped|deferred>` only. * - When zero of either: no body line. */ export declare function buildTallyBodyLine(opts: { appliedCount: number; committedShasCount: number; skippedPromptsCount: number; insideAgent: boolean; }): string | null; /** * Body lines for the end-of-run retained-state warning. Fires on the success * path — the run completed but one or more migrations' own commits failed * and were never absorbed. */ export declare function buildRetainedAtSuccessBody(retainedNames: ReadonlyArray<string>): string[]; /** * Builds the body lines for the inside-agent directive block. Sub-sections * drop independently when empty. Returns an empty array when the block has * nothing actionable (no deferred prompts AND no migration-emitted notes) — * the caller skips emitting the block entirely in that case. */ export declare function buildDirectiveBlockBodyLines(opts: { skippedPrompts: ReadonlyArray<{ prompt?: string; name: string; implementation?: string; factory?: string; }>; migrationEmittedNextSteps: string[]; }): string[];