mirror of
https://github.com/modelstudioai/cli.git
synced 2026-09-14 19:49:23 +08:00
refactor(core): replace skipDefaultApiKeySetup with required auth field
Commands now declare their credential requirement explicitly via a required `auth: "apiKey" | "console" | "none"` field instead of the boolean `skipDefaultApiKeySetup`. The runtime prepares credentials based on this declaration and skips API-key setup under --dry-run. - core: add AuthRequirement type and required `auth` field to Command/CommandSpec; drop skipDefaultApiKeySetup - runtime: gate API-key setup on `auth === "apiKey" && !dryRun` - commands: annotate all 45 commands (apiKey 25 / console 11 / none 9)
This commit is contained in:
@@ -217,6 +217,7 @@ function isEmptyResult(result: RecommendResult): boolean {
|
||||
export default defineCommand({
|
||||
description:
|
||||
"Recommend the best models for your use case (intent analysis → candidate recall → LLM ranking)",
|
||||
auth: "apiKey",
|
||||
usageArgs: "<prompt> [flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ import { emitResult, emitBare } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Call a Bailian application (agent or workflow)",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--app-id <id> --prompt <text> [flags]",
|
||||
options: [
|
||||
{ flag: "--app-id <id>", description: "Application ID (required)", required: true },
|
||||
|
||||
@@ -12,7 +12,7 @@ const APP_LIST_API = "zeldaEasy.broadscope-bailian.app-control.list";
|
||||
|
||||
export default defineCommand({
|
||||
description: "List Bailian applications",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "console",
|
||||
usageArgs: "[flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
|
||||
export default defineCommand({
|
||||
description: "Authenticate with API key or console browser login (credentials can coexist)",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "none",
|
||||
usageArgs: "--api-key <key> | --console",
|
||||
options: [
|
||||
{ flag: "--api-key <key>", description: "DashScope API key to store" },
|
||||
|
||||
@@ -19,7 +19,7 @@ async function clearConsoleToken(): Promise<boolean> {
|
||||
|
||||
export default defineCommand({
|
||||
description: "Clear stored credentials",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "none",
|
||||
usageArgs: "[--console] [--yes] [--dry-run]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -140,6 +140,7 @@ function emitTextStatus(status: AuthStatusPayload, config: Config): void {
|
||||
|
||||
export default defineCommand({
|
||||
description: "Show current authentication state",
|
||||
auth: "none",
|
||||
options: [
|
||||
{ flag: "--console-region <region>", description: "Console region" },
|
||||
{
|
||||
|
||||
@@ -51,7 +51,7 @@ const KEY_ALIASES: Record<string, string> = {
|
||||
|
||||
export default defineCommand({
|
||||
description: "Set a config value",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "none",
|
||||
usageArgs: "--key <key> --value <value>",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ import { emitResult } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Display current configuration",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "none",
|
||||
exampleArgs: ["", "--output json"],
|
||||
async run(config: Config, _flags: GlobalFlags) {
|
||||
const file = loadConfigFile();
|
||||
|
||||
@@ -14,7 +14,7 @@ import { emitResult } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Call a Bailian console API via the CLI gateway",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "console",
|
||||
usageArgs: "--api <api> --data <json> [flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@ import { emitResult, emitBare } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Upload a local file to DashScope temporary storage (48h)",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--file <path> --model <model>",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -28,6 +28,7 @@ import { BOOL_FLAG_PROMPT_EXTEND_CLI_TRUE, BOOL_FLAG_WATERMARK } from "bailian-c
|
||||
|
||||
export default defineCommand({
|
||||
description: "Edit an existing image with text instructions (Qwen-Image)",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--image <url> --prompt <text> [flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -39,6 +39,7 @@ function isSyncModel(model: string): boolean {
|
||||
|
||||
export default defineCommand({
|
||||
description: "Generate images (Qwen-Image / wan2.x)",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--prompt <text> [flags]",
|
||||
options: [
|
||||
{ flag: "--prompt <text>", description: "Image description", required: true },
|
||||
|
||||
@@ -24,7 +24,7 @@ const BAILIAN_HOST = "bailian.cn-beijing.aliyuncs.com";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Retrieve from a Bailian knowledge base",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "apiKey",
|
||||
usageArgs: "--index-id <id> --query <text> [flags]",
|
||||
options: [
|
||||
{ flag: "--index-id <id>", description: "Knowledge base index ID (required)", required: true },
|
||||
|
||||
@@ -31,7 +31,7 @@ function parseArgFlags(raw: string[]): Record<string, unknown> {
|
||||
|
||||
export default defineCommand({
|
||||
description: "Call a tool on an MCP server (tools/call)",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "apiKey",
|
||||
usageArgs: "<server-code>.<tool> [--arg k=v ...] [--json '{...}'] [--url <url>]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@ interface ServerSummary {
|
||||
|
||||
export default defineCommand({
|
||||
description: "List MCP servers activated under your Bailian account",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "console",
|
||||
usageArgs: "[flags]",
|
||||
options: [
|
||||
{ flag: "--name <text>", description: "Filter by server name (substring match)" },
|
||||
|
||||
@@ -12,7 +12,7 @@ import { ensureApiKey } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "List tools exposed by an MCP server (tools/list)",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "apiKey",
|
||||
usageArgs: "<server-code> [--url <url>]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@ import { emitResult, emitBare } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Add memory from messages or custom content",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--user-id <id> [--messages <json>] [--content <text>] [flags]",
|
||||
options: [
|
||||
{ flag: "--user-id <id>", description: "User ID (required)", required: true },
|
||||
|
||||
@@ -11,6 +11,7 @@ import { emitResult, emitBare } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Delete a memory node",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--node-id <id> --user-id <id>",
|
||||
options: [
|
||||
{ flag: "--node-id <id>", description: "Memory node ID (required)", required: true },
|
||||
|
||||
@@ -12,6 +12,7 @@ import { emitResult, emitBare } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "List memory nodes for a user",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--user-id <id> [flags]",
|
||||
options: [
|
||||
{ flag: "--user-id <id>", description: "User ID (required)", required: true },
|
||||
|
||||
@@ -13,6 +13,7 @@ import { emitResult, emitBare } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Create a user profile schema for memory profiling",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--name <name> --attributes <json> [flags]",
|
||||
options: [
|
||||
{ flag: "--name <name>", description: "Schema name (required)", required: true },
|
||||
|
||||
@@ -12,6 +12,7 @@ import { emitResult, emitBare } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Get user profile by schema ID and user ID",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--schema-id <id> --user-id <id>",
|
||||
options: [
|
||||
{ flag: "--schema-id <id>", description: "Profile schema ID (required)", required: true },
|
||||
|
||||
@@ -13,6 +13,7 @@ import { emitResult, emitBare } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Search memory nodes by query or messages",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--user-id <id> [--query <text>] [flags]",
|
||||
options: [
|
||||
{ flag: "--user-id <id>", description: "User ID (required)", required: true },
|
||||
|
||||
@@ -12,6 +12,7 @@ import { emitResult, emitBare } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Update a memory node content",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--node-id <id> --user-id <id> --content <text>",
|
||||
options: [
|
||||
{ flag: "--node-id <id>", description: "Memory node ID (required)", required: true },
|
||||
|
||||
@@ -86,6 +86,7 @@ function buildWavHeader(dataLength: number): Buffer {
|
||||
|
||||
export default defineCommand({
|
||||
description: "Multimodal chat with text + audio output (Qwen-Omni)",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--message <text> [flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@ import { loadPipelineFile } from "./load-file.ts";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Run a pipeline workflow definition",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "none",
|
||||
usageArgs: "<file> [flags]",
|
||||
options: [
|
||||
{ flag: "--input <json>", description: "Runtime input as inline JSON" },
|
||||
|
||||
@@ -7,7 +7,7 @@ import { loadPipelineFile } from "./load-file.ts";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Validate a pipeline definition without executing",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "none",
|
||||
usageArgs: "<file>",
|
||||
options: [],
|
||||
exampleArgs: ["workflow.yaml", "workflow.json --output json"],
|
||||
|
||||
@@ -236,7 +236,7 @@ function printTable(rows: CheckRow[], noColor: boolean): void {
|
||||
|
||||
export default defineCommand({
|
||||
description: "Check current usage against rate limits",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "console",
|
||||
usageArgs: "[--model <model>] [flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -92,7 +92,7 @@ function printTable(records: LimitApplicationItem[], noColor: boolean, total: nu
|
||||
|
||||
export default defineCommand({
|
||||
description: "View quota change history",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "console",
|
||||
usageArgs: "[flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -151,7 +151,7 @@ function printTable(models: ModelWithQpm[], noColor: boolean): void {
|
||||
|
||||
export default defineCommand({
|
||||
description: "View model RPM/TPM rate limits",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "console",
|
||||
usageArgs: "[--model <model>] [flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -79,7 +79,7 @@ async function fetchModelQpmInfo(
|
||||
|
||||
export default defineCommand({
|
||||
description: "Request a temporary quota increase",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "console",
|
||||
usageArgs: "--model <model> --tpm <value> [flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@ import { emitResult } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Search the web using DashScope MCP WebSearch service",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--query <text> [flags]",
|
||||
options: [
|
||||
{ flag: "--query <text>", description: "Search query text", required: true },
|
||||
|
||||
@@ -24,6 +24,7 @@ import { emitResult, emitBare } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Recognize speech from audio files (FunAudio-ASR)",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--url <audio-url> [flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -143,6 +143,7 @@ function printVoiceList(model: string): void {
|
||||
|
||||
export default defineCommand({
|
||||
description: "Synthesize speech from text (CosyVoice TTS)",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--text <text> [flags]",
|
||||
options: [
|
||||
{ flag: "--text <text>", description: "Text to synthesize into speech", required: true },
|
||||
|
||||
@@ -69,6 +69,7 @@ function parseMessages(flags: GlobalFlags): ParsedMessages {
|
||||
|
||||
export default defineCommand({
|
||||
description: "Send a chat completion (OpenAI compatible, DashScope)",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--message <text> [flags]",
|
||||
options: [
|
||||
{ flag: "--model <model>", description: "Model ID (default: qwen3.7-max)" },
|
||||
|
||||
@@ -29,7 +29,7 @@ function updateAgentSkill(colors: { green: string; yellow: string; reset: string
|
||||
|
||||
export default defineCommand({
|
||||
description: "Update the CLI to the latest version",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "none",
|
||||
exampleArgs: [""],
|
||||
async run(config) {
|
||||
const npmPackage = config.npmPackage!;
|
||||
|
||||
@@ -185,7 +185,7 @@ async function fetchAllModels(config: Config, token: string): Promise<ModelInfo[
|
||||
|
||||
export default defineCommand({
|
||||
description: "Query free-tier quota for models (all models if --model is omitted)",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "console",
|
||||
usageArgs: "[--model <model>[,model2,...]] [flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -102,7 +102,7 @@ async function fetchAllModelNames(config: Config, token: string): Promise<string
|
||||
export default defineCommand({
|
||||
description:
|
||||
"Enable or disable auto-stop for free-tier models. Enables by default; use --off to disable",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "console",
|
||||
usageArgs: "<--model <model>[,model2,...] | --all> [--off] [flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -286,7 +286,7 @@ function printModelTable(
|
||||
|
||||
export default defineCommand({
|
||||
description: "Query model usage statistics",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "console",
|
||||
usageArgs: "[--model <model>] [--days <days>] [flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@ import { emitResult, emitBare } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Download a completed video by task ID",
|
||||
auth: "none",
|
||||
usageArgs: "--task-id <id> --out <path>",
|
||||
options: [
|
||||
{ flag: "--task-id <id>", description: "Task ID to download from" },
|
||||
|
||||
@@ -27,6 +27,7 @@ import { BOOL_FLAG_PROMPT_EXTEND_API_DEFAULT, BOOL_FLAG_WATERMARK } from "bailia
|
||||
export default defineCommand({
|
||||
description:
|
||||
"Edit a video with happyhorse-1.0-video-edit (style transfer, object replacement, etc.)",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--video <url> --prompt <text> [flags]",
|
||||
options: [
|
||||
{ flag: "--model <model>", description: "Model ID (default: happyhorse-1.0-video-edit)" },
|
||||
|
||||
@@ -28,6 +28,7 @@ import { BOOL_FLAG_PROMPT_EXTEND_API_DEFAULT, BOOL_FLAG_WATERMARK } from "bailia
|
||||
export default defineCommand({
|
||||
description:
|
||||
"Generate a video from text or image (happyhorse-1.0-t2v / happyhorse-1.0-i2v / wan2.6-t2v)",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--prompt <text> [--image <url>] [flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@ import { BOOL_FLAG_PROMPT_EXTEND_API_DEFAULT, BOOL_FLAG_WATERMARK } from "bailia
|
||||
export default defineCommand({
|
||||
description:
|
||||
"Reference-to-video generation (happyhorse-1.0-r2v / wan2.6-r2v): multi-subject, multi-shot with voice",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--prompt <text> --image <url>... [--ref-video <url>...] [flags]",
|
||||
options: [
|
||||
{ flag: "--model <model>", description: "Model ID (default: happyhorse-1.0-r2v)" },
|
||||
|
||||
@@ -12,6 +12,7 @@ import { emitResult, emitBare } from "bailian-cli-runtime";
|
||||
|
||||
export default defineCommand({
|
||||
description: "Query async task status",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--task-id <id>",
|
||||
options: [{ flag: "--task-id <id>", description: "Async task ID" }],
|
||||
exampleArgs: [
|
||||
|
||||
@@ -58,6 +58,7 @@ async function toImageUrl(image: string): Promise<string> {
|
||||
|
||||
export default defineCommand({
|
||||
description: "Describe an image or video using Qwen-VL",
|
||||
auth: "apiKey",
|
||||
usageArgs: "--image <path-or-url> [--video <url>] [--prompt <text>]",
|
||||
options: [
|
||||
{ flag: "--image <path-or-url>", description: "Local image path or URL" },
|
||||
|
||||
@@ -77,7 +77,7 @@ function printTable(workspaces: WorkspaceInfo[], noColor: boolean): void {
|
||||
|
||||
export default defineCommand({
|
||||
description: "List all workspaces",
|
||||
skipDefaultApiKeySetup: true,
|
||||
auth: "console",
|
||||
usageArgs: "[flags]",
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -8,6 +8,15 @@ export interface OptionDef {
|
||||
required?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Credential a command requires. The runtime prepares it before execution.
|
||||
* - "apiKey" : DashScope API Key. The runtime runs ensureApiKey beforehand,
|
||||
* except under --dry-run (which only prints the request).
|
||||
* - "console" : Console Gateway credential (usage / quota / app list / workspace, …).
|
||||
* - "none" : No credential (config / auth login flow / pipeline validate / update, …).
|
||||
*/
|
||||
export type AuthRequirement = "apiKey" | "console" | "none";
|
||||
|
||||
export interface Command {
|
||||
description: string;
|
||||
/**
|
||||
@@ -24,7 +33,8 @@ export interface Command {
|
||||
* `<bin> <path>` per product when rendering help.
|
||||
*/
|
||||
exampleArgs?: string[];
|
||||
skipDefaultApiKeySetup?: boolean;
|
||||
/** Credential this command requires. See {@link AuthRequirement}. */
|
||||
auth: AuthRequirement;
|
||||
notes?: string[];
|
||||
execute: (config: Config, flags: GlobalFlags) => Promise<void>;
|
||||
}
|
||||
@@ -36,7 +46,8 @@ export interface CommandSpec {
|
||||
options?: OptionDef[];
|
||||
/** See {@link Command.exampleArgs} — argument strings only, no `<bin> <path>` prefix. */
|
||||
exampleArgs?: string[];
|
||||
skipDefaultApiKeySetup?: boolean;
|
||||
/** Credential this command requires. See {@link AuthRequirement}. */
|
||||
auth: AuthRequirement;
|
||||
notes?: string[];
|
||||
run: (config: Config, flags: GlobalFlags) => Promise<void>;
|
||||
}
|
||||
@@ -47,7 +58,7 @@ export function defineCommand(spec: CommandSpec): Command {
|
||||
usageArgs: spec.usageArgs,
|
||||
options: spec.options,
|
||||
exampleArgs: spec.exampleArgs,
|
||||
skipDefaultApiKeySetup: spec.skipDefaultApiKeySetup,
|
||||
auth: spec.auth,
|
||||
notes: spec.notes,
|
||||
execute: (config, flags) => spec.run(config, flags),
|
||||
};
|
||||
|
||||
@@ -123,8 +123,9 @@ export function createCli(commands: Record<string, Command>, opts: CliOptions):
|
||||
config.binName = opts.binName;
|
||||
config.npmPackage = npmPackage;
|
||||
|
||||
// 默认执行 ensureApiKey;自行处理鉴权或仅需 Console/AK-SK 等的命令在 defineCommand 上设 skipDefaultApiKeySetup
|
||||
if (!command.skipDefaultApiKeySetup) {
|
||||
// 仅 apiKey 类命令由框架统一准备 API Key;dry-run 时跳过(只打印请求,不要求凭证)。
|
||||
// console 命令在命令体内解析 Console Gateway 凭证;none 命令无需凭证。
|
||||
if (command.auth === "apiKey" && !config.dryRun) {
|
||||
await ensureApiKey(config);
|
||||
try {
|
||||
const credential = await resolveCredential(config);
|
||||
|
||||
Reference in New Issue
Block a user