@@ -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. */
2415const BAILIAN_PREFIX = "bailian-" ;
2516
2617/** Max number of skills downloading/installing at the same time. */
2718const 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+
2936export 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