Skip to content

Feature/#812 implement vscode extension and mcp#831

Open
Ivanruii wants to merge 21 commits intodevfrom
feature/#812-implement-vscode-ext-and-mcp
Open

Feature/#812 implement vscode extension and mcp#831
Ivanruii wants to merge 21 commits intodevfrom
feature/#812-implement-vscode-ext-and-mcp

Conversation

@Ivanruii
Copy link
Copy Markdown
Collaborator

Close #812

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements the QuickMock VS Code extension (custom editor + MCP integration) and adds an MCP server package with headless wireframe rendering support, closing #812.

Changes:

  • Added a VS Code custom editor for .qm files backed by a webview-hosted QuickMock app, plus a webview bridge protocol.
  • Added an MCP server (tools for listing/reading/rendering wireframes, headless screenshots via Puppeteer) and extension-side MCP registration/definition provider.
  • Updated build/configuration to bundle webview assets, copy MCP artifacts into the extension, and introduce new shared protocol utilities.

Reviewed changes

Copilot reviewed 80 out of 81 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tooling/typescript/node.json Adds Node types to the shared TS node config.
packages/vscode-extension/tsdown.config.ts Splits bundling into extension (CJS) and webview (IIFE) outputs.
packages/vscode-extension/tsconfig.json Adds DOM lib to support webview TS sources.
packages/vscode-extension/src/webview/main.ts Boots the webview iframe and initializes the bridge.
packages/vscode-extension/src/webview/bridge.ts Forwards postMessage traffic between iframe ↔ extension.
packages/vscode-extension/src/mcp/server-definition-provider.ts Registers a dynamic MCP server definition provider in VS Code.
packages/vscode-extension/src/mcp/registry-server.ts Adds a local registry HTTP server for live document content.
packages/vscode-extension/src/mcp/mcp-registration.ts Implements MCP registration across VS Code and other client config files.
packages/vscode-extension/src/mcp/mcp-config-file.ts Reads/writes MCP JSON config files for external clients.
packages/vscode-extension/src/mcp/mcp-command.ts Adds a command UX for MCP registration and inspection.
packages/vscode-extension/src/mcp/mcp-client-targets.ts Detects MCP client config locations across OSes.
packages/vscode-extension/src/index.ts Wires activation: editor provider, registry server, MCP provider/registration.
packages/vscode-extension/src/editor/provider.ts Implements CustomEditorProvider for .qm documents.
packages/vscode-extension/src/editor/panel.ts Generates webview HTML/CSP and injects app URL for iframe.
packages/vscode-extension/src/editor/handlers.ts Handles webview messages (load/save) and file I/O.
packages/vscode-extension/src/editor/document.ts Implements document open/read/write helpers.
packages/vscode-extension/src/core/paths.ts Centralizes extension paths (MCP entrypoint, app-url file).
packages/vscode-extension/src/core/logger.ts Adds basic logging helpers for the extension runtime.
packages/vscode-extension/src/core/document-registry.ts Tracks in-memory document contents for MCP consumption.
packages/vscode-extension/src/core/config.ts Adds quickmock.appUrl config + writes headless app URL to disk.
packages/vscode-extension/scripts/copy-mcp.mjs Copies MCP package dist into the extension dist on build.
packages/vscode-extension/package.json Adds activation/events, commands, custom editor, MCP contributions, build pipeline.
packages/vscode-extension/.vscodeignore Excludes scripts/env/vsix from VSIX packaging.
packages/mcp/tsdown.config.ts Forces bundling all deps for the MCP server distribution.
packages/mcp/tsconfig.json Adds DOM lib for renderer-related code.
packages/mcp/src/tools/list-wireframes/list-wireframes.tool.ts Defines the list_wireframes MCP tool.
packages/mcp/src/tools/list-wireframes/list-wireframes.handler.ts Implements workspace scan for .qm files.
packages/mcp/src/tools/list-wireframes/index.ts Re-exports list wireframes tool.
packages/mcp/src/tools/get-wireframe-pages/index.ts Re-exports get wireframe pages tool.
packages/mcp/src/tools/get-wireframe-pages/get-wireframe-pages.tool.ts Defines the get_wireframe_pages MCP tool.
packages/mcp/src/tools/get-wireframe-pages/get-wireframe-pages.schema.ts Adds Zod schema for get wireframe pages.
packages/mcp/src/tools/get-wireframe-pages/get-wireframe-pages.models.ts Adds wireframe page model for tool output.
packages/mcp/src/tools/get-wireframe-pages/get-wireframe-pages.handler.ts Implements page metadata extraction from .qm files.
packages/mcp/src/tools/get-wireframe-json/index.ts Re-exports get wireframe JSON tool.
packages/mcp/src/tools/get-wireframe-json/get-wireframe-json.tool.ts Defines the get_wireframe_json MCP tool.
packages/mcp/src/tools/get-wireframe-json/get-wireframe-json.schema.ts Adds Zod schema for get wireframe JSON.
packages/mcp/src/tools/get-wireframe-json/get-wireframe-json.handler.ts Implements JSON retrieval (registry-first, disk fallback).
packages/mcp/src/tools/get-wireframe-assets/index.ts Re-exports get wireframe assets tool.
packages/mcp/src/tools/get-wireframe-assets/get-wireframe-assets.tool.ts Defines the get_wireframe_assets MCP tool.
packages/mcp/src/tools/get-wireframe-assets/get-wireframe-assets.schema.ts Adds Zod schema for asset extraction options.
packages/mcp/src/tools/get-wireframe-assets/get-wireframe-assets.models.ts Adds wireframe asset model.
packages/mcp/src/tools/get-wireframe-assets/get-wireframe-assets.handler.ts Extracts embedded image assets to disk and reports results.
packages/mcp/src/tools/capture-wireframe/index.ts Re-exports capture wireframe tool.
packages/mcp/src/tools/capture-wireframe/capture-wireframe.tool.ts Defines the capture_wireframe MCP tool.
packages/mcp/src/tools/capture-wireframe/capture-wireframe.schema.ts Adds Zod schema for capture options.
packages/mcp/src/tools/capture-wireframe/capture-wireframe.handler.ts Implements headless screenshot capture using the renderer.
packages/mcp/src/renderer/renderer.consts.ts Adds renderer timeouts and local-instance hint string.
packages/mcp/src/renderer/page.session.ts Implements Puppeteer page session (ready, send file, render complete, screenshot).
packages/mcp/src/renderer/index.ts Re-exports renderer entrypoints.
packages/mcp/src/renderer/headless.renderer.ts Launches Chromium and orchestrates end-to-end rendering flow.
packages/mcp/src/renderer/chromium.resolver.ts Downloads/resolves a Chromium executable via @puppeteer/browsers.
packages/mcp/src/renderer/bridge.server.ts Serves a local HTML bridge page for Puppeteer ↔ iframe messaging.
packages/mcp/src/renderer/app-url.consts.ts Reads headless app URL from ~/.quickmock/app-url with default fallback.
packages/mcp/src/index.ts Implements the MCP server process and registers all tools.
packages/mcp/src/core/registry.utils.ts Adds workspace hashing used for registry server discovery.
packages/mcp/src/core/registry.models.ts Defines registry client interface and null implementation.
packages/mcp/src/core/registry.client.ts Implements registry HTTP client to fetch live doc content.
packages/mcp/src/core/mcp.logger.ts Adds MCP-side logging helpers.
packages/mcp/src/core/index.ts Re-exports MCP core utilities.
packages/mcp/src/commons/wireframe-file.service.ts Adds a service wrapper for reading .qm files via registry/disk.
packages/mcp/src/commons/tool-response.helpers.ts Adds helper builders for MCP tool responses (text/image/errors).
packages/mcp/src/commons/qm-file.utils.ts Adds .qm read/parse logic with registry-first behavior.
packages/mcp/src/commons/qm-file.models.ts Defines .qm file/page/shape contract models.
packages/mcp/package.json Adds MCP runtime deps (MCP SDK, Puppeteer, Zod) and an inspector script.
packages/bridge-protocol/tsconfig.json Adds TS config for the shared bridge protocol package.
packages/bridge-protocol/src/index.ts Defines shared postMessage protocol types/constants.
packages/bridge-protocol/package.json Adds the (private) workspace package for bridge protocol sharing.
package-lock.json Updates lockfile for new workspace packages and new MCP/renderer dependencies.
apps/web/src/scenes/main.scene.tsx Adds headless mode rendering path (Canvas-only) for screenshots.
apps/web/src/core/vscode/vscode-sync.utils.ts Adds serialize/deserialize helpers for VS Code sync.
apps/web/src/core/vscode/use-vscode-sync.hook.ts Adds top-level hook that wires all VS Code bridge behaviors.
apps/web/src/core/vscode/use-vscode-file-load.hook.ts Implements LOAD_FILE handling and READY/WEBVIEW_READY handshake.
apps/web/src/core/vscode/use-vscode-auto-save.hook.ts Implements debounced SAVE messages back to the extension.
apps/web/src/core/vscode/use-headless-render-complete.hook.ts Emits RENDER_COMPLETE with computed bounding box for cropping.
apps/web/src/common/utils/vscode-bridge.utils.ts Adds client-side message bus utilities for iframe ↔ webview comms.
apps/web/src/common/utils/env.utils.ts Adds env/headless detection via query params.
apps/web/src/common/utils/compute-content-bbox.utils.ts Computes content bounding box for renderer cropping.
apps/web/src/App.tsx Enables VS Code sync hook at app startup.
apps/web/package.json Adds dependency on the shared bridge protocol package.
.vscode/settings.json Adds workspace setting for quickmock.appUrl (local dev URL).
.changeset/quick-meals-send.md Adds release notes/changeset for the extension and MCP server.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +66 to +69
// Messages coming DOWN from Puppeteer (page.evaluate) → forward to iframe
if (iframe.contentWindow) {
iframe.contentWindow.postMessage(event.data, '*')
}
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bridge forwards Puppeteer → iframe messages using postMessage(..., '*'). Since the iframe URL is known (QUICKMOCK_URL), restrict the targetOrigin to that origin to prevent message leakage if the iframe is ever navigated elsewhere.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines +13 to +17
const BROWSER_LAUNCH_ARGS = [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-web-security',
'--disable-features=IsolateOrigins,site-per-process',
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Chromium launch args include --no-sandbox, --disable-web-security, and --disable-features=IsolateOrigins,site-per-process, which significantly weaken isolation when loading remote content. If these flags aren't strictly required for rendering, remove them; if they are required, document why and keep the minimal necessary subset.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines +62 to +66
const path = url.searchParams.get('path');
if (!path) {
res.writeHead(400);
res.end('Missing path parameter');
return;
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The registry HTTP server exposes in-memory document contents on 127.0.0.1 with no authentication. Since the port is discoverable via the tmp .port file, consider adding a shared secret (written alongside the port) and requiring it via a header/query param to mitigate local-process data exfiltration.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines +10 to +14
const iframe = document.createElement('iframe');
iframe.src = appUrl;
iframe.allow = 'clipboard-read; clipboard-write';
iframe.title = 'QuickMock Application';
document.body.appendChild(iframe);
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The embedded QuickMock app iframe is created without a sandbox attribute. Since this can load a configurable remote origin, consider adding a sandbox with the minimal required allowances (e.g. scripts/forms/same-origin as needed) to reduce the impact of a compromised/incorrect appUrl.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment thread .vscode/settings.json
Comment on lines +8 to +9
},
"quickmock.appUrl": "http://localhost:5173/editor.html"
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workspace-level VS Code setting forces quickmock.appUrl to a localhost dev server for everyone who opens the repo. That’s likely to break the extension/editor unless the dev server is running. Consider removing this from source control or moving it to a documented example (e.g. .vscode/settings.example.json).

Suggested change
},
"quickmock.appUrl": "http://localhost:5173/editor.html"
}

Copilot uses AI. Check for mistakes.
Comment thread packages/mcp/src/core/mcp.logger.ts Outdated
const PREFIX = '[quickmock-mcp]';

export const logInfo = (message: string, ...rest: unknown[]): void => {
console.error(`${PREFIX} ${message}`, ...rest);
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logInfo currently logs using console.error, which will mark normal informational output as errors and can confuse users/telemetry. Switch this to console.info (or console.log) so info and error logs are correctly separated.

Suggested change
console.error(`${PREFIX} ${message}`, ...rest);
console.info(`${PREFIX} ${message}`, ...rest);

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines +39 to +41
return toolError(
`Error capturing wireframe at "${path} with ${QUICKMOCK_URL}": ${String(err)}`
);
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message string here has mismatched quotes/formatting: it currently interpolates path and QUICKMOCK_URL inside the same opening quote, which will render oddly and makes the path ambiguous. Adjust the message to quote the path and URL separately (e.g. ... at "${path}" with ${QUICKMOCK_URL}: ...).

Copilot uses AI. Check for mistakes.
Comment on lines +81 to +85
const iframe = document.querySelector('iframe') as HTMLIFrameElement;
iframe.contentWindow?.postMessage(
{ type: 'LOAD_FILE', payload: { data: JSON.parse(content), fileName } },
'*'
);
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

postMessage is sent to the QuickMock iframe with targetOrigin: '*'. Since QM_APP_ORIGIN is available in this module, use it as the targetOrigin to avoid sending wireframe contents to an unexpected origin if the iframe URL changes or is navigated.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

{
...baseTsdownConfig,
entry: ['src/index.ts'],
format: 'cjs',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you have to chage to cjs? It should works with es modules

Comment thread packages/vscode-extension/tsdown.config.ts Outdated
"title": "QuickMock: New Wireframe"
},
{
"command": "quickmock.connectMcp",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review if we have to remove it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[VScode Extension] Implement Vscode extension and mcp server

3 participants