11import {
22 addLocalClientToken ,
3+ type LocalClientTokenRecord ,
34 loadLocalClientTokenStore ,
45 revokeLocalClientToken ,
56 rotateLocalClientToken ,
@@ -14,14 +15,45 @@ function printBridgeUsage(logInfo: (message: string) => void): void {
1415 logInfo (
1516 [
1617 "Usage:" ,
17- " codex auth bridge token create [--label <label>]" ,
18- " codex auth bridge token list" ,
19- " codex auth bridge token rotate <id>" ,
20- " codex auth bridge token revoke <id>" ,
18+ " codex auth bridge token create [--label <label>] [--json] " ,
19+ " codex auth bridge token list [--json] " ,
20+ " codex auth bridge token rotate <id> [--json] " ,
21+ " codex auth bridge token revoke <id> [--json] " ,
2122 ] . join ( "\n" ) ,
2223 ) ;
2324}
2425
26+ function printJson ( logInfo : ( message : string ) => void , value : unknown ) : void {
27+ logInfo ( JSON . stringify ( value , null , 2 ) ) ;
28+ }
29+
30+ function publicTokenRecord ( token : LocalClientTokenRecord ) : {
31+ id : string ;
32+ label : string ;
33+ prefix : string ;
34+ createdAt : number ;
35+ lastUsedAt : number | null ;
36+ revokedAt : number | null ;
37+ state : "active" | "revoked" ;
38+ } {
39+ return {
40+ id : token . id ,
41+ label : token . label ,
42+ prefix : token . prefix ,
43+ createdAt : token . createdAt ,
44+ lastUsedAt : token . lastUsedAt ,
45+ revokedAt : token . revokedAt ,
46+ state : token . revokedAt === null ? "active" : "revoked" ,
47+ } ;
48+ }
49+
50+ function consumeJsonFlag ( args : string [ ] ) : { json : boolean ; rest : string [ ] } {
51+ return {
52+ json : args . includes ( "--json" ) || args . includes ( "-j" ) ,
53+ rest : args . filter ( ( arg ) => arg !== "--json" && arg !== "-j" ) ,
54+ } ;
55+ }
56+
2557function parseLabel ( args : string [ ] ) : { ok : true ; label ?: string } | { ok : false ; message : string } {
2658 let label : string | undefined ;
2759 for ( let i = 0 ; i < args . length ; i += 1 ) {
@@ -58,19 +90,40 @@ export async function runBridgeCommand(
5890 return 1 ;
5991 }
6092 if ( action === "create" ) {
61- const parsed = parseLabel ( rest ) ;
93+ const { json, rest : actionArgs } = consumeJsonFlag ( rest ) ;
94+ const parsed = parseLabel ( actionArgs ) ;
6295 if ( ! parsed . ok ) {
6396 logError ( parsed . message ) ;
6497 return 1 ;
6598 }
6699 const created = await addLocalClientToken ( { label : parsed . label } ) ;
100+ if ( json ) {
101+ printJson ( logInfo , {
102+ command : "bridge token create" ,
103+ token : publicTokenRecord ( created . record ) ,
104+ plainToken : created . plainToken ,
105+ } ) ;
106+ return 0 ;
107+ }
67108 logInfo ( `Token id: ${ created . record . id } ` ) ;
68109 logInfo ( `Token prefix: ${ created . record . prefix } ` ) ;
69110 logInfo ( `Token: ${ created . plainToken } ` ) ;
70111 return 0 ;
71112 }
72113 if ( action === "list" ) {
114+ const { json, rest : actionArgs } = consumeJsonFlag ( rest ) ;
115+ if ( actionArgs . length > 0 ) {
116+ logError ( `Unknown bridge token list option: ${ actionArgs [ 0 ] ?? "" } ` ) ;
117+ return 1 ;
118+ }
73119 const store = await loadLocalClientTokenStore ( ) ;
120+ if ( json ) {
121+ printJson ( logInfo , {
122+ command : "bridge token list" ,
123+ tokens : store . tokens . map ( publicTokenRecord ) ,
124+ } ) ;
125+ return 0 ;
126+ }
74127 if ( store . tokens . length === 0 ) {
75128 logInfo ( "No local bridge tokens configured." ) ;
76129 return 0 ;
@@ -82,32 +135,58 @@ export async function runBridgeCommand(
82135 return 0 ;
83136 }
84137 if ( action === "rotate" ) {
85- const id = rest [ 0 ] ;
138+ const { json, rest : actionArgs } = consumeJsonFlag ( rest ) ;
139+ const id = actionArgs [ 0 ] ;
86140 if ( ! id ) {
87141 logError ( "Missing token id" ) ;
88142 return 1 ;
89143 }
144+ if ( actionArgs . length > 1 ) {
145+ logError ( `Unknown bridge token rotate option: ${ actionArgs [ 1 ] ?? "" } ` ) ;
146+ return 1 ;
147+ }
90148 const rotated = await rotateLocalClientToken ( { id } ) ;
91149 if ( ! rotated ) {
92150 logError ( "Token not found or already revoked." ) ;
93151 return 1 ;
94152 }
153+ if ( json ) {
154+ printJson ( logInfo , {
155+ command : "bridge token rotate" ,
156+ token : publicTokenRecord ( rotated . record ) ,
157+ plainToken : rotated . plainToken ,
158+ } ) ;
159+ return 0 ;
160+ }
95161 logInfo ( `Token id: ${ rotated . record . id } ` ) ;
96162 logInfo ( `Token prefix: ${ rotated . record . prefix } ` ) ;
97163 logInfo ( `Token: ${ rotated . plainToken } ` ) ;
98164 return 0 ;
99165 }
100166 if ( action === "revoke" ) {
101- const id = rest [ 0 ] ;
167+ const { json, rest : actionArgs } = consumeJsonFlag ( rest ) ;
168+ const id = actionArgs [ 0 ] ;
102169 if ( ! id ) {
103170 logError ( "Missing token id" ) ;
104171 return 1 ;
105172 }
173+ if ( actionArgs . length > 1 ) {
174+ logError ( `Unknown bridge token revoke option: ${ actionArgs [ 1 ] ?? "" } ` ) ;
175+ return 1 ;
176+ }
106177 const revoked = await revokeLocalClientToken ( id ) ;
107178 if ( ! revoked ) {
108179 logError ( "Token not found or already revoked." ) ;
109180 return 1 ;
110181 }
182+ if ( json ) {
183+ printJson ( logInfo , {
184+ command : "bridge token revoke" ,
185+ id,
186+ revoked : true ,
187+ } ) ;
188+ return 0 ;
189+ }
111190 logInfo ( "Token revoked." ) ;
112191 return 0 ;
113192 }
0 commit comments