/** * npm 全局更新通用辅助。 * * 共用于 server.ts 的 /api/update / performAutoUpdate,以及 TUI 的 installUpdate。 * * 解决的核心问题:当 wand 进程正在运行(systemd/launchd/nohup/直接前台都算)时, * `npm install -g @co0ontty/wand@latest` 会把旧包目录 rename 成 `.wand-XXXXXX` 备份。 * 如果安装中途失败,这个备份目录会留下,之后每次 npm install 都会因为目标 dest 已存在 * 报 `ENOTEMPTY: directory not empty, rename ...`。 * * 我们的策略:安装前备份当前全局包,补齐 npm 子进程 PATH,清掉 * `@co0ontty/.wand-*` 残留目录;失败时恢复备份,避免运行中的服务被半成品安装拆掉。 */ export type UpdateChannel = "stable" | "beta"; export interface PackageUpdateInfo { channel: UpdateChannel; current: string; latest: string | null; updateAvailable: boolean; distTag: "latest" | "beta"; installSpec: string; } export declare function normalizeUpdateChannel(value: unknown): UpdateChannel; export declare function getInstallSpecForChannel(channel: UpdateChannel): string; export declare function buildPackageUpdateInfo(currentVersion: string, channel: UpdateChannel, latestVersion: string | null): PackageUpdateInfo; export declare function checkPackageUpdateAsync(currentVersion: string, channel: UpdateChannel, timeoutMs?: number): Promise; export declare function checkPackageUpdateSync(currentVersion: string, channel: UpdateChannel, timeoutMs?: number): PackageUpdateInfo; /** * 更新时同时存在旧包备份、npm 正在解包的新版本和下载/回滚余量。 * 旧包大小按三倍计(安全备份、新包、回滚 staging),再保留 512 MiB, * 避免 ENOSPC 把全局 CLI 拆成半包。 */ export declare function requiredUpdateFreeBytes(currentInstallBytes: number): number; /** * 异步版本的全局安装: * 1. 清理残留 * 2. `npm install -g ` * 3. 撞上 ENOTEMPTY/EEXIST:再清一次 + 重试一次 * 4. 再不行:`npm uninstall -g ` + `npm install -g --force ` * * @param pkg 包名带版本,例如 `@co0ontty/wand@latest` * @param timeoutMs 单次 npm 调用超时 * @param log 可选 logger,用来把过程写入控制台或前端日志 * @returns 与本次安装使用同一个 npm root 校验出的 dist/cli.js 绝对路径 */ export declare function installPackageGloballyAsync(pkg: string, timeoutMs: number, log?: (line: string) => void): Promise; /** * 同步版本,给 TUI installUpdate 用。 * * 返回值兼容 spawnSync:包含最后一次尝试的 stdout/stderr/status。 */ export declare function installPackageGloballySync(pkg: string, timeoutMs: number): { status: number | null; stdout: string; stderr: string; attempts: string[]; }; /** * 解析「刚装好的全局 wand CLI 入口」(dist/cli.js) 的绝对路径。 * * 用途:应用内更新装完新包后,要把 systemd/launchd unit 的 ExecStart 钉到这个 * 全局安装,而不是 process.argv[1](源码安装场景下 argv[1] 是旧源码路径)。 * * 优先 `npm root -g`/@co0ontty/wand/dist/cli.js(最准确);失败回退 `which wand` * (npm 全局 bin 里的符号链接,node 跟随软链一样能跑)。都找不到返回 null。 */ export declare function resolveGlobalWandCli(): string | null; /** * 返回 npm 全局命令 shim 的稳定路径。服务 unit 应固定到这个入口,而不是包目录内的 * dist/cli.js;更新回滚期间 shim 会临时指向同盘安全备份,始终保持可启动。 */ export declare function resolveGlobalWandBin(): string | null;