Skip to content

Commit 8a0dd70

Browse files
committed
feat(cli): show command authentication requirements in help
1 parent 0e4dd4b commit 8a0dd70

37 files changed

Lines changed: 1051 additions & 866 deletions

File tree

packages/cli/tests/e2e/registry.smoke.e2e.test.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,40 @@ const commandPaths = Object.keys(commands).sort();
77
const groupPaths = deriveGroupPaths(commandPaths);
88

99
describe("e2e: bl registry smoke", () => {
10-
test("根帮助展示 bl 与全局 flag", async () => {
10+
test("根帮助展示 bl、逐命令鉴权域与全局 flag", async () => {
1111
const { stderr, exitCode } = await runCli(["--help"]);
1212
expect(exitCode, stderr).toBe(0);
1313
expect(stderr).toMatch(/\bbl\b/i);
14+
expect(stderr).not.toMatch(/COMMAND\s+AUTH\s+DESCRIPTION/);
15+
expect(stderr).toMatch(/app call\s+\[API Key\]\s+Call a Bailian application/);
16+
expect(stderr).toMatch(/app list\s+\[Console\]\s+List Bailian applications/);
17+
expect(stderr).toMatch(/token-plan create-key\s+\[AK\/SK\]\s+Create a Token Plan API key/);
18+
expect(stderr).toMatch(/config show\s+\[No Auth\]\s+Display current configuration/);
1419
expect(stderr).toMatch(/--base-url/);
1520
expect(stderr).toMatch(/--console-region/);
1621
expect(stderr).toMatch(/--console-site/);
1722
expect(stderr).toMatch(/--console-switch-agent/);
1823
expect(stderr).not.toMatch(/^\s*--region\s/m);
1924
});
2025

26+
test("分组帮助按叶子命令展示不同鉴权域", async () => {
27+
const { stderr, exitCode } = await runCli(["app", "--help"]);
28+
expect(exitCode, stderr).toBe(0);
29+
expect(stderr).toMatch(/app call\s+\[API Key\]\s+Call a Bailian application/);
30+
expect(stderr).toMatch(/app list\s+\[Console\]\s+List Bailian applications/);
31+
});
32+
33+
test.each([
34+
[["text", "chat"], "API Key"],
35+
[["app", "list"], "Console"],
36+
[["token-plan", "list-seats"], "AK/SK"],
37+
[["config", "show"], "No Auth"],
38+
] as const)("%s --help 明确展示鉴权域 %s", async (commandPath, authLabel) => {
39+
const { stderr, exitCode } = await runCli([...commandPath, "--help"]);
40+
expect(exitCode, stderr).toBe(0);
41+
expect(stderr).toContain(`Authentication: ${authLabel}`);
42+
});
43+
2144
test("quota check --help:Flags 含 console 域鉴权 flag,Global Flags 全量列出", async () => {
2245
const { stderr, exitCode } = await runCli(["quota", "check", "--help"]);
2346
expect(exitCode, stderr).toBe(0);

packages/runtime/src/registry.ts

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ interface CommandNode {
2525
children: Map<string, CommandNode>;
2626
}
2727

28+
const AUTH_LABELS = {
29+
apiKey: "API Key",
30+
console: "Console",
31+
openapi: "AK/SK",
32+
none: "No Auth",
33+
} satisfies Record<AuthRequirement, string>;
34+
2835
/**
2936
* What a command path resolves to in the registry. The single judgement that
3037
* feeds `resolve()` — no scattered `isGroupPath` + throwing `resolve`.
@@ -157,14 +164,37 @@ export class CommandRegistry {
157164
};
158165
}
159166

160-
private buildResourceLines(a: (s: string) => string, d: (s: string) => string): string {
161-
const entries: Array<{ path: string; desc: string }> = [];
167+
private buildCommandLines(
168+
entries: Array<{ path: string; auth: AuthRequirement; desc: string }>,
169+
accent: (text: string) => string,
170+
dim: (text: string) => string,
171+
): string {
172+
const maxPathLength = Math.max(...entries.map((entry) => entry.path.length));
173+
const maxAuthLength = Math.max(
174+
...entries.map((entry) => `[${AUTH_LABELS[entry.auth]}]`.length),
175+
);
176+
const rows = entries.map((entry) => {
177+
const authLabel = `[${AUTH_LABELS[entry.auth]}]`;
178+
return ` ${accent(entry.path.padEnd(maxPathLength + 2))} ${accent(authLabel.padEnd(maxAuthLength + 2))} ${dim(entry.desc)}`;
179+
});
180+
return rows.join("\n");
181+
}
182+
183+
private buildResourceLines(
184+
accent: (text: string) => string,
185+
dim: (text: string) => string,
186+
): string {
187+
const entries: Array<{ path: string; auth: AuthRequirement; desc: string }> = [];
162188

163189
const collect = (node: CommandNode, prefix: string) => {
164190
for (const [name, child] of node.children) {
165191
const fullPath = prefix ? `${prefix} ${name}` : name;
166192
if (child.command) {
167-
entries.push({ path: fullPath, desc: child.command.description });
193+
entries.push({
194+
path: fullPath,
195+
auth: child.command.auth,
196+
desc: child.command.description,
197+
});
168198
}
169199
if (child.children.size > 0) {
170200
collect(child, fullPath);
@@ -173,8 +203,7 @@ export class CommandRegistry {
173203
};
174204
collect(this.root, "");
175205

176-
const maxLen = Math.max(...entries.map((e) => e.path.length));
177-
return entries.map((e) => ` ${a(e.path.padEnd(maxLen + 2))} ${d(e.desc)}`).join("\n");
206+
return this.buildCommandLines(entries, accent, dim);
178207
}
179208

180209
private buildFlagLines(
@@ -341,6 +370,7 @@ ${authFlagSections ? `${authFlagSections}\n\n` : ""}${b("Getting Help:")}
341370

342371
out.write(`\n${cmd.description}\n`);
343372
out.write(`${b("Usage:")} ${prefix}${cmd.usageArgs ? ` ${cmd.usageArgs}` : ""}\n`);
373+
out.write(`${b("Authentication:")} ${a(AUTH_LABELS[cmd.auth])}\n`);
344374
const flagEntries = [
345375
...Object.entries(cmd.flags ?? {}),
346376
...Object.entries(credentialFlagDefs(cmd)),
@@ -373,18 +403,25 @@ ${authFlagSections ? `${authFlagSections}\n\n` : ""}${b("Getting Help:")}
373403
}
374404

375405
private printChildren(node: CommandNode, prefix: string, out: NodeJS.WriteStream): void {
376-
const entries: Array<{ fullName: string; description: string }> = [];
377-
const collect = (n: CommandNode, p: string) => {
378-
for (const [name, child] of n.children) {
406+
const entries: Array<{ path: string; auth: AuthRequirement; desc: string }> = [];
407+
const collect = (currentNode: CommandNode, currentPath: string) => {
408+
for (const [name, child] of currentNode.children) {
379409
if (child.command)
380-
entries.push({ fullName: `${p} ${name}`, description: child.command.description });
381-
if (child.children.size > 0) collect(child, `${p} ${name}`);
410+
entries.push({
411+
path: `${currentPath} ${name}`,
412+
auth: child.command.auth,
413+
desc: child.command.description,
414+
});
415+
if (child.children.size > 0) collect(child, `${currentPath} ${name}`);
382416
}
383417
};
384418
collect(node, prefix);
385-
const maxLen = Math.max(...entries.map((e) => e.fullName.length));
386-
for (const { fullName, description } of entries) {
387-
out.write(` ${this.accent(fullName.padEnd(maxLen), out)} ${this.dim(description, out)}\n`);
388-
}
419+
out.write(
420+
this.buildCommandLines(
421+
entries,
422+
(text) => this.accent(text, out),
423+
(text) => this.dim(text, out),
424+
) + "\n",
425+
);
389426
}
390427
}

skills/bailian-cli/reference/advisor.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,20 @@ Index: [index.md](index.md)
77

88
## Commands in this group
99

10-
| Command | Description |
11-
| ---------------------- | ---------------------------------------------------------------------------------------------- |
12-
| `bl advisor recommend` | Recommend the best models for your use case (intent analysis → candidate recall → LLM ranking) |
10+
| Command | Authentication | Description |
11+
| ---------------------- | -------------- | ---------------------------------------------------------------------------------------------- |
12+
| `bl advisor recommend` | API Key | Recommend the best models for your use case (intent analysis → candidate recall → LLM ranking) |
1313

1414
## Command details
1515

1616
### `bl advisor recommend`
1717

18-
| Field | Value |
19-
| --------------- | ---------------------------------------------------------------------------------------------- |
20-
| **Name** | `advisor recommend` |
21-
| **Description** | Recommend the best models for your use case (intent analysis → candidate recall → LLM ranking) |
22-
| **Usage** | `bl advisor recommend --message <text> [flags]` |
18+
| Field | Value |
19+
| ------------------ | ---------------------------------------------------------------------------------------------- |
20+
| **Name** | `advisor recommend` |
21+
| **Description** | Recommend the best models for your use case (intent analysis → candidate recall → LLM ranking) |
22+
| **Authentication** | API Key |
23+
| **Usage** | `bl advisor recommend --message <text> [flags]` |
2324

2425
#### Flags
2526

skills/bailian-cli/reference/app.md

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,21 @@ Index: [index.md](index.md)
77

88
## Commands in this group
99

10-
| Command | Description |
11-
| ------------- | ---------------------------------------------- |
12-
| `bl app call` | Call a Bailian application (agent or workflow) |
13-
| `bl app list` | List Bailian applications |
10+
| Command | Authentication | Description |
11+
| ------------- | -------------- | ---------------------------------------------- |
12+
| `bl app call` | API Key | Call a Bailian application (agent or workflow) |
13+
| `bl app list` | Console | List Bailian applications |
1414

1515
## Command details
1616

1717
### `bl app call`
1818

19-
| Field | Value |
20-
| --------------- | --------------------------------------------------- |
21-
| **Name** | `app call` |
22-
| **Description** | Call a Bailian application (agent or workflow) |
23-
| **Usage** | `bl app call --app-id <id> --prompt <text> [flags]` |
19+
| Field | Value |
20+
| ------------------ | --------------------------------------------------- |
21+
| **Name** | `app call` |
22+
| **Description** | Call a Bailian application (agent or workflow) |
23+
| **Authentication** | API Key |
24+
| **Usage** | `bl app call --app-id <id> --prompt <text> [flags]` |
2425

2526
#### Flags
2627

@@ -67,11 +68,12 @@ bl app call --app-id abc123 --prompt "Start" --biz-params '{"key":"value"}'
6768

6869
### `bl app list`
6970

70-
| Field | Value |
71-
| --------------- | ------------------------- |
72-
| **Name** | `app list` |
73-
| **Description** | List Bailian applications |
74-
| **Usage** | `bl app list [flags]` |
71+
| Field | Value |
72+
| ------------------ | ------------------------- |
73+
| **Name** | `app list` |
74+
| **Description** | List Bailian applications |
75+
| **Authentication** | Console |
76+
| **Usage** | `bl app list [flags]` |
7577

7678
#### Flags
7779

skills/bailian-cli/reference/auth.md

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,23 @@ Index: [index.md](index.md)
77

88
## Commands in this group
99

10-
| Command | Description |
11-
| ------------------------------- | -------------------------------------------------------------------------------------------- |
12-
| `bl auth generate-access-token` | Generate a CLI access token using OpenAPI AK/SK |
13-
| `bl auth login` | Authenticate with API key, console browser login, or OpenAPI AK/SK (credentials can coexist) |
14-
| `bl auth logout` | Clear stored credentials; full logout also clears the model Base URL |
15-
| `bl auth status` | Show current authentication state |
10+
| Command | Authentication | Description |
11+
| ------------------------------- | -------------- | -------------------------------------------------------------------------------------------- |
12+
| `bl auth generate-access-token` | No Auth | Generate a CLI access token using OpenAPI AK/SK |
13+
| `bl auth login` | No Auth | Authenticate with API key, console browser login, or OpenAPI AK/SK (credentials can coexist) |
14+
| `bl auth logout` | No Auth | Clear stored credentials; full logout also clears the model Base URL |
15+
| `bl auth status` | No Auth | Show current authentication state |
1616

1717
## Command details
1818

1919
### `bl auth generate-access-token`
2020

21-
| Field | Value |
22-
| --------------- | ---------------------------------------------------------------------------------------------------------- |
23-
| **Name** | `auth generate-access-token` |
24-
| **Description** | Generate a CLI access token using OpenAPI AK/SK |
25-
| **Usage** | `bl auth generate-access-token --access-key-id <id> --access-key-secret <secret> --security-token <token>` |
21+
| Field | Value |
22+
| ------------------ | ---------------------------------------------------------------------------------------------------------- |
23+
| **Name** | `auth generate-access-token` |
24+
| **Description** | Generate a CLI access token using OpenAPI AK/SK |
25+
| **Authentication** | No Auth |
26+
| **Usage** | `bl auth generate-access-token --access-key-id <id> --access-key-secret <secret> --security-token <token>` |
2627

2728
#### Flags
2829

@@ -40,11 +41,12 @@ bl auth generate-access-token --access-key-id LTAIxxxxx --access-key-secret xxxx
4041

4142
### `bl auth login`
4243

43-
| Field | Value |
44-
| --------------- | ------------------------------------------------------------------------------------------------------------ |
45-
| **Name** | `auth login` |
46-
| **Description** | Authenticate with API key, console browser login, or OpenAPI AK/SK (credentials can coexist) |
47-
| **Usage** | `bl auth login --api-key <key> \| --console \| --open-api --access-key-id <id> --access-key-secret <secret>` |
44+
| Field | Value |
45+
| ------------------ | ------------------------------------------------------------------------------------------------------------ |
46+
| **Name** | `auth login` |
47+
| **Description** | Authenticate with API key, console browser login, or OpenAPI AK/SK (credentials can coexist) |
48+
| **Authentication** | No Auth |
49+
| **Usage** | `bl auth login --api-key <key> \| --console \| --open-api --access-key-id <id> --access-key-secret <secret>` |
4850

4951
#### Flags
5052

@@ -78,11 +80,12 @@ bl auth login --open-api --access-key-id LTAIxxxxx --access-key-secret xxxxx
7880

7981
### `bl auth logout`
8082

81-
| Field | Value |
82-
| --------------- | -------------------------------------------------------------------- |
83-
| **Name** | `auth logout` |
84-
| **Description** | Clear stored credentials; full logout also clears the model Base URL |
85-
| **Usage** | `bl auth logout [--console \| --open-api] [--dry-run]` |
83+
| Field | Value |
84+
| ------------------ | -------------------------------------------------------------------- |
85+
| **Name** | `auth logout` |
86+
| **Description** | Clear stored credentials; full logout also clears the model Base URL |
87+
| **Authentication** | No Auth |
88+
| **Usage** | `bl auth logout [--console \| --open-api] [--dry-run]` |
8689

8790
#### Flags
8891

@@ -111,11 +114,12 @@ bl auth logout --dry-run
111114

112115
### `bl auth status`
113116

114-
| Field | Value |
115-
| --------------- | --------------------------------- |
116-
| **Name** | `auth status` |
117-
| **Description** | Show current authentication state |
118-
| **Usage** | `bl auth status` |
117+
| Field | Value |
118+
| ------------------ | --------------------------------- |
119+
| **Name** | `auth status` |
120+
| **Description** | Show current authentication state |
121+
| **Authentication** | No Auth |
122+
| **Usage** | `bl auth status` |
119123

120124
#### Flags
121125

0 commit comments

Comments
 (0)