/** * Performing the upgrade, for the two install methods where performing it is * ours to do. * * `check.ts` answers whether a copy is behind and prints the command. This * module runs it -- and, just as importantly, refuses to run it for the four * methods where running it would be wrong: * * - `NpxCache` has nothing to upgrade. The cache entry is immutable; the * next `npx -y @latest` fetches the newer one. Running that command * here would EXECUTE this package rather than upgrade anything, and would * then report success for work it did not do. * - `ClaudePlugin` is upgraded by the client, through `/plugin update`. That * is a slash command typed into an agent, not a program this process can * spawn. * - `SourceCheckout` is a developer's working tree. `npm install -g` over it * replaces their work with a published copy. * - `Unknown` is an install this package did not place and cannot speak for. * * So the surface is four named refusals and two real upgrades, and a refusal * says what to run instead whenever there is something to run. The alternative * -- one `upgrade()` that always claims to have done something -- is the * fabricated-success shape this repo has spent its whole history removing. * * NOTHING HERE RUNS ON ITS OWN. The upgrade happens when a person invokes * `token-optimizer-update`, never from the server, a hook or a check. An * installer that upgrades itself because it noticed a new version is an * install the operator did not consent to. */ import { type UpdateReport } from './check.js'; import { InstallMethod } from './install-method.js'; /** How long an upgrade may take before it is abandoned. */ export declare const UPGRADE_TIMEOUT_MS = 300000; /** What happened, and the only values `applyUpdate` reports. */ export declare enum UpgradeOutcome { /** The upgrade command ran and exited zero. */ Upgraded = "Upgraded", /** Nothing to do: the installed copy is already the published one. */ AlreadyCurrent = "AlreadyCurrent", /** `--dry-run`: the command was printed and not run. */ Planned = "Planned", /** This install method is not one this package may upgrade in place. */ NotOurs = "NotOurs", /** The command ran and failed. */ Failed = "Failed" } export interface UpgradeResult { readonly outcome: UpgradeOutcome; /** The argv that ran, would have run, or null when there is none. */ readonly argv: readonly string[] | null; /** One sentence naming what happened and what the reader should do. */ readonly message: string; /** The command runner's output, when it ran. */ readonly output: string | null; } /** * The upgrade command as argv, for the methods this package may upgrade. * * SEPARATE FROM `upgradeCommand` AND PINNED AGAINST IT. A shell string cannot * be spawned safely -- `shell: false` is what keeps a package name out of a * shell -- so the argv is the executable form and the string is the printable * one. A test asserts the two spell the same command for every enum member, * because two hand-written copies of one command is exactly how a tool ends up * printing one thing and running another. */ export declare function upgradeArgv(method: InstallMethod): readonly string[] | null; export interface ApplyOptions { /** Print the command instead of running it. */ readonly dryRun?: boolean; /** * Upgrade even when the check says the installed copy is current. A reader * who has just been told they are current and asks anyway is answered. */ readonly force?: boolean; /** Injected so a test never spawns a package manager. */ readonly runner?: (file: string, args: readonly string[]) => Promise<{ stdout: string; stderr: string; }>; readonly cwd?: string; } /** * Upgrade this install, or say exactly why it was not touched. * * The report is passed in rather than fetched here so the decision and the * lookup stay separable: a caller that already ran `checkForUpdate` for its * own output does not ask the registry twice, and a test needs no network. */ export declare function applyUpdate(report: UpdateReport, options?: ApplyOptions): Promise; //# sourceMappingURL=apply.d.ts.map