feat: 自建命令框架重构 + 合入 main 新功能#90
Open
XXPermanentXX wants to merge 23 commits into
Open
Conversation
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)
…tion 把 main 从一堆 if + process.exit 重构为「argv 解析成数据 → 交给统一管线执行」。 内核 - resolve(argv) → Resolution(version/help/run/usageError):路由即数据,dispatch 只 switch - compose 洋葱中间件 (versionCheck/telemetry/auth/runCommand),命令仍收 (config, flags) - registry.locate() 统一 leaf/group/unknown,取代 isGroupPath + 抛异常的 resolve - 删除 command-help.ts 全局可变单例:help 渲染收口到错误边界 错误模型 - 新增 UsageError(写错了 → exit 2) 与 IncompleteCommandError(没写完 → 打 help、exit 0) - version / help / onboarding / 组帮助统一由 resolve 产出、dispatch 分派 参数与校验 - parseFlags 重写:无 positional、新增 switch 类型、值/类型/重复校验 - 无条件必填 → 解析器声明式强制 (OptionDef.required) - 跨 flag / 条件约束 → 新增 command.validate(flags) 钩子 (text-chat / search-web / speech / vision / video-ref) - 移除全部交互式输入 (promptText/Select/Confirm),缺输入直接打 help 输出 - detectOutputFormat 默认 text,不再按 TTY 切 json 测试 - 删除 3 个 stale cli 测试,runtime 单测重写 (29 passed),e2e 适配新行为
…ws help - drop IncompleteCommandError: missing-required, failed validate, and bad/unknown flags are all UsageError now - error boundary keys on bareness — bare command that fails → help (exit 0); non-bare invalid → error + message (exit 2) - login: drop config.apiKey fallback, --api-key required-unless-console via validate - speech: drop empty --text-file guard (empty content is the API's concern)
Replace the positional `OptionDef[]` array (key/type regex-parsed from "--x <v>" strings) with a keyed `FlagsDef` record whose `type` drives both runtime parsing and compile-time flag-type inference (`Flags<typeof DEF>`). GLOBAL_FLAGS becomes the single source; the hand-kept GlobalFlags interface (types/flags.ts) is deleted. - core: SwitchFlag|ValueFlag union, ParsedFlags/Flags inference, defineCommand infers F from spec.flags - runtime: parseFlags dispatches on def.type (switch/string/number/boolean/ array/choices) with declarative required-flag enforcement - commands: migrate every flag declaration to the keyed form - naming: option→flag throughout (OptionDef→FlagDef, OptionsDef→FlagsDef, GLOBAL_OPTIONS→GLOBAL_FLAGS, command field options→flags), plus user-facing "Options:"→"Flags:" in help and the regenerated skill reference docs Behavior-preserving aside from the intentional Options→Flags wording: vp check clean across all packages, 29 parser tests pass, reference regen byte-identical before the terminology swap.
Move all credential handling out of commands into one place. authStage resolves the credential for the command's declared `auth` and bakes it into `ctx.client`, gating (throw) when missing; commands reach the network only through `ctx.client` and never touch tokens or baseUrl. - add Client (request/requestJson/uploadFile/mcp/console/url) wrapping the token + baseUrl; commands call it instead of self-resolving - run(config, flags) → run(ctx) + CommandContext; migrate all 45 commands - split domains: model = pure api-key (drop access-token fallback), console = config.json only (drop DASHSCOPE_ACCESS_TOKEN env) - consolidate env reads in loadConfig; CredentialSource = flag | env | config; priority flag > env > config - endpoints return paths (xxxPath) instead of full URLs; baseUrl owned by Client - auth status now uses describeAuth - video/download: auth "none" → "apiKey" (it needs the model API) - dedupe fetchModelList behind an injected console-call function - remove ensureApiKey/ensure-key.ts, prompt.ts + isInteractive, and the old resolveCredential/resolveConsoleGatewayCredential resolvers - tests: adapt auth.e2e to the new auth status shape; drop the DASHSCOPE_ACCESS_TOKEN branch from console-readiness gates
AK/SK signing was used only by `knowledge retrieve`'s deprecated fallback, which the api-key auth gate now makes unreachable. Drop it; the command is pure api-key. - knowledge/retrieve: remove the AK/SK path + --access-key-id/secret/workspace-id flags; api-key only - delete client/ak-sign.ts and its signRequest/AkSignConfig exports - drop access_key_id/access_key_secret from config schema, loader, and `config show` / `config set` - remove the now-unused PascalCase KnowledgeRetrieve request/response types
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
Missing required flags now throw UsageError (exit code 2, error on stderr, JSON under --output json) instead of printing help and exiting 0. Update assertions and titles accordingly: - missing-flag cases: exitCode 0/1 -> 2, retitle to "errors as usage error (2)" - auth / video-task-get under --output json: assert the error JSON on stderr - proxy probe: import setupProxyFromEnv from runtime/src/proxy.ts - drop tests for the removed config export-schema command - fix t2v dry-run: cliTimeoutPrefix misplaced between --model and its value
- drop the CI / non-TTY early-return so agents see "Update available" too - widen check interval 4h→24h; stay silent inside the window (no per-command repeat) - remove orphan isCI() helper (zero callers) - versioning.md: drop the now-false "banner suppressed under agent" rationale
…solved at the dispatch boundary - commands consume a narrowed context (identity/settings/own flags/client); config/auth commands additionally use configStore()/authStore() accessors - resolution happens once at dispatch: buildSources/buildSettings plus per-domain credential resolvers; dry-run tolerates missing credentials - transport takes structured deps; credentials are injected only by Client; console gateway takes a resolved target with optional token (anonymous catalog calls); pipeline steps and advisor run against client/settings - telemetry receives authMethod as a value; global/command flags are split at dispatch with a same-type shadowing guard at registry build - behavior change: base URL resolution now prefers DASHSCOPE_BASE_URL env over config file base_url (unified flag > env > file > default chain) - priority chains, store semantics and command capability boundaries are locked by unit tests
- flags split into GLOBAL_FLAGS (all commands) plus MODEL_AUTH_FLAGS / CONSOLE_AUTH_FLAGS, parsed only for commands of the matching auth domain; cross-domain flags now fail with "Unknown flag" instead of being silently ignored - all shadow redeclarations removed; the registry guard now rejects any own flag named after a reserved (global or visible-domain) flag - --workspace-id joins the console domain (chain: flag > env > file); usage stats drops its private declaration and in-command priority - auth login declares its credential args as own command parameters (--api-key / --base-url / --console-site, original behavior intact); auth status no longer accepts credential-domain overrides (use env or config set instead) - command help and the generated reference both show Flags (own + auth domain) plus a full Global Flags section, replacing the footer hint - breaking: pipeline run --timeout renamed to --step-timeout (collided with the global request timeout)
- remove nonInteractive plus yes/async/concurrent from GLOBAL_FLAGS and Settings; command dispatch no longer resolves command-only switches into global settings - add shared ASYNC_FLAG / CONCURRENT_FLAG definitions for commands that actually support task-only return or parallel requests - keep quota downgrade protection by moving --yes onto quota request and reading flags.yes for confirmed downgrade submission - update existing async/concurrent consumers to read own flags; no new capability matrix entries are added - refresh generated command reference and remove stale --non-interactive usage from e2e/stress invocations
- scope image/video task execution to --async and --concurrent - add concurrent task fan-out for video edit and video ref - extend image edit to the async image task path - refresh e2e coverage and generated command references
- remove --no-color from GLOBAL_FLAGS and drop Settings.noColor - move ANSI styling decisions into runtime color helpers with NO_COLOR support - update command text renderers to use shared color helpers instead of local ANSI codes - refresh e2e invocations, generated reference, and agent skill guidance
- add openapi auth requirement with command-scoped access key flags and paired credential resolution - persist OpenAPI credentials through auth login/status/logout using access_key_* config fields - route token-plan commands through the centralized ACS signing client - keep legacy openapi_access_key_* config readable while rejecting it as a new config set key - refresh docs, generated references, telemetry authMethod, and e2e coverage
- render auth flag sections only for auth domains used by registered commands - make quick-start prompts opt-in through createCli options - keep the existing quick-start prompts wired only for bl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
将 CLI 从旧命令框架重构为自建框架,并把
main上按旧框架新增的功能全部迁移过来。分支拆成core / runtime / commands / cli / kscli五个包,命令与框架解耦。架构改动
bare command显示帮助Config拆成Identity / Settings / Credential,在 dispatch 边界一次解析;鉴权集中到authStage + Client,命令必须声明auth: "apiKey" | "console" | "none"run(config, flags)→run(ctx);options: []数组 → keyed 类型推导的FlagsDef;yes / async / concurrent / 凭证flag 按命令归属UsageError,所有退出集中到 runtime 的handleError--no-color(改走NO_COLOR)合入 main 的新功能(已迁移到新框架)
packages/rag→packages/kscli更名 + 独立发布--output时默认人读文本(不再按 TTY 自动 json)。脚本/agent 需显式--output json--yes:dataset delete、finetune create/cancel/delete、deploy create/delete/scale/update 不再交互确认,缺--yes直接 exit 2deploy models --version→--catalog-version;finetune watch --timeout→--poll-timeoutadvisor recommend:移除位置参数与交互追问,--message必填(默认仍出 json)--output rich/--no-color/--non-interactive移除;DASHSCOPE_ACCESS_TOKEN不再用于 console 凭证验证
vp check(格式 + lint + 类型)、build、单测全绿--help/--dry-run/ 本地校验冒烟通过建议 reviewer 重点回归
--yes门)