Skip to content
This repository was archived by the owner on Feb 25, 2026. It is now read-only.

Commit c4d31b5

Browse files
committed
feat(kilo-vscode): add dev reload and cache busting for webview
- Watch dist/webview.* for changes in development mode and auto-reload the webview HTML so changes during `pnpm watch` are reflected without manually reloading the extension host window. - Append ?v=<timestamp> cache-buster to script/style URIs so the webview browser doesn't serve stale bundles after a rebuild. - Pass extensionMode to KiloProvider so dev reload is only active when running from the Extension Development Host.
1 parent 31361d3 commit c4d31b5

2 files changed

Lines changed: 43 additions & 4 deletions

File tree

packages/kilo-vscode/src/KiloProvider.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ export class KiloProvider implements vscode.WebviewViewProvider {
1616
private unsubscribeEvent: (() => void) | null = null
1717
private unsubscribeState: (() => void) | null = null
1818
private webviewMessageDisposable: vscode.Disposable | null = null
19+
private devReloadWatcher: vscode.FileSystemWatcher | null = null
1920

2021
constructor(
2122
private readonly extensionUri: vscode.Uri,
2223
private readonly connectionService: KiloConnectionService,
24+
private readonly extensionMode: vscode.ExtensionMode = vscode.ExtensionMode.Production,
2325
) {}
2426

2527
/**
@@ -105,6 +107,11 @@ export class KiloProvider implements vscode.WebviewViewProvider {
105107
// Handle messages from webview (shared handler)
106108
this.setupWebviewMessageHandler(webviewView.webview)
107109

110+
// In development, watch for webview dist changes and auto-reload
111+
if (this.extensionMode === vscode.ExtensionMode.Development) {
112+
this.setupDevReload(webviewView.webview)
113+
}
114+
108115
// Initialize connection to CLI backend
109116
this.initializeConnection()
110117
}
@@ -127,9 +134,37 @@ export class KiloProvider implements vscode.WebviewViewProvider {
127134
// Handle messages from webview (shared handler)
128135
this.setupWebviewMessageHandler(panel.webview)
129136

137+
// In development, watch for webview dist changes and auto-reload
138+
if (this.extensionMode === vscode.ExtensionMode.Development) {
139+
this.setupDevReload(panel.webview)
140+
}
141+
130142
this.initializeConnection()
131143
}
132144

145+
/**
146+
* Watch for changes to the webview dist files and auto-reload the webview.
147+
* Only active in development mode so changes during `pnpm watch` are
148+
* reflected without manually reloading the extension host window.
149+
*/
150+
private setupDevReload(webview: vscode.Webview): void {
151+
this.devReloadWatcher?.dispose()
152+
153+
const pattern = new vscode.RelativePattern(vscode.Uri.joinPath(this.extensionUri, "dist"), "webview.*")
154+
const watcher = vscode.workspace.createFileSystemWatcher(pattern)
155+
156+
const reload = () => {
157+
console.log("[Kilo New] KiloProvider: 🔄 Dev reload — webview dist changed, reloading HTML")
158+
webview.html = ""
159+
webview.html = this._getHtmlForWebview(webview)
160+
}
161+
162+
watcher.onDidChange(reload)
163+
watcher.onDidCreate(reload)
164+
165+
this.devReloadWatcher = watcher
166+
}
167+
133168
/**
134169
* Set up the shared message handler for both sidebar and tab webviews.
135170
* Handles ALL message types so tabs have full functionality.
@@ -766,6 +801,9 @@ export class KiloProvider implements vscode.WebviewViewProvider {
766801
const styleUri = webview.asWebviewUri(vscode.Uri.joinPath(this.extensionUri, "dist", "webview.css"))
767802

768803
const nonce = getNonce()
804+
// Cache-bust so the browser inside the webview doesn't serve stale bundles
805+
// after a rebuild (especially useful during development with watch mode).
806+
const bust = Date.now()
769807

770808
// CSP allows:
771809
// - default-src 'none': Block everything by default
@@ -788,7 +826,7 @@ export class KiloProvider implements vscode.WebviewViewProvider {
788826
<meta name="viewport" content="width=device-width, initial-scale=1.0">
789827
<meta http-equiv="Content-Security-Policy" content="${csp}">
790828
<title>Kilo Code</title>
791-
<link rel="stylesheet" href="${styleUri}">
829+
<link rel="stylesheet" href="${styleUri}?v=${bust}">
792830
<style>
793831
html, body {
794832
margin: 0;
@@ -813,7 +851,7 @@ export class KiloProvider implements vscode.WebviewViewProvider {
813851
</head>
814852
<body>
815853
<div id="root"></div>
816-
<script nonce="${nonce}" src="${scriptUri}"></script>
854+
<script nonce="${nonce}" src="${scriptUri}?v=${bust}"></script>
817855
</body>
818856
</html>`
819857
}
@@ -826,6 +864,7 @@ export class KiloProvider implements vscode.WebviewViewProvider {
826864
this.unsubscribeEvent?.()
827865
this.unsubscribeState?.()
828866
this.webviewMessageDisposable?.dispose()
867+
this.devReloadWatcher?.dispose()
829868
this.trackedSessionIds.clear()
830869
}
831870
}

packages/kilo-vscode/src/extension.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export function activate(context: vscode.ExtensionContext) {
1111
const connectionService = new KiloConnectionService(context)
1212

1313
// Create the provider with shared service
14-
const provider = new KiloProvider(context.extensionUri, connectionService)
14+
const provider = new KiloProvider(context.extensionUri, connectionService, context.extensionMode)
1515

1616
// Register the webview view provider for the sidebar
1717
context.subscriptions.push(vscode.window.registerWebviewViewProvider(KiloProvider.viewType, provider))
@@ -77,7 +77,7 @@ async function openKiloInNewTab(context: vscode.ExtensionContext, connectionServ
7777
dark: vscode.Uri.joinPath(context.extensionUri, "assets", "icons", "kilo-dark.svg"),
7878
}
7979

80-
const tabProvider = new KiloProvider(context.extensionUri, connectionService)
80+
const tabProvider = new KiloProvider(context.extensionUri, connectionService, context.extensionMode)
8181
tabProvider.resolveWebviewPanel(panel)
8282

8383
// Wait for the new panel to become active before locking the editor group.

0 commit comments

Comments
 (0)