@@ -269,7 +269,11 @@ export class ClineProvider implements vscode.WebviewViewProvider {
269269 enableScripts : true ,
270270 localResourceRoots : [ this . context . extensionUri ] ,
271271 }
272- webviewView . webview . html = this . getHtmlContent ( webviewView . webview )
272+
273+ webviewView . webview . html =
274+ this . context . extensionMode === vscode . ExtensionMode . Production
275+ ? this . getHtmlContent ( webviewView . webview )
276+ : this . getHMRHtmlContent ( webviewView . webview )
273277
274278 // Sets up an event listener to listen for messages passed from the webview view context
275279 // and executes code based on the message that is recieved
@@ -393,6 +397,64 @@ export class ClineProvider implements vscode.WebviewViewProvider {
393397 await this . view ?. webview . postMessage ( message )
394398 }
395399
400+ private getHMRHtmlContent ( webview : vscode . Webview ) : string {
401+ const nonce = getNonce ( )
402+
403+ const stylesUri = getUri ( webview , this . context . extensionUri , [ "webview-ui" , "build" , "assets" , "index.css" ] )
404+ const codiconsUri = getUri ( webview , this . context . extensionUri , [
405+ "node_modules" ,
406+ "@vscode" ,
407+ "codicons" ,
408+ "dist" ,
409+ "codicon.css" ,
410+ ] )
411+
412+ const file = "src/index.tsx"
413+ const localPort = "5173"
414+ const localServerUrl = `localhost:${ localPort } `
415+ const scriptUri = `http://${ localServerUrl } /${ file } `
416+
417+ const reactRefreshHash = "sha256-YmMpkm5ow6h+lfI3ZRp0uys+EUCt6FOyLkJERkfVnTY="
418+
419+ const reactRefresh = /*html*/ `
420+ <script sha256="${ reactRefreshHash } " nonce="${ nonce } " type="module">
421+ import RefreshRuntime from "http://localhost:${ localPort } /@react-refresh"
422+ RefreshRuntime.injectIntoGlobalHook(window)
423+ window.$RefreshReg$ = () => {}
424+ window.$RefreshSig$ = () => (type) => type
425+ window.__vite_plugin_react_preamble_installed__ = true
426+ </script>
427+ `
428+
429+ const csp = [
430+ "default-src 'none'" ,
431+ `font-src ${ webview . cspSource } ` ,
432+ `style-src ${ webview . cspSource } 'unsafe-inline' https://* http://${ localServerUrl } http://0.0.0.0:${ localPort } ` ,
433+ `img-src ${ webview . cspSource } data:` ,
434+ `script-src 'unsafe-eval' https://* http://${ localServerUrl } http://0.0.0.0:${ localPort } '${ reactRefreshHash } ' 'nonce-${ nonce } '` ,
435+ `connect-src https://* ws://${ localServerUrl } ws://0.0.0.0:${ localPort } http://${ localServerUrl } http://0.0.0.0:${ localPort } ` ,
436+ ]
437+
438+ return /*html*/ `
439+ <!DOCTYPE html>
440+ <html lang="en">
441+ <head>
442+ <meta charset="utf-8">
443+ <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
444+ <meta http-equiv="Content-Security-Policy" content="${ csp . join ( "; " ) } ">
445+ <link rel="stylesheet" type="text/css" href="${ stylesUri } ">
446+ <link href="${ codiconsUri } " rel="stylesheet" />
447+ <title>Roo Code</title>
448+ </head>
449+ <body>
450+ <div id="root"></div>
451+ ${ reactRefresh }
452+ <script type="module" src="${ scriptUri } "></script>
453+ </body>
454+ </html>
455+ `
456+ }
457+
396458 /**
397459 * Defines and returns the HTML that should be rendered within the webview panel.
398460 *
@@ -548,7 +610,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
548610 }
549611 }
550612
551- let currentConfigName = ( await this . getGlobalState ( "currentApiConfigName" ) ) as string
613+ const currentConfigName = ( await this . getGlobalState ( "currentApiConfigName" ) ) as string
552614
553615 if ( currentConfigName ) {
554616 if ( ! ( await this . configManager . hasConfig ( currentConfigName ) ) ) {
@@ -1124,7 +1186,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
11241186 if ( message . text && message . apiConfiguration ) {
11251187 try {
11261188 await this . configManager . saveConfig ( message . text , message . apiConfiguration )
1127- let listApiConfig = await this . configManager . listConfig ( )
1189+ const listApiConfig = await this . configManager . listConfig ( )
11281190
11291191 await Promise . all ( [
11301192 this . updateGlobalState ( "listApiConfigMeta" , listApiConfig ) ,
@@ -1149,7 +1211,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
11491211 await this . configManager . saveConfig ( newName , message . apiConfiguration )
11501212 await this . configManager . deleteConfig ( oldName )
11511213
1152- let listApiConfig = await this . configManager . listConfig ( )
1214+ const listApiConfig = await this . configManager . listConfig ( )
11531215 const config = listApiConfig ?. find ( ( c ) => c . name === newName )
11541216
11551217 // Update listApiConfigMeta first to ensure UI has latest data
@@ -1207,7 +1269,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
12071269 await this . updateGlobalState ( "listApiConfigMeta" , listApiConfig )
12081270
12091271 // If this was the current config, switch to first available
1210- let currentApiConfigName = await this . getGlobalState ( "currentApiConfigName" )
1272+ const currentApiConfigName = await this . getGlobalState ( "currentApiConfigName" )
12111273 if ( message . text === currentApiConfigName && listApiConfig ?. [ 0 ] ?. name ) {
12121274 const apiConfig = await this . configManager . loadConfig ( listApiConfig [ 0 ] . name )
12131275 await Promise . all ( [
@@ -1227,7 +1289,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
12271289 break
12281290 case "getListApiConfiguration" :
12291291 try {
1230- let listApiConfig = await this . configManager . listConfig ( )
1292+ const listApiConfig = await this . configManager . listConfig ( )
12311293 await this . updateGlobalState ( "listApiConfigMeta" , listApiConfig )
12321294 this . postMessageToWebview ( { type : "listApiConfig" , listApiConfig } )
12331295 } catch ( error ) {
@@ -1267,7 +1329,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
12671329 this . outputChannel . appendLine (
12681330 `Failed to update timeout for ${ message . serverName } : ${ JSON . stringify ( error , Object . getOwnPropertyNames ( error ) , 2 ) } ` ,
12691331 )
1270- vscode . window . showErrorMessage ( ` Failed to update server timeout` )
1332+ vscode . window . showErrorMessage ( " Failed to update server timeout" )
12711333 }
12721334 }
12731335 break
@@ -1620,7 +1682,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
16201682 async refreshGlamaModels ( ) {
16211683 const glamaModelsFilePath = path . join ( await this . ensureCacheDirectoryExists ( ) , GlobalFileNames . glamaModels )
16221684
1623- let models : Record < string , ModelInfo > = { }
1685+ const models : Record < string , ModelInfo > = { }
16241686 try {
16251687 const response = await axios . get ( "https://glama.ai/api/gateway/v1/models" )
16261688 /*
@@ -1710,7 +1772,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
17101772 GlobalFileNames . openRouterModels ,
17111773 )
17121774
1713- let models : Record < string , ModelInfo > = { }
1775+ const models : Record < string , ModelInfo > = { }
17141776 try {
17151777 const response = await axios . get ( "https://openrouter.ai/api/v1/models" )
17161778 /*
0 commit comments