Skip to content

Commit 468b4d7

Browse files
committed
refactor(flags): scope yes/async/concurrent to command-owned flags
- 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
1 parent deab3b3 commit 468b4d7

63 files changed

Lines changed: 106 additions & 323 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/agents/cli-e2e-tests.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe.skipIf(<ready>)("e2e: <topic>(DashScope …)", () => {
4646

4747
1. **分组 help**`runCli(["image"])``exitCode === 0`,stdout+stderr 含子命令名
4848
2. **--help**`runCli([..., "--help"])` → stderr 含主要 flags
49-
3. **缺参**`--non-interactive` 且不传 required flag → `exitCode === 2`,stderr 匹配 `--flag|Missing required argument`
49+
3. **缺参**带一个无害全局 flag(如 `--quiet`且不传 required flag → `exitCode === 2`,stderr 匹配 `--flag|Missing required argument`
5050
4. **--dry-run**:仅当实现在联网/上传/写盘**之前**返回;断言 stdout JSON/文本,不入网
5151
5. **真实集成**:保留既有用例名称与断言;放在 skip 块**末尾**
5252

@@ -70,7 +70,7 @@ describe.skipIf(<ready>)("e2e: <topic>(DashScope …)", () => {
7070

7171
```ts
7272
test("foo bar 缺少 --prompt 时退出为用法错误 (2)", async () => {
73-
const { stderr, exitCode } = await runCli(["foo", "bar", "--non-interactive"]);
73+
const { stderr, exitCode } = await runCli(["foo", "bar", "--quiet"]);
7474
expect(exitCode).toBe(2);
7575
expect(stderr).toMatch(/--prompt|Missing required argument/i);
7676
});
@@ -82,7 +82,6 @@ test("foo bar --dry-run 仅输出计划", async () => {
8282
"--dry-run",
8383
"--prompt",
8484
"x",
85-
"--non-interactive",
8685
"--output",
8786
"json",
8887
]);

docs/agents/error-hint-change.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,10 @@ process.exit(err.exitCode)
104104

105105
```sh
106106
# 触发对应错误,看 text 输出
107-
HOME=/tmp/empty node packages/cli/src/main.ts text chat --message "x" --non-interactive
107+
HOME=/tmp/empty node packages/cli/src/main.ts text chat --message "x"
108108

109109
# 看 JSON 输出(应包含 cause 字段当 cause 存在时)
110-
HOME=/tmp/empty node packages/cli/src/main.ts text chat --message "x" --non-interactive --output json
110+
HOME=/tmp/empty node packages/cli/src/main.ts text chat --message "x" --output json
111111

112112
# 模拟网络层错误,验证 errno 透传
113113
DASHSCOPE_BASE_URL=https://nonexistent-host.invalid \

docs/agents/stress-batch-tests.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ pnpm run test:stress -- video-edit --reuse-fixtures -- --count 3
121121

122122
### 必须带的 CLI 参数(通用)
123123

124-
- `--non-interactive`
125124
-`speech recognize` 外,压测子进程宜带 `--output json`(语音识别以 `--out` 文件为准 stdout 可能为纯文本)
126125
- 异步类命令带 `--timeout`、对应 `--poll-interval`
127126

docs/agents/url-change.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ grep -rnE "https://dashscope[a-z-]*\.aliyuncs\.com" packages/ --include="*.ts" \
5959

6060
```sh
6161
# 验证错误 hint 不再泄漏旧 URL
62-
HOME=/tmp/empty node packages/cli/src/main.ts text chat --message x --non-interactive
62+
HOME=/tmp/empty node packages/cli/src/main.ts text chat --message x
6363
# 看输出的 Get API Key URL 是否走新值
6464

6565
# 验证 banner / help

packages/cli/tests/e2e/advisor-recommend.e2e.test.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,7 @@ describe("e2e: advisor recommend", () => {
1717

1818
describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend (DashScope)", () => {
1919
test("advisor recommend without --message errors as usage error (2)", async () => {
20-
const { stdout, stderr, exitCode } = await runCli([
21-
"advisor",
22-
"recommend",
23-
"--non-interactive",
24-
]);
20+
const { stdout, stderr, exitCode } = await runCli(["advisor", "recommend", "--quiet"]);
2521
expect(exitCode).toBe(2);
2622
expect(`${stdout}\n${stderr}`).toMatch(/--message|Usage:/i);
2723
});
@@ -33,7 +29,6 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend (DashScope)", ()
3329
"--dry-run",
3430
"--message",
3531
"I want to build a customer service bot that understands images",
36-
"--non-interactive",
3732
"--output",
3833
"json",
3934
]);
@@ -58,7 +53,6 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend (DashScope)", ()
5853
"recommend",
5954
"--message",
6055
"low-cost high-concurrency online customer service",
61-
"--non-interactive",
6256
"--output",
6357
"json",
6458
]);
@@ -90,7 +84,6 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend (DashScope)", ()
9084
"--dry-run",
9185
"--message",
9286
"Which model in the deepseek family is best for fast reasoning?",
93-
"--non-interactive",
9487
"--output",
9588
"json",
9689
]);
@@ -114,7 +107,6 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend (DashScope)", ()
114107
"--dry-run",
115108
"--message",
116109
"Which is better for code generation, qwen-max or deepseek-v3?",
117-
"--non-interactive",
118110
"--output",
119111
"json",
120112
]);
@@ -133,7 +125,6 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend (DashScope)", ()
133125
"--dry-run",
134126
"--message",
135127
"Not qwen, recommend a model suitable for text generation",
136-
"--non-interactive",
137128
"--output",
138129
"json",
139130
]);
@@ -160,7 +151,6 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend (DashScope)", ()
160151
"--dry-run",
161152
"--message",
162153
"I want to build a customer service bot that understands images",
163-
"--non-interactive",
164154
"--output",
165155
"json",
166156
]);

packages/cli/tests/e2e/auth.e2e.test.ts

Lines changed: 5 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ describe("e2e: auth", () => {
3333
});
3434

3535
test("auth login 缺少 --api-key 时报用法错误并退出 (2)", async () => {
36-
const { stderr, exitCode } = await runCli(["auth", "login", "--non-interactive"]);
36+
const { stderr, exitCode } = await runCli(["auth", "login", "--quiet"]);
3737
expect(exitCode, stderr).toBe(2);
3838
expect(stderr).toMatch(/--api-key|Usage:/i);
3939
});
@@ -45,7 +45,6 @@ describe("e2e: auth", () => {
4545
"--dry-run",
4646
"--api-key",
4747
"sk-e2e-dry-run-placeholder",
48-
"--non-interactive",
4948
]);
5049
expect(exitCode, stderr).toBe(0);
5150
expect(stdout).toContain("Would validate and save API key.");
@@ -58,7 +57,6 @@ describe("e2e: auth", () => {
5857
"--dry-run",
5958
"--api-key",
6059
"sk-e2e-dry-run-placeholder",
61-
"--non-interactive",
6260
"--output",
6361
"json",
6462
"--timeout",
@@ -70,13 +68,7 @@ describe("e2e: auth", () => {
7068
});
7169

7270
test("auth login 缺少密钥且 --output json 时报用法错误并退出 (2)", async () => {
73-
const { stderr, exitCode } = await runCli([
74-
"auth",
75-
"login",
76-
"--non-interactive",
77-
"--output",
78-
"json",
79-
]);
71+
const { stderr, exitCode } = await runCli(["auth", "login", "--output", "json"]);
8072
expect(exitCode).toBe(2);
8173
const err = JSON.parse(stderr.trim()) as { error?: { code?: number; message?: string } };
8274
expect(err.error?.code).toBe(2);
@@ -90,19 +82,6 @@ describe("e2e: auth", () => {
9082
expect(stderr).not.toContain("Cleared api_key");
9183
});
9284

93-
test("auth logout --dry-run --yes --non-interactive", async () => {
94-
const { stdout, stderr, exitCode } = await runCli([
95-
"auth",
96-
"logout",
97-
"--dry-run",
98-
"--yes",
99-
"--non-interactive",
100-
]);
101-
expect(exitCode, stderr).toBe(0);
102-
expect(stdout).toContain("No changes made.");
103-
expect(stderr).not.toContain("Cleared api_key");
104-
});
105-
10685
test("auth logout --dry-run --quiet --no-color", async () => {
10786
const { stdout, stderr, exitCode } = await runCli([
10887
"auth",
@@ -122,35 +101,22 @@ describe("e2e: auth", () => {
122101
"--dry-run",
123102
"--output",
124103
"json",
125-
"--non-interactive",
126104
]);
127105
expect(exitCode, stderr).toBe(0);
128106
expect(stdout).toContain("No changes made.");
129107
expect(stderr).not.toContain("Cleared api_key");
130108
});
131109

132110
test.skipIf(!isDashScopeE2EReady())("auth status 文本输出", async () => {
133-
const { stdout, stderr, exitCode } = await runCli([
134-
"auth",
135-
"status",
136-
"--non-interactive",
137-
"--output",
138-
"text",
139-
]);
111+
const { stdout, stderr, exitCode } = await runCli(["auth", "status", "--output", "text"]);
140112
expect(exitCode, stderr).toBe(0);
141113
expect(stdout).toMatch(
142114
/Authentication Status|API key:|Console token:|DashScope API:|Console gateway:/,
143115
);
144116
});
145117

146118
test.skipIf(!isDashScopeE2EReady())("auth status --output json", async () => {
147-
const { stdout, stderr, exitCode } = await runCli([
148-
"auth",
149-
"status",
150-
"--non-interactive",
151-
"--output",
152-
"json",
153-
]);
119+
const { stdout, stderr, exitCode } = await runCli(["auth", "status", "--output", "json"]);
154120
expect(exitCode, stderr).toBe(0);
155121
const data = parseStdoutJson<{
156122
authenticated?: boolean;
@@ -164,7 +130,7 @@ describe("e2e: auth", () => {
164130
"auth status --output json --quiet(base_url 经 env 指定;凭证域 flag 对 status 不可见)",
165131
async () => {
166132
const { stdout, stderr, exitCode } = await runCli(
167-
["auth", "status", "--non-interactive", "--output", "json", "--quiet"],
133+
["auth", "status", "--output", "json", "--quiet"],
168134
{ DASHSCOPE_BASE_URL: "https://dashscope.aliyuncs.com" },
169135
);
170136
expect(exitCode, stderr).toBe(0);

packages/cli/tests/e2e/config.e2e.test.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,7 @@ describe("e2e: config", () => {
2626
});
2727

2828
test("config show --output json", async () => {
29-
const { stdout, stderr, exitCode } = await runCli([
30-
"config",
31-
"show",
32-
"--non-interactive",
33-
"--output",
34-
"json",
35-
]);
29+
const { stdout, stderr, exitCode } = await runCli(["config", "show", "--output", "json"]);
3630
expect(exitCode, stderr).toBe(0);
3731
const data = parseStdoutJson<{
3832
config_file?: string;
@@ -48,7 +42,6 @@ describe("e2e: config", () => {
4842
const { stdout, stderr, exitCode } = await runCli([
4943
"config",
5044
"show",
51-
"--non-interactive",
5245
"--output",
5346
"text",
5447
"--no-color",
@@ -58,7 +51,7 @@ describe("e2e: config", () => {
5851
});
5952

6053
test("config set 缺少 --key / --value 时报用法错误并退出 (2)", async () => {
61-
const { stderr, exitCode } = await runCli(["config", "set", "--non-interactive"]);
54+
const { stderr, exitCode } = await runCli(["config", "set", "--quiet"]);
6255
expect(exitCode, stderr).toBe(2);
6356
expect(stderr).toMatch(/--key|--value|Usage:/i);
6457
});
@@ -67,7 +60,6 @@ describe("e2e: config", () => {
6760
const { stderr, exitCode } = await runCli([
6861
"config",
6962
"set",
70-
"--non-interactive",
7163
"--key",
7264
"not-a-real-key",
7365
"--value",
@@ -81,7 +73,6 @@ describe("e2e: config", () => {
8173
const { stderr, exitCode } = await runCli([
8274
"config",
8375
"set",
84-
"--non-interactive",
8576
"--key",
8677
"output",
8778
"--value",
@@ -95,7 +86,6 @@ describe("e2e: config", () => {
9586
const { stderr, exitCode } = await runCli([
9687
"config",
9788
"set",
98-
"--non-interactive",
9989
"--key",
10090
"timeout",
10191
"--value",
@@ -110,7 +100,6 @@ describe("e2e: config", () => {
110100
"config",
111101
"set",
112102
"--dry-run",
113-
"--non-interactive",
114103
"--key",
115104
"output",
116105
"--value",
@@ -128,7 +117,6 @@ describe("e2e: config", () => {
128117
"config",
129118
"set",
130119
"--dry-run",
131-
"--non-interactive",
132120
"--key",
133121
"default-text-model",
134122
"--value",

packages/cli/tests/e2e/console-flags.e2e.test.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ describe("e2e: console global flags", () => {
8383
"--data",
8484
"{}",
8585
"--dry-run",
86-
"--non-interactive",
8786
"--output",
8887
"json",
8988
]);
@@ -102,7 +101,6 @@ describe("e2e: console global flags", () => {
102101
"--data",
103102
"{}",
104103
"--dry-run",
105-
"--non-interactive",
106104
"--output",
107105
"json",
108106
"--console-region",
@@ -128,7 +126,6 @@ describe("e2e: console global flags", () => {
128126
"--data",
129127
"{}",
130128
"--dry-run",
131-
"--non-interactive",
132129
"--region",
133130
"cn",
134131
]);
@@ -141,7 +138,6 @@ describe("e2e: console global flags", () => {
141138
"mcp",
142139
"list",
143140
"--dry-run",
144-
"--non-interactive",
145141
"--output",
146142
"json",
147143
"--console-region",
@@ -157,7 +153,6 @@ describe("e2e: console global flags", () => {
157153
"quota",
158154
"check",
159155
"--dry-run",
160-
"--non-interactive",
161156
"--output",
162157
"json",
163158
"--console-region",

packages/cli/tests/e2e/file-upload.e2e.test.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,14 @@ describe("e2e: file upload", () => {
2626

2727
describe.skipIf(!isDashScopeE2EReady())("e2e: file upload(DashScope)", () => {
2828
test("file upload 缺少 --file 时报用法错误并退出 (2)", async () => {
29-
const { stderr, exitCode } = await runCli([
30-
"file",
31-
"upload",
32-
"--model",
33-
"qwen3-vl-plus",
34-
"--non-interactive",
35-
]);
29+
const { stderr, exitCode } = await runCli(["file", "upload", "--model", "qwen3-vl-plus"]);
3630
expect(exitCode).toBe(2);
3731
expect(stderr).toMatch(/--file|Usage:/i);
3832
});
3933

4034
test("file upload 缺少 --model 时报用法错误并退出 (2)", async () => {
4135
const testFile = join(__dirname, ".smoke-32.png");
42-
const { stderr, exitCode } = await runCli([
43-
"file",
44-
"upload",
45-
"--file",
46-
testFile,
47-
"--non-interactive",
48-
]);
36+
const { stderr, exitCode } = await runCli(["file", "upload", "--file", testFile]);
4937
expect(exitCode).toBe(2);
5038
expect(stderr).toMatch(/--model|Usage:/i);
5139
});
@@ -59,7 +47,6 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: file upload(DashScope)", () =>
5947
testFile,
6048
"--model",
6149
"qwen3-vl-plus",
62-
"--non-interactive",
6350
"--output",
6451
"json",
6552
]);

0 commit comments

Comments
 (0)