@@ -246,6 +246,17 @@ interface WhoamiOrg {
246246 plan : string | null ;
247247}
248248
249+ interface AccountMe {
250+ user : {
251+ id : string ;
252+ name : string | null ;
253+ email : string | null ;
254+ avatarUrl : string | null ;
255+ githubLogin : string | null ;
256+ } | null ;
257+ tokenType : string ;
258+ }
259+
249260const whoamiCommand = new Command < GlobalContext > ( )
250261 . description (
251262 "Verify the current Deno Deploy token and list reachable organizations" ,
@@ -260,16 +271,16 @@ const whoamiCommand = new Command<GlobalContext>()
260271 // AUTH_INVALID_TOKEN envelope from the errorLink if the token is bad,
261272 // without ever calling `requireInteractive()` or opening a browser.
262273 const trpcClient = createTrpcClient ( options ) ;
263- const orgs = await trpcClient . query ( "orgs.list" ) as WhoamiOrg [ ] ;
274+ const [ me , orgs ] = await Promise . all ( [
275+ trpcClient . query ( "account.me" ) as Promise < AccountMe > ,
276+ trpcClient . query ( "orgs.list" ) as Promise < WhoamiOrg [ ] > ,
277+ ] ) ;
264278
265279 if ( options . json ) {
266280 writeJsonResult ( {
267281 authenticated : true ,
268- // The deployng tRPC router does not currently expose user identity,
269- // so we surface what we can (orgs the token can reach). When that
270- // procedure lands, this output will gain a `user` field; existing
271- // consumers reading `authenticated` / `orgs[]` keep working.
272- user : null ,
282+ user : me . user ,
283+ tokenType : me . tokenType ,
273284 orgs : orgs . map ( ( org ) => ( {
274285 id : org . id ,
275286 slug : org . slug ,
@@ -280,8 +291,15 @@ const whoamiCommand = new Command<GlobalContext>()
280291 return ;
281292 }
282293
294+ const who = me . user
295+ ? ( me . user . githubLogin
296+ ? `@${ me . user . githubLogin } `
297+ : me . user . email ?? me . user . name ?? me . user . id )
298+ : `org-scoped token (${ me . tokenType } )` ;
283299 console . log (
284- `${ green ( "✔" ) } Authenticated. ${ orgs . length } reachable organization${
300+ `${
301+ green ( "✔" )
302+ } Authenticated as ${ who } . ${ orgs . length } reachable organization${
285303 orgs . length === 1 ? "" : "s"
286304 } :`,
287305 ) ;
@@ -300,7 +318,27 @@ export const deployCommand = new Command()
300318 . description ( `Interact with Deno Deploy
301319
302320Calling this subcommand without any further subcommands will
303- deploy your local directory to the specified application.` )
321+ deploy your local directory to the specified application.
322+
323+ For non-interactive use (CI, AI agents), authenticate via the
324+ DENO_DEPLOY_TOKEN env var (or --token) and pass --json --non-interactive
325+ to every subcommand. The CLI then emits a single JSON object on stdout,
326+ a structured { error: { code, message, hint } } envelope on stderr,
327+ and a stable exit code (0 OK, 1 GENERIC, 2 USAGE, 3 AUTH, 4 NOT_FOUND,
328+ 5 CONFLICT, 6 NETWORK). See https://docs.deno.com/runtime/reference/cli/deploy/#agent--ci-usage
329+ for the full reference.` )
330+ . example (
331+ "Verify the active token" ,
332+ "whoami --json" ,
333+ )
334+ . example (
335+ "Deploy current directory non-interactively" ,
336+ "--json --non-interactive --org my-org --app my-app --prod" ,
337+ )
338+ . example (
339+ "Create a static app from CI" ,
340+ "create --json --non-interactive --org my-org --app my-app --source local --runtime-mode static --static-dir dist --region us" ,
341+ )
304342 . globalOption ( "--endpoint <endpoint:string>" , "the endpoint" , {
305343 default : "https://console.deno.com" ,
306344 hidden : true ,
0 commit comments