diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5977477f..c151838f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,43 +72,12 @@ jobs: run: cargo ci test vscode-extension: - name: VSCode Extension Tests - strategy: - matrix: - os: [ubuntu-latest, macos-latest] - - runs-on: ${{ matrix.os }} + name: VSCode Extension Build + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Install Rust - uses: dtolnay/rust-toolchain@stable - - - name: Cache Rust dependencies - uses: actions/cache@v4 - with: - path: | - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-cargo-vscode-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo-vscode- - ${{ runner.os }}-cargo- - - - name: Cache VS Code test download - uses: actions/cache@v4 - with: - path: vscode-extension/.vscode-test - key: ${{ runner.os }}-vscode-test-1.108.0 - - - name: Install ACP tools - run: | - cargo install --force elizacp - cargo install --force --path src/symposium-acp-agent - - name: Setup Node.js uses: actions/setup-node@v4 with: @@ -116,12 +85,6 @@ jobs: cache: "npm" cache-dependency-path: vscode-extension/package-lock.json - - name: Build vendored mynah-ui - working-directory: vendor/mynah-ui - run: | - npm ci - npm run build - - name: Install dependencies working-directory: vscode-extension run: npm ci @@ -129,13 +92,3 @@ jobs: - name: Compile TypeScript working-directory: vscode-extension run: npm run compile - - - name: Run tests - working-directory: vscode-extension - run: xvfb-run -a npm test - if: runner.os == 'Linux' - - - name: Run tests (macOS) - working-directory: vscode-extension - run: npm test - if: runner.os == 'macOS' diff --git a/.github/workflows/release-binaries.yml b/.github/workflows/release-binaries.yml index 8df6a065..1065d846 100644 --- a/.github/workflows/release-binaries.yml +++ b/.github/workflows/release-binaries.yml @@ -120,12 +120,6 @@ jobs: if: runner.os != 'Windows' run: chmod +x vscode-extension/bin/${{ matrix.vscode-target }}/${{ matrix.binary }} - - name: Build vendored mynah-ui - working-directory: vendor/mynah-ui - run: | - npm ci - npm run build - - name: Install extension dependencies working-directory: vscode-extension run: npm ci diff --git a/Cargo.lock b/Cargo.lock index 74406cf1..8f833f17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3815,6 +3815,7 @@ dependencies = [ "serial_test", "sha2", "shell-words", + "symposium-editor-context", "symposium-recommendations", "tar", "tempfile", @@ -3858,9 +3859,22 @@ dependencies = [ "which 4.4.2", ] +[[package]] +name = "symposium-editor-context" +version = "0.1.0" +dependencies = [ + "anyhow", + "sacp", + "sacp-tokio", + "serde", + "serde_json", + "tokio", + "tracing", +] + [[package]] name = "symposium-ferris" -version = "1.0.3" +version = "1.1.0" dependencies = [ "anyhow", "cargo_metadata 0.18.1", diff --git a/Cargo.toml b/Cargo.toml index 6fc8ac2e..90950472 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ members = [ "src/symposium-recommendations", "src/cli-agent-util", "src/symposium-benchmark", + "src/symposium-editor-context", ] resolver = "2" diff --git a/md/SUMMARY.md b/md/SUMMARY.md index 1f396be9..d28d3939 100644 --- a/md/SUMMARY.md +++ b/md/SUMMARY.md @@ -46,20 +46,12 @@ - [Run Mode](./design/run-mode.md) - [Rust Crate Sources](./design/rust-crate-sources.md) - [VSCode Extension](./design/vscode-extension/architecture.md) - - [Message Protocol](./design/vscode-extension/message-protocol.md) - - [Tool Authorization](./design/vscode-extension/tool-authorization.md) - - [State Persistence](./design/vscode-extension/state-persistence.md) - - [Webview Lifecycle](./design/vscode-extension/webview-lifecycle.md) - [Testing](./design/vscode-extension/testing.md) - - [Testing Implementation](./design/vscode-extension/testing-implementation.md) - [Packaging](./design/vscode-extension/packaging.md) - [Mods UI](./design/vscode-extension/mods.md) - [Language Model Provider](./design/vscode-extension/lm-provider.md) - [Language Model Tool Bridging](./design/vscode-extension/lm-tool-bridging.md) - - [Implementation Status](./design/vscode-extension/implementation-status.md) - [Reference material](./references/index.md) - - [MynahUI GUI Capabilities](./references/mynah-ui-guide.md) - - [VSCode Webview Lifecycle](./references/vscode-webview-lifecycle.md) - [VSCode Language Model Tool API](./references/vscode-lm-tool-api.md) - [VSCode Language Model Tool Rejection](./references/vscode-lm-tool-rejection.md) - [GitHub Actions Rust Releases](./references/gh-actions-rust-releases.md) diff --git a/md/design/components.md b/md/design/components.md index 140c0a72..d023886a 100644 --- a/md/design/components.md +++ b/md/design/components.md @@ -81,6 +81,19 @@ Provides AI collaboration framework through prompt injection and MCP tooling. - **Function:** Enables partnership dynamics, pattern anchors, and meta-collaboration capabilities - **Documentation:** [Sparkle docs](https://symposium-dev.github.io/sparkle/) +### Editor Context + +Injects the editor's current state (active file, selection) into agent prompts. + +- **Type:** Standalone component (no adapter) +- **Implementation:** Reads a JSON state file written by the editor extension, prepends an `` block to each `PromptRequest` +- **Activation:** Conditional — only inserted into the proxy chain when the `SYMPOSIUM_EDITOR_STATE_FILE` environment variable is set +- **Staleness:** Skips injection if the state file is older than 30 seconds +- **Crate:** `symposium-editor-context` +- **Documentation:** [VSCode Extension Architecture](./vscode-extension/architecture.md#editor-context-proxy) + +The editor extension writes the state file; the proxy reads it. They communicate only through the filesystem, bridged by the environment variable. This means the proxy works with any editor that writes the expected JSON format — it is not VSCode-specific. + ## Future Components Additional components can be added following these patterns: diff --git a/md/design/vscode-extension/architecture.md b/md/design/vscode-extension/architecture.md index a8e4a95b..29aee98e 100644 --- a/md/design/vscode-extension/architecture.md +++ b/md/design/vscode-extension/architecture.md @@ -1,171 +1,138 @@ # VSCode Extension Architecture -The Symposium VSCode extension provides a chat interface for interacting with AI agents. The architecture divides responsibilities across three layers to handle VSCode's webview constraints while maintaining clean separation of concerns. +The Symposium VSCode extension provides a chat interface for interacting with AI agents. The extension delegates UI and agent communication to [Toad](https://github.com/anthropics/toad), embedding its web frontend in a webview iframe. -## Components Overview - -**mynah-ui:** AWS's open-source chat interface library ([github.com/aws/mynah-ui](https://github.com/aws/mynah-ui)). Provides the chat UI rendering, tab management, and message display. The webview layer uses mynah-ui for all visual presentation. - -**Agent:** Currently a mock implementation (HomerActor) that responds with Homer Simpson quotes. Future implementation will spawn an ACP-compatible agent process (see ACP Integration chapter when available). - -**Extension activation:** VSCode activates the extension when the user first opens the Symposium sidebar or runs a Symposium command. The extension spawns the agent process during activation (or lazily on first use) and keeps it alive for the entire VSCode session. - -## Three-Layer Model +## Architecture ``` ┌─────────────────────────────────────────────────┐ -│ Webview (Browser Context) │ -│ - mynah-ui rendering │ -│ - User interaction capture │ -│ - Tab management │ -└─────────────────┬───────────────────────────────┘ - │ VSCode postMessage API -┌─────────────────▼───────────────────────────────┐ -│ Extension (Node.js Context) │ -│ - Message routing │ -│ - Agent lifecycle │ -│ - Webview lifecycle │ -└─────────────────┬───────────────────────────────┘ - │ Process spawning / stdio -┌─────────────────▼───────────────────────────────┐ -│ Agent (Separate Process) │ -│ - Session management │ -│ - AI interaction │ -│ - Streaming responses │ +│ VSCode Extension (Node.js) │ +│ - Spawns Toad as a detached process │ +│ - Embeds Toad's web UI in an iframe │ +│ - Tracks editor state (active file, selection) │ +│ - Manages Toad process lifecycle │ +└────────┬──────────────────────────┬─────────────┘ + │ │ + │ iframe (localhost) │ SYMPOSIUM_EDITOR_STATE_FILE + ▼ ▼ +┌──────────────────┐ ┌─────────────────────────┐ +│ Toad │ │ State File (JSON) │ +│ - Chat UI │ │ - Active file path │ +│ - Tool approval │ │ - Language ID │ +│ - Tab management │ │ - Selected text │ +│ - Session state │ │ - Workspace folders │ +└────────┬──────────┘ └─────────────┬───────────┘ + │ ACP (stdio) │ std::fs::read + ▼ ▼ +┌─────────────────────────────────────────────────┐ +│ Symposium Conductor │ +│ ┌────────────────────────────────────────────┐ │ +│ │ Editor Context Proxy (reads state file) │ │ +│ ├────────────────────────────────────────────┤ │ +│ │ Sparkle / Ferris / Cargo / other proxies │ │ +│ └────────────────────────────────────────────┘ │ +│ ↓ ACP (stdio) │ +│ Downstream Agent │ └─────────────────────────────────────────────────┘ ``` -## Why Three Layers? - -### Webview Isolation - -VSCode webviews run in isolated browser contexts without Node.js APIs. This security boundary prevents direct file system access, process spawning, or network operations. The webview can only communicate with the extension through VSCode's `postMessage` API. +## Toad Integration -**Design consequence:** UI code must be pure browser JavaScript. All privileged operations (spawning agents, workspace access, persistence) happen in the extension layer. +The extension spawns Toad as a **detached process** that runs an HTTP server on a local port. The webview displays an iframe pointing to `http://localhost:/`. -### Extension as Coordinator +Toad handles: +- Chat UI rendering and interaction +- Tool permission approval cards +- Tab and session management +- Streaming response display -The extension runs in Node.js with full VSCode API access. It bridges between the isolated webview and external agent processes. +The extension handles: +- Finding a free port and spawning Toad +- Persisting the Toad process across VSCode reloads (via `globalState`) +- Reconnecting to an existing Toad process if one is already running +- Tracking editor state for the editor context proxy -**Key responsibilities:** -- **Message routing** - Translates between webview UI events and agent protocol messages -- **Agent lifecycle** - Spawns and manages the agent process -- **Webview lifecycle** - Handles visibility changes and ensures messages reach the UI +### Process Lifecycle -The extension deliberately avoids understanding message semantics. It routes based on IDs (tab ID, message ID) without interpreting content. +Toad is spawned with `detached: true` and `child.unref()`, so it survives extension host restarts. The extension stores `{pid, port}` in `globalState`. On activation, it checks whether the saved port is still responding before spawning a new process. -### Agent Independence - -The agent runs as a separate process communicating via stdio. This isolation provides: - -- **Flexibility** - Agent can be any executable (Rust, Python, TypeScript) -- **Stability** - Agent crashes don't kill the extension -- **Multiple sessions** - Single agent process handles all tabs/conversations - -The agent owns all session state and conversation logic. The extension only tracks which tab corresponds to which session. +The Toad command is: +```bash +toad acp " run" --serve --port +``` -## Communication Boundaries +Toad spawns the Symposium conductor internally and manages the ACP connection over stdio. -### Webview ↔ Extension +### Webview -**Transport:** `postMessage` API (asynchronous, JSON-serializable messages only) +The webview is minimal — an HTML page containing a single iframe: -**Direction:** -- Webview → Extension: User actions (new tab, send prompt, close tab) -- Extension → Webview: Agent responses (response chunks, completion signals) +```html + + + +`; + } + + private getErrorHtml(message: string): string { + return ` + + + + + + +

Failed to start Symposium

+

${this.escapeHtml(message)}

+

Make sure toad is installed and available on your PATH.

+

You can configure the path in Settings: symposium.toadCommand

+ +`; + } + + private escapeHtml(text: string): string { + return text + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """); + } +} diff --git a/vscode-extension/src/workspaceFileIndex.ts b/vscode-extension/src/workspaceFileIndex.ts deleted file mode 100644 index 5b21d068..00000000 --- a/vscode-extension/src/workspaceFileIndex.ts +++ /dev/null @@ -1,417 +0,0 @@ -import * as vscode from "vscode"; -import * as cp from "child_process"; -import { logger } from "./extension"; - -/** Maximum number of files to include in context commands */ -const MAX_CONTEXT_FILES = 16000; - -/** Maximum number of symbols to include in context commands */ -const MAX_CONTEXT_SYMBOLS = 5000; - -/** Represents a workspace symbol for context */ -export interface ContextSymbol { - name: string; - kind: vscode.SymbolKind; - location: string; // relative file path - containerName?: string; - /** Full definition range (from DocumentSymbol.range) */ - range: { - startLine: number; - startChar: number; - endLine: number; - endChar: number; - }; - /** Selection range - just the symbol name (from DocumentSymbol.selectionRange) */ - selectionRange?: { - startLine: number; - startChar: number; - endLine: number; - endChar: number; - }; -} - -/** - * Maintains a live index of files and symbols in the workspace. - * - * Files: - * - Initializes from `git ls-files` (respects .gitignore) - * - Falls back to `workspace.findFiles` for non-git workspaces - * - Uses FileSystemWatcher for live updates - * - Tracks open editor tabs (even files outside workspace) - * - * Symbols: - * - Fetched via executeWorkspaceSymbolProvider with empty query - * - Results depend on language server support - */ -export class WorkspaceFileIndex { - #workspaceFolder: vscode.WorkspaceFolder; - #files: Set = new Set(); - #symbols: ContextSymbol[] = []; - #watcher: vscode.FileSystemWatcher | undefined; - #openTabsDisposable: vscode.Disposable | undefined; - #onDidChange = new vscode.EventEmitter(); - #isGitRepo: boolean = false; - - /** Fires when the file or symbol list changes */ - readonly onDidChange = this.#onDidChange.event; - - constructor(workspaceFolder: vscode.WorkspaceFolder) { - this.#workspaceFolder = workspaceFolder; - } - - /** Initialize the index - call this before using */ - async initialize(): Promise { - // Try git ls-files first - this.#isGitRepo = await this.#tryGitLsFiles(); - - if (!this.#isGitRepo) { - // Fall back to workspace.findFiles - await this.#fallbackFindFiles(); - } - - // Set up file watcher for live updates - this.#setupWatcher(); - - // Track open tabs - this.#setupOpenTabsTracking(); - - // Fetch workspace symbols (async, non-blocking) - this.#fetchWorkspaceSymbols(); - - logger.debug("fileIndex", "Initialized workspace file index", { - workspace: this.#workspaceFolder.name, - fileCount: this.#files.size, - isGitRepo: this.#isGitRepo, - }); - } - - /** Get all indexed files as relative paths */ - getFiles(): string[] { - // Combine workspace files with open tabs, limit to MAX_CONTEXT_FILES - const allFiles = new Set(this.#files); - - // Add open tabs (may include files outside workspace) - for (const tabGroup of vscode.window.tabGroups.all) { - for (const tab of tabGroup.tabs) { - if (tab.input instanceof vscode.TabInputText) { - const uri = tab.input.uri; - const relativePath = this.#getRelativePath(uri); - if (relativePath) { - allFiles.add(relativePath); - } - } - } - } - - // Convert to sorted array and limit - const sorted = Array.from(allFiles).sort(); - if (sorted.length > MAX_CONTEXT_FILES) { - logger.debug("fileIndex", "Truncating file list", { - total: sorted.length, - limit: MAX_CONTEXT_FILES, - }); - return sorted.slice(0, MAX_CONTEXT_FILES); - } - return sorted; - } - - /** Get all indexed symbols */ - getSymbols(): ContextSymbol[] { - return this.#symbols; - } - - /** Get the workspace folder this index is for */ - get workspaceFolder(): vscode.WorkspaceFolder { - return this.#workspaceFolder; - } - - /** Fetch workspace symbols using DocumentSymbol for full definition ranges */ - async #fetchWorkspaceSymbols(): Promise { - try { - const startTime = Date.now(); - const files = this.getFiles(); - - // Filter to source files that are likely to have symbols - const sourceExtensions = new Set([ - "ts", - "tsx", - "js", - "jsx", - "rs", - "py", - "go", - "java", - "c", - "cpp", - "h", - "hpp", - "cs", - "rb", - "swift", - "kt", - "scala", - "vue", - "svelte", - ]); - - const sourceFiles = files.filter((f) => { - const ext = f.split(".").pop()?.toLowerCase(); - return ext && sourceExtensions.has(ext); - }); - - logger.debug("fileIndex", "Fetching DocumentSymbols for source files", { - totalFiles: files.length, - sourceFiles: sourceFiles.length, - }); - - const contextSymbols: ContextSymbol[] = []; - let filesProcessed = 0; - let filesWithSymbols = 0; - - // Process files in parallel batches for performance - const batchSize = 10; - for (let i = 0; i < sourceFiles.length; i += batchSize) { - if (contextSymbols.length >= MAX_CONTEXT_SYMBOLS) { - break; - } - - const batch = sourceFiles.slice(i, i + batchSize); - const results = await Promise.all( - batch.map((relativePath) => this.#fetchDocumentSymbols(relativePath)), - ); - - for (let j = 0; j < results.length; j++) { - const symbols = results[j]; - const relativePath = batch[j]; - filesProcessed++; - - if (symbols && symbols.length > 0) { - filesWithSymbols++; - this.#collectSymbols( - symbols, - relativePath, - contextSymbols, - undefined, - ); - } - - if (contextSymbols.length >= MAX_CONTEXT_SYMBOLS) { - break; - } - } - } - - this.#symbols = contextSymbols; - - const elapsed = Date.now() - startTime; - logger.debug("fileIndex", "Fetched DocumentSymbols", { - filesProcessed, - filesWithSymbols, - symbolCount: contextSymbols.length, - elapsed, - }); - - // Notify listeners - if (contextSymbols.length > 0) { - this.#onDidChange.fire(); - } - } catch (err) { - logger.error("fileIndex", "Failed to fetch workspace symbols", { - error: err, - }); - } - } - - /** Fetch DocumentSymbol for a single file */ - async #fetchDocumentSymbols( - relativePath: string, - ): Promise { - try { - const uri = vscode.Uri.joinPath(this.#workspaceFolder.uri, relativePath); - const symbols = await vscode.commands.executeCommand< - vscode.DocumentSymbol[] - >("vscode.executeDocumentSymbolProvider", uri); - return symbols || null; - } catch { - // File might not exist or no language server available - return null; - } - } - - /** Recursively collect symbols from DocumentSymbol tree */ - #collectSymbols( - symbols: vscode.DocumentSymbol[], - relativePath: string, - output: ContextSymbol[], - parentName: string | undefined, - ): void { - for (const sym of symbols) { - if (output.length >= MAX_CONTEXT_SYMBOLS) { - return; - } - - // Build container name from parent - const containerName = parentName; - - output.push({ - name: sym.name, - kind: sym.kind, - location: relativePath, - containerName, - range: { - startLine: sym.range.start.line, - startChar: sym.range.start.character, - endLine: sym.range.end.line, - endChar: sym.range.end.character, - }, - selectionRange: { - startLine: sym.selectionRange.start.line, - startChar: sym.selectionRange.start.character, - endLine: sym.selectionRange.end.line, - endChar: sym.selectionRange.end.character, - }, - }); - - // Recurse into children - if (sym.children && sym.children.length > 0) { - const childParent = parentName - ? `${parentName}::${sym.name}` - : sym.name; - this.#collectSymbols(sym.children, relativePath, output, childParent); - } - } - } - - /** Try to populate from git ls-files */ - async #tryGitLsFiles(): Promise { - return new Promise((resolve) => { - const cwd = this.#workspaceFolder.uri.fsPath; - - cp.exec( - "git ls-files", - { cwd, maxBuffer: 10 * 1024 * 1024 }, - (error, stdout) => { - if (error) { - logger.debug("fileIndex", "git ls-files failed, will use fallback", { - error: error.message, - }); - resolve(false); - return; - } - - const files = stdout - .split("\n") - .map((f) => f.trim()) - .filter((f) => f.length > 0); - - for (const file of files) { - this.#files.add(file); - } - - resolve(true); - }, - ); - }); - } - - /** Fallback: use workspace.findFiles for non-git workspaces */ - async #fallbackFindFiles(): Promise { - // Use a reasonable exclude pattern - const excludePattern = - "**/node_modules/**,**/.git/**,**/target/**,**/dist/**,**/build/**"; - - const uris = await vscode.workspace.findFiles( - new vscode.RelativePattern(this.#workspaceFolder, "**/*"), - excludePattern, - MAX_CONTEXT_FILES, - ); - - for (const uri of uris) { - const relativePath = this.#getRelativePath(uri); - if (relativePath) { - this.#files.add(relativePath); - } - } - } - - /** Set up file watcher for live updates */ - #setupWatcher(): void { - // Watch all files in workspace - this.#watcher = vscode.workspace.createFileSystemWatcher( - new vscode.RelativePattern(this.#workspaceFolder, "**/*"), - ); - - this.#watcher.onDidCreate((uri) => { - const relativePath = this.#getRelativePath(uri); - if (relativePath && this.#shouldIncludeFile(relativePath)) { - this.#files.add(relativePath); - logger.debug("fileIndex", "File created", { path: relativePath }); - this.#onDidChange.fire(); - } - }); - - this.#watcher.onDidDelete((uri) => { - const relativePath = this.#getRelativePath(uri); - if (relativePath && this.#files.has(relativePath)) { - this.#files.delete(relativePath); - logger.debug("fileIndex", "File deleted", { path: relativePath }); - this.#onDidChange.fire(); - } - }); - - // Note: We don't listen to onDidChange (file content changes) as that - // doesn't affect the file list - } - - /** Set up tracking for open editor tabs */ - #setupOpenTabsTracking(): void { - this.#openTabsDisposable = vscode.window.tabGroups.onDidChangeTabs(() => { - // When tabs change, the file list might include new external files - this.#onDidChange.fire(); - }); - } - - /** Get relative path for a URI, or undefined if outside workspace */ - #getRelativePath(uri: vscode.Uri): string | undefined { - // Check if it's within the workspace - const workspacePath = this.#workspaceFolder.uri.fsPath; - const filePath = uri.fsPath; - - if (filePath.startsWith(workspacePath)) { - // Inside workspace - return relative path - let relative = filePath.slice(workspacePath.length); - if (relative.startsWith("/") || relative.startsWith("\\")) { - relative = relative.slice(1); - } - return relative; - } else { - // Outside workspace - return full path - return filePath; - } - } - - /** Check if a file should be included (basic filtering for non-git) */ - #shouldIncludeFile(relativePath: string): boolean { - // For git repos, git ls-files already filters - if (this.#isGitRepo) { - // But watcher might catch files not in git - check common excludes - const excludePatterns = [ - /node_modules\//, - /\.git\//, - /target\//, - /dist\//, - /build\//, - /\.DS_Store$/, - ]; - return !excludePatterns.some((p) => p.test(relativePath)); - } - return true; - } - - /** Dispose of resources */ - dispose(): void { - this.#watcher?.dispose(); - this.#openTabsDisposable?.dispose(); - this.#onDidChange.dispose(); - } -} diff --git a/vscode-extension/test-workspace/.vscode/settings.json b/vscode-extension/test-workspace/.vscode/settings.json deleted file mode 100644 index fce9fb7d..00000000 --- a/vscode-extension/test-workspace/.vscode/settings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "symposium.currentAgentId": "elizacp", - "symposium.extensions": [ - { "id": "ferris", "_enabled": true, "_source": "built-in" }, - { "id": "cargo", "_enabled": true, "_source": "built-in" }, - ], -} diff --git a/vscode-extension/test-workspace/README.md b/vscode-extension/test-workspace/README.md deleted file mode 100644 index 396a8e70..00000000 --- a/vscode-extension/test-workspace/README.md +++ /dev/null @@ -1 +0,0 @@ -# Test Workspace diff --git a/vscode-extension/webpack.config.js b/vscode-extension/webpack.config.js index e1955d78..9a485325 100644 --- a/vscode-extension/webpack.config.js +++ b/vscode-extension/webpack.config.js @@ -1,3 +1,5 @@ +"use strict"; + const path = require("path"); /** @type {import('webpack').Configuration} */ @@ -21,55 +23,11 @@ const extensionConfig = { { test: /\.ts$/, exclude: /node_modules/, - use: [ - { - loader: "ts-loader", - }, - ], - }, - ], - }, - devtool: "nosources-source-map", - infrastructureLogging: { - level: "log", - }, -}; - -/** @type {import('webpack').Configuration} */ -const webviewConfig = { - target: "web", - mode: "none", - entry: "./src/symposium-webview.ts", - output: { - path: path.resolve(__dirname, "out"), - filename: "webview.js", - libraryTarget: "umd", - globalObject: "this", - }, - resolve: { - extensions: [".ts", ".js"], - }, - module: { - rules: [ - { - test: /\.ts$/, - exclude: /node_modules/, - use: [ - { - loader: "ts-loader", - }, - ], - }, - { - test: /\.css$/, - use: ["style-loader", "css-loader"], + use: [{ loader: "ts-loader" }], }, ], }, devtool: "nosources-source-map", - infrastructureLogging: { - level: "log", - }, }; -module.exports = [extensionConfig, webviewConfig]; +module.exports = extensionConfig;