/** * train-status, one read-only table per release-train cycle showing what the * cycle actually involves across the family's local checkouts. * * Strictly read-only: every git/npm call this module makes is a query (no * push, tag, install, or write outside stdout). Decision and rendering logic * (classifySdkPin/deriveAction/deriveRow/render*) is pure over gathered * structs, so unit tests drive it without touching git or npm; gatherOneRepo * and gatherTrainStatus are the only impure pieces, and take their subprocess * runner as an injectable `Exec` (see effects.ts) so a real integration test * can point them at throwaway repos while stubbing out `npm view`. */ import type { Exec } from './effects.js'; export type RepoKind = 'sdk' | 'sdk-consumer' | 'independent'; export interface TrainStatusRepoEntry { readonly path: string; readonly name: string; readonly kind: RepoKind; readonly releaseCommand?: string; } export interface TrainStatusManifest { readonly repos: readonly TrainStatusRepoEntry[]; } /** Parse and validate a train-status manifest from raw JSON text. Throws a clear, field-named error on a bad shape. */ export declare function parseTrainStatusManifest(raw: string): TrainStatusManifest; export interface RepoGathered { readonly entry: TrainStatusRepoEntry; /** `n/a` for repos with no package.json (e.g. a Python repo in the family). */ readonly version: string; /** The @pellux/goodvibes-sdk pin read from dependencies/devDependencies; null when absent or not an sdk-consumer. */ readonly sdkPin: string | null; readonly lastTag: string | null; readonly commitsSinceTag: number; readonly unpushedCommits: number; } export interface RepoRow { readonly name: string; readonly kind: RepoKind; readonly version: string; /** `n/a` for kinds other than sdk-consumer. */ readonly sdkPin: string; readonly lastTag: string; readonly commitsSinceTag: number; readonly unpushedCommits: number; readonly action: string; /** Set only on a gather failure (path missing / not a git repo); the row still prints. */ readonly error?: string; } export declare const SDK_PACKAGE_NAME = "@pellux/goodvibes-sdk"; /** Render the sdk-consumer pin ⇄ latest column. `n/a` for non-consumer kinds. */ export declare function classifySdkPin(pin: string | null, latest: string | null, kind: RepoKind): string; /** Derive the suggested action for one repo. Pure; the manifest's releaseCommand is used verbatim when present. */ export declare function deriveAction(gathered: RepoGathered, latestSdkVersion: string | null): string; /** Turn gathered facts into the printed row. Pure. */ export declare function deriveRow(gathered: RepoGathered, latestSdkVersion: string | null): RepoRow; /** Build the one error row for a repo whose facts could not be gathered. Never throws. */ export declare function errorRow(entry: TrainStatusRepoEntry, message: string): RepoRow; /** Repos whose action is neither idle nor an error, the "needs action" count for the summary line. */ export declare function countNeedingAction(rows: readonly RepoRow[]): number; /** Render the aligned plain-text table plus a one-line summary. */ export declare function renderTrainStatusTable(rows: readonly RepoRow[]): string; export interface TrainStatusResult { readonly latestSdkVersion: string | null; readonly rows: readonly RepoRow[]; } /** Render the raw structured result as JSON (the `--json` output). */ export declare function renderTrainStatusJson(result: TrainStatusResult): string; /** Read `package.json`'s version at a repo path. `n/a` when the file is absent or unparsable (e.g. a Python repo). */ export declare function readPackageVersion(repoPath: string): string; /** Read the @pellux/goodvibes-sdk pin from dependencies or devDependencies. Null when absent. */ export declare function readTrainStatusSdkPin(repoPath: string): string | null; interface GitFacts { readonly lastTag: string | null; readonly commitsSinceTag: number; readonly unpushedCommits: number; } /** Last release tag, commits since it (or total commits with no tag), and unpushed commits. Tolerates no tag / no upstream. */ export declare function gatherGitFacts(exec: Exec, repoPath: string): GitFacts; /** Fetches the latest published SDK version once for the whole run. Null when npm view fails or returns nothing. */ export type FetchLatestSdkVersion = (exec: Exec) => string | null; export declare const realFetchLatestSdkVersion: FetchLatestSdkVersion; /** Gather one repo's row. Never throws: a missing path or non-git-repo path becomes a single error row. */ export declare function gatherOneRepo(exec: Exec, entry: TrainStatusRepoEntry, latestSdkVersion: string | null): RepoRow; export interface GatherTrainStatusOptions { readonly exec?: Exec; /** Overridable so an integration test can skip the real npm registry call. */ readonly fetchLatestSdkVersion?: FetchLatestSdkVersion; } /** Gather every repo in the manifest into the full train-status result. The only network/subprocess entry point. */ export declare function gatherTrainStatus(manifest: TrainStatusManifest, options?: GatherTrainStatusOptions): TrainStatusResult; export {}; //# sourceMappingURL=train-status.d.ts.map