Files
openclaw/src/cli/program/error-output.test.ts
T
Glenn-Agent 2f12755498 fix: suggest close CLI commands (#91345)
Summary:
- The PR adds descriptor-backed CLI command suggestions for unknown root commands, wires them into Commander parse errors and early unowned-root diagnostics, and covers both paths with focused CLI tests.
- PR surface: Source +104, Tests +71. Total +175 across 5 files.
- Reproducibility: yes. for the behavior gap: current main's formatter and early unowned-root path emit generic diagnostics without closest-command hints, and the PR proof shows the after-fix CLI output.

Automerge notes:
- PR branch already contained follow-up commit before automerge: fix: suppress suggestions for plugin policy diagnostics
- PR branch already contained follow-up commit before automerge: Merge remote-tracking branch 'origin/main' into fix/83999-cli-command…
- PR branch already contained follow-up commit before automerge: test: align agent model expectations
- PR branch already contained follow-up commit before automerge: test: restore unrelated agent test fixture

Validation:
- ClawSweeper review passed for head b98f5b59e6.
- Required merge gates passed before the squash merge.

Prepared head SHA: b98f5b59e6
Review: https://github.com/openclaw/openclaw/pull/91345#issuecomment-4646215016

Co-authored-by: Glenn-Agent <glenn_agent@163.com>
2026-06-19 05:54:14 +00:00

72 lines
2.6 KiB
TypeScript

// Error output tests cover program-level error display and exit messaging.
import { describe, expect, it } from "vitest";
import { formatCliParseErrorOutput } from "./error-output.js";
describe("formatCliParseErrorOutput", () => {
it("explains unknown commands with root help and plugin hints", () => {
const output = formatCliParseErrorOutput("error: unknown command 'wat'\n", {
argv: ["node", "openclaw", "wat"],
});
expect(output).toBe(
'OpenClaw does not know the command "wat".\nTry: openclaw --help\nPlugin command? openclaw plugins list\nDocs: https://docs.openclaw.ai/cli\n',
);
});
it("suggests close known commands for unknown commands", () => {
const output = formatCliParseErrorOutput("error: unknown command 'upate'\n", {
argv: ["node", "openclaw", "upate"],
});
expect(output).toBe(
'OpenClaw does not know the command "upate".\nDid you mean this?\n openclaw update\nTry: openclaw --help\nPlugin command? openclaw plugins list\nDocs: https://docs.openclaw.ai/cli\n',
);
});
it("suggests explicit aliases for common adjacent terminology", () => {
const output = formatCliParseErrorOutput("error: unknown command 'upgrade'\n", {
argv: ["node", "openclaw", "upgrade"],
});
expect(output).toContain("Did you mean this?\n openclaw update\n");
});
it("preserves active profile context in command suggestions", () => {
const originalProfile = process.env.OPENCLAW_PROFILE;
process.env.OPENCLAW_PROFILE = "work";
try {
const output = formatCliParseErrorOutput("error: unknown command 'doctr'\n", {
argv: ["node", "openclaw", "doctr"],
});
expect(output).toContain("Did you mean this?\n openclaw --profile work doctor\n");
} finally {
if (originalProfile === undefined) {
delete process.env.OPENCLAW_PROFILE;
} else {
process.env.OPENCLAW_PROFILE = originalProfile;
}
}
});
it("points unknown options at the active command help", () => {
const output = formatCliParseErrorOutput("error: unknown option '--wat'\n", {
argv: ["node", "openclaw", "channels", "status", "--wat"],
});
expect(output).toBe(
'OpenClaw does not recognize option "--wat".\nTry: openclaw channels status --help\n',
);
});
it("points missing required arguments at command help", () => {
const output = formatCliParseErrorOutput("error: missing required argument 'name'\n", {
argv: ["node", "openclaw", "plugins", "install"],
});
expect(output).toBe(
'Missing required argument "name".\nTry: openclaw plugins install --help\n',
);
});
});