How SecureDesign Detects and Integrates with Cursor and Windsurf Development Environments
SecureDesign detects Cursor and Windsurf by inspecting vscode.env.appName and creates IDE-specific rule files (.cursor/rules/design.mdc and .windsurfrules) to expose the Open Canvas command while adapting UI elements like prompt copying and icons accordingly.
SecureDesign is a VS Code extension that brings secure design workflows to AI-powered development environments. According to the hbmartin/secure-design source code, the extension automatically detects whether it is running inside Cursor or Windsurf and configures itself to expose the Open Canvas command through custom rule files tailored to each platform.
IDE Detection via VS Code Environment
The detection logic resides in src/extension.ts within the detectCurrentIDE function (lines 141-147). This utility inspects the vscode.env.appName property and checks for substring matches to determine the host environment.
function detectCurrentIDE(): { isCursor: boolean; isWindsurf: boolean } {
const appName = vscode.env.appName.toLowerCase();
return {
isCursor: appName.includes('cursor'),
isWindsurf: appName.includes('windsurf'),
};
}
This simple string-checking approach returns two boolean flags that drive all subsequent IDE-specific behavior throughout the extension lifecycle. The method runs during the project initialization routine (initializeSecuredesignProject) to determine which helper files to generate.
IDE-Specific Rule File Generation
During project initialization, SecureDesign creates custom rule files that register the Open Canvas command within the host IDE's custom-rules engine. The extension only generates files for the detected environment, leaving other platforms untouched.
Cursor Integration with .cursor/rules/design.mdc
When isCursor is true, the extension creates a .cursor/rules/design.mdc file inside the workspace root. This file contains a "securedesign: Open Canvas View" command that Cursor's rule engine recognizes and surfaces in the command palette.
The file creation logic (lines 1142-1150 and 1151-1169) ensures the directory structure exists before writing:
if (isCursor) {
const cursorRulesFolder = vscode.Uri.joinPath(workspaceRoot, '.cursor', 'rules');
await vscode.workspace.fs.createDirectory(cursorRulesFolder);
const designMdcPath = vscode.Uri.joinPath(cursorRulesFolder, 'design.mdc');
await vscode.workspace.fs.writeFile(designMdcPath, Buffer.from(designRuleMdcContent));
}
Windsurf Integration with .windsurfrules
For Windsurf environments (isWindsurf is true), the extension writes a .windsurfrules file directly to the workspace root (lines 1197-1206 and 1207-1218). This flat file structure aligns with Windsurf's configuration conventions and similarly exposes the Open Canvas functionality:
if (isWindsurf) {
const windsurfRulesPath = vscode.Uri.joinPath(workspaceRoot, '.windsurfrules');
await vscode.workspace.fs.writeFile(windsurfRulesPath, Buffer.from(designRuleContent));
}
Both files are generated at runtime and are not bundled with the extension source, allowing them to reflect the current project state.
UI Adaptations for Cursor and Windsurf
Beyond file generation, SecureDesign adjusts its webview UI to match the detected IDE. The extension passes the platform identifier to React components, which modify both the prompt-copying behavior and the displayed brand assets.
Platform-Specific Prompt Copying
In src/webview/components/DesignFrame.tsx (lines 18-27), the handleCopyPrompt function builds distinct prompt strings for each platform. Cursor receives instructions to "use that as a reference to build a similar UI component," while Windsurf prompts request the AI to "analyze this design and create a similar UI component."
switch (platform) {
case 'cursor':
promptText = `${file.content}\n\nAbove is the design implementation, please use that as a reference to build a similar UI component.`;
platformName = 'Cursor';
break;
case 'windsurf':
promptText = `${file.content}\n\nAbove is the design implementation. Please analyze this design and create a similar UI component.`;
platformName = 'Windsurf';
break;
// …other platforms
}
This differentiation ensures that the copied prompts align with each IDE's AI assistant conventions and expected context formats.
IDE Logo Assets in Webview
The extension registers distinct logo assets for each environment in src/templates/chatTemplate.ts (lines 14-15). The chatTemplate function resolves URIs for both Cursor and Windsurf logos, allowing the React frontend to display the correct brand icon based on the active platform:
export const chatTemplate = (extensionUri: vscode.Uri) => ({
// …
windsurf: webview.asWebviewUri(vscode.Uri.joinPath(extensionUri, 'src', 'assets', 'windsurf_logo.png')).toString(),
cursor: webview.asWebviewUri(vscode.Uri.joinPath(extensionUri, 'src', 'assets', 'cursor_logo.png')).toString(),
});
Summary
- Environment Detection: SecureDesign uses
vscode.env.appNamesubstring matching indetectCurrentIDEto identify Cursor and Windsurf. - Rule File Creation: The extension generates
.cursor/rules/design.mdcfor Cursor and.windsurfrulesfor Windsurf to expose the Open Canvas command in each IDE's rule engine. - UI Customization: Prompt copying logic in
DesignFrame.tsxand logo assets inchatTemplate.tsadapt to the detected platform, providing tailored AI instructions and visual branding.
Frequently Asked Questions
How does SecureDesign know which IDE is hosting it?
SecureDesign inspects the vscode.env.appName property and checks for the substrings "cursor" or "windsurf" in the detectCurrentIDE function located in src/extension.ts. This runtime detection returns boolean flags that determine which integration paths to activate.
What files does SecureDesign create for Cursor integration?
When running inside Cursor, SecureDesign creates a .cursor/rules/design.mdc file within the workspace. This file contains custom rules that register the "Open Canvas" command with Cursor's AI assistant, making the SecureDesign workflow visible in Cursor's command palette.
Can SecureDesign work with both Cursor and Windsurf simultaneously?
The extension detects one environment per session based on vscode.env.appName. While the detection logic can theoretically identify both flags if the app name contains both substrings, the standard behavior creates files for the specific detected IDE only. The codebase supports both integrations, but each workspace typically activates one at a time.
Where are the IDE detection rules defined in the codebase?
The detection rules are defined in src/extension.ts at lines 141-147 within the detectCurrentIDE function. The actual file creation logic for Cursor appears at lines 1142-1169, while Windsurf file creation is handled at lines 1197-1218 in the same file.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →