From 1f56feab24568b49aac3abb0c8e244cc604804af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=A5=E9=BA=92?= Date: Mon, 29 Jun 2026 09:07:12 +0800 Subject: [PATCH] refactor(commands): route all exits through the central error handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commands no longer call process.exit() directly. Every failure now throws UsageError (bad input → exit 2) or BailianError (runtime failure, with AUTH/TIMEOUT codes), so the runtime's handleError stays the single exit point and telemetry always flushes. - convert 27 process.exit() sites across 15 commands to throws - move cross-flag/value checks into validate(); use flag `choices` for --events / --sort; drop dead --model required check - keep pipeline's process.exitCode for lint-style soft failures - enforce with unicorn/no-process-exit, allowed only in runtime/tools/tests - fix incidental lint: void floating run(), narrow console errorCode, align generate-reference type imports to source --- packages/cli/src/main.ts | 2 +- packages/cli/tests/e2e/pipeline.e2e.test.ts | 2 +- packages/cli/tests/e2e/quota.e2e.test.ts | 4 +- packages/commands/src/commands/app/call.ts | 4 +- .../commands/src/commands/console/call.ts | 10 +++- packages/commands/src/commands/mcp/call.ts | 32 ++++++----- packages/commands/src/commands/memory/add.ts | 4 +- .../src/commands/memory/profile-create.ts | 4 +- .../commands/src/commands/memory/search.ts | 4 +- .../src/commands/pipeline/load-file.ts | 4 +- .../commands/src/commands/pipeline/run.ts | 18 +++--- packages/commands/src/commands/quota/check.ts | 9 +-- .../commands/src/commands/quota/history.ts | 9 +-- packages/commands/src/commands/quota/list.ts | 5 +- .../commands/src/commands/quota/request.ts | 56 +++++++++---------- packages/commands/src/commands/search/web.ts | 8 +-- packages/commands/src/commands/usage/free.ts | 8 +-- packages/commands/src/commands/usage/stats.ts | 22 +++++--- packages/core/src/console/gateway.ts | 2 +- packages/rag/src/main.ts | 2 +- skills/bailian-cli/reference/pipeline.md | 2 +- skills/bailian-cli/reference/usage.md | 2 +- tools/generate-reference.ts | 8 +-- vite.config.ts | 13 ++++- 24 files changed, 116 insertions(+), 118 deletions(-) diff --git a/packages/cli/src/main.ts b/packages/cli/src/main.ts index 1e32e7f..0968516 100644 --- a/packages/cli/src/main.ts +++ b/packages/cli/src/main.ts @@ -2,7 +2,7 @@ import { createCli } from "bailian-cli-runtime"; import { commands } from "./commands.ts"; import pkg from "../package.json" with { type: "json" }; -createCli(commands, { +void createCli(commands, { binName: "bl", version: pkg.version, clientName: "bailian-cli", diff --git a/packages/cli/tests/e2e/pipeline.e2e.test.ts b/packages/cli/tests/e2e/pipeline.e2e.test.ts index 9d562e1..d555627 100644 --- a/packages/cli/tests/e2e/pipeline.e2e.test.ts +++ b/packages/cli/tests/e2e/pipeline.e2e.test.ts @@ -245,6 +245,6 @@ describe("e2e: pipeline", () => { ]); expect(exitCode).toBe(2); expect(stdout).toBe(""); - expect(stderr).toMatch(/unsupported --events format: bogus/i); + expect(stderr).toMatch(/--events must be one of: jsonl/i); }); }); diff --git a/packages/cli/tests/e2e/quota.e2e.test.ts b/packages/cli/tests/e2e/quota.e2e.test.ts index b2eae02..e380ef1 100644 --- a/packages/cli/tests/e2e/quota.e2e.test.ts +++ b/packages/cli/tests/e2e/quota.e2e.test.ts @@ -53,7 +53,7 @@ describe("e2e: quota", () => { test("quota check --period 0 报错最小值", async () => { const { stderr, exitCode } = await runCli(["quota", "check", "--period", "0.5"]); - expect(exitCode).toBe(1); + expect(exitCode).toBe(2); expect(stderr).toContain("at least 1 minute"); }); }); @@ -184,7 +184,7 @@ describe.skipIf(!isConsoleE2EReady())("e2e: quota(Console)", () => { "--tpm", "999", ]); - expect(exitCode).toBe(1); + expect(exitCode).toBe(2); expect(stderr).toContain("out of range"); expect(stderr).toContain("Current"); expect(stderr).toContain("Range"); diff --git a/packages/commands/src/commands/app/call.ts b/packages/commands/src/commands/app/call.ts index d8bbddd..ecc83c3 100644 --- a/packages/commands/src/commands/app/call.ts +++ b/packages/commands/src/commands/app/call.ts @@ -1,5 +1,6 @@ import { defineCommand, + UsageError, appCompletionPath, parseSSE, detectOutputFormat, @@ -114,8 +115,7 @@ export default defineCommand({ try { body.input.biz_params = JSON.parse(flags.bizParams); } catch { - process.stderr.write("Error: --biz-params must be valid JSON\n"); - process.exit(1); + throw new UsageError("--biz-params must be valid JSON"); } } diff --git a/packages/commands/src/commands/console/call.ts b/packages/commands/src/commands/console/call.ts index d7b6048..f35d387 100644 --- a/packages/commands/src/commands/console/call.ts +++ b/packages/commands/src/commands/console/call.ts @@ -1,4 +1,9 @@ -import { defineCommand, effectiveConsoleGatewayConfig, detectOutputFormat } from "bailian-cli-core"; +import { + defineCommand, + UsageError, + effectiveConsoleGatewayConfig, + detectOutputFormat, +} from "bailian-cli-core"; import { emitResult } from "bailian-cli-runtime"; export default defineCommand({ @@ -39,8 +44,7 @@ export default defineCommand({ try { data = JSON.parse(dataRaw) as Record; } catch { - process.stderr.write("Error: --data must be valid JSON\n"); - process.exit(1); + throw new UsageError("--data must be valid JSON"); } const format = detectOutputFormat(config.output); diff --git a/packages/commands/src/commands/mcp/call.ts b/packages/commands/src/commands/mcp/call.ts index dad77d0..d641bff 100644 --- a/packages/commands/src/commands/mcp/call.ts +++ b/packages/commands/src/commands/mcp/call.ts @@ -1,4 +1,10 @@ -import { defineCommand, bailianMcpPath, detectOutputFormat } from "bailian-cli-core"; +import { + defineCommand, + UsageError, + BailianError, + bailianMcpPath, + detectOutputFormat, +} from "bailian-cli-core"; import { emitResult } from "bailian-cli-runtime"; function parseArgFlags(raw: string[]): Record { @@ -6,8 +12,7 @@ function parseArgFlags(raw: string[]): Record { for (const item of raw) { const idx = item.indexOf("="); if (idx <= 0) { - process.stderr.write(`Error: --arg must be in K=V form, got: ${item}\n`); - process.exit(1); + throw new UsageError(`--arg must be in K=V form, got: ${item}`); } const key = item.slice(0, idx).trim(); const rawVal = item.slice(idx + 1); @@ -64,25 +69,23 @@ export default defineCommand({ const dot = target.indexOf("."); if (dot <= 0 || dot === target.length - 1) { - process.stderr.write(`Error: target must be ., got "${target}".\n`); - process.exit(1); + throw new UsageError(`target must be ., got "${target}".`); } const serverCode = target.slice(0, dot); const toolName = target.slice(dot + 1); let toolArgs: Record = {}; if (flags.json) { + let parsed: unknown; try { - const parsed = JSON.parse(flags.json); - if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) { - process.stderr.write("Error: --json must decode to an object.\n"); - process.exit(1); - } - toolArgs = parsed as Record; + parsed = JSON.parse(flags.json); } catch (err) { - process.stderr.write(`Error: --json is not valid JSON — ${(err as Error).message}\n`); - process.exit(1); + throw new UsageError(`--json is not valid JSON — ${(err as Error).message}`); } + if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) { + throw new UsageError("--json must decode to an object."); + } + toolArgs = parsed as Record; } Object.assign(toolArgs, parseArgFlags(flags.arg ?? [])); if (flags.query !== undefined) toolArgs.query = flags.query; @@ -109,8 +112,7 @@ export default defineCommand({ if (result.isError) { const errText = result.content.map((c) => c.text || "").join("\n"); - process.stderr.write(`Tool error: ${errText}\n`); - process.exit(1); + throw new BailianError(`Tool error: ${errText}`); } emitResult(result, format); diff --git a/packages/commands/src/commands/memory/add.ts b/packages/commands/src/commands/memory/add.ts index 88bbd56..00a3edd 100644 --- a/packages/commands/src/commands/memory/add.ts +++ b/packages/commands/src/commands/memory/add.ts @@ -1,5 +1,6 @@ import { defineCommand, + UsageError, memoryAddPath, detectOutputFormat, type FlagsDef, @@ -52,8 +53,7 @@ export default defineCommand({ try { body.messages = JSON.parse(flags.messages); } catch { - process.stderr.write("Error: --messages must be valid JSON array\n"); - process.exit(1); + throw new UsageError("--messages must be valid JSON array"); } } diff --git a/packages/commands/src/commands/memory/profile-create.ts b/packages/commands/src/commands/memory/profile-create.ts index 912b7de..065e48b 100644 --- a/packages/commands/src/commands/memory/profile-create.ts +++ b/packages/commands/src/commands/memory/profile-create.ts @@ -1,5 +1,6 @@ import { defineCommand, + UsageError, profileSchemaPath, detectOutputFormat, type ProfileSchemaCreateRequest, @@ -38,8 +39,7 @@ export default defineCommand({ try { attributes = JSON.parse(attrStr); } catch { - process.stderr.write("Error: --attributes must be valid JSON array\n"); - process.exit(1); + throw new UsageError("--attributes must be valid JSON array"); } const body: ProfileSchemaCreateRequest = { name, attributes }; diff --git a/packages/commands/src/commands/memory/search.ts b/packages/commands/src/commands/memory/search.ts index c40911e..9f9fa8d 100644 --- a/packages/commands/src/commands/memory/search.ts +++ b/packages/commands/src/commands/memory/search.ts @@ -1,5 +1,6 @@ import { defineCommand, + UsageError, memorySearchPath, detectOutputFormat, type FlagsDef, @@ -49,8 +50,7 @@ export default defineCommand({ try { body.messages = JSON.parse(flags.messages); } catch { - process.stderr.write("Error: --messages must be valid JSON array\n"); - process.exit(1); + throw new UsageError("--messages must be valid JSON array"); } } diff --git a/packages/commands/src/commands/pipeline/load-file.ts b/packages/commands/src/commands/pipeline/load-file.ts index b7a24c3..e8d0644 100644 --- a/packages/commands/src/commands/pipeline/load-file.ts +++ b/packages/commands/src/commands/pipeline/load-file.ts @@ -1,11 +1,11 @@ import { readFile } from "node:fs/promises"; import { extname } from "node:path"; +import { UsageError } from "bailian-cli-core"; import type { PipelineDefinition } from "bailian-cli-runtime"; export async function loadPipelineFile(filePath: string): Promise { const raw = await readFile(filePath, "utf-8").catch((err: Error) => { - process.stderr.write(`Error: cannot read pipeline file: ${err.message}\n`); - process.exit(2); + throw new UsageError(`cannot read pipeline file: ${err.message}`); }); const ext = extname(filePath).toLowerCase(); let parsed: unknown; diff --git a/packages/commands/src/commands/pipeline/run.ts b/packages/commands/src/commands/pipeline/run.ts index 036fa1f..73a0489 100644 --- a/packages/commands/src/commands/pipeline/run.ts +++ b/packages/commands/src/commands/pipeline/run.ts @@ -25,7 +25,12 @@ const RUN_FLAGS = { valueHint: "", description: "Max parallel steps (default: 1)", }, - events: { type: "string", valueHint: "", description: "Emit lifecycle events: jsonl" }, + events: { + type: "string", + valueHint: "", + description: "Emit lifecycle events: jsonl", + choices: ["jsonl"] as const, + }, timeout: { type: "number", valueHint: "", @@ -46,6 +51,7 @@ export default defineCommand({ "--file workflow.json --events jsonl", "--file workflow.yaml --output json", ], + validate: (f) => (f.input && f.inputFile ? "use --input or --input-file, not both" : undefined), async run(ctx) { const { config, flags } = ctx; const file = flags.file; @@ -53,12 +59,6 @@ export default defineCommand({ initPipelineSteps(); const eventsFormat = flags.events; - if (eventsFormat !== undefined && eventsFormat !== "jsonl") { - process.stderr.write( - `Error: unsupported --events format: ${eventsFormat}. Supported: jsonl\n`, - ); - process.exit(2); - } const filePath = resolve(file); const pipeline = await loadPipelineFile(filePath); @@ -98,10 +98,6 @@ export default defineCommand({ async function resolveRuntimeInput(flags: RunFlags): Promise> { const inputJson = flags.input; const inputFile = flags.inputFile; - if (inputJson && inputFile) { - process.stderr.write("Error: use --input or --input-file, not both\n"); - process.exit(2); - } if (inputJson) return JSON.parse(inputJson) as Record; if (inputFile) { const raw = await readFile(resolve(inputFile), "utf-8"); diff --git a/packages/commands/src/commands/quota/check.ts b/packages/commands/src/commands/quota/check.ts index 72d72af..1b4be03 100644 --- a/packages/commands/src/commands/quota/check.ts +++ b/packages/commands/src/commands/quota/check.ts @@ -254,15 +254,12 @@ export default defineCommand({ "--model qwen3.6-plus,qwen-turbo", "--output json", ], + validate: (f) => + (Number(f.period) || 2) < 1 ? "--period must be at least 1 minute." : undefined, async run(ctx) { const { config, flags } = ctx; const modelFlag = flags.model || undefined; - const rawPeriod = Number(flags.period) || 2; - if (rawPeriod < 1) { - process.stderr.write("Error: --period must be at least 1 minute.\n"); - process.exit(1); - } - const windowMinutes = rawPeriod; + const windowMinutes = Number(flags.period) || 2; const format = detectOutputFormat(config.output); if (config.dryRun) { diff --git a/packages/commands/src/commands/quota/history.ts b/packages/commands/src/commands/quota/history.ts index fe449a9..488c86e 100644 --- a/packages/commands/src/commands/quota/history.ts +++ b/packages/commands/src/commands/quota/history.ts @@ -1,4 +1,4 @@ -import { defineCommand, detectOutputFormat, BailianError } from "bailian-cli-core"; +import { defineCommand, detectOutputFormat, BailianError, ExitCode } from "bailian-cli-core"; import { emitResult } from "bailian-cli-runtime"; import { displayWidth, padEnd } from "bailian-cli-runtime"; @@ -132,10 +132,11 @@ export default defineCommand({ result = await ctx.client.console(HISTORY_API, requestData); } catch (err) { if (err instanceof BailianError && err.message.includes("NotLogined")) { - process.stderr.write( - `Error: session expired. Run \`${config.binName} auth login --console\` to re-authenticate.\n`, + throw new BailianError( + "session expired.", + ExitCode.AUTH, + `Run \`${config.binName} auth login --console\` to re-authenticate.`, ); - process.exit(1); } throw err; } diff --git a/packages/commands/src/commands/quota/list.ts b/packages/commands/src/commands/quota/list.ts index b259036..a36ad35 100644 --- a/packages/commands/src/commands/quota/list.ts +++ b/packages/commands/src/commands/quota/list.ts @@ -1,4 +1,4 @@ -import { defineCommand, detectOutputFormat, type Client } from "bailian-cli-core"; +import { defineCommand, BailianError, detectOutputFormat, type Client } from "bailian-cli-core"; import { emitResult } from "bailian-cli-runtime"; import { displayWidth, padEnd } from "bailian-cli-runtime"; @@ -197,8 +197,7 @@ export default defineCommand({ ); models = models.filter((m) => names.has(m.model)); if (models.length === 0) { - process.stderr.write(`Error: no matching models found for "${modelFlag}".\n`); - process.exit(1); + throw new BailianError(`no matching models found for "${modelFlag}".`); } } diff --git a/packages/commands/src/commands/quota/request.ts b/packages/commands/src/commands/quota/request.ts index 7dc035b..8338daf 100644 --- a/packages/commands/src/commands/quota/request.ts +++ b/packages/commands/src/commands/quota/request.ts @@ -1,4 +1,11 @@ -import { defineCommand, detectOutputFormat, BailianError, type Client } from "bailian-cli-core"; +import { + defineCommand, + UsageError, + BailianError, + ExitCode, + detectOutputFormat, + type Client, +} from "bailian-cli-core"; import { emitResult } from "bailian-cli-runtime"; const MODEL_LIST_API = "zeldaHttp.dashscopeModel./zelda/api/v1/modelCenter/listFoundationModels"; @@ -96,20 +103,11 @@ export default defineCommand({ "--model qwen3.6-plus --tpm 8000000 --yes", "--model qwen-turbo --tpm 100000 --output json", ], + validate: (f) => (Number(f.tpm) > 0 ? undefined : "--tpm must be a positive number."), async run(ctx) { const { config, flags } = ctx; const modelName = flags.model; - if (!modelName) { - process.stderr.write("Error: --model is required.\n"); - process.exit(1); - } - const tpmValue = Number(flags.tpm); - if (!tpmValue || tpmValue <= 0) { - process.stderr.write("Error: --tpm must be a positive number.\n"); - process.exit(1); - } - const autoConfirm = Boolean(flags.yes) || config.yes; const format = detectOutputFormat(config.output); @@ -126,13 +124,11 @@ export default defineCommand({ const modelInfo = await fetchModelQpmInfo(ctx.client, modelName); if (!modelInfo) { - process.stderr.write( - `Error: model "${modelName}" not found or does not support self-service quota increase.\n`, + throw new BailianError( + `model "${modelName}" not found or does not support self-service quota increase.`, + ExitCode.GENERAL, + `Run \`${config.binName} quota list\` to view available models.`, ); - process.stderr.write( - `Hint: run \`${config.binName} quota list\` to view available models.\n`, - ); - process.exit(1); } const modelDefault = modelInfo.qpmInfo["model-default"]; @@ -142,12 +138,10 @@ export default defineCommand({ const maxLimit = minLimit * 2; if (tpmValue < minLimit || tpmValue > maxLimit) { - process.stderr.write( - `Error: TPM value ${tpmValue.toLocaleString()} is out of range.\n` + - ` Current: ${currentLimit.toLocaleString()}\n` + - ` Range: ${minLimit.toLocaleString()} ~ ${maxLimit.toLocaleString()}\n`, + throw new UsageError( + `TPM value ${tpmValue.toLocaleString()} is out of range. ` + + `Current: ${currentLimit.toLocaleString()}, Range: ${minLimit.toLocaleString()} ~ ${maxLimit.toLocaleString()}.`, ); - process.exit(1); } const requestData = { @@ -166,10 +160,11 @@ export default defineCommand({ return await ctx.client.console(UPDATE_LIMITS_API, requestData); } catch (err) { if (err instanceof BailianError && err.message.includes("NotLogined")) { - process.stderr.write( - `Error: session expired. Run \`${config.binName} auth login --console\` to re-authenticate.\n`, + throw new BailianError( + "session expired.", + ExitCode.AUTH, + `Run \`${config.binName} auth login --console\` to re-authenticate.`, ); - process.exit(1); } throw err; } @@ -182,17 +177,16 @@ export default defineCommand({ const confirmCode = resp.confirmCode as string; if (confirmCode === "Refresh_Required") { - process.stderr.write("Error: rate limit has been updated externally. Please retry.\n"); - process.exit(1); + throw new BailianError("rate limit has been updated externally. Please retry."); } if (confirmCode === "Downgrade") { if (!autoConfirm) { - process.stderr.write( - `Warning: target TPM (${tpmValue.toLocaleString()}) is lower than current (${currentLimit.toLocaleString()}).\n` + - "Use --yes to confirm downgrade.\n", + throw new BailianError( + `target TPM (${tpmValue.toLocaleString()}) is lower than current (${currentLimit.toLocaleString()}).`, + ExitCode.GENERAL, + "Use --yes to confirm downgrade.", ); - process.exit(1); } result = await submitRequest(true); } diff --git a/packages/commands/src/commands/search/web.ts b/packages/commands/src/commands/search/web.ts index ffe9228..8591e21 100644 --- a/packages/commands/src/commands/search/web.ts +++ b/packages/commands/src/commands/search/web.ts @@ -1,5 +1,6 @@ import { defineCommand, + BailianError, detectOutputFormat, mcpWebSearchPath, type FlagsDef, @@ -85,15 +86,14 @@ export default defineCommand({ // Call the search tool const result = await client.callTool("bailian_web_search", toolArgs); - if (!config.quiet) spinner.stop("Done."); - // Handle error response if (result.isError) { const errText = result.content.map((c) => c.text || "").join("\n"); - process.stderr.write(`Search error: ${errText}\n`); - process.exit(1); + throw new BailianError(`Search error: ${errText}`); } + if (!config.quiet) spinner.stop("Done."); + // Output results — always structured to stdout if (format === "json") { emitResult(result, format); diff --git a/packages/commands/src/commands/usage/free.ts b/packages/commands/src/commands/usage/free.ts index 475e01e..59b8287 100644 --- a/packages/commands/src/commands/usage/free.ts +++ b/packages/commands/src/commands/usage/free.ts @@ -197,6 +197,7 @@ export default defineCommand({ type: "string", valueHint: "", description: "Sort by: remaining (ascending), expires (ascending)", + choices: ["remaining", "expires"] as const, }, consoleRegion: { type: "string", valueHint: "", description: "Console region" }, consoleSite: { @@ -219,14 +220,7 @@ export default defineCommand({ const { config, flags } = ctx; const modelFlag = flags.model || undefined; const expiringDays = Number(flags.expiring) || 0; - const VALID_SORT_FIELDS = ["remaining", "expires"] as const; const sortField = flags.sort || undefined; - if (sortField && !VALID_SORT_FIELDS.includes(sortField as (typeof VALID_SORT_FIELDS)[number])) { - process.stderr.write( - `Error: invalid --sort value "${sortField}". Must be one of: ${VALID_SORT_FIELDS.join(", ")}\n`, - ); - process.exit(1); - } const format = detectOutputFormat(config.output); let models: string[]; diff --git a/packages/commands/src/commands/usage/stats.ts b/packages/commands/src/commands/usage/stats.ts index 0cc6643..c138293 100644 --- a/packages/commands/src/commands/usage/stats.ts +++ b/packages/commands/src/commands/usage/stats.ts @@ -1,4 +1,11 @@ -import { defineCommand, detectOutputFormat, type Config, type Client } from "bailian-cli-core"; +import { + defineCommand, + BailianError, + ExitCode, + detectOutputFormat, + type Config, + type Client, +} from "bailian-cli-core"; import { emitResult } from "bailian-cli-runtime"; import { displayWidth, padEnd } from "bailian-cli-runtime"; @@ -89,13 +96,11 @@ function resolveWorkspaceId(config: Config, flagWorkspaceId?: string): string { if (flagWorkspaceId) return flagWorkspaceId; if (config.workspaceId) return config.workspaceId; - process.stderr.write( - `Error: workspace-id is required. Set via --workspace-id, BAILIAN_WORKSPACE_ID, or \`${config.binName} config set workspace_id \`.\n`, + throw new BailianError( + `workspace-id is required. Set via --workspace-id, BAILIAN_WORKSPACE_ID, or \`${config.binName} config set workspace_id \`.`, + ExitCode.GENERAL, + `Run \`${config.binName} workspace list\` to view available workspaces.`, ); - process.stderr.write( - `Hint: run \`${config.binName} workspace list\` to view available workspaces.\n`, - ); - process.exit(1); } function formatNumber(num: number): string { @@ -408,8 +413,7 @@ export default defineCommand({ const result = await pollTelemetryApi(ctx.client, OVERVIEW_API, reqDTO); if (!result) { - process.stderr.write("Error: request timed out.\n"); - process.exit(1); + throw new BailianError("Request timed out.", ExitCode.TIMEOUT); } const stat = extractOverviewData(result); diff --git a/packages/core/src/console/gateway.ts b/packages/core/src/console/gateway.ts index 2ea083e..30700ed 100644 --- a/packages/core/src/console/gateway.ts +++ b/packages/core/src/console/gateway.ts @@ -142,7 +142,7 @@ export async function callConsoleGateway( const innerData = json.data as Record | undefined; if (innerData?.success === false && innerData.errorCode) { - const errorCode = String(innerData.errorCode); + const errorCode = String(innerData.errorCode as string | number); const notLogined = errorCode.includes("NotLogined"); const errorMsg = typeof innerData.errorMsg === "string" ? innerData.errorMsg : undefined; throw new BailianError( diff --git a/packages/rag/src/main.ts b/packages/rag/src/main.ts index d81ef56..ce13605 100644 --- a/packages/rag/src/main.ts +++ b/packages/rag/src/main.ts @@ -42,7 +42,7 @@ const commands: Record = { retrieve: knowledgeRetrieve, }; -createCli(commands, { +void createCli(commands, { binName: "rag", version: pkg.version, clientName: "rag-cli", diff --git a/skills/bailian-cli/reference/pipeline.md b/skills/bailian-cli/reference/pipeline.md index d66bd3e..97711b6 100644 --- a/skills/bailian-cli/reference/pipeline.md +++ b/skills/bailian-cli/reference/pipeline.md @@ -30,7 +30,7 @@ Index: [index.md](index.md) | `--input ` | string | no | Runtime input as inline JSON | | `--input-file ` | string | no | Runtime input from a JSON file | | `--concurrency ` | number | no | Max parallel steps (default: 1) | -| `--events ` | string | no | Emit lifecycle events: jsonl | +| `--events ` | string | no | Emit lifecycle events: jsonl | | `--timeout ` | number | no | Default step timeout in seconds | #### Examples diff --git a/skills/bailian-cli/reference/usage.md b/skills/bailian-cli/reference/usage.md index b5e0c2e..192ec88 100644 --- a/skills/bailian-cli/reference/usage.md +++ b/skills/bailian-cli/reference/usage.md @@ -29,7 +29,7 @@ Index: [index.md](index.md) | ------------------------------ | ------ | -------- | ------------------------------------------------------------------------- | | `--model ` | string | no | Model name(s) to query, comma-separated for multiple; omit for all models | | `--expiring ` | string | no | Only show quotas expiring within N days | -| `--sort ` | string | no | Sort by: remaining (ascending), expires (ascending) | +| `--sort ` | string | no | Sort by: remaining (ascending), expires (ascending) | | `--console-region ` | string | no | Console region | | `--console-site ` | string | no | Console site: domestic, international | | `--console-switch-agent ` | number | no | Switch agent UID | diff --git a/tools/generate-reference.ts b/tools/generate-reference.ts index 4b44f92..c7e8a4e 100644 --- a/tools/generate-reference.ts +++ b/tools/generate-reference.ts @@ -11,12 +11,8 @@ import { mkdirSync, readdirSync, rmSync, writeFileSync } from "node:fs"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; -import { - GLOBAL_FLAGS, - type AnyCommand, - type FlagDef, - type FlagsDef, -} from "../packages/core/dist/index.mjs"; +import { GLOBAL_FLAGS } from "../packages/core/dist/index.mjs"; +import type { AnyCommand, FlagDef, FlagsDef } from "../packages/core/src/index.ts"; import { commands } from "../packages/cli/src/commands.ts"; const __dirname = dirname(fileURLToPath(import.meta.url)); diff --git a/vite.config.ts b/vite.config.ts index 82982f6..ad25ebb 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -9,7 +9,18 @@ export default defineConfig({ staged: { "*.{js,mjs,cjs,ts,mts,cts,jsx,tsx,json,yaml,yml,md}": "vp check --fix", }, - lint: { options: { typeAware: true, typeCheck: true } }, + lint: { + options: { typeAware: true, typeCheck: true }, + // 命令只许抛错;进程退出统一收口到 runtime 的 handleError。 + rules: { "unicorn/no-process-exit": "error" }, + overrides: [ + { + // runtime 是统一出口层;tools/ 与测试是独立脚本入口,可直接退出。 + files: ["packages/runtime/src/**", "tools/**", "**/tests/**"], + rules: { "unicorn/no-process-exit": "off" }, + }, + ], + }, run: { cache: true, },