fix(cli): show group help

This commit is contained in:
2026-06-07 18:57:48 +08:00
parent 4b03aa3a91
commit ff87817fb5
+90 -5
View File
@@ -180,6 +180,18 @@ async function main() {
return 0;
}
if (isLocalHelpCommand(parsed.command)) {
const result = await dispatch(parsed, null);
emitSuccess({
summary: result.summary,
data: result.local,
ctx: null,
durationMs: 0,
nextCommands: result.nextCommands,
});
return 0;
}
const ctx = await buildContext(parsed.global);
const startedAt = Date.now();
const result = await dispatch(parsed, ctx);
@@ -194,14 +206,27 @@ async function main() {
return 0;
}
function isLocalHelpCommand(command) {
if (command.length === 1 && GROUPS[command[0]]) return true;
return command.length > 1 && command.at(-1) === "help";
}
async function dispatch(parsed, ctx) {
const [group, ...rest] = parsed.command;
if (group === "network") {
if (rest.length === 0 || rest[0] === "help") return helpResult(["network"], NETWORK_COMMANDS);
return commandFromMap(NETWORK_COMMANDS, rest, parsed, ctx);
}
if (group === "component" && rest[0] === "option") {
if (rest.length === 1 || rest[1] === "help") return helpResult(["component", "option"], {
schema: { summary: "读取选项 schema" },
get: { summary: "读取选项属性" },
});
return componentOption(rest.slice(1), parsed, ctx);
}
if (group === "component" && (rest.length === 0 || rest[0] === "help")) {
return helpResult(["component"], { option: { summary: GROUPS.component } });
}
if (group === "simulation" && rest[0] === "run") {
requireOptions(parsed.args, { "start-time": { required: true }, duration: { required: true } });
const start = parseTime(parsed.args["start-time"], "--start-time");
@@ -218,10 +243,24 @@ async function dispatch(parsed, ctx) {
],
};
}
if (group === "simulation" && (rest.length === 0 || rest[0] === "help")) {
return helpResult(["simulation"], { run: { summary: "触发指定绝对时间的模拟运行" } });
}
if (group === "analysis") {
if (rest.length === 0 || rest[0] === "help") return helpResult(["analysis"], {
age: { summary: "执行水龄分析" },
leakage: { summary: "漏损分析相关命令" },
"burst-detection": { summary: "爆管检测相关命令" },
"sensor-placement": { summary: "传感器选址相关命令" },
});
return analysis(rest, parsed, ctx);
}
if (group === "data") {
if (rest.length === 0 || rest[0] === "help") return helpResult(["data"], {
timeseries: { summary: "时序数据查询命令" },
scada: { summary: "SCADA 元数据查询命令" },
scheme: { summary: "方案数据查询命令" },
});
return dataCommand(rest, parsed, ctx);
}
throw cliError("未找到命令", "COMMAND_NOT_FOUND", `unknown command: ${parsed.command.join(" ")}`, 2, {
@@ -229,6 +268,19 @@ async function dispatch(parsed, ctx) {
});
}
function helpResult(command, commands) {
return {
summary: `命令帮助:${command.join(" ")}`,
local: {
command: command.join(" "),
commands: Object.fromEntries(
Object.entries(commands).map(([name, spec]) => [name, spec.summary ?? ""]),
),
examples: examplesFor(command),
},
};
}
function commandFromMap(map, commandPath, parsed, ctx) {
const name = commandPath[0];
const spec = map[name];
@@ -383,6 +435,9 @@ function dataCommand(rest, parsed, ctx) {
}
async function requestJson(ctx, request) {
if (request.local !== undefined) {
return request.local;
}
if (request.requireProject) {
requireProject(ctx);
}
@@ -557,15 +612,45 @@ function emitSuccess({ summary, data, ctx, durationMs, nextCommands }) {
schema_version: SCHEMA_VERSION,
summary,
data,
metadata: {
server: ctx.server,
request_id: ctx.requestId,
duration_ms: durationMs,
},
metadata: ctx
? {
server: ctx.server,
request_id: ctx.requestId,
duration_ms: durationMs,
}
: undefined,
next_commands: nextCommands,
}));
}
function examplesFor(command) {
const key = command.join(" ");
const examples = {
network: [
"tjwater-cli network get-all-pipes-properties",
"tjwater-cli network get-pipe-properties --pipe P1",
],
component: ["tjwater-cli component option help"],
"component option": [
"tjwater-cli component option schema --kind time",
"tjwater-cli component option get --kind network",
],
simulation: [
"tjwater-cli simulation run --start-time 2025-01-01T00:00:00+08:00 --duration 30",
],
analysis: [
"tjwater-cli analysis age --start-time 2025-01-01T00:00:00+08:00 --duration 900",
"tjwater-cli analysis leakage schemes list",
],
data: [
"tjwater-cli data timeseries realtime links --start-time 2025-01-01T00:00:00+08:00 --end-time 2025-01-01T01:00:00+08:00",
"tjwater-cli data scada list",
"tjwater-cli data scheme list",
],
};
return examples[key] ?? ["tjwater-cli help"];
}
function emitFailure(error) {
const payload = {
ok: false,