mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(build): refresh cached CLI help per build
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
// Resolves the generated root-help bundle identity for CLI startup metadata caching.
|
||||
import { createHash } from "node:crypto";
|
||||
import { readdirSync, readFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
export function resolveCliStartupRootHelpBundleIdentity(
|
||||
distDir: string,
|
||||
): { bundleName: string; signature: string } | null {
|
||||
const bundleName = readdirSync(distDir).find(
|
||||
(entry) =>
|
||||
entry.startsWith("root-help-") &&
|
||||
!entry.startsWith("root-help-metadata-") &&
|
||||
entry.endsWith(".js"),
|
||||
);
|
||||
if (!bundleName) {
|
||||
return null;
|
||||
}
|
||||
const bundleContents = readFileSync(path.join(distDir, bundleName), "utf8");
|
||||
const buildInfo = readBuildIdentity(distDir);
|
||||
return {
|
||||
bundleName,
|
||||
signature: createHash("sha1")
|
||||
.update(bundleContents)
|
||||
.update(JSON.stringify(buildInfo))
|
||||
.digest("hex"),
|
||||
};
|
||||
}
|
||||
|
||||
function readBuildIdentity(distDir: string): { version: string | null; commit: string | null } {
|
||||
try {
|
||||
const parsed = JSON.parse(readFileSync(path.join(distDir, "build-info.json"), "utf8")) as {
|
||||
commit?: unknown;
|
||||
version?: unknown;
|
||||
};
|
||||
return {
|
||||
version: typeof parsed.version === "string" ? parsed.version : null,
|
||||
commit: typeof parsed.commit === "string" ? parsed.commit : null,
|
||||
};
|
||||
} catch {
|
||||
return { version: null, commit: null };
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import pMap from "p-map";
|
||||
import type { RootHelpRenderOptions } from "../src/cli/program/root-help.js";
|
||||
import type { OpenClawConfig } from "../src/config/config.js";
|
||||
import { resolveCliStartupRootHelpBundleIdentity } from "./lib/cli-startup-root-help-bundle.js";
|
||||
import { resolveWindowsTaskkillPath } from "./lib/windows-taskkill.mjs";
|
||||
|
||||
function dedupe(values: string[]): string[] {
|
||||
@@ -155,26 +156,6 @@ function signalCliStartupMetadataProcessTree(
|
||||
child.kill(signal);
|
||||
}
|
||||
|
||||
function resolveRootHelpBundleIdentity(
|
||||
distDirOverride: string = distDir,
|
||||
): { bundleName: string; signature: string } | null {
|
||||
const bundleName = readdirSync(distDirOverride).find(
|
||||
(entry) =>
|
||||
entry.startsWith("root-help-") &&
|
||||
!entry.startsWith("root-help-metadata-") &&
|
||||
entry.endsWith(".js"),
|
||||
);
|
||||
if (!bundleName) {
|
||||
return null;
|
||||
}
|
||||
const bundlePath = path.join(distDirOverride, bundleName);
|
||||
const raw = readFileSync(bundlePath, "utf8");
|
||||
return {
|
||||
bundleName,
|
||||
signature: createHash("sha1").update(raw).digest("hex"),
|
||||
};
|
||||
}
|
||||
|
||||
function updateHashFromFiles(
|
||||
hash: ReturnType<typeof createHash>,
|
||||
files: string[],
|
||||
@@ -591,7 +572,7 @@ export async function renderBundledRootHelpText(
|
||||
: extensionsDir,
|
||||
),
|
||||
): Promise<string> {
|
||||
const bundleIdentity = resolveRootHelpBundleIdentity(_distDirOverride);
|
||||
const bundleIdentity = resolveCliStartupRootHelpBundleIdentity(_distDirOverride);
|
||||
if (!bundleIdentity) {
|
||||
throw new Error("No root-help bundle found in dist; cannot write CLI startup metadata.");
|
||||
}
|
||||
@@ -778,7 +759,7 @@ export async function writeCliStartupMetadata(options?: {
|
||||
const resolvedExtensionsDir = options?.extensionsDir ?? extensionsDir;
|
||||
const resolvedSourceRootDir = options?.sourceRootDir ?? rootDir;
|
||||
const channelCatalog = readBundledChannelCatalog(resolvedExtensionsDir);
|
||||
const bundleIdentity = resolveRootHelpBundleIdentity(resolvedDistDir);
|
||||
const bundleIdentity = resolveCliStartupRootHelpBundleIdentity(resolvedDistDir);
|
||||
const browserHelpSourceSignature = resolveBrowserHelpSourceSignature(resolvedSourceRootDir);
|
||||
const secretsHelpSourceSignature = resolveSecretsHelpSourceSignature(resolvedSourceRootDir);
|
||||
const nodesHelpSourceSignature = resolveNodesHelpSourceSignature(resolvedSourceRootDir);
|
||||
|
||||
@@ -592,4 +592,64 @@ describe("write-cli-startup-metadata", () => {
|
||||
expect(nodesRenderCount).toBe(3);
|
||||
expect(written.nodesHelpText).toContain("openclaw nodes 3");
|
||||
});
|
||||
|
||||
it("regenerates help when build version or commit changes", async () => {
|
||||
const tempRoot = createTempDir("openclaw-startup-metadata-build-identity-");
|
||||
const distDir = path.join(tempRoot, "dist");
|
||||
const extensionsDir = path.join(tempRoot, "extensions");
|
||||
const outputPath = path.join(distDir, "cli-startup-metadata.json");
|
||||
let renderCount = 0;
|
||||
|
||||
writeStartupMetadataSourceSignatureFixture(tempRoot);
|
||||
writeFixtureFile(distDir, "root-help-fixture.js", "export function outputRootHelp() {}\n");
|
||||
|
||||
const writeMetadata = async (): Promise<void> => {
|
||||
await writeCliStartupMetadata({
|
||||
distDir,
|
||||
outputPath,
|
||||
extensionsDir,
|
||||
sourceRootDir: tempRoot,
|
||||
renderBundledRootHelpText: async () => {
|
||||
renderCount += 1;
|
||||
return `Usage: openclaw ${renderCount}\n`;
|
||||
},
|
||||
renderSourceBrowserHelpText: () => "Usage: openclaw browser\n",
|
||||
renderSourceSecretsHelpText: () => "Usage: openclaw secrets\n",
|
||||
renderSourceNodesHelpText: () => "Usage: openclaw nodes\n",
|
||||
renderSourceSubcommandHelpTextRecord: () => ({
|
||||
doctor: "Usage: openclaw doctor\n",
|
||||
gateway: "Usage: openclaw gateway\n",
|
||||
models: "Usage: openclaw models\n",
|
||||
plugins: "Usage: openclaw plugins\n",
|
||||
sessions: "Usage: openclaw sessions\n",
|
||||
tasks: "Usage: openclaw tasks\n",
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
||||
writeFixtureFile(
|
||||
distDir,
|
||||
"build-info.json",
|
||||
JSON.stringify({ version: "2026.7.2", commit: "a".repeat(40) }),
|
||||
);
|
||||
await writeMetadata();
|
||||
await writeMetadata();
|
||||
expect(renderCount).toBe(1);
|
||||
|
||||
writeFixtureFile(
|
||||
distDir,
|
||||
"build-info.json",
|
||||
JSON.stringify({ version: "2026.7.2", commit: "b".repeat(40) }),
|
||||
);
|
||||
await writeMetadata();
|
||||
expect(renderCount).toBe(2);
|
||||
|
||||
writeFixtureFile(
|
||||
distDir,
|
||||
"build-info.json",
|
||||
JSON.stringify({ version: "2026.7.3", commit: "b".repeat(40) }),
|
||||
);
|
||||
await writeMetadata();
|
||||
expect(renderCount).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user