Skip to content

Commit 57c2d98

Browse files
authored
Merge pull request #160 from modelstudioai/feat/skill-init-simplify
feat: update skill init output
2 parents 78e6993 + 4ccda5f commit 57c2d98

1 file changed

Lines changed: 54 additions & 36 deletions

File tree

  • packages/commands/src/commands/skill

packages/commands/src/commands/skill/init.ts

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,35 @@ import {
44
defineCommand,
55
detectInstalledAgents,
66
fetchSkillsIndex,
7-
getSkillRegistryBaseUrl,
87
installSkillWithFanout,
98
readSkillLock,
109
runWithConcurrency,
1110
writeSkillLock,
1211
} from "bailian-cli-core";
13-
import { emitBare, emitResult, formatTable } from "bailian-cli-runtime";
14-
15-
interface InitOutcome {
16-
name: string;
17-
status: "installed" | "failed";
18-
publishedAt?: string;
19-
agents?: string[];
20-
reason?: string;
21-
}
12+
import { emitBare, emitResult } from "bailian-cli-runtime";
2213

2314
/** Prefix used to identify first-party Bailian skills in the registry. */
2415
const BAILIAN_PREFIX = "bailian-";
2516

2617
/** Max number of skills downloading/installing at the same time. */
2718
const INIT_CONCURRENCY = 3;
2819

20+
/** Default output format when user does not pass --output explicitly. */
21+
const DEFAULT_FORMAT = "json";
22+
23+
/** All status values used by skill init (per-skill outcome + aggregate result). */
24+
const STATUS = {
25+
success: "success",
26+
partial: "partial",
27+
failed: "failed",
28+
} as const;
29+
30+
interface InitOutcome {
31+
name: string;
32+
status: typeof STATUS.success | typeof STATUS.failed;
33+
reason?: string;
34+
}
35+
2936
export default defineCommand({
3037
description: "Install all bailian-* skills (one-shot bootstrap for new environments)",
3138
auth: "none",
@@ -36,7 +43,7 @@ export default defineCommand({
3643
"Equivalent to: bl skill add --all (filtered to bailian-* skills)",
3744
],
3845
async run(ctx) {
39-
const format = ctx.settings.outputExplicit ? ctx.settings.output : "json";
46+
const format = ctx.settings.outputExplicit ? ctx.settings.output : DEFAULT_FORMAT;
4047
const index = await fetchSkillsIndex();
4148

4249
// Discover all bailian-* skills from the live registry index
@@ -55,47 +62,58 @@ export default defineCommand({
5562
lock.skills[name]?.links ?? [],
5663
);
5764
lock.skills[name] = record.lockEntry;
58-
return {
59-
name,
60-
status: "installed",
61-
publishedAt: entry.publishedAt,
62-
agents: record.linkedAgents,
63-
};
65+
return { name, status: STATUS.success };
6466
} catch (err) {
6567
return {
6668
name,
67-
status: "failed",
69+
status: STATUS.failed,
6870
reason: err instanceof Error ? err.message : String(err),
6971
};
7072
}
7173
});
7274
const results = await runWithConcurrency(tasks, INIT_CONCURRENCY);
7375
writeSkillLock(lock);
7476

75-
if (format === "json") {
76-
emitResult(
77-
{
78-
registry: getSkillRegistryBaseUrl(),
79-
agents: agents.map((agent) => agent.id),
80-
skills: results,
81-
},
82-
format,
83-
);
77+
const installed = results.filter((result) => result.status === STATUS.success);
78+
const failed = results.filter((result) => result.status === STATUS.failed);
79+
80+
const status =
81+
failed.length === 0
82+
? STATUS.success
83+
: installed.length === 0
84+
? STATUS.failed
85+
: STATUS.partial;
86+
87+
if (format === DEFAULT_FORMAT) {
88+
const agentIds = agents.map((agent) => agent.id);
89+
const payload: Record<string, unknown> = {
90+
status,
91+
skills: installed.map((result) => result.name),
92+
};
93+
if (failed.length > 0) {
94+
payload.failed = failed.map((result) => ({
95+
name: result.name,
96+
reason: result.reason,
97+
agents: agentIds,
98+
}));
99+
}
100+
emitResult(payload, format);
84101
} else if (results.length === 0) {
85102
emitBare("No bailian-* skills found in the registry.");
86103
} else {
87-
const rows = results.map((result) => [
88-
result.name,
89-
result.status,
90-
result.publishedAt ? result.publishedAt.slice(0, 10) : "-",
91-
result.status === "installed" ? result.agents?.join(", ") || "-" : (result.reason ?? "-"),
92-
]);
93-
for (const line of formatTable(["NAME", "STATUS", "PUBLISHED", "AGENTS / REASON"], rows)) {
94-
emitBare(line);
104+
emitBare(
105+
status === STATUS.success
106+
? `Installed ${installed.length} bailian-* skills.`
107+
: `Installed ${installed.length}/${results.length} bailian-* skills.`,
108+
);
109+
if (failed.length > 0) {
110+
emitBare("Failed:");
111+
for (const item of failed) {
112+
emitBare(` ${item.name}: ${item.reason}`);
113+
}
95114
}
96115
}
97116

98-
const failed = results.filter((result) => result.status === "failed");
99117
if (failed.length > 0) {
100118
throw new BailianError(
101119
`${failed.length}/${results.length} skill(s) failed to install`,

0 commit comments

Comments
 (0)