Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
A concise VS Code extension to build high‑quality XML prompts from selected workspace files and apply LLM‑suggested changes back to your code.

<p align="center">
<img src="https://github.com/user-attachments/assets/9701b7a7-5f39-4961-81ae-24d0b2d75157" alt="Overwrite extension interface showing the Context tab with file explorer, selected files, token counts, and copy buttons" width="800" />
<img src="resources/screenshot-1.jpg" alt="Overwrite extension interface showing the Context tab with file explorer, selected files, token counts, and copy buttons" width="800" />
</p>

## Features
Expand All @@ -26,7 +26,7 @@ A concise VS Code extension to build high‑quality XML prompts from selected wo
- Privacy-preserving telemetry controls.

<p align="center">
<img src="https://github.com/user-attachments/assets/b80f2319-19bb-43cd-9c10-4b15fe1ef4a6" alt="Overwrite extension interface showing the Context tab with file explorer, selected files, token counts, and copy buttons" width="800" />
<img src="resources/screenshot-4.jpg" alt="Overwrite extension interface showing the Context tab with file explorer, selected files, token counts, and copy buttons" width="800" />
</p>

## How to use
Expand All @@ -49,3 +49,7 @@ For complete details, see [TELEMETRY.md](TELEMETRY.md).
## Requirements

- VS Code 1.85.0+

## Acknowledgments

This project is heavily inspired by [RepoPrompt](https://repoprompt.com/) by @provencher.
Binary file modified resources/screenshot-1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/screenshot-4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
119 changes: 1 addition & 118 deletions src/providers/file-explorer/html-generator.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import * as fs from 'node:fs'
import * as path from 'node:path'
import * as vscode from 'vscode'
import { getNonce } from '../../utils/webview'

const DEV_WEBVIEW_URL = 'http://localhost:5173'
const DEV_TIMEOUT = 3000 // 3 seconds timeout for dev server connection

/**
* Generates the HTML content for the webview, choosing between dev and prod.
Expand All @@ -26,14 +23,6 @@ export function getHtmlForWebview(
function getDevHtml(webview: vscode.Webview, extensionUri: vscode.Uri): string {
const nonce = getNonce()

// Check if we have built webview assets for fallback
const webviewAssetsDir = vscode.Uri.joinPath(
extensionUri,
'dist',
'webview-ui',
)
const hasBuiltAssets = checkIfAssetsExist(webviewAssetsDir)

// Path to codicons from the extension's node_modules
const codiconUri = webview.asWebviewUri(
vscode.Uri.joinPath(
Expand All @@ -46,116 +35,10 @@ function getDevHtml(webview: vscode.Webview, extensionUri: vscode.Uri): string {
),
)

if (hasBuiltAssets) {
// Use built assets with development features
return getDevHtmlWithBuiltAssets(webview, extensionUri, nonce, codiconUri)
}

// Use dev server (original behavior)
// Use dev server (original behavior) - prefer dev server for development
return getDevHtmlWithServer(webview, extensionUri, nonce, codiconUri)
}

/**
* Check if built webview assets exist and are valid.
*/
function checkIfAssetsExist(assetsDir: vscode.Uri): boolean {
try {
const assetsPath = assetsDir.fsPath

// Check if directory exists
if (!fs.existsSync(assetsPath)) {
return false
}

// Check for required files
const requiredFiles = [
path.join(assetsPath, 'assets', 'index.js'),
path.join(assetsPath, 'assets', 'index.css'),
path.join(assetsPath, 'assets', 'codicon.css'),
]

return requiredFiles.every((file) => fs.existsSync(file))
} catch {
return false
}
}

/**
* Development HTML using built assets with hot reload capabilities.
*/
function getDevHtmlWithBuiltAssets(
webview: vscode.Webview,
extensionUri: vscode.Uri,
nonce: string,
codiconUri: vscode.Uri,
): string {
const cspSource = webview.cspSource

// Paths to built assets
const scriptUri = webview.asWebviewUri(
vscode.Uri.joinPath(
extensionUri,
'dist',
'webview-ui',
'assets',
'index.js',
),
)
const styleUri = webview.asWebviewUri(
vscode.Uri.joinPath(
extensionUri,
'dist',
'webview-ui',
'assets',
'index.css',
),
)

// CSP for development with built assets
const csp = [
`default-src 'none'`,
`font-src ${cspSource} data:`,
`connect-src ws://localhost:5173 ${cspSource}`, // Allow WebSocket for HMR
`img-src ${cspSource} https: data:`,
`script-src 'nonce-${nonce}' 'unsafe-eval' 'unsafe-inline'`, // Allow eval for HMR
`style-src ${cspSource} 'unsafe-inline'`,
].join('; ')

return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="${codiconUri}" rel="stylesheet" id="vscode-codicon-stylesheet" />
<meta http-equiv="Content-Security-Policy" content="${csp}">
<link rel="stylesheet" type="text/css" href="${styleUri}">
<title>Overwrite (Dev)</title>
</head>
<body>
<div id="root"></div>
<script type="module" nonce="${nonce}" src="${scriptUri}"></script>
<script nonce="${nonce}">
// Pass vscode API and nonce to the webview
window.nonce = "${nonce}"
window.vscodeApi = acquireVsCodeApi()

// Attempt to connect to Vite dev server for HMR
setTimeout(() => {
try {
const script = document.createElement('script')
script.type = 'module'
script.src = '${DEV_WEBVIEW_URL}/@vite/client'
document.head.appendChild(script)
console.log('[HMR] Attempting to connect to Vite dev server...')
} catch (err) {
console.log('[HMR] Could not connect to Vite dev server, using built assets')
}
}, ${DEV_TIMEOUT})
</script>
</body>
</html>`
}

/**
* Development HTML using Vite dev server (original behavior).
*/
Expand Down
17 changes: 14 additions & 3 deletions src/webview-ui/src/components/context-tab/user-instructions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,20 @@ const UserInstructions: React.FC<UserInstructionsProps> = ({
}) => {
return (
<div className="flex flex-col">
<vscode-label htmlFor="user-instructions" className="block mb-1">
User Instruction
</vscode-label>
<div className="flex items-center justify-between mb-1">
<vscode-label htmlFor="user-instructions">
User Instruction
</vscode-label>
<a
className="text-[8px] text-muted hover:underline hover:text-fg flex items-center gap-1"
href="https://mnismt.com/overwrite"
target="_blank"
rel="noreferrer"
aria-label="Open Overwrite docs and video demo in your browser"
>
<span>Docs</span>
</a>
</div>
<vscode-textarea
id="user-instructions"
resize="vertical"
Expand Down