openclaw/scripts/lib/version-script-args.ts
Peter Steinberger 3cb68020b6
refactor(scripts): deslop shared tooling
## What Problem This Solves

Repository scripts retain private copies of shared tooling helpers and an unused translation subprocess runner, increasing maintenance work across sibling scripts.

## User Impact

Internal tooling cleanup: existing flags, diagnostics, generated bytes, JSON formats, exit codes, and cleanup policies stay the same. The build wrapper additionally detects forbidden dynamic-import warnings when compiler output splits the warning marker across chunks.

## Why This Change Was Made

- Remove the retired i18n process runner. Its final production caller moved to the shared formatter in #95534; retain real CLI/privacy/provider tests and run their subprocesses with the existing dependency.
- Share Docker resource, signal-trap, platform, workspace-staging, and plugin-selection helpers while retaining each caller's environment precedence and lifecycle decisions.
- Reuse existing E2E fixture JSON/assertion and package-path helpers; retain distinct write modes, recovery ordering, and mounted/frozen harness contracts.
- Share macOS guest desktop-user/home resolution through its existing owner while preserving per-caller timeout policy.
- Route release/mobile flags through the existing version flag specifications, preserving split-only values, duplicate/mode rules, help timing, and error text. Reuse existing retry sleep and comparator owners and remove an unreachable iOS output branch.
- Reuse existing guard entrypoint, failure-trailer, diagnostic-line, and metadata-normalization owners.

Measured reduction: **732 net production lines**, with test changes counted separately. PR tooling and its protected import closure, CI planners/shards, baselines, and generated artifacts are unchanged.

## Fixes Found Along the Way

The tsdown scanner checked each raw output chunk for its warning marker. It now checks the existing combined-line buffer. The regression exercises every split inside the marker and fails on the original source for the intended missing-warning assertion.

## Evidence

- Blacksmith Testbox `tbx_01m3tp4sabwd0807kj9jkqqmbr`: frozen dependency install and candidate source-byte verification; all nine changed test files and 59 selected sibling files passed, including real CLI, package fixture, recovery, Docker harness, and Parallels transport contracts.
- Generated channel metadata is byte-identical; differential metadata normalization cases passed.
- SDK surface check passed. Independent isolated Codex review completed with no P0–P2 findings.
- Initial changed checks caught an invalid direct source import in a proposed snapshot-distance consolidation; that independent change was withdrawn. No boundary exception was added. The final changed checks pass, including script/test lint and Docker shell/scheduler checks; madge reports 0 cycles and the runtime import check reports 0 cycles.
- Per-file single-worker wall time for changed suites: translation 9.92s; Docker helper 38.88s; live Docker auth 1.71s; mobile ref 2.36s; mobile release 6.23s; release preparation 2.42s; version 2.04s; installer 15.01s; tsdown 2.70s. The existing Docker helper suite executes shell/process cleanup and container-command boundary fixtures; new assertions reuse those fixtures. New parser/scanner cases use no sleeps or polling.

Hosted CI will be verified against this PR's exact pushed head. No live deployment or release was performed.
2026-10-01 05:14:07 +00:00

96 lines
2.7 KiB
TypeScript

import path from "node:path";
import { booleanFlag, parseFlagArgs, stringFlag, type FlagSpec } from "./arg-utils.mts";
type VersionScriptFormat = "json" | "shell";
type CommonVersionCliOptions = {
appStoreRevision: string | null;
help: boolean;
releaseVersion: string | null;
rootDir: string;
};
type VersionQueryCliOptions = CommonVersionCliOptions & {
field: string | null;
format: VersionScriptFormat;
};
type VersionSyncMode = "check" | "write";
type VersionSyncCliOptions = CommonVersionCliOptions & {
mode: VersionSyncMode;
};
export function versionValueFlag<T extends Record<string, unknown>>(
flag: string,
key: string,
transform?: (value: string) => unknown,
): FlagSpec<T> {
return stringFlag<T>(flag, key, {
allowInline: false,
missingValueMessage: `Missing value for ${flag}.`,
rejectShortOptions: true,
repeatable: true,
transform,
});
}
function parseVersionArgs<T extends CommonVersionCliOptions & Record<string, unknown>>(
argv: string[],
args: T,
specs: FlagSpec<T>[],
allowAppStoreRevision: boolean,
): T {
const commonSpecs = [
versionValueFlag<T>("--root", "rootDir", path.resolve),
...(allowAppStoreRevision ? [versionValueFlag<T>("--revision", "appStoreRevision")] : []),
versionValueFlag<T>("--version", "releaseVersion"),
booleanFlag<T>("-h", "help", true, { repeatable: true }),
booleanFlag<T>("--help", "help", true, { repeatable: true }),
];
return parseFlagArgs(argv, args, [...specs, ...commonSpecs], {
onUnhandledArg(arg) {
throw new Error(`Unknown argument: ${arg}`);
},
});
}
export function parseVersionQueryArgs(
argv: string[],
options?: { allowAppStoreRevision?: boolean },
): VersionQueryCliOptions {
return parseVersionArgs<VersionQueryCliOptions & Record<string, unknown>>(
argv,
{
appStoreRevision: null,
field: null,
format: "json",
help: false,
releaseVersion: null,
rootDir: path.resolve("."),
},
[
versionValueFlag("--field", "field"),
booleanFlag("--json", "format", "json", { repeatable: true }),
booleanFlag("--shell", "format", "shell", { repeatable: true }),
],
options?.allowAppStoreRevision === true,
);
}
export function parseVersionSyncArgs(
argv: string[],
options?: { allowAppStoreRevision?: boolean },
): VersionSyncCliOptions {
return parseVersionArgs<VersionSyncCliOptions & Record<string, unknown>>(
argv,
{
appStoreRevision: null,
help: false,
mode: "write",
releaseVersion: null,
rootDir: path.resolve("."),
},
[
booleanFlag("--check", "mode", "check", { repeatable: true }),
booleanFlag("--write", "mode", "write", { repeatable: true }),
],
options?.allowAppStoreRevision === true,
);
}