66import vscode , { env , version } from 'vscode'
77import * as nls from 'vscode-nls'
88import * as crypto from 'crypto'
9+ import * as jose from 'jose'
910import { LanguageClient , LanguageClientOptions } from 'vscode-languageclient'
1011import { InlineCompletionManager } from '../app/inline/completion'
1112import { AuthUtil } from 'aws-core-vscode/codewhisperer'
12- import { ConnectionMetadata } from '@aws/language-server-runtimes/protocol'
13- import { Settings , oidcClientName , createServerOptions , globals , Experiments , Commands } from 'aws-core-vscode/shared'
13+ import {
14+ ConnectionMetadata ,
15+ GetSsoTokenProgress ,
16+ GetSsoTokenProgressToken ,
17+ GetSsoTokenProgressType ,
18+ MessageActionItem ,
19+ ShowDocumentParams ,
20+ ShowDocumentRequest ,
21+ ShowDocumentResult ,
22+ ShowMessageRequest ,
23+ ShowMessageRequestParams ,
24+ } from '@aws/language-server-runtimes/protocol'
25+ import {
26+ Settings ,
27+ oidcClientName ,
28+ createServerOptions ,
29+ globals ,
30+ Experiments ,
31+ Commands ,
32+ openUrl ,
33+ getLogger ,
34+ } from 'aws-core-vscode/shared'
1435import { activate } from './chat/activation'
1536import { AmazonQResourcePaths } from './lspInstaller'
1637import { auth2 } from 'aws-core-vscode/auth'
1738
1839const localize = nls . loadMessageBundle ( )
1940
41+ export const clientId = 'amazonq'
42+ export const clientName = oidcClientName ( )
2043export const encryptionKey = crypto . randomBytes ( 32 )
2144
2245export async function startLanguageServer (
@@ -41,8 +64,6 @@ export async function startLanguageServer(
4164 } )
4265
4366 const documentSelector = [ { scheme : 'file' , language : '*' } ]
44-
45- const clientId = 'amazonq'
4667 const traceServerEnabled = Settings . instance . isSet ( `${ clientId } .trace.server` )
4768
4869 // Options to control the language client
@@ -82,12 +103,8 @@ export async function startLanguageServer(
82103 } ) ,
83104 }
84105
85- const client = new LanguageClient (
86- clientId ,
87- localize ( 'amazonq.server.name' , 'Amazon Q Language Server' ) ,
88- serverOptions ,
89- clientOptions
90- )
106+ const lspName = localize ( 'amazonq.server.name' , 'Amazon Q Language Server' )
107+ const client = new LanguageClient ( clientId , lspName , serverOptions , clientOptions )
91108
92109 const disposable = client . start ( )
93110 toDispose . push ( disposable )
@@ -102,6 +119,59 @@ export async function startLanguageServer(
102119 }
103120 } )
104121
122+ client . onRequest < ShowDocumentResult , Error > ( ShowDocumentRequest . method , async ( params : ShowDocumentParams ) => {
123+ try {
124+ return { success : await openUrl ( vscode . Uri . parse ( params . uri ) , lspName ) }
125+ } catch ( err : any ) {
126+ getLogger ( ) . error ( `Failed to open document for LSP: ${ lspName } , error: %s` , err )
127+ return { success : false }
128+ }
129+ } )
130+
131+ client . onRequest < MessageActionItem | null , Error > (
132+ ShowMessageRequest . method ,
133+ async ( params : ShowMessageRequestParams ) => {
134+ const actions = params . actions ?. map ( ( a ) => a . title ) ?? [ ]
135+ const response = await vscode . window . showInformationMessage ( params . message , { modal : true } , ...actions )
136+ return params . actions ?. find ( ( a ) => a . title === response ) ?? ( undefined as unknown as null )
137+ }
138+ )
139+
140+ let promise : Promise < void > | undefined
141+ let resolver : ( ) => void = ( ) => { }
142+ client . onProgress (
143+ GetSsoTokenProgressType ,
144+ GetSsoTokenProgressToken ,
145+ async ( partialResult : GetSsoTokenProgress ) => {
146+ const decryptedKey = await jose . compactDecrypt ( partialResult as unknown as string , encryptionKey )
147+ const val : GetSsoTokenProgress = JSON . parse ( decryptedKey . plaintext . toString ( ) )
148+
149+ if ( val . state === 'InProgress' ) {
150+ if ( promise ) {
151+ resolver ( )
152+ }
153+ promise = new Promise < void > ( ( resolve ) => {
154+ resolver = resolve
155+ } )
156+ } else {
157+ resolver ( )
158+ promise = undefined
159+ return
160+ }
161+
162+ void vscode . window . withProgress (
163+ {
164+ cancellable : true ,
165+ location : vscode . ProgressLocation . Notification ,
166+ title : val . message ,
167+ } ,
168+ async ( _ ) => {
169+ await promise
170+ }
171+ )
172+ }
173+ )
174+
105175 if ( Experiments . instance . get ( 'amazonqLSPInline' , false ) ) {
106176 const inlineManager = new InlineCompletionManager ( client )
107177 inlineManager . registerInlineCompletion ( )
@@ -118,6 +188,8 @@ export async function startLanguageServer(
118188
119189 if ( Experiments . instance . get ( 'amazonqChatLSP' , false ) ) {
120190 activate ( client , encryptionKey , resourcePaths . ui )
191+ AuthUtil . create ( new auth2 . LanguageClientAuth ( client , clientId , encryptionKey ) )
192+ await AuthUtil . instance . restore ( )
121193 }
122194 } )
123195}
0 commit comments