@@ -8,97 +8,139 @@ import {
88 loadAuthConfig ,
99} from "./auth/workos.js" ;
1010import { services } from "./services/index.js" ;
11- import { getCurrentSession , getSessionFilePath } from "./session.js" ;
11+ import {
12+ getCurrentSession ,
13+ getSessionFilePath ,
14+ getSessionUsage ,
15+ } from "./session.js" ;
1216import { logger } from "./util/logger.js" ;
1317import { getVersion } from "./version.js" ;
1418
15- export async function handleInfoSlashCommand ( ) {
16- const infoLines = [ ] ;
17-
18- // Version and working directory info
19+ function getVersionInfo ( ) : string [ ] {
1920 const version = getVersion ( ) ;
2021 const cwd = process . cwd ( ) ;
2122
22- infoLines . push (
23+ return [
2324 chalk . white ( "CLI Information:" ) ,
2425 ` Version: ${ chalk . green ( version ) } ` ,
2526 ` Working Directory: ${ chalk . blue ( cwd ) } ` ,
26- ) ;
27+ ] ;
28+ }
29+
30+ async function getAuthInfo ( ) : Promise < string [ ] > {
31+ const lines : string [ ] = [ "" , chalk . white ( "Authentication:" ) ] ;
2732
28- // Auth info
2933 if ( await isAuthenticated ( ) ) {
3034 const config = loadAuthConfig ( ) ;
3135 if ( config && isAuthenticatedConfig ( config ) ) {
3236 const email = config . userEmail || config . userId ;
3337 const orgId = config . organizationId ;
34- infoLines . push (
35- "" ,
36- chalk . white ( "Authentication:" ) ,
38+ lines . push (
3739 ` Email: ${ chalk . green ( email ) } ` ,
3840 ` Org ID: ${ chalk . cyan ( orgId ) } ` ,
3941 ) ;
4042 } else {
41- infoLines . push (
42- "" ,
43- chalk . white ( "Authentication:" ) ,
44- ` ${ chalk . yellow ( "Authenticated via environment variable" ) } ` ,
45- ) ;
43+ lines . push ( ` ${ chalk . yellow ( "Authenticated via environment variable" ) } ` ) ;
4644 }
4745 } else {
48- infoLines . push (
49- "" ,
50- chalk . white ( "Authentication:" ) ,
51- ` ${ chalk . red ( "Not logged in" ) } ` ,
52- ) ;
46+ lines . push ( ` ${ chalk . red ( "Not logged in" ) } ` ) ;
5347 }
5448
55- // Config info
49+ return lines ;
50+ }
51+
52+ function getConfigInfo ( ) : string [ ] {
53+ const lines : string [ ] = [ "" , chalk . white ( "Configuration:" ) ] ;
54+
5655 try {
5756 const configState = services . config . getState ( ) ;
58- infoLines . push ( "" , chalk . white ( "Configuration:" ) ) ;
5957 if ( configState . config ) {
60- infoLines . push ( ` ${ chalk . gray ( `Using ${ configState . config ?. name } ` ) } ` ) ;
58+ lines . push ( ` ${ chalk . gray ( `Using ${ configState . config ?. name } ` ) } ` ) ;
6159 } else {
62- infoLines . push ( ` ${ chalk . red ( `Config not found` ) } ` ) ;
60+ lines . push ( ` ${ chalk . red ( `Config not found` ) } ` ) ;
6361 }
6462 if ( configState . configPath ) {
65- infoLines . push ( ` Path: ${ chalk . blue ( configState . configPath ) } ` ) ;
63+ lines . push ( ` Path: ${ chalk . blue ( configState . configPath ) } ` ) ;
6664 }
6765
6866 // Add current model info
6967 try {
7068 const modelInfo = services . model ?. getModelInfo ( ) ;
7169 if ( modelInfo ) {
72- infoLines . push ( ` Model: ${ chalk . cyan ( modelInfo . name ) } ` ) ;
70+ lines . push ( ` Model: ${ chalk . cyan ( modelInfo . name ) } ` ) ;
7371 } else {
74- infoLines . push ( ` Model: ${ chalk . red ( "Not available" ) } ` ) ;
72+ lines . push ( ` Model: ${ chalk . red ( "Not available" ) } ` ) ;
7573 }
7674 } catch {
77- infoLines . push ( ` Model: ${ chalk . red ( "Error retrieving model info" ) } ` ) ;
75+ lines . push ( ` Model: ${ chalk . red ( "Error retrieving model info" ) } ` ) ;
7876 }
7977 } catch {
80- infoLines . push (
81- "" ,
82- chalk . white ( "Configuration:" ) ,
83- ` ${ chalk . red ( "Configuration service not available" ) } ` ,
84- ) ;
78+ lines . push ( ` ${ chalk . red ( "Configuration service not available" ) } ` ) ;
8579 }
8680
87- // Session info
88- infoLines . push ( "" , chalk . white ( "Session:" ) ) ;
81+ return lines ;
82+ }
83+
84+ function getSessionInfo ( ) : string [ ] {
85+ const lines : string [ ] = [ "" , chalk . white ( "Session:" ) ] ;
86+
8987 try {
9088 const currentSession = getCurrentSession ( ) ;
9189 const sessionFilePath = getSessionFilePath ( ) ;
92- infoLines . push (
90+ lines . push (
9391 ` Title: ${ chalk . green ( currentSession . title ) } ` ,
9492 ` ID: ${ chalk . gray ( currentSession . sessionId ) } ` ,
9593 ` File: ${ chalk . blue ( sessionFilePath ) } ` ,
9694 ) ;
9795 } catch {
98- infoLines . push ( ` ${ chalk . red ( "Session not available" ) } ` ) ;
96+ lines . push ( ` ${ chalk . red ( "Session not available" ) } ` ) ;
9997 }
10098
101- // Runtime diagnostic info
99+ return lines ;
100+ }
101+
102+ function getUsageInfo ( ) : string [ ] {
103+ const lines : string [ ] = [ "" , chalk . white ( "Usage:" ) ] ;
104+
105+ try {
106+ const usage = getSessionUsage ( ) ;
107+ if ( usage . totalCost > 0 ) {
108+ lines . push (
109+ ` Total Cost: ${ chalk . green ( `$${ usage . totalCost . toFixed ( 6 ) } ` ) } ` ,
110+ ) ;
111+ lines . push (
112+ ` Input Tokens: ${ chalk . cyan ( usage . promptTokens . toLocaleString ( ) ) } ` ,
113+ ) ;
114+ lines . push (
115+ ` Output Tokens: ${ chalk . cyan ( usage . completionTokens . toLocaleString ( ) ) } ` ,
116+ ) ;
117+
118+ if ( usage . promptTokensDetails ?. cachedTokens ) {
119+ lines . push (
120+ ` Cache Read Tokens: ${ chalk . cyan ( usage . promptTokensDetails . cachedTokens . toLocaleString ( ) ) } ` ,
121+ ) ;
122+ }
123+
124+ if ( usage . promptTokensDetails ?. cacheWriteTokens ) {
125+ lines . push (
126+ ` Cache Write Tokens: ${ chalk . cyan ( usage . promptTokensDetails . cacheWriteTokens . toLocaleString ( ) ) } ` ,
127+ ) ;
128+ }
129+
130+ const totalTokens = usage . promptTokens + usage . completionTokens ;
131+ lines . push ( ` Total Tokens: ${ chalk . cyan ( totalTokens . toLocaleString ( ) ) } ` ) ;
132+ } else {
133+ lines . push ( ` ${ chalk . gray ( "No usage data yet" ) } ` ) ;
134+ }
135+ } catch ( error ) {
136+ logger . warn ( "Failed to get session usage:" , error ) ;
137+ lines . push ( ` ${ chalk . red ( "Usage data not available" ) } ` ) ;
138+ }
139+
140+ return lines ;
141+ }
142+
143+ function getDiagnosticInfo ( ) : string [ ] {
102144 const nodePath = process . execPath ;
103145 const invokedPath = process . argv [ 1 ] ;
104146
@@ -111,20 +153,27 @@ export async function handleInfoSlashCommand() {
111153 stdio : [ "pipe" , "pipe" , "ignore" ] ,
112154 } ) . trim ( ) ;
113155 } catch ( error ) {
114- // If npm command fails, fallback to "unknown"
115156 logger . warn ( "Failed to get npm version:" , error ) ;
116157 }
117158
118- // Diagnostic info
119- infoLines . push (
159+ return [
120160 "" ,
121161 chalk . white ( "Diagnostic Info" ) ,
122162 ` Currently running: npm-global (${ chalk . green ( npmVersion ) } )` ,
123163 ` Path: ${ chalk . blue ( nodePath ) } ` ,
124164 ` Invoked: ${ chalk . blue ( invokedPath ) } ` ,
125- ) ;
165+ ] ;
166+ }
126167
127- // TODO add global settings like auto update etc.
168+ export async function handleInfoSlashCommand ( ) {
169+ const infoLines = [
170+ ...getVersionInfo ( ) ,
171+ ...( await getAuthInfo ( ) ) ,
172+ ...getConfigInfo ( ) ,
173+ ...getSessionInfo ( ) ,
174+ ...getUsageInfo ( ) ,
175+ ...getDiagnosticInfo ( ) ,
176+ ] ;
128177
129178 return {
130179 exit : false ,
0 commit comments