Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion packages/cli/tests/e2e/registry.smoke.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,40 @@ const commandPaths = Object.keys(commands).sort();
const groupPaths = deriveGroupPaths(commandPaths);

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

test("分组帮助按叶子命令展示不同鉴权域", async () => {
const { stderr, exitCode } = await runCli(["app", "--help"]);
expect(exitCode, stderr).toBe(0);
expect(stderr).toMatch(/app call\s+\[API Key\]\s+Call a Bailian application/);
expect(stderr).toMatch(/app list\s+\[Console\]\s+List Bailian applications/);
});

test.each([
[["text", "chat"], "API Key"],
[["app", "list"], "Console"],
[["token-plan", "list-seats"], "AK/SK"],
[["config", "show"], "No Auth"],
] as const)("%s --help 明确展示鉴权域 %s", async (commandPath, authLabel) => {
const { stderr, exitCode } = await runCli([...commandPath, "--help"]);
expect(exitCode, stderr).toBe(0);
expect(stderr).toContain(`Authentication: ${authLabel}`);
});

test("quota check --help:Flags 含 console 域鉴权 flag,Global Flags 全量列出", async () => {
const { stderr, exitCode } = await runCli(["quota", "check", "--help"]);
expect(exitCode, stderr).toBe(0);
Expand Down
65 changes: 51 additions & 14 deletions packages/runtime/src/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ interface CommandNode {
children: Map<string, CommandNode>;
}

const AUTH_LABELS = {
apiKey: "API Key",
console: "Console",
openapi: "AK/SK",
none: "No Auth",
} satisfies Record<AuthRequirement, string>;

/**
* What a command path resolves to in the registry. The single judgement that
* feeds `resolve()` — no scattered `isGroupPath` + throwing `resolve`.
Expand Down Expand Up @@ -157,14 +164,37 @@ export class CommandRegistry {
};
}

private buildResourceLines(a: (s: string) => string, d: (s: string) => string): string {
const entries: Array<{ path: string; desc: string }> = [];
private buildCommandLines(
entries: Array<{ path: string; auth: AuthRequirement; desc: string }>,
accent: (text: string) => string,
dim: (text: string) => string,
): string {
const maxPathLength = Math.max(...entries.map((entry) => entry.path.length));
const maxAuthLength = Math.max(
...entries.map((entry) => `[${AUTH_LABELS[entry.auth]}]`.length),
);
const rows = entries.map((entry) => {
const authLabel = `[${AUTH_LABELS[entry.auth]}]`;
return ` ${accent(entry.path.padEnd(maxPathLength + 2))} ${accent(authLabel.padEnd(maxAuthLength + 2))} ${dim(entry.desc)}`;
});
return rows.join("\n");
}

private buildResourceLines(
accent: (text: string) => string,
dim: (text: string) => string,
): string {
const entries: Array<{ path: string; auth: AuthRequirement; desc: string }> = [];

const collect = (node: CommandNode, prefix: string) => {
for (const [name, child] of node.children) {
const fullPath = prefix ? `${prefix} ${name}` : name;
if (child.command) {
entries.push({ path: fullPath, desc: child.command.description });
entries.push({
path: fullPath,
auth: child.command.auth,
desc: child.command.description,
});
}
if (child.children.size > 0) {
collect(child, fullPath);
Expand All @@ -173,8 +203,7 @@ export class CommandRegistry {
};
collect(this.root, "");

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

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

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

private printChildren(node: CommandNode, prefix: string, out: NodeJS.WriteStream): void {
const entries: Array<{ fullName: string; description: string }> = [];
const collect = (n: CommandNode, p: string) => {
for (const [name, child] of n.children) {
const entries: Array<{ path: string; auth: AuthRequirement; desc: string }> = [];
const collect = (currentNode: CommandNode, currentPath: string) => {
for (const [name, child] of currentNode.children) {
if (child.command)
entries.push({ fullName: `${p} ${name}`, description: child.command.description });
if (child.children.size > 0) collect(child, `${p} ${name}`);
entries.push({
path: `${currentPath} ${name}`,
auth: child.command.auth,
desc: child.command.description,
});
if (child.children.size > 0) collect(child, `${currentPath} ${name}`);
}
};
collect(node, prefix);
const maxLen = Math.max(...entries.map((e) => e.fullName.length));
for (const { fullName, description } of entries) {
out.write(` ${this.accent(fullName.padEnd(maxLen), out)} ${this.dim(description, out)}\n`);
}
out.write(
this.buildCommandLines(
entries,
(text) => this.accent(text, out),
(text) => this.dim(text, out),
) + "\n",
);
}
}
17 changes: 9 additions & 8 deletions skills/bailian-cli/reference/advisor.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@ Index: [index.md](index.md)

## Commands in this group

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

## Command details

### `bl advisor recommend`

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

#### Flags

Expand Down
30 changes: 16 additions & 14 deletions skills/bailian-cli/reference/app.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,21 @@ Index: [index.md](index.md)

## Commands in this group

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

## Command details

### `bl app call`

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

#### Flags

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

### `bl app list`

| Field | Value |
| --------------- | ------------------------- |
| **Name** | `app list` |
| **Description** | List Bailian applications |
| **Usage** | `bl app list [flags]` |
| Field | Value |
| ------------------ | ------------------------- |
| **Name** | `app list` |
| **Description** | List Bailian applications |
| **Authentication** | Console |
| **Usage** | `bl app list [flags]` |

#### Flags

Expand Down
56 changes: 30 additions & 26 deletions skills/bailian-cli/reference/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,23 @@ Index: [index.md](index.md)

## Commands in this group

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

## Command details

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

| Field | Value |
| --------------- | ---------------------------------------------------------------------------------------------------------- |
| **Name** | `auth generate-access-token` |
| **Description** | Generate a CLI access token using OpenAPI AK/SK |
| **Usage** | `bl auth generate-access-token --access-key-id <id> --access-key-secret <secret> --security-token <token>` |
| Field | Value |
| ------------------ | ---------------------------------------------------------------------------------------------------------- |
| **Name** | `auth generate-access-token` |
| **Description** | Generate a CLI access token using OpenAPI AK/SK |
| **Authentication** | No Auth |
| **Usage** | `bl auth generate-access-token --access-key-id <id> --access-key-secret <secret> --security-token <token>` |

#### Flags

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

### `bl auth login`

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

#### Flags

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

### `bl auth logout`

| Field | Value |
| --------------- | -------------------------------------------------------------------- |
| **Name** | `auth logout` |
| **Description** | Clear stored credentials; full logout also clears the model Base URL |
| **Usage** | `bl auth logout [--console \| --open-api] [--dry-run]` |
| Field | Value |
| ------------------ | -------------------------------------------------------------------- |
| **Name** | `auth logout` |
| **Description** | Clear stored credentials; full logout also clears the model Base URL |
| **Authentication** | No Auth |
| **Usage** | `bl auth logout [--console \| --open-api] [--dry-run]` |

#### Flags

Expand Down Expand Up @@ -111,11 +114,12 @@ bl auth logout --dry-run

### `bl auth status`

| Field | Value |
| --------------- | --------------------------------- |
| **Name** | `auth status` |
| **Description** | Show current authentication state |
| **Usage** | `bl auth status` |
| Field | Value |
| ------------------ | --------------------------------- |
| **Name** | `auth status` |
| **Description** | Show current authentication state |
| **Authentication** | No Auth |
| **Usage** | `bl auth status` |

#### Flags

Expand Down
Loading