| |
|
|
| import * as vscode from 'vscode'; |
|
|
| |
| |
| |
| interface SymbolicCommand { |
| name: string; |
| description: string; |
| parameters?: { |
| name: string; |
| description: string; |
| required?: boolean; |
| default?: any; |
| }[]; |
| examples: string[]; |
| provider?: { |
| claude?: boolean; |
| openai?: boolean; |
| qwen?: boolean; |
| gemini?: boolean; |
| ollama?: boolean; |
| }; |
| } |
|
|
| |
| |
| |
| export function activate(context: vscode.ExtensionContext) { |
| console.log('Universal Developer extension is now active'); |
|
|
| |
| const insertSymbolicCommand = vscode.commands.registerCommand( |
| 'universal-developer.insertSymbolicCommand', |
| async () => { |
| const commandName = await showSymbolicCommandQuickPick(); |
| if (!commandName) return; |
|
|
| const command = SYMBOLIC_COMMANDS.find(cmd => cmd.name === commandName); |
| if (!command) return; |
|
|
| |
| let commandString = `/${command.name}`; |
| |
| if (command.parameters && command.parameters.length > 0) { |
| const parameters = await collectCommandParameters(command); |
| if (parameters) { |
| Object.entries(parameters).forEach(([key, value]) => { |
| if (value !== undefined && value !== null && value !== '') { |
| commandString += ` --${key}=${value}`; |
| } |
| }); |
| } |
| } |
|
|
| |
| const editor = vscode.window.activeTextEditor; |
| if (editor) { |
| editor.edit(editBuilder => { |
| editBuilder.insert(editor.selection.active, commandString + ' '); |
| }); |
| } |
| } |
| ); |
|
|
| |
| const buildSymbolicChain = vscode.commands.registerCommand( |
| 'universal-developer.buildSymbolicChain', |
| async () => { |
| await showCommandChainBuilder(); |
| } |
| ); |
|
|
| |
| const hoverProvider = vscode.languages.registerHoverProvider( |
| ['javascript', 'typescript', 'python', 'markdown', 'plaintext'], |
| { |
| provideHover(document, position, token) { |
| const range = document.getWordRangeAtPosition(position, /\/[a-zA-Z0-9_]+/); |
| if (!range) return; |
|
|
| const commandText = document.getText(range); |
| const commandName = commandText.substring(1); |
| |
| const command = SYMBOLIC_COMMANDS.find(cmd => cmd.name === commandName); |
| if (!command) return; |
|
|
| |
| const hoverContent = new vscode.MarkdownString(); |
| hoverContent.appendMarkdown(`**/${command.name}**\n\n`); |
| hoverContent.appendMarkdown(`${command.description}\n\n`); |
| |
| if (command.parameters && command.parameters.length > 0) { |
| hoverContent.appendMarkdown('**Parameters:**\n\n'); |
| command.parameters.forEach(param => { |
| const required = param.required ? ' (required)' : ''; |
| const defaultValue = param.default !== undefined ? ` (default: ${param.default})` : ''; |
| hoverContent.appendMarkdown(`- \`--${param.name}\`${required}${defaultValue}: ${param.description}\n`); |
| }); |
| hoverContent.appendMarkdown('\n'); |
| } |
|
|
| if (command.examples && command.examples.length > 0) { |
| hoverContent.appendMarkdown('**Examples:**\n\n'); |
| command.examples.forEach(example => { |
| hoverContent.appendCodeBlock(example, 'markdown'); |
| }); |
| } |
|
|
| |
| if (command.provider) { |
| hoverContent.appendMarkdown('\n**Compatible with:**\n\n'); |
| const supported = Object.entries(command.provider) |
| .filter(([_, isSupported]) => isSupported) |
| .map(([provider]) => provider); |
| hoverContent.appendMarkdown(supported.join(', ')); |
| } |
|
|
| return new vscode.Hover(hoverContent, range); |
| } |
| } |
| ); |
|
|
| |
| const completionProvider = vscode.languages.registerCompletionItemProvider( |
| ['javascript', 'typescript', 'python', 'markdown', 'plaintext'], |
| { |
| provideCompletionItems(document, position) { |
| const linePrefix = document.lineAt(position).text.substring(0, position.character); |
| |
| |
| if (!linePrefix.endsWith('/')) { |
| return undefined; |
| } |
|
|
| const completionItems = SYMBOLIC_COMMANDS.map(command => { |
| const item = new vscode.CompletionItem( |
| command.name, |
| vscode.CompletionItemKind.Keyword |
| ); |
| item.insertText = command.name; |
| item.detail = command.description; |
| item.documentation = new vscode.MarkdownString(command.description); |
| return item; |
| }); |
|
|
| return completionItems; |
| } |
| }, |
| '/' |
| ); |
|
|
| |
| const parameterCompletionProvider = vscode.languages.registerCompletionItemProvider( |
| ['javascript', 'typescript', 'python', 'markdown', 'plaintext'], |
| { |
| provideCompletionItems(document, position) { |
| const linePrefix = document.lineAt(position).text.substring(0, position.character); |
| |
| |
| const commandMatch = linePrefix.match(/\/([a-zA-Z0-9_]+)(?:\s+(?:[^\s]+\s+)*)?--$/); |
| if (!commandMatch) { |
| return undefined; |
| } |
|
|
| const commandName = commandMatch[1]; |
| const command = SYMBOLIC_COMMANDS.find(cmd => cmd.name === commandName); |
| |
| if (!command || !command.parameters || command.parameters.length === 0) { |
| return undefined; |
| } |
|
|
| |
| const completionItems = command.parameters.map(param => { |
| const item = new vscode.CompletionItem( |
| param.name, |
| vscode.CompletionItemKind.Property |
| ); |
| item.insertText = `${param.name}=`; |
| item.detail = param.description; |
| |
| if (param.default !== undefined) { |
| item.documentation = new vscode.MarkdownString( |
| `${param.description}\n\nDefault: \`${param.default}\`` |
| ); |
| } else { |
| item.documentation = new vscode.MarkdownString(param.description); |
| } |
| |
| return item; |
| }); |
|
|
| return completionItems; |
| } |
| }, |
| '-' |
| ); |
|
|
| |
| const codeActionsProvider = vscode.languages.registerCodeActionsProvider( |
| ['javascript', 'typescript', 'python'], |
| { |
| provideCodeActions(document, range, context, token) { |
| |
| const line = document.lineAt(range.start.line).text; |
| |
| const llmApiPatterns = [ |
| /\.generate\(\s*{/, |
| /\.createCompletion\(/, |
| /\.createChatCompletion\(/, |
| /\.chat\.completions\.create\(/, |
| /\.messages\.create\(/, |
| /\.generateContent\(/ |
| ]; |
|
|
| if (!llmApiPatterns.some(pattern => pattern.test(line))) { |
| return; |
| } |
|
|
| |
| const actions: vscode.CodeAction[] = []; |
| |
| |
| const promptMatch = line.match(/(prompt|messages|content)\s*:/); |
| if (!promptMatch) return; |
|
|
| |
| ['think', 'fast', 'reflect', 'loop'].forEach(commandName => { |
| const command = SYMBOLIC_COMMANDS.find(cmd => cmd.name === commandName); |
| if (!command) return; |
| |
| const action = new vscode.CodeAction( |
| `Add /${commandName} command`, |
| vscode.CodeActionKind.RefactorRewrite |
| ); |
| |
| action.command = { |
| title: `Insert /${commandName}`, |
| command: 'universal-developer.insertSymbolicCommandAtPrompt', |
| arguments: [range.start.line, command] |
| }; |
| |
| actions.push(action); |
| }); |
|
|
| return actions; |
| } |
| } |
| ); |
|
|
| |
| const insertSymbolicCommandAtPrompt = vscode.commands.registerCommand( |
| 'universal-developer.insertSymbolicCommandAtPrompt', |
| async (line: number, command: SymbolicCommand) => { |
| const editor = vscode.window.activeTextEditor; |
| if (!editor) return; |
| |
| const document = editor.document; |
| const lineText = document.lineAt(line).text; |
| |
| |
| const promptMatch = lineText.match(/(prompt|messages|content)\s*:\s*['"]/); |
| if (!promptMatch) return; |
| |
| const promptStartIdx = promptMatch.index! + promptMatch[0].length; |
| const position = new vscode.Position(line, promptStartIdx); |
| |
| editor.edit(editBuilder => { |
| editBuilder.insert(position, `/${command.name} `); |
| }); |
| } |
| ); |
|
|
| |
| const statusBarItem = vscode.window.createStatusBarItem( |
| vscode.StatusBarAlignment.Right, |
| 100 |
| ); |
| statusBarItem.text = "$(symbol-keyword) Symbolic"; |
| statusBarItem.tooltip = "Universal Developer: Click to insert symbolic command"; |
| statusBarItem.command = 'universal-developer.insertSymbolicCommand'; |
| statusBarItem.show(); |
|
|
| |
| const showDocumentation = vscode.commands.registerCommand( |
| 'universal-developer.showDocumentation', |
| () => { |
| const panel = vscode.window.createWebviewPanel( |
| 'universalDeveloperDocs', |
| 'Universal Developer Documentation', |
| vscode.ViewColumn.One, |
| { enableScripts: true } |
| ); |
| |
| panel.webview.html = getDocumentationHtml(); |
| } |
| ); |
|
|
| |
| context.subscriptions.push( |
| insertSymbolicCommand, |
| buildSymbolicChain, |
| hoverProvider, |
| completionProvider, |
| parameterCompletionProvider, |
| codeActionsProvider, |
| insertSymbolicCommandAtPrompt, |
| statusBarItem, |
| showDocumentation |
| ); |
|
|
| |
| context.subscriptions.push( |
| vscode.commands.registerCommand( |
| 'universal-developer.trackCommandUsage', |
| (commandName: string) => { |
| |
| const config = vscode.workspace.getConfiguration('universal-developer'); |
| if (config.get('enableTelemetry', true)) { |
| sendAnonymizedTelemetry('command_used', { command: commandName }); |
| } |
| } |
| ) |
| ); |
| } |
|
|
| |
| async function showSymbolicCommandQuickPick(): Promise<string | undefined> { |
| const items = SYMBOLIC_COMMANDS.map(command => ({ |
| label: `/${command.name}`, |
| description: command.description, |
| detail: command.parameters && command.parameters.length > 0 |
| ? `Parameters: ${command.parameters.map(p => p.name).join(', ')}` |
| : undefined |
| })); |
|
|
| const selected = await vscode |
| |
|
|
| |
| async function showSymbolicCommandQuickPick(): Promise<string | undefined> { |
| const items = SYMBOLIC_COMMANDS.map(command => ({ |
| label: `/${command.name}`, |
| description: command.description, |
| detail: command.parameters && command.parameters.length > 0 |
| ? `Parameters: ${command.parameters.map(p => p.name).join(', ')}` |
| : undefined |
| })); |
|
|
| const selected = await vscode.window.showQuickPick(items, { |
| placeHolder: 'Select a symbolic runtime command', |
| }); |
|
|
| return selected ? selected.label.substring(1) : undefined; |
| } |
|
|
| |
| async function collectCommandParameters(command: SymbolicCommand): Promise<Record<string, any> | undefined> { |
| if (!command.parameters || command.parameters.length === 0) { |
| return {}; |
| } |
|
|
| const parameters: Record<string, any> = {}; |
| |
| |
| command.parameters.forEach(param => { |
| if (param.default !== undefined) { |
| parameters[param.name] = param.default; |
| } |
| }); |
|
|
| |
| for (const param of command.parameters) { |
| const value = await vscode.window.showInputBox({ |
| prompt: param.description, |
| placeHolder: param.default !== undefined ? `Default: ${param.default}` : undefined, |
| ignoreFocusOut: true, |
| validateInput: text => { |
| if (param.required && !text) { |
| return `${param.name} is required`; |
| } |
| return null; |
| } |
| }); |
|
|
| |
| if (value === undefined) { |
| return undefined; |
| } |
|
|
| |
| if (value !== '') { |
| parameters[param.name] = value; |
| } |
| } |
|
|
| return parameters; |
| } |
|
|
| |
| async function showCommandChainBuilder() { |
| |
| const panel = vscode.window.createWebviewPanel( |
| 'universalDeveloperChainBuilder', |
| 'Symbolic Command Chain Builder', |
| vscode.ViewColumn.Two, |
| { |
| enableScripts: true, |
| retainContextWhenHidden: true |
| } |
| ); |
|
|
| |
| panel.webview.html = getCommandChainBuilderHtml(); |
|
|
| |
| panel.webview.onDidReceiveMessage( |
| message => { |
| switch (message.command) { |
| case 'insertCommandChain': |
| const editor = vscode.window.activeTextEditor; |
| if (editor) { |
| editor.edit(editBuilder => { |
| editBuilder.insert(editor.selection.active, message.commandChain); |
| }); |
| } |
| break; |
| case 'getCommandInfo': |
| panel.webview.postMessage({ |
| command: 'commandInfo', |
| commands: SYMBOLIC_COMMANDS |
| }); |
| break; |
| } |
| }, |
| undefined, |
| [] |
| ); |
| } |
|
|
| |
| function getCommandChainBuilderHtml() { |
| return `<!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Symbolic Command Chain Builder</title> |
| <style> |
| body { |
| font-family: var(--vscode-font-family); |
| padding: 20px; |
| color: var(--vscode-foreground); |
| background-color: var(--vscode-editor-background); |
| } |
| |
| h1 { |
| font-size: 1.5em; |
| margin-bottom: 20px; |
| } |
| |
| .command-chain { |
| display: flex; |
| flex-direction: column; |
| gap: 10px; |
| margin-bottom: 20px; |
| padding: 10px; |
| background-color: var(--vscode-editor-inactiveSelectionBackground); |
| border-radius: 4px; |
| } |
| |
| .command-step { |
| display: flex; |
| align-items: center; |
| gap: 10px; |
| } |
| |
| .command-preview { |
| margin-top: 20px; |
| padding: 10px; |
| background-color: var(--vscode-input-background); |
| border-radius: 4px; |
| font-family: var(--vscode-editor-font-family); |
| } |
| |
| button { |
| padding: 8px 12px; |
| background-color: var(--vscode-button-background); |
| color: var(--vscode-button-foreground); |
| border: none; |
| border-radius: 4px; |
| cursor: pointer; |
| } |
| |
| button:hover { |
| background-color: var(--vscode-button-hoverBackground); |
| } |
| |
| select, input { |
| padding: 6px; |
| background-color: var(--vscode-input-background); |
| color: var(--vscode-input-foreground); |
| border: 1px solid var(--vscode-input-border); |
| border-radius: 4px; |
| } |
| |
| .command-step .remove { |
| color: var(--vscode-errorForeground); |
| } |
| |
| .parameter-group { |
| margin-left: 20px; |
| margin-top: 5px; |
| display: flex; |
| flex-wrap: wrap; |
| gap: 5px; |
| } |
| |
| .parameter-item { |
| display: flex; |
| align-items: center; |
| gap: 5px; |
| } |
| |
| .parameter-label { |
| font-size: 0.9em; |
| color: var(--vscode-descriptionForeground); |
| } |
| |
| .command-description { |
| font-size: 0.9em; |
| margin-left: 20px; |
| color: var(--vscode-descriptionForeground); |
| } |
| |
| .buttons { |
| display: flex; |
| gap: 10px; |
| margin-top: 20px; |
| } |
| </style> |
| </head> |
| <body> |
| <h1>Symbolic Command Chain Builder</h1> |
| |
| <div class="command-chain" id="commandChain"> |
| <!-- Command steps will be added here --> |
| </div> |
| |
| <button id="addCommand">Add Command</button> |
| |
| <div class="command-preview"> |
| <div><strong>Preview:</strong></div> |
| <div id="previewText"></div> |
| </div> |
| |
| <div class="buttons"> |
| <button id="insertChain">Insert Into Editor</button> |
| <button id="clearChain">Clear</button> |
| </div> |
| |
| <script> |
| // Communication with VSCode extension |
| const vscode = acquireVsCodeApi(); |
| |
| // Request command info from extension |
| vscode.postMessage({ command: 'getCommandInfo' }); |
| |
| // Store commands when received from extension |
| let commands = []; |
| window.addEventListener('message', event => { |
| const message = event.data; |
| if (message.command === 'commandInfo') { |
| commands = message.commands; |
| |
| // If we already have commands in the UI, update their descriptions |
| updateCommandDescriptions(); |
| } |
| }); |
| |
| // Chain state |
| let commandChain = []; |
| |
| // DOM elements |
| const commandChainEl = document.getElementById('commandChain'); |
| const addCommandBtn = document.getElementById('addCommand'); |
| const previewTextEl = document.getElementById('previewText'); |
| const insertChainBtn = document.getElementById('insertChain'); |
| const clearChainBtn = document.getElementById('clearChain'); |
| |
| // Add new command |
| addCommandBtn.addEventListener('click', () => { |
| addCommandStep(); |
| }); |
| |
| // Insert chain into editor |
| insertChainBtn.addEventListener('click', () => { |
| const commandChainText = generateCommandChainText(); |
| vscode.postMessage({ |
| command: 'insertCommandChain', |
| commandChain: commandChainText |
| }); |
| }); |
| |
| // Clear command chain |
| clearChainBtn.addEventListener('click', () => { |
| commandChain = []; |
| commandChainEl.innerHTML = ''; |
| updatePreview(); |
| }); |
| |
| // Add a command step to the chain |
| function addCommandStep() { |
| const stepIndex = commandChain.length; |
| commandChain.push({ |
| name: '', |
| parameters: {} |
| }); |
| |
| const stepEl = document.createElement('div'); |
| stepEl.className = 'command-step'; |
| stepEl.dataset.index = stepIndex; |
| |
| const selectEl = document.createElement('select'); |
| selectEl.innerHTML = '<option value="">Select command</option>' + |
| commands.map(cmd => `<option value="${cmd.name}">/${cmd.name}</option>`).join(''); |
| |
| selectEl.addEventListener('change', function() { |
| const commandName = this.value; |
| commandChain[stepIndex].name = commandName; |
| |
| // Update command description |
| updateCommandDescription(stepIndex); |
| |
| // Clear existing parameters |
| const existingParamGroup = stepEl.querySelector('.parameter-group'); |
| if (existingParamGroup) { |
| existingParamGroup.remove(); |
| } |
| |
| // Add parameter inputs if command has parameters |
| const command = commands.find(c => c.name === commandName); |
| if (command && command.parameters && command.parameters.length > 0) { |
| const paramGroup = document.createElement('div'); |
| paramGroup.className = 'parameter-group'; |
| |
| command.parameters.forEach(param => { |
| const paramItem = document.createElement('div'); |
| paramItem.className = 'parameter-item'; |
| |
| const paramLabel = document.createElement('div'); |
| paramLabel.className = 'parameter-label'; |
| paramLabel.textContent = param.name + ':'; |
| |
| const paramInput = document.createElement('input'); |
| paramInput.type = 'text'; |
| paramInput.placeholder = param.default !== undefined ? `Default: ${param.default}` : ''; |
| paramInput.dataset.paramName = param.name; |
| paramInput.title = param.description; |
| |
| // Set parameter value |
| paramInput.addEventListener('change', function() { |
| if (this.value) { |
| commandChain[stepIndex].parameters[param.name] = this.value; |
| } else { |
| delete commandChain[stepIndex].parameters[param.name]; |
| } |
| updatePreview(); |
| }); |
| |
| paramItem.appendChild(paramLabel); |
| paramItem.appendChild(paramInput); |
| paramGroup.appendChild(paramItem); |
| }); |
| |
| stepEl.appendChild(paramGroup); |
| } |
| |
| updatePreview(); |
| }); |
| |
| const removeBtn = document.createElement('button'); |
| removeBtn.className = 'remove'; |
| removeBtn.textContent = '✕'; |
| removeBtn.title = 'Remove command'; |
| removeBtn.addEventListener('click', () => { |
| commandChain.splice(stepIndex, 1); |
| |
| // Update all step indices |
| const steps = commandChainEl.querySelectorAll('.command-step'); |
| steps.forEach((step, i) => { |
| step.dataset.index = i; |
| }); |
| |
| stepEl.remove(); |
| updatePreview(); |
| }); |
| |
| stepEl.appendChild(selectEl); |
| stepEl.appendChild(removeBtn); |
| |
| // Add description element (will be populated when command is selected) |
| const descEl = document.createElement('div'); |
| descEl.className = 'command-description'; |
| stepEl.appendChild(descEl); |
| |
| commandChainEl.appendChild(stepEl); |
| } |
| |
| // Update the description for a specific command |
| function updateCommandDescription(stepIndex) { |
| const stepEl = commandChainEl.querySelector(`.command-step[data-index="${stepIndex}"]`); |
| if (!stepEl) return; |
| |
| const descEl = stepEl.querySelector('.command-description'); |
| if (!descEl) return; |
| |
| const commandName = commandChain[stepIndex].name; |
| const command = commands.find(c => c.name === commandName); |
| |
| if (command) { |
| descEl.textContent = command.description; |
| } else { |
| descEl.textContent = ''; |
| } |
| } |
| |
| // Update all command descriptions |
| function updateCommandDescriptions() { |
| commandChain.forEach((_, index) => { |
| updateCommandDescription(index); |
| }); |
| } |
| |
| // Generate preview text |
| function updatePreview() { |
| const previewText = generateCommandChainText(); |
| previewTextEl.textContent = previewText || 'No commands added yet'; |
| } |
| |
| // Generate the command chain text |
| function generateCommandChainText() { |
| return commandChain |
| .filter(cmd => cmd.name) |
| .map(cmd => { |
| let commandText = \`/${cmd.name}\`; |
| |
| // Add parameters if any |
| const params = Object.entries(cmd.parameters || {}); |
| if (params.length > 0) { |
| const paramText = params |
| .map(([key, value]) => \`--\${key}=\${value}\`) |
| .join(' '); |
| commandText += ' ' + paramText; |
| } |
| |
| return commandText; |
| }) |
| .join(' '); |
| } |
| |
| // Add initial command step |
| addCommandStep(); |
| </script> |
| </body> |
| </html>`; |
| } |
|
|
| |
| function getDocumentationHtml() { |
| return `<!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Universal Developer Documentation</title> |
| <style> |
| body { |
| font-family: var(--vscode-font-family); |
| padding: 20px; |
| color: var(--vscode-foreground); |
| background-color: var(--vscode-editor-background); |
| line-height: 1.5; |
| } |
| |
| h1, h2, h3 { |
| font-weight: 600; |
| margin-top: 1.5em; |
| margin-bottom: 0.5em; |
| } |
| |
| h1 { |
| font-size: 2em; |
| border-bottom: 1px solid var(--vscode-panel-border); |
| padding-bottom: 0.3em; |
| } |
| |
| h2 { |
| font-size: 1.5em; |
| } |
| |
| h3 { |
| font-size: 1.25em; |
| } |
| |
| code { |
| font-family: var(--vscode-editor-font-family); |
| background-color: var(--vscode-editor-inactiveSelectionBackground); |
| padding: 2px 5px; |
| border-radius: 3px; |
| } |
| |
| pre { |
| background-color: var(--vscode-editor-inactiveSelectionBackground); |
| padding: 10px; |
| border-radius: 5px; |
| overflow: auto; |
| } |
| |
| pre code { |
| background-color: transparent; |
| padding: 0; |
| } |
| |
| table { |
| border-collapse: collapse; |
| width: 100%; |
| margin: 1em 0; |
| } |
| |
| th, td { |
| border: 1px solid var(--vscode-panel-border); |
| padding: 8px 12px; |
| text-align: left; |
| } |
| |
| th { |
| background-color: var(--vscode-editor-inactiveSelectionBackground); |
| } |
| |
| .command-section { |
| margin-bottom: 30px; |
| padding: 15px; |
| background-color: var(--vscode-editor-selectionHighlightBackground); |
| border-radius: 5px; |
| } |
| |
| .example { |
| margin: 10px 0; |
| padding: 10px; |
| background-color: var(--vscode-input-background); |
| border-radius: 5px; |
| } |
| |
| .tag { |
| display: inline-block; |
| padding: 2px 8px; |
| border-radius: 3px; |
| font-size: 0.8em; |
| margin-right: 5px; |
| } |
| |
| .tag.compatibility { |
| background-color: var(--vscode-debugIcon-startForeground); |
| color: white; |
| } |
| |
| .tag.advanced { |
| background-color: var(--vscode-debugIcon-restartForeground); |
| color: white; |
| } |
| |
| .tag.experimental { |
| background-color: var(--vscode-debugIcon-pauseForeground); |
| color: white; |
| } |
| </style> |
| </head> |
| <body> |
| <h1>Universal Developer Documentation</h1> |
| |
| <p> |
| The Universal Developer extension enables you to control large language model behavior through intuitive symbolic commands. |
| These commands provide a standardized interface for controlling model reasoning depth, response format, and other behaviors |
| across all major LLM platforms. |
| </p> |
| |
| <h2>Core Symbolic Commands</h2> |
| |
| <div class="command-section"> |
| <h3><code>/think</code> <span class="tag compatibility">All Providers</span></h3> |
| <p>Activates extended reasoning pathways, encouraging the model to approach the problem with deeper analysis and step-by-step reasoning.</p> |
| |
| <div class="example"> |
| <strong>Example:</strong> |
| <pre><code>/think What are the economic implications of increasing minimum wage?</code></pre> |
| </div> |
| |
| <p><strong>When to use:</strong> Complex questions, strategic planning, multi-factor analysis, ethical dilemmas.</p> |
| </div> |
| |
| <div class="command-section"> |
| <h3><code>/fast</code> <span class="tag compatibility">All Providers</span></h3> |
| <p>Optimizes for low-latency, concise responses. Prioritizes brevity and directness over comprehensiveness.</p> |
| |
| <div class="example"> |
| <strong>Example:</strong> |
| <pre><code>/fast What's the capital of France?</code></pre> |
| </div> |
| |
| <p><strong>When to use:</strong> Simple fact queries, quick summaries, situations where speed is prioritized over depth.</p> |
| </div> |
| |
| <div class="command-section"> |
| <h3><code>/loop</code> <span class="tag compatibility">All Providers</span></h3> |
| <p>Enables iterative refinement cycles, where the model improves its response through multiple revisions.</p> |
| |
| <div class="example"> |
| <strong>Example:</strong> |
| <pre><code>/loop --iterations=3 Improve this paragraph: Climate change is a big problem that affects many people and animals.</code></pre> |
| </div> |
| |
| <p><strong>Parameters:</strong></p> |
| <ul> |
| <li><code>iterations</code>: Number of refinement iterations (default: 3)</li> |
| </ul> |
| |
| <p><strong>When to use:</strong> Content refinement, code improvement, iterative problem-solving.</p> |
| </div> |
| |
| <div class="command-section"> |
| <h3><code>/reflect</code> <span class="tag compatibility">All Providers</span></h3> |
| <p>Triggers meta-analysis of outputs, causing the model to critically examine its own response for biases, limitations, and improvements.</p> |
| |
| <div class="example"> |
| <strong>Example:</strong> |
| <pre><code>/reflect How might AI impact the future of work?</code></pre> |
| </div> |
| |
| <p><strong>When to use:</strong> Critical analysis, identifying biases, ensuring balanced perspectives, philosophical inquiries.</p> |
| </div> |
| |
| <div class="command-section"> |
| <h3><code>/fork</code> <span class="tag compatibility">All Providers</span></h3> |
| <p>Generates multiple alternative responses representing different approaches or perspectives.</p> |
| |
| <div class="example"> |
| <strong>Example:</strong> |
| <pre><code>/fork --count=3 What are some approaches to reducing carbon emissions?</code></pre> |
| </div> |
| |
| <p><strong>Parameters:</strong></p> |
| <ul> |
| <li><code>count</code>: Number of alternatives to generate (default: 2)</li> |
| </ul> |
| |
| <p><strong>When to use:</strong> Exploring multiple options, creative brainstorming, presenting diverse perspectives.</p> |
| </div> |
| |
| <div class="command-section"> |
| <h3><code>/collapse</code> <span class="tag compatibility">All Providers</span></h3> |
| <p>Returns to default behavior, disabling any special processing modes.</p> |
| |
| <div class="example"> |
| <strong>Example:</strong> |
| <pre><code>/collapse What time is it?</code></pre> |
| </div> |
| |
| <p><strong>When to use:</strong> Basic queries, resetting to default behavior, standard responses.</p> |
| </div> |
| |
| <h2>Command Chaining</h2> |
| |
| <p>Commands can be chained together to create complex behaviors. The order of commands matters:</p> |
| |
| <div class="example"> |
| <strong>Example:</strong> |
| <pre><code>/think /loop --iterations=2 What strategy should a startup use to enter a competitive market?</code></pre> |
| <p><em>This will engage deep thinking mode and then apply two refinement iterations to the output.</em></p> |
| </div> |
| |
| <div class="example"> |
| <strong>Example:</strong> |
| <pre><code>/reflect /fork --count=2 What are the ethical implications of AI in healthcare?</code></pre> |
| <p><em>This will generate two alternative responses, each with critical reflection on limitations and biases.</em></p> |
| </div> |
| |
| <h2>Provider Compatibility</h2> |
| |
| <p> |
| The Universal Developer extension adapts these symbolic commands to work across different LLM providers, |
| ensuring consistent behavior regardless of the underlying model API. |
| </p> |
| |
| <table> |
| <tr> |
| <th>Provider</th> |
| <th>Supported Models</th> |
| <th>Implementation Notes</th> |
| </tr> |
| <tr> |
| <td>Anthropic</td> |
| <td>Claude 3 Opus, Sonnet, Haiku</td> |
| <td>Native thinking mode support via <code>enable_thinking</code> parameter</td> |
| </tr> |
| <tr> |
| <td>OpenAI</td> |
| <td>GPT-4, GPT-3.5</td> |
| <td>System prompt engineering for command emulation</td> |
| </tr> |
| <tr> |
| <td>Qwen</td> |
| <td>Qwen 3 models</td> |
| <td>Native thinking mode support via <code>/think</code> and <code>/no_think</code> markers</td> |
| </tr> |
| <tr> |
| <td>Gemini</td> |
| <td>Gemini Pro, Ultra</td> |
| <td>System prompt engineering with temperature adjustments</td> |
| </tr> |
| <tr> |
| <td>Local Models</td> |
| <td>Ollama, LMStudio</td> |
| <td>Limited support via prompt engineering</td> |
| </tr> |
| </table> |
| |
| <h2>Code Integration</h2> |
| |
| <div class="example"> |
| <strong>JavaScript/TypeScript:</strong> |
| <pre><code>import { UniversalLLM } from 'universal-developer'; |
| |
| const llm = new UniversalLLM({ |
| provider: 'anthropic', |
| apiKey: process.env.ANTHROPIC_API_KEY |
| }); |
| |
| async function analyze() { |
| const response = await llm.generate({ |
| prompt: "/think What are the implications of quantum computing for cybersecurity?" |
| }); |
| console.log(response); |
| }</code></pre> |
| </div> |
| |
| <div class="example"> |
| <strong>Python:</strong> |
| <pre><code>from universal_developer import UniversalLLM |
| |
| llm = UniversalLLM( |
| provider="openai", |
| api_key=os.environ["OPENAI_API_KEY"] |
| ) |
| |
| def improve_code(): |
| code = "def factorial(n):\\n result = 0\\n for i in range(1, n+1):\\n result *= i\\n return result" |
| response = llm.generate( |
| prompt=f"/loop --iterations=2 Improve this code:\\n```python\\n{code}\\n```" |
| ) |
| print(response)</code></pre> |
| </div> |
| |
| <h2>Custom Commands</h2> |
| |
| <p>You can register custom symbolic commands to extend functionality:</p> |
| |
| <div class="example"> |
| <pre><code>llm.registerCommand("debate", { |
| description: "Generate a balanced debate with arguments for both sides", |
| parameters: [ |
| { |
| name: "format", |
| description: "Format for the debate output", |
| required: false, |
| default: "point-counterpoint" |
| } |
| ], |
| transform: async (prompt, options) => { |
| // Custom implementation |
| } |
| });</code></pre> |
| </div> |
| |
| <h2>Extension Settings</h2> |
| |
| <p>The Universal Developer extension includes the following settings:</p> |
| |
| <ul> |
| <li><code>universal-developer.enableTelemetry</code>: Enable anonymous usage data collection (default: true)</li> |
| <li><code>universal-developer.defaultProvider</code>: Default provider for command examples</li> |
| <li><code>universal-developer.showStatusBar</code>: Show status bar item (default: true)</li> |
| </ul> |
| |
| <p><em>/reflect This interface creates a new layer of intentionality between developer and model—enabling deeper connection through structured symbolic prompting.</em></p> |
| </body> |
| </html>`; |
| } |
|
|
| |
| async function sendAnonymizedTelemetry(event: string, data: Record<string, any> = {}) { |
| try { |
| const config = vscode.workspace.getConfiguration('universal-developer'); |
| const telemetryEndpoint = config.get('telemetryEndpoint', 'https://telemetry.universal-developer.org/v1/events'); |
| |
| |
| const extensionContext = await getContext(); |
| let anonymousId = extensionContext.globalState.get('anonymousId'); |
| if (!anonymousId) { |
| anonymousId = generateAnonymousId(); |
| extensionContext.globalState.update('anonymousId', anonymousId); |
| } |
| |
| |
| const payload = { |
| event, |
| properties: { |
| ...data, |
| timestamp: new Date().toISOString(), |
| extension_version: vscode.extensions.getExtension('universal-developer.vscode')?.packageJSON.version, |
| vscode_version: vscode.version |
| }, |
| anonymousId |
| }; |
| |
| |
| fetch(telemetryEndpoint, { |
| method: 'POST', |
| headers: { 'Content-Type': 'application/json' }, |
| body: JSON.stringify(payload) |
| }).catch(() => { |
| |
| }); |
| } catch (error) { |
| |
| } |
| } |
|
|
| |
| async function getContext(): Promise<vscode.ExtensionContext> { |
| return new Promise((resolve) => { |
| vscode.commands.executeCommand('universal-developer.getContext') |
| .then((context: vscode.ExtensionContext) => resolve(context)); |
| }); |
| } |
|
|
| |
| function generateAnonymousId(): string { |
| return Math.random().toString(36).substring(2, 15) + |
| Math.random().toString(36).substring(2, 15); |
| } |
|
|
| |
| const SYMBOLIC_COMMANDS: SymbolicCommand[] = [ |
| { |
| name: 'think', |
| description: 'Activate extended reasoning pathways', |
| examples: [ |
| '/think What are the implications of quantum computing for cybersecurity?', |
| '/think Analyze the economic impact of increasing minimum wage.' |
| ], |
| provider: { |
| claude: true, |
| openai: true, |
| qwen: true, |
| gemini: true, |
| ollama: true |
| } |
| }, |
| { |
| name: 'fast', |
| description: 'Optimize for low-latency responses', |
| examples: [ |
| '/fast What\'s the capital of France?', |
| '/fast Summarize the key points of this article.' |
| ], |
| provider: { |
| claude: true, |
| openai: true, |
| qwen: true, |
| gemini: true, |
| ollama: true |
| } |
| }, |
| { |
| name: 'loop', |
| description: 'Enable iterative refinement cycles', |
| parameters: [ |
| { |
| name: 'iterations', |
| description: 'Number of refinement iterations', |
| required: false, |
| default: 3 |
| } |
| ], |
| examples: [ |
| '/loop Improve this code snippet: function add(a, b) { return a + b }', |
| '/loop --iterations=5 Refine this paragraph until it\'s clear and concise.' |
| ], |
| provider: { |
| claude: true, |
| openai: true, |
| qwen: true, |
| gemini: true, |
| ollama: true |
| } |
| }, |
| { |
| name: 'reflect', |
| description: 'Trigger meta-analysis of outputs', |
| examples: [ |
| '/reflect How might AI impact the future of work?', |
| '/reflect What are the ethical implications of genetic engineering?' |
| ], |
| provider: { |
| claude: true, |
| openai: true, |
| qwen: true, |
| gemini: true, |
| ollama: true |
| } |
| }, |
| { |
| name: 'collapse', |
| description: 'Return to default behavior', |
| examples: [ |
| '/collapse What time is it?', |
| '/collapse Tell me about the history of Rome.' |
| ], |
| provider: { |
| claude: true, |
| openai: true, |
| qwen: true, |
| gemini: true, |
| ollama: true |
| } |
| }, |
| { |
| name: 'fork', |
| description: 'Generate multiple alternative responses', |
| parameters: [ |
| { |
| name: 'count', |
| description: 'Number of alternatives to generate', |
| required: false, |
| default: 2 |
| } |
| ], |
| examples: [ |
| '/fork --count=3 What are some approaches to reducing carbon emissions?', |
| '/fork Generate two different marketing slogans |
| { |
| "name": "universal-developer", |
| "displayName": "Universal Developer - Symbolic Runtime Controls", |
| "description": "Control LLM behavior through symbolic runtime commands across all major AI platforms", |
| "version": "0.1.0", |
| "engines": { |
| "vscode": "^1.60.0" |
| }, |
| "publisher": "universal-developer", |
| "categories": [ |
| "Programming Languages", |
| "Snippets", |
| "Other" |
| ], |
| "keywords": [ |
| "ai", |
| "llm", |
| "claude", |
| "gpt", |
| "qwen", |
| "gemini", |
| "prompt engineering", |
| "symbolic commands" |
| ], |
| "icon": "images/icon.png", |
| "galleryBanner": { |
| "color": "#24292e", |
| "theme": "dark" |
| }, |
| "activationEvents": [ |
| "onLanguage:javascript", |
| "onLanguage:typescript", |
| "onLanguage:python", |
| "onLanguage:markdown", |
| "onLanguage:plaintext" |
| ], |
| "main": "./out/extension.js", |
| "contributes": { |
| "commands": [ |
| { |
| "command": "universal-developer.insertSymbolicCommand", |
| "title": "Universal Developer: Insert Symbolic Command" |
| }, |
| { |
| "command": "universal-developer.buildSymbolicChain", |
| "title": "Universal Developer: Build Symbolic Command Chain" |
| }, |
| { |
| "command": "universal-developer.showDocumentation", |
| "title": "Universal Developer: Open Documentation" |
| }, |
| { |
| "command": "universal-developer.getContext", |
| "title": "Universal Developer: Get Extension Context" |
| } |
| ], |
| "keybindings": [ |
| { |
| "command": "universal-developer.insertSymbolicCommand", |
| "key": "ctrl+shift+/", |
| "mac": "cmd+shift+/", |
| "when": "editorTextFocus" |
| }, |
| { |
| "command": "universal-developer.buildSymbolicChain", |
| "key": "ctrl+shift+.", |
| "mac": "cmd+shift+.", |
| "when": "editorTextFocus" |
| } |
| ], |
| "menus": { |
| "editor/context": [ |
| { |
| "command": "universal-developer.insertSymbolicCommand", |
| "group": "universal-developer", |
| "when": "editorTextFocus" |
| }, |
| { |
| "command": "universal-developer.buildSymbolicChain", |
| "group": "universal-developer", |
| "when": "editorTextFocus" |
| } |
| ] |
| }, |
| "configuration": { |
| "title": "Universal Developer", |
| "properties": { |
| "universal-developer.enableTelemetry": { |
| "type": "boolean", |
| "default": true, |
| "description": "Enable anonymous usage data collection to improve the extension" |
| }, |
| "universal-developer.defaultProvider": { |
| "type": "string", |
| "enum": [ |
| "anthropic", |
| "openai", |
| "qwen", |
| "gemini", |
| "ollama" |
| ], |
| "default": "anthropic", |
| "description": "Default LLM provider for command examples" |
| }, |
| "universal-developer.showStatusBar": { |
| "type": "boolean", |
| "default": true, |
| "description": "Show Universal Developer status bar item" |
| }, |
| "universal-developer.telemetryEndpoint": { |
| "type": "string", |
| "default": "https://telemetry.universal-developer.org/v1/events", |
| "description": "Endpoint for telemetry data collection" |
| } |
| } |
| }, |
| "snippets": [ |
| { |
| "language": "javascript", |
| "path": "./snippets/javascript.json" |
| }, |
| { |
| "language": "typescript", |
| "path": "./snippets/typescript.json" |
| }, |
| { |
| "language": "python", |
| "path": "./snippets/python.json" |
| } |
| ] |
| }, |
| "scripts": { |
| "vscode:prepublish": "npm run compile", |
| "compile": "tsc -p ./", |
| "watch": "tsc -watch -p ./", |
| "pretest": "npm run compile && npm run lint", |
| "lint": "eslint src --ext ts", |
| "test": "node ./out/test/runTest.js", |
| "package": "vsce package" |
| }, |
| "devDependencies": { |
| "@types/glob": "^7.1.3", |
| "@types/mocha": "^8.2.2", |
| "@types/node": "^14.14.37", |
| "@types/vscode": "^1.60.0", |
| "@typescript-eslint/eslint-plugin": "^4.21.0", |
| "@typescript-eslint/parser": "^4.21.0", |
| "eslint": "^7.24.0", |
| "glob": "^7.1.7", |
| "mocha": "^8.3.2", |
| "typescript": "^4.2.4", |
| "vscode-test": "^1.5.2", |
| "vsce": "^2.7.0" |
| }, |
| "dependencies": { |
| "node-fetch": "^2.6.7" |
| }, |
| "repository": { |
| "type": "git", |
| "url": "https://github.com/universal-developer/vscode-extension.git" |
| }, |
| "homepage": "https://github.com/universal-developer/vscode-extension", |
| "bugs": { |
| "url": "https://github.com/universal-developer/vscode-extension/issues" |
| }, |
| "license": "MIT" |
| } |
| |