@@ -32,35 +32,35 @@ export async function runDoctor(options: CliOverrides): Promise<void> {
3232
3333 const results = await Promise . all ( [
3434 // 1. Node.js version check
35- check ( 'Node.js version >= 20 ' , ( ) => {
35+ check ( 'Node.js' , ( ) => {
3636 const version = process . version ;
3737 const major = parseInt ( version . slice ( 1 ) . split ( '.' ) [ 0 ] ?? '0' , 10 ) ;
3838 if ( major < 20 ) {
3939 return Promise . resolve ( { status : 'fail' as const , detail : `Node.js ${ version } detected — upgrade to v20 or later` } ) ;
4040 }
41- return Promise . resolve ( { status : 'pass' as const , detail : version } ) ;
41+ return Promise . resolve ( { status : 'pass' as const , detail : ` ${ version } — solid.` } ) ;
4242 } ) ,
4343
4444 // 2. Config file parse check
45- check ( 'Config file is valid ' , async ( ) => {
45+ check ( 'Config' , async ( ) => {
4646 const config = await loadConfig ( process . cwd ( ) , options ) ;
47- return { status : 'pass' as const , detail : `Active profile: "${ config . defaultProfile } "` } ;
47+ return { status : 'pass' as const , detail : `using "${ config . defaultProfile } " profile. ` } ;
4848 } ) ,
4949
5050 // 3. Provider connectivity
51- check ( 'Provider connectivity ' , async ( ) => {
51+ check ( 'Provider' , async ( ) => {
5252 const config = await loadConfig ( process . cwd ( ) , options ) ;
5353 const profile = getActiveProfile ( config ) ;
5454 const adapter = await createProvider ( profile ) ;
5555 await adapter . validateCredentials ( ) ;
5656 const via = profile . provider === 'copilot' && process . env [ 'JAM_VSCODE_LM_PORT' ]
5757 ? 'copilot (via VSCode)'
5858 : profile . provider ;
59- return { status : 'pass' as const , detail : `Provider: ${ via } ` } ;
59+ return { status : 'pass' as const , detail : `${ via } connected and ready. ` } ;
6060 } ) ,
6161
6262 // 4. Copilot CLI availability
63- check ( 'Copilot CLI (@github/copilot) ' , async ( ) => {
63+ check ( 'Copilot CLI' , async ( ) => {
6464 try {
6565 const { stdout } = await execFileAsync ( 'npx' , [ '@github/copilot' , '--version' ] , { timeout : 15_000 } ) ;
6666 return { status : 'pass' as const , detail : stdout . trim ( ) } ;
@@ -73,46 +73,42 @@ export async function runDoctor(options: CliOverrides): Promise<void> {
7373 } ) ,
7474
7575 // 5. ripgrep availability (optional)
76- check ( 'ripgrep (rg) is available ' , async ( ) => {
76+ check ( 'ripgrep' , async ( ) => {
7777 try {
7878 const { stdout } = await execFileAsync ( 'rg' , [ '--version' ] , { timeout : 5000 } ) ;
7979 const firstLine = stdout . split ( '\n' ) [ 0 ] ?. trim ( ) ?? 'rg' ;
80- return { status : 'pass' as const , detail : firstLine } ;
80+ return { status : 'pass' as const , detail : ` ${ firstLine } — searches will be fast.` } ;
8181 } catch {
82- return { status : 'warn' as const , detail : 'Not installed — using JavaScript-based search ( slower) ' } ;
82+ return { status : 'warn' as const , detail : 'Not installed — searches will be slower without it ' } ;
8383 }
8484 } ) ,
8585
8686 // 6. Keytar availability (optional)
87- check ( 'keytar (secure credential storage) ' , async ( ) => {
87+ check ( 'Keychain ' , async ( ) => {
8888 try {
8989 await import ( 'keytar' ) ;
90- return { status : 'pass' as const , detail : 'loaded ' } ;
90+ return { status : 'pass' as const , detail : 'secrets are secure. ' } ;
9191 } catch {
9292 return {
9393 status : 'warn' as const ,
94- detail : 'Not available — API keys must be provided via environment variables or config ' ,
94+ detail : 'Not available — use env vars for API keys ' ,
9595 } ;
9696 }
9797 } ) ,
9898 ] ) ;
9999
100- process . stdout . write ( '\nJam Doctor — system diagnostics\n' ) ;
101- process . stdout . write ( chalk . dim ( '─' . repeat ( 60 ) + '\n\n' ) ) ;
100+ process . stdout . write ( '\nChecking your setup...\n\n' ) ;
102101
103102 for ( const result of results ) {
104103 let icon : string ;
105- let label : string ;
106104 if ( result . status === 'pass' ) {
107- icon = chalk . green ( '[✓]' ) ;
108- label = chalk . green ( result . description ) ;
105+ icon = chalk . green ( ' ✓' ) ;
109106 } else if ( result . status === 'warn' ) {
110- icon = chalk . yellow ( '[!]' ) ;
111- label = chalk . yellow ( result . description ) ;
107+ icon = chalk . yellow ( ' !' ) ;
112108 } else {
113- icon = chalk . red ( '[✗]' ) ;
114- label = chalk . red ( result . description ) ;
109+ icon = chalk . red ( ' ✗' ) ;
115110 }
111+ const label = result . status === 'fail' ? chalk . red ( result . description ) : result . description ;
116112 const detail = result . detail ? chalk . dim ( ` — ${ result . detail } ` ) : '' ;
117113 process . stdout . write ( `${ icon } ${ label } ${ detail } \n` ) ;
118114 }
@@ -123,12 +119,10 @@ export async function runDoctor(options: CliOverrides): Promise<void> {
123119 const warnCount = results . filter ( ( r ) => r . status === 'warn' ) . length ;
124120
125121 if ( failCount === 0 && warnCount === 0 ) {
126- process . stdout . write ( chalk . green ( 'All checks passed .\n' ) ) ;
122+ process . stdout . write ( chalk . green ( '\nYou\'re good to go .\n' ) ) ;
127123 } else if ( failCount === 0 ) {
128- process . stdout . write ( chalk . green ( `All checks passed ( ${ warnCount } optional) .\n` ) ) ;
124+ process . stdout . write ( chalk . green ( `\nLooking good. ${ warnCount } optional thing ${ warnCount === 1 ? '' : 's' } to improve .\n` ) ) ;
129125 } else {
130- process . stdout . write (
131- chalk . yellow ( `${ failCount } check${ failCount === 1 ? '' : 's' } failed, ${ warnCount } optional.\n` )
132- ) ;
126+ process . stdout . write ( chalk . yellow ( `\n${ failCount } issue${ failCount === 1 ? '' : 's' } to fix.\n` ) ) ;
133127 }
134128}
0 commit comments