@@ -279,7 +279,11 @@ export class ClineProvider implements vscode.WebviewViewProvider {
279279 enableScripts : true ,
280280 localResourceRoots : [ this . context . extensionUri ] ,
281281 }
282- webviewView . webview . html = this . getHtmlContent ( webviewView . webview )
282+
283+ webviewView . webview . html =
284+ this . context . extensionMode === vscode . ExtensionMode . Development
285+ ? this . getHMRHtmlContent ( webviewView . webview )
286+ : this . getHtmlContent ( webviewView . webview )
283287
284288 // Sets up an event listener to listen for messages passed from the webview view context
285289 // and executes code based on the message that is recieved
@@ -403,6 +407,62 @@ export class ClineProvider implements vscode.WebviewViewProvider {
403407 await this . view ?. webview . postMessage ( message )
404408 }
405409
410+ private getHMRHtmlContent ( webview : vscode . Webview ) : string {
411+ const nonce = getNonce ( )
412+
413+ const stylesUri = getUri ( webview , this . context . extensionUri , [ "webview-ui" , "build" , "assets" , "index.css" ] )
414+ const codiconsUri = getUri ( webview , this . context . extensionUri , [
415+ "node_modules" ,
416+ "@vscode" ,
417+ "codicons" ,
418+ "dist" ,
419+ "codicon.css" ,
420+ ] )
421+
422+ const file = "src/index.tsx"
423+ const localPort = "5173"
424+ const localServerUrl = `localhost:${ localPort } `
425+ const scriptUri = `http://${ localServerUrl } /${ file } `
426+
427+ const reactRefresh = /*html*/ `
428+ <script nonce="${ nonce } " type="module">
429+ import RefreshRuntime from "http://localhost:${ localPort } /@react-refresh"
430+ RefreshRuntime.injectIntoGlobalHook(window)
431+ window.$RefreshReg$ = () => {}
432+ window.$RefreshSig$ = () => (type) => type
433+ window.__vite_plugin_react_preamble_installed__ = true
434+ </script>
435+ `
436+
437+ const csp = [
438+ "default-src 'none'" ,
439+ `font-src ${ webview . cspSource } ` ,
440+ `style-src ${ webview . cspSource } 'unsafe-inline' https://* http://${ localServerUrl } http://0.0.0.0:${ localPort } ` ,
441+ `img-src ${ webview . cspSource } data:` ,
442+ `script-src 'unsafe-eval' https://* http://${ localServerUrl } http://0.0.0.0:${ localPort } 'nonce-${ nonce } '` ,
443+ `connect-src https://* ws://${ localServerUrl } ws://0.0.0.0:${ localPort } http://${ localServerUrl } http://0.0.0.0:${ localPort } ` ,
444+ ]
445+
446+ return /*html*/ `
447+ <!DOCTYPE html>
448+ <html lang="en">
449+ <head>
450+ <meta charset="utf-8">
451+ <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
452+ <meta http-equiv="Content-Security-Policy" content="${ csp . join ( "; " ) } ">
453+ <link rel="stylesheet" type="text/css" href="${ stylesUri } ">
454+ <link href="${ codiconsUri } " rel="stylesheet" />
455+ <title>Roo Code</title>
456+ </head>
457+ <body>
458+ <div id="root"></div>
459+ ${ reactRefresh }
460+ <script type="module" src="${ scriptUri } "></script>
461+ </body>
462+ </html>
463+ `
464+ }
465+
406466 /**
407467 * Defines and returns the HTML that should be rendered within the webview panel.
408468 *
@@ -558,7 +618,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
558618 }
559619 }
560620
561- let currentConfigName = ( await this . getGlobalState ( "currentApiConfigName" ) ) as string
621+ const currentConfigName = ( await this . getGlobalState ( "currentApiConfigName" ) ) as string
562622
563623 if ( currentConfigName ) {
564624 if ( ! ( await this . configManager . hasConfig ( currentConfigName ) ) ) {
@@ -1134,7 +1194,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
11341194 if ( message . text && message . apiConfiguration ) {
11351195 try {
11361196 await this . configManager . saveConfig ( message . text , message . apiConfiguration )
1137- let listApiConfig = await this . configManager . listConfig ( )
1197+ const listApiConfig = await this . configManager . listConfig ( )
11381198
11391199 await Promise . all ( [
11401200 this . updateGlobalState ( "listApiConfigMeta" , listApiConfig ) ,
@@ -1159,7 +1219,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
11591219 await this . configManager . saveConfig ( newName , message . apiConfiguration )
11601220 await this . configManager . deleteConfig ( oldName )
11611221
1162- let listApiConfig = await this . configManager . listConfig ( )
1222+ const listApiConfig = await this . configManager . listConfig ( )
11631223 const config = listApiConfig ?. find ( ( c ) => c . name === newName )
11641224
11651225 // Update listApiConfigMeta first to ensure UI has latest data
@@ -1217,7 +1277,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
12171277 await this . updateGlobalState ( "listApiConfigMeta" , listApiConfig )
12181278
12191279 // If this was the current config, switch to first available
1220- let currentApiConfigName = await this . getGlobalState ( "currentApiConfigName" )
1280+ const currentApiConfigName = await this . getGlobalState ( "currentApiConfigName" )
12211281 if ( message . text === currentApiConfigName && listApiConfig ?. [ 0 ] ?. name ) {
12221282 const apiConfig = await this . configManager . loadConfig ( listApiConfig [ 0 ] . name )
12231283 await Promise . all ( [
@@ -1237,7 +1297,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
12371297 break
12381298 case "getListApiConfiguration" :
12391299 try {
1240- let listApiConfig = await this . configManager . listConfig ( )
1300+ const listApiConfig = await this . configManager . listConfig ( )
12411301 await this . updateGlobalState ( "listApiConfigMeta" , listApiConfig )
12421302 this . postMessageToWebview ( { type : "listApiConfig" , listApiConfig } )
12431303 } catch ( error ) {
@@ -1277,7 +1337,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
12771337 this . outputChannel . appendLine (
12781338 `Failed to update timeout for ${ message . serverName } : ${ JSON . stringify ( error , Object . getOwnPropertyNames ( error ) , 2 ) } ` ,
12791339 )
1280- vscode . window . showErrorMessage ( ` Failed to update server timeout` )
1340+ vscode . window . showErrorMessage ( " Failed to update server timeout" )
12811341 }
12821342 }
12831343 break
@@ -1630,7 +1690,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
16301690 async refreshGlamaModels ( ) {
16311691 const glamaModelsFilePath = path . join ( await this . ensureCacheDirectoryExists ( ) , GlobalFileNames . glamaModels )
16321692
1633- let models : Record < string , ModelInfo > = { }
1693+ const models : Record < string , ModelInfo > = { }
16341694 try {
16351695 const response = await axios . get ( "https://glama.ai/api/gateway/v1/models" )
16361696 /*
@@ -1720,7 +1780,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
17201780 GlobalFileNames . openRouterModels ,
17211781 )
17221782
1723- let models : Record < string , ModelInfo > = { }
1783+ const models : Record < string , ModelInfo > = { }
17241784 try {
17251785 const response = await axios . get ( "https://openrouter.ai/api/v1/models" )
17261786 /*
0 commit comments