diff --git a/packages/cli/src/main.ts b/packages/cli/src/main.ts index 0968516..6377b94 100644 --- a/packages/cli/src/main.ts +++ b/packages/cli/src/main.ts @@ -2,9 +2,17 @@ import { createCli } from "bailian-cli-runtime"; import { commands } from "./commands.ts"; import pkg from "../package.json" with { type: "json" }; +const quickStartTasks = [ + "Help me generate a set of Amazon e-commerce main images for baseball caps (white background + lifestyle shots + model wear shots)", + "Help me generate a 3-minute humorous crosstalk audio clip", + "Help me generate a Little Red Riding Hood picture-book PDF (with illustrations)", + "Help me analyze this video and write a Xiaohongshu-style post", +] as const; + void createCli(commands, { binName: "bl", version: pkg.version, clientName: "bailian-cli", npmPackage: "bailian-cli", + quickStartTasks, }).run(); diff --git a/packages/runtime/src/create-cli.ts b/packages/runtime/src/create-cli.ts index e1a8d2d..986a30c 100644 --- a/packages/runtime/src/create-cli.ts +++ b/packages/runtime/src/create-cli.ts @@ -40,6 +40,8 @@ export interface CliOptions { clientName: string; /** npm package name for self-update (e.g. "bailian-cli", "bailian-cli-rag"). */ npmPackage: string; + /** Root-help suggestions shown after credentials are configured. */ + quickStartTasks?: readonly string[]; } export interface Cli { @@ -112,8 +114,11 @@ export function createCli(commands: Record, opts: CliOptions } catch { /* unparseable global flags on the bare invocation — fall through to welcome */ } - if (hasKey) printQuickStart(); - else printWelcomeBanner(binName); + if (hasKey) { + if (opts.quickStartTasks?.length) printQuickStart(opts.quickStartTasks); + } else { + printWelcomeBanner(binName); + } } async function dispatch(argv: string[]): Promise { diff --git a/packages/runtime/src/output/banner.ts b/packages/runtime/src/output/banner.ts index ebb8090..44ebce0 100644 --- a/packages/runtime/src/output/banner.ts +++ b/packages/runtime/src/output/banner.ts @@ -1,13 +1,6 @@ import { API_KEY_PAGE } from "../urls.ts"; import { ansi } from "./color.ts"; -const QUICK_START_TASKS = [ - "Help me generate a set of Amazon e-commerce main images for baseball caps (white background + lifestyle shots + model wear shots)", - "Help me generate a 3-minute humorous crosstalk audio clip", - "Help me generate a Little Red Riding Hood picture-book PDF (with illustrations)", - "Help me analyze this video and write a Xiaohongshu-style post", -]; - export function printWelcomeBanner(cliName: string): void { const color = ansi(process.stderr); process.stderr.write(`\n Welcome to ${color.purple("Bailian")} CLI!\n\n`); @@ -16,10 +9,10 @@ export function printWelcomeBanner(cliName: string): void { process.stderr.write(` 2. Login: ${cliName} auth login --api-key \n\n`); } -export function printQuickStart(): void { +export function printQuickStart(tasks: readonly string[]): void { const color = ansi(process.stderr); process.stderr.write("\nšŸŽÆ Try these with your AI coding assistant:\n\n"); - QUICK_START_TASKS.forEach((task, i) => { + tasks.forEach((task, i) => { process.stderr.write(`${color.dim(String(i + 1))} ${task}\n`); }); process.stderr.write("\n"); diff --git a/packages/runtime/src/registry.ts b/packages/runtime/src/registry.ts index 636ee97..22ebd98 100644 --- a/packages/runtime/src/registry.ts +++ b/packages/runtime/src/registry.ts @@ -1,4 +1,4 @@ -import type { AnyCommand, FlagDef } from "bailian-cli-core"; +import type { AnyCommand, AuthRequirement, FlagDef, FlagsDef } from "bailian-cli-core"; import { UsageError } from "bailian-cli-core"; import { CONSOLE_AUTH_FLAGS, @@ -42,6 +42,7 @@ export class CommandRegistry { private root: CommandNode = { children: new Map() }; /** Binary name shown in usage/help/error strings (e.g. "bl", "rag"). */ private readonly cliName: string; + private readonly authRequirements = new Set(); constructor(commands: Record, cliName: string) { this.cliName = cliName; @@ -67,6 +68,7 @@ export class CommandRegistry { node = node.children.get(part)!; } node.command = command; + this.authRequirements.add(command.auth); } getAllCommands(): AnyCommand[] { @@ -176,7 +178,7 @@ export class CommandRegistry { } private buildFlagLines( - defs: Record, + defs: FlagsDef, a: (s: string) => string, d: (s: string) => string, ): string { @@ -188,6 +190,19 @@ export class CommandRegistry { return lines.map((l) => ` ${a(l.flag.padEnd(maxLen + 2))} ${d(l.desc)}`).join("\n"); } + private buildAuthFlagSection( + auth: AuthRequirement, + label: string, + scope: string, + defs: FlagsDef, + b: (s: string) => string, + a: (s: string) => string, + d: (s: string) => string, + ): string | null { + if (!this.authRequirements.has(auth)) return null; + return `${b(label)} ${d(scope)}\n${this.buildFlagLines(defs, a, d)}`; + } + // Color helpers — no-ops when output is not a TTY. private bold = (s: string, out: NodeJS.WriteStream) => ansi(out).bold(s); private accent = (s: string, out: NodeJS.WriteStream) => ansi(out).accent(s); @@ -268,9 +283,37 @@ ${d(` ${this.cliName} pipeline run workflow.yaml --dry-run --output json`)} const commandLines = this.buildResourceLines(a, d); const globalFlagLines = this.buildFlagLines(GLOBAL_FLAGS, a, d); - const modelFlagLines = this.buildFlagLines(MODEL_AUTH_FLAGS, a, d); - const consoleFlagLines = this.buildFlagLines(CONSOLE_AUTH_FLAGS, a, d); - const openapiFlagLines = this.buildFlagLines(OPENAPI_AUTH_FLAGS, a, d); + const authFlagSections = [ + this.buildAuthFlagSection( + "apiKey", + "Model Auth Flags:", + "(model-domain commands)", + MODEL_AUTH_FLAGS, + b, + a, + d, + ), + this.buildAuthFlagSection( + "console", + "Console Auth Flags:", + "(console-domain commands)", + CONSOLE_AUTH_FLAGS, + b, + a, + d, + ), + this.buildAuthFlagSection( + "openapi", + "OpenAPI Auth Flags:", + "(openapi-domain commands)", + OPENAPI_AUTH_FLAGS, + b, + a, + d, + ), + ] + .filter((section): section is string => section !== null) + .join("\n\n"); out.write(` ${b("Usage:")} ${this.cliName} [flags] @@ -281,16 +324,7 @@ ${commandLines} ${b("Global Flags:")} ${globalFlagLines} -${b("Model Auth Flags:")} ${d("(model-domain commands)")} -${modelFlagLines} - -${b("Console Auth Flags:")} ${d("(console-domain commands)")} -${consoleFlagLines} - -${b("OpenAPI Auth Flags:")} ${d("(openapi-domain commands)")} -${openapiFlagLines} - -${b("Getting Help:")} +${authFlagSections ? `${authFlagSections}\n\n` : ""}${b("Getting Help:")} ${d("Add --help after any command to see its full list of flags, defaults,")} ${d("and usage examples. For example:")} ${this.cliName} ${this.helpExample()} --help `);