mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-03 00:56:22 +00:00
fix(cli): gate exported subcli descriptors (#84519)
Summary: - This PR filters exported sub-CLI descriptors through the private-QA gate, centralizes that filter, adds regr ... ge, and carries small validation repairs in workspace glob and tunnel-timeout tests plus a changelog entry. - Reproducibility: yes. Current-main source shows the raw SUB_CLI_DESCRIPTORS export can include qa while the helper surfaces filter it, and src/cli/argv.ts consumes that export for root command policy. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(cli): gate exported subcli descriptors - PR branch already contained follow-up commit before automerge: fix(clawsweeper): address review for automerge-openclaw-openclaw-8451… Validation: - ClawSweeper review passed for headba197a6f30. - Required merge gates passed before the squash merge. Prepared head SHA:ba197a6f30Review: https://github.com/openclaw/openclaw/pull/84519#issuecomment-4496549642 Co-authored-by: Zhaocun <zhaocunsun@gmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
This commit is contained in:
65
src/cli/program/subcli-descriptors.test.ts
Normal file
65
src/cli/program/subcli-descriptors.test.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
async function importSubCliDescriptors() {
|
||||
vi.resetModules();
|
||||
return import("./subcli-descriptors.js");
|
||||
}
|
||||
|
||||
function descriptorNames(descriptors: ReadonlyArray<{ name: string }>): string[] {
|
||||
return descriptors.map((descriptor) => descriptor.name);
|
||||
}
|
||||
|
||||
describe("sub-cli descriptors", () => {
|
||||
const originalPrivateQaCli = process.env.OPENCLAW_ENABLE_PRIVATE_QA_CLI;
|
||||
|
||||
afterEach(() => {
|
||||
if (originalPrivateQaCli === undefined) {
|
||||
delete process.env.OPENCLAW_ENABLE_PRIVATE_QA_CLI;
|
||||
} else {
|
||||
process.env.OPENCLAW_ENABLE_PRIVATE_QA_CLI = originalPrivateQaCli;
|
||||
}
|
||||
vi.resetModules();
|
||||
});
|
||||
|
||||
it("keeps the exported descriptor list aligned with private QA visibility when disabled (#83927)", async () => {
|
||||
delete process.env.OPENCLAW_ENABLE_PRIVATE_QA_CLI;
|
||||
|
||||
const { SUB_CLI_DESCRIPTORS, getSubCliEntries } = await importSubCliDescriptors();
|
||||
const exportedNames = descriptorNames(SUB_CLI_DESCRIPTORS);
|
||||
|
||||
expect(exportedNames).toEqual(descriptorNames(getSubCliEntries()));
|
||||
expect(exportedNames).not.toContain("qa");
|
||||
});
|
||||
|
||||
it("keeps all sub-cli filter surfaces aligned when private QA is disabled (#83926)", async () => {
|
||||
delete process.env.OPENCLAW_ENABLE_PRIVATE_QA_CLI;
|
||||
|
||||
const {
|
||||
SUB_CLI_DESCRIPTORS,
|
||||
getSubCliCommandsWithSubcommands,
|
||||
getSubCliParentDefaultHelpCommands,
|
||||
} = await importSubCliDescriptors();
|
||||
const exportedNames = descriptorNames(SUB_CLI_DESCRIPTORS);
|
||||
|
||||
expect(exportedNames).not.toContain("qa");
|
||||
expect(getSubCliCommandsWithSubcommands()).not.toContain("qa");
|
||||
expect(getSubCliParentDefaultHelpCommands()).not.toContain("qa");
|
||||
});
|
||||
|
||||
it("includes qa in the exported descriptor list when private QA is enabled", async () => {
|
||||
process.env.OPENCLAW_ENABLE_PRIVATE_QA_CLI = "1";
|
||||
|
||||
const {
|
||||
SUB_CLI_DESCRIPTORS,
|
||||
getSubCliCommandsWithSubcommands,
|
||||
getSubCliEntries,
|
||||
getSubCliParentDefaultHelpCommands,
|
||||
} = await importSubCliDescriptors();
|
||||
const exportedNames = descriptorNames(SUB_CLI_DESCRIPTORS);
|
||||
|
||||
expect(exportedNames).toEqual(descriptorNames(getSubCliEntries()));
|
||||
expect(exportedNames).toContain("qa");
|
||||
expect(getSubCliCommandsWithSubcommands()).toContain("qa");
|
||||
expect(getSubCliParentDefaultHelpCommands()).not.toContain("qa");
|
||||
});
|
||||
});
|
||||
@@ -179,28 +179,42 @@ const subCliCommandCatalog = defineCommandDescriptorCatalog([
|
||||
},
|
||||
] as const satisfies ReadonlyArray<SubCliDescriptor>);
|
||||
|
||||
export const SUB_CLI_DESCRIPTORS = subCliCommandCatalog.descriptors;
|
||||
function filterPrivateQaItems<T>(
|
||||
items: ReadonlyArray<T>,
|
||||
getName: (item: T) => string,
|
||||
): ReadonlyArray<T> {
|
||||
if (isPrivateQaCliEnabled()) {
|
||||
return items;
|
||||
}
|
||||
return items.filter((item) => getName(item) !== "qa");
|
||||
}
|
||||
|
||||
export const SUB_CLI_DESCRIPTORS = filterPrivateQaItems(
|
||||
subCliCommandCatalog.descriptors,
|
||||
(descriptor) => descriptor.name,
|
||||
);
|
||||
|
||||
export function getSubCliEntries(): ReadonlyArray<SubCliDescriptor> {
|
||||
const descriptors = subCliCommandCatalog.getDescriptors();
|
||||
if (isPrivateQaCliEnabled()) {
|
||||
return descriptors;
|
||||
}
|
||||
return descriptors.filter((descriptor) => descriptor.name !== "qa");
|
||||
return filterPrivateQaItems(
|
||||
subCliCommandCatalog.getDescriptors(),
|
||||
(descriptor) => descriptor.name,
|
||||
);
|
||||
}
|
||||
|
||||
export function getSubCliCommandsWithSubcommands(): string[] {
|
||||
const commands = subCliCommandCatalog.getCommandsWithSubcommands();
|
||||
if (isPrivateQaCliEnabled()) {
|
||||
return commands;
|
||||
}
|
||||
return commands.filter((command) => command !== "qa");
|
||||
return [
|
||||
...filterPrivateQaItems(
|
||||
subCliCommandCatalog.getCommandsWithSubcommands(),
|
||||
(command) => command,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
export function getSubCliParentDefaultHelpCommands(): string[] {
|
||||
const commands = subCliCommandCatalog.getParentDefaultHelpCommands();
|
||||
if (isPrivateQaCliEnabled()) {
|
||||
return commands;
|
||||
}
|
||||
return commands.filter((command) => command !== "qa");
|
||||
return [
|
||||
...filterPrivateQaItems(
|
||||
subCliCommandCatalog.getParentDefaultHelpCommands(),
|
||||
(command) => command,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user