Skip to main content
Glama
aegntic

Obsidian Elite RAG MCP Server

vscode-extension.ts.disabled34.9 kB
/** * VS Code Extension integration for DailyDoco Pro * Provides capture triggers, Git integration, and development workflow automation */ import { z } from 'zod'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import * as vscode from 'vscode'; import * as cp from 'child_process'; import * as fs from 'fs/promises'; import * as path from 'path'; // VS Code Extension Tool Schema const VSCodeExtensionInputSchema = z.object({ action: z.enum([ 'install-extension', 'create-capture-trigger', 'setup-git-hooks', 'start-capture', 'stop-capture', 'configure-settings', 'show-status', 'open-dashboard' ]), projectPath: z.string().optional(), settings: z.record(z.any()).optional(), triggerEvents: z.array(z.string()).optional(), }); interface CaptureEvent { type: 'git-commit' | 'test-run' | 'debug-start' | 'file-save' | 'build-complete'; timestamp: Date; context: Record<string, any>; } interface VSCodeExtensionManifest { name: string; displayName: string; description: string; version: string; engines: { vscode: string; }; categories: string[]; activationEvents: string[]; main: string; contributes: { commands: Command[]; configuration: Configuration; views: Views; menus: Menus; keybindings: KeyBinding[]; }; scripts: Record<string, string>; devDependencies: Record<string, string>; dependencies: Record<string, string>; } interface Command { command: string; title: string; category: string; icon?: string; } interface Configuration { title: string; properties: Record<string, ConfigProperty>; } interface ConfigProperty { type: string; default: any; description: string; enum?: string[]; } interface Views { explorer: ViewContainer[]; } interface ViewContainer { id: string; name: string; when: string; } interface Menus { 'view/title': MenuItem[]; 'view/item/context': MenuItem[]; 'editor/context': MenuItem[]; commandPalette: MenuItem[]; } interface MenuItem { command: string; when?: string; group?: string; } interface KeyBinding { command: string; key: string; when?: string; } /** * VS Code Extension Builder and Manager */ export class VSCodeExtensionBuilder { private projectPath: string; private settings: Record<string, any>; private captureEvents: CaptureEvent[] = []; constructor(projectPath: string) { this.projectPath = projectPath; this.settings = {}; } /** * Create the complete VS Code extension */ async createExtension(): Promise<string> { const extensionPath = path.join(this.projectPath, '.vscode', 'extensions', 'dailydoco-pro'); // Create extension directory structure await fs.mkdir(extensionPath, { recursive: true }); await fs.mkdir(path.join(extensionPath, 'src'), { recursive: true }); await fs.mkdir(path.join(extensionPath, 'media'), { recursive: true }); // Generate package.json manifest const manifest = this.generateManifest(); await fs.writeFile( path.join(extensionPath, 'package.json'), JSON.stringify(manifest, null, 2) ); // Generate main extension file const mainCode = this.generateMainExtensionCode(); await fs.writeFile( path.join(extensionPath, 'src', 'extension.ts'), mainCode ); // Generate status provider const statusCode = this.generateStatusProvider(); await fs.writeFile( path.join(extensionPath, 'src', 'statusProvider.ts'), statusCode ); // Generate capture controller const captureCode = this.generateCaptureController(); await fs.writeFile( path.join(extensionPath, 'src', 'captureController.ts'), captureCode ); // Generate Git hooks await this.setupGitHooks(); // Generate TypeScript configuration const tsConfig = this.generateTsConfig(); await fs.writeFile( path.join(extensionPath, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2) ); // Generate webpack configuration const webpackConfig = this.generateWebpackConfig(); await fs.writeFile( path.join(extensionPath, 'webpack.config.js'), webpackConfig ); return extensionPath; } /** * Generate VS Code extension manifest (package.json) */ private generateManifest(): VSCodeExtensionManifest { return { name: 'dailydoco-pro-vscode', displayName: 'DailyDoco Pro', description: 'Automatic development documentation capture and video generation', version: '1.0.0', engines: { vscode: '^1.60.0' }, categories: ['Other', 'Debuggers', 'Testing'], activationEvents: [ 'onStartupFinished', 'onCommand:dailydoco.startCapture', 'workspaceContains:**/.git' ], main: './out/src/extension.js', contributes: { commands: [ { command: 'dailydoco.startCapture', title: 'Start Capture', category: 'DailyDoco', icon: '$(record)' }, { command: 'dailydoco.stopCapture', title: 'Stop Capture', category: 'DailyDoco', icon: '$(stop)' }, { command: 'dailydoco.openDashboard', title: 'Open Dashboard', category: 'DailyDoco', icon: '$(dashboard)' }, { command: 'dailydoco.viewProjects', title: 'View Projects', category: 'DailyDoco', icon: '$(folder-opened)' }, { command: 'dailydoco.configureSettings', title: 'Configure Settings', category: 'DailyDoco', icon: '$(gear)' }, { command: 'dailydoco.refreshStatus', title: 'Refresh Status', category: 'DailyDoco', icon: '$(refresh)' } ], configuration: { title: 'DailyDoco Pro', properties: { 'dailydoco.enableAutoCapture': { type: 'boolean', default: true, description: 'Automatically start capture when VS Code opens' }, 'dailydoco.captureEvents': { type: 'array', default: ['git-commit', 'test-run', 'debug-start'], description: 'Events that trigger documentation capture', enum: ['git-commit', 'test-run', 'debug-start', 'file-save', 'build-complete'] }, 'dailydoco.serverUrl': { type: 'string', default: 'http://localhost:8080', description: 'DailyDoco Pro server URL' }, 'dailydoco.enableAegnt27': { type: 'boolean', default: true, description: 'Enable aegnt-27 humanization features' }, 'dailydoco.captureQuality': { type: 'string', default: 'high', description: 'Video capture quality', enum: ['draft', 'good', 'high', 'lossless'] }, 'dailydoco.enableNotifications': { type: 'boolean', default: true, description: 'Show notifications for capture events' } } }, views: { explorer: [ { id: 'dailydocoStatus', name: 'DailyDoco Status', when: 'workspaceContains:**/.git' } ] }, menus: { 'view/title': [ { command: 'dailydoco.refreshStatus', when: 'view == dailydocoStatus', group: 'navigation' } ], 'view/item/context': [ { command: 'dailydoco.startCapture', when: 'view == dailydocoStatus && viewItem == project', group: 'inline' } ], 'editor/context': [ { command: 'dailydoco.startCapture', group: 'dailydoco@1' } ], commandPalette: [ { command: 'dailydoco.startCapture' }, { command: 'dailydoco.stopCapture' }, { command: 'dailydoco.openDashboard' } ] }, keybindings: [ { command: 'dailydoco.startCapture', key: 'ctrl+shift+r', when: 'editorTextFocus' }, { command: 'dailydoco.stopCapture', key: 'ctrl+shift+s', when: 'editorTextFocus' } ] }, scripts: { 'vscode:prepublish': 'npm run compile', compile: 'webpack --mode production', watch: 'webpack --mode development --watch', pretest: 'npm run compile && npm run lint', lint: 'eslint src --ext ts', test: 'node ./out/test/runTest.js' }, devDependencies: { '@types/vscode': '^1.60.0', '@types/node': '16.x', '@typescript-eslint/eslint-plugin': '^4.31.1', '@typescript-eslint/parser': '^4.31.1', 'eslint': '^7.32.0', 'typescript': '^4.4.3', 'webpack': '^5.52.1', 'webpack-cli': '^4.8.0', 'ts-loader': '^9.2.5' }, dependencies: { 'axios': '^0.24.0', 'ws': '^8.2.3' } }; } /** * Generate main extension code */ private generateMainExtensionCode(): string { return `import * as vscode from 'vscode'; import { StatusProvider } from './statusProvider'; import { CaptureController } from './captureController'; export function activate(context: vscode.ExtensionContext) { console.log('DailyDoco Pro extension is now active!'); // Initialize components const statusProvider = new StatusProvider(); const captureController = new CaptureController(); // Register tree data provider vscode.window.createTreeView('dailydocoStatus', { treeDataProvider: statusProvider, showCollapseAll: true }); // Register commands const commands = [ vscode.commands.registerCommand('dailydoco.startCapture', () => { captureController.startCapture(); }), vscode.commands.registerCommand('dailydoco.stopCapture', () => { captureController.stopCapture(); }), vscode.commands.registerCommand('dailydoco.openDashboard', () => { vscode.env.openExternal(vscode.Uri.parse('http://localhost:8080/dashboard')); }), vscode.commands.registerCommand('dailydoco.viewProjects', () => { vscode.env.openExternal(vscode.Uri.parse('http://localhost:8080/projects')); }), vscode.commands.registerCommand('dailydoco.configureSettings', () => { vscode.commands.executeCommand('workbench.action.openSettings', 'dailydoco'); }), vscode.commands.registerCommand('dailydoco.refreshStatus', () => { statusProvider.refresh(); }) ]; // Auto-start capture if enabled const config = vscode.workspace.getConfiguration('dailydoco'); if (config.get('enableAutoCapture', true)) { captureController.startCapture(); } // Listen for workspace events setupEventListeners(captureController); // Add all commands to context commands.forEach(command => context.subscriptions.push(command)); // Register providers context.subscriptions.push(statusProvider); context.subscriptions.push(captureController); // Show welcome message vscode.window.showInformationMessage( 'DailyDoco Pro is ready to capture your development workflow!', 'Open Dashboard', 'Configure Settings' ).then(selection => { if (selection === 'Open Dashboard') { vscode.commands.executeCommand('dailydoco.openDashboard'); } else if (selection === 'Configure Settings') { vscode.commands.executeCommand('dailydoco.configureSettings'); } }); } function setupEventListeners(captureController: CaptureController) { const config = vscode.workspace.getConfiguration('dailydoco'); const captureEvents = config.get('captureEvents', ['git-commit', 'test-run', 'debug-start']); // File save events if (captureEvents.includes('file-save')) { vscode.workspace.onDidSaveTextDocument(() => { captureController.triggerEvent('file-save'); }); } // Debug events if (captureEvents.includes('debug-start')) { vscode.debug.onDidStartDebugSession(() => { captureController.triggerEvent('debug-start'); }); } // Terminal events for test runs and builds vscode.window.onDidChangeActiveTerminal(() => { // Monitor terminal for test/build commands captureController.monitorTerminalActivity(); }); // Git events (through file system watcher) const gitWatcher = vscode.workspace.createFileSystemWatcher('**/.git/**'); gitWatcher.onDidChange(() => { if (captureEvents.includes('git-commit')) { captureController.triggerEvent('git-commit'); } }); } export function deactivate() { console.log('DailyDoco Pro extension is now deactivated'); }`; } /** * Generate status provider code */ private generateStatusProvider(): string { return `import * as vscode from 'vscode'; import axios from 'axios'; export class StatusProvider implements vscode.TreeDataProvider<StatusItem> { private _onDidChangeTreeData: vscode.EventEmitter<StatusItem | undefined | null | void> = new vscode.EventEmitter<StatusItem | undefined | null | void>(); readonly onDidChangeTreeData: vscode.Event<StatusItem | undefined | null | void> = this._onDidChangeTreeData.event; private status: any = null; constructor() { this.refreshStatus(); // Refresh every 5 seconds setInterval(() => this.refreshStatus(), 5000); } refresh(): void { this.refreshStatus(); this._onDidChangeTreeData.fire(); } async refreshStatus(): Promise<void> { try { const config = vscode.workspace.getConfiguration('dailydoco'); const serverUrl = config.get('serverUrl', 'http://localhost:8080'); const response = await axios.get(\`\${serverUrl}/api/status\`, { timeout: 2000 }); this.status = response.data; } catch (error) { this.status = { connected: false, error: 'Cannot connect to DailyDoco Pro server' }; } } getTreeItem(element: StatusItem): vscode.TreeItem { return element; } getChildren(element?: StatusItem): Thenable<StatusItem[]> { if (!this.status) { return Promise.resolve([ new StatusItem('Loading...', vscode.TreeItemCollapsibleState.None, 'loading', '$(loading~spin)') ]); } if (!this.status.connected) { return Promise.resolve([ new StatusItem('Disconnected', vscode.TreeItemCollapsibleState.None, 'error', '$(error)'), new StatusItem(this.status.error || 'Server unavailable', vscode.TreeItemCollapsibleState.None, 'info') ]); } if (!element) { // Root level items return Promise.resolve([ new StatusItem( \`Capture: \${this.status.capture?.isActive ? 'Active' : 'Inactive'}\`, vscode.TreeItemCollapsibleState.Collapsed, 'capture', this.status.capture?.isActive ? '$(record)' : '$(stop)' ), new StatusItem( \`Processing: \${this.status.processing?.queueLength || 0} jobs\`, vscode.TreeItemCollapsibleState.Collapsed, 'processing', '$(gear)' ), new StatusItem( \`AI Models: \${this.status.ai?.modelsLoaded?.length || 0} loaded\`, vscode.TreeItemCollapsibleState.Collapsed, 'ai', '$(robot)' ), new StatusItem( \`System Health\`, vscode.TreeItemCollapsibleState.Collapsed, 'system', '$(pulse)' ) ]); } // Child items based on parent switch (element.contextValue) { case 'capture': return Promise.resolve([ new StatusItem(\`FPS: \${this.status.capture?.fps || 0}\`, vscode.TreeItemCollapsibleState.None, 'info'), new StatusItem(\`Resolution: \${this.status.capture?.resolution || 'Unknown'}\`, vscode.TreeItemCollapsibleState.None, 'info'), new StatusItem(\`CPU: \${this.status.capture?.cpuUsage || 0}%\`, vscode.TreeItemCollapsibleState.None, 'info'), new StatusItem(\`Memory: \${this.status.capture?.memoryUsage || 0}MB\`, vscode.TreeItemCollapsibleState.None, 'info') ]); case 'processing': return Promise.resolve([ new StatusItem(\`Queue: \${this.status.processing?.queueLength || 0}\`, vscode.TreeItemCollapsibleState.None, 'info'), new StatusItem(\`Completed Today: \${this.status.processing?.completedToday || 0}\`, vscode.TreeItemCollapsibleState.None, 'info'), new StatusItem(\`Avg Time: \${this.status.processing?.averageProcessingTime || 0}s\`, vscode.TreeItemCollapsibleState.None, 'info'), ...(this.status.processing?.currentJob ? [ new StatusItem(\`Current: \${this.status.processing.currentJob}\`, vscode.TreeItemCollapsibleState.None, 'info') ] : []) ]); case 'ai': return Promise.resolve([ new StatusItem(\`Capacity: \${this.status.ai?.availableCapacity || 0}%\`, vscode.TreeItemCollapsibleState.None, 'info'), new StatusItem(\`Active Tasks: \${this.status.ai?.currentTasks || 0}\`, vscode.TreeItemCollapsibleState.None, 'info'), ...(this.status.ai?.modelsLoaded?.map((model: string) => new StatusItem(model, vscode.TreeItemCollapsibleState.None, 'info', '$(chip)') ) || []) ]); case 'system': return Promise.resolve([ new StatusItem(\`Disk: \${100 - (this.status.system?.diskSpace || 0)}% free\`, vscode.TreeItemCollapsibleState.None, 'info'), new StatusItem(\`Temp: \${this.status.system?.temperature || 0}°C\`, vscode.TreeItemCollapsibleState.None, 'info'), new StatusItem(\`Network: \${this.status.system?.networkStatus || 'Unknown'}\`, vscode.TreeItemCollapsibleState.None, 'info'), ...(this.status.system?.batteryLevel ? [ new StatusItem(\`Battery: \${this.status.system.batteryLevel}%\`, vscode.TreeItemCollapsibleState.None, 'info') ] : []) ]); default: return Promise.resolve([]); } } } class StatusItem extends vscode.TreeItem { constructor( public readonly label: string, public readonly collapsibleState: vscode.TreeItemCollapsibleState, public readonly contextValue?: string, public readonly iconPath?: string ) { super(label, collapsibleState); this.tooltip = \`\${this.label}\`; } }`; } /** * Generate capture controller code */ private generateCaptureController(): string { return `import * as vscode from 'vscode'; import axios from 'axios'; import * as WebSocket from 'ws'; export class CaptureController implements vscode.Disposable { private ws: WebSocket | null = null; private isCapturing = false; private terminalWatcher: vscode.Disposable | null = null; constructor() { this.connectWebSocket(); } private connectWebSocket(): void { const config = vscode.workspace.getConfiguration('dailydoco'); const serverUrl = config.get('serverUrl', 'http://localhost:8080'); const wsUrl = serverUrl.replace('http://', 'ws://').replace('https://', 'wss://') + '/ws'; try { this.ws = new WebSocket(wsUrl); this.ws.on('open', () => { console.log('Connected to DailyDoco WebSocket'); }); this.ws.on('message', (data: WebSocket.Data) => { const message = JSON.parse(data.toString()); this.handleWebSocketMessage(message); }); this.ws.on('close', () => { console.log('DailyDoco WebSocket connection closed'); // Reconnect after 5 seconds setTimeout(() => this.connectWebSocket(), 5000); }); this.ws.on('error', (error) => { console.error('DailyDoco WebSocket error:', error); }); } catch (error) { console.error('Failed to connect to DailyDoco WebSocket:', error); } } private handleWebSocketMessage(message: any): void { switch (message.type) { case 'capture-started': this.isCapturing = true; this.showNotification('Capture started', 'DailyDoco is now recording your workflow'); break; case 'capture-stopped': this.isCapturing = false; this.showNotification('Capture stopped', 'Recording has been saved'); break; case 'video-processed': this.showNotification( 'Video ready', \`Your documentation video has been processed with \${message.data.authenticityScore}% authenticity\`, 'View Video' ); break; case 'error': vscode.window.showErrorMessage(\`DailyDoco Error: \${message.data.error}\`); break; } } async startCapture(): Promise<void> { try { const config = vscode.workspace.getConfiguration('dailydoco'); const serverUrl = config.get('serverUrl', 'http://localhost:8080'); const workspaceFolder = vscode.workspace.workspaceFolders?.[0]; if (!workspaceFolder) { vscode.window.showErrorMessage('No workspace folder open'); return; } const response = await axios.post(\`\${serverUrl}/api/capture/start\`, { projectPath: workspaceFolder.uri.fsPath, captureQuality: config.get('captureQuality', 'high'), enableAegnt27: config.get('enableAegnt27', true) }); this.isCapturing = true; this.showNotification('Capture started', 'DailyDoco is now recording your workflow'); } catch (error) { vscode.window.showErrorMessage(\`Failed to start capture: \${error}\`); } } async stopCapture(): Promise<void> { try { const config = vscode.workspace.getConfiguration('dailydoco'); const serverUrl = config.get('serverUrl', 'http://localhost:8080'); await axios.post(\`\${serverUrl}/api/capture/stop\`); this.isCapturing = false; this.showNotification('Capture stopped', 'Processing your documentation video...'); } catch (error) { vscode.window.showErrorMessage(\`Failed to stop capture: \${error}\`); } } triggerEvent(eventType: string): void { if (!this.isCapturing) { return; } if (this.ws && this.ws.readyState === WebSocket.OPEN) { this.ws.send(JSON.stringify({ type: 'capture-event', data: { eventType, timestamp: new Date().toISOString(), workspace: vscode.workspace.workspaceFolders?.[0]?.uri.fsPath, activeFile: vscode.window.activeTextEditor?.document.fileName } })); } this.showNotification( 'Event captured', \`Recorded \${eventType} event for documentation\` ); } monitorTerminalActivity(): void { // Clean up existing watcher if (this.terminalWatcher) { this.terminalWatcher.dispose(); } const activeTerminal = vscode.window.activeTerminal; if (!activeTerminal) { return; } // Listen for terminal text changes (simplified) // In a real implementation, this would be more sophisticated this.terminalWatcher = vscode.window.onDidWriteTerminalData(e => { const data = e.data.toLowerCase(); if (data.includes('npm test') || data.includes('yarn test') || data.includes('jest')) { this.triggerEvent('test-run'); } else if (data.includes('npm run build') || data.includes('yarn build')) { this.triggerEvent('build-complete'); } }); } private showNotification(title: string, message: string, action?: string): void { const config = vscode.workspace.getConfiguration('dailydoco'); if (!config.get('enableNotifications', true)) { return; } if (action) { vscode.window.showInformationMessage(message, action).then(selection => { if (selection === action && action === 'View Video') { vscode.env.openExternal(vscode.Uri.parse('http://localhost:8080/videos')); } }); } else { vscode.window.showInformationMessage(message); } } dispose(): void { if (this.ws) { this.ws.close(); } if (this.terminalWatcher) { this.terminalWatcher.dispose(); } } }`; } /** * Setup Git hooks for capture events */ private async setupGitHooks(): Promise<void> { const gitHooksPath = path.join(this.projectPath, '.git', 'hooks'); try { await fs.access(gitHooksPath); } catch { // No .git directory, skip Git hooks return; } // Pre-commit hook const preCommitHook = `#!/bin/sh # DailyDoco Pro pre-commit hook curl -X POST http://localhost:8080/api/capture/event \\ -H "Content-Type: application/json" \\ -d '{"type": "pre-commit", "timestamp": "'$(date -Iseconds)'"}' \\ --silent --max-time 2 || true `; await fs.writeFile(path.join(gitHooksPath, 'pre-commit'), preCommitHook); await fs.chmod(path.join(gitHooksPath, 'pre-commit'), 0o755); // Post-commit hook const postCommitHook = `#!/bin/sh # DailyDoco Pro post-commit hook curl -X POST http://localhost:8080/api/capture/event \\ -H "Content-Type: application/json" \\ -d '{"type": "git-commit", "timestamp": "'$(date -Iseconds)'", "commit": "'$(git rev-parse HEAD)'"}' \\ --silent --max-time 2 || true `; await fs.writeFile(path.join(gitHooksPath, 'post-commit'), postCommitHook); await fs.chmod(path.join(gitHooksPath, 'post-commit'), 0o755); } /** * Generate TypeScript configuration */ private generateTsConfig(): any { return { compilerOptions: { module: 'commonjs', target: 'es6', lib: ['es6'], declaration: true, outDir: 'out', rootDir: 'src', strict: true, moduleResolution: 'node', baseUrl: './src', esModuleInterop: true, skipLibCheck: true, forceConsistentCasingInFileNames: true, resolveJsonModule: true }, exclude: ['node_modules', '.vscode-test'] }; } /** * Generate Webpack configuration */ private generateWebpackConfig(): string { return `const path = require('path'); module.exports = { target: 'node', entry: './src/extension.ts', output: { path: path.resolve(__dirname, 'out'), filename: 'extension.js', libraryTarget: 'commonjs2', devtoolModuleFilenameTemplate: '../[resource-path]' }, devtool: 'source-map', externals: { vscode: 'commonjs vscode' }, resolve: { extensions: ['.ts', '.js'] }, module: { rules: [ { test: /\\.ts$/, exclude: /node_modules/, use: [ { loader: 'ts-loader' } ] } ] } };`; } } /** * VS Code Extension Tool Implementation */ export const vscodeExtensionTool: Tool = { name: 'vscode-extension', description: 'Create and manage VS Code extension for DailyDoco Pro integration', inputSchema: VSCodeExtensionInputSchema, }; export async function handleVSCodeExtension(input: z.infer<typeof VSCodeExtensionInputSchema>) { const { action, projectPath = process.cwd(), settings = {}, triggerEvents = [] } = input; const builder = new VSCodeExtensionBuilder(projectPath); switch (action) { case 'install-extension': return await installExtension(projectPath); case 'create-capture-trigger': return await createCaptureTrigger(projectPath, triggerEvents); case 'setup-git-hooks': return await setupGitHooksForProject(projectPath); case 'start-capture': return await startCaptureFromExtension(projectPath); case 'stop-capture': return await stopCaptureFromExtension(projectPath); case 'configure-settings': return await configureExtensionSettings(projectPath, settings); case 'show-status': return await showExtensionStatus(projectPath); case 'open-dashboard': return await openDashboardFromExtension(); default: throw new Error(`Unknown VS Code extension action: ${action}`); } } async function installExtension(projectPath: string): Promise<string> { const builder = new VSCodeExtensionBuilder(projectPath); const extensionPath = await builder.createExtension(); // Install the extension via command line const installCommand = `code --install-extension ${extensionPath}`; return new Promise((resolve, reject) => { cp.exec(installCommand, (error, stdout, stderr) => { if (error) { reject(`Failed to install extension: ${error.message}`); } else { resolve(`DailyDoco Pro VS Code extension installed successfully at ${extensionPath}`); } }); }); } async function createCaptureTrigger(projectPath: string, triggerEvents: string[]): Promise<string> { const triggerConfig = { events: triggerEvents, projectPath, timestamp: new Date().toISOString() }; const configPath = path.join(projectPath, '.vscode', 'dailydoco.json'); await fs.mkdir(path.dirname(configPath), { recursive: true }); await fs.writeFile(configPath, JSON.stringify(triggerConfig, null, 2)); return `Capture triggers configured for events: ${triggerEvents.join(', ')}`; } async function setupGitHooksForProject(projectPath: string): Promise<string> { const builder = new VSCodeExtensionBuilder(projectPath); await builder['setupGitHooks'](); // Access private method for this specific case return 'Git hooks configured for DailyDoco Pro capture events'; } async function startCaptureFromExtension(projectPath: string): Promise<string> { try { const response = await fetch('http://localhost:8080/api/capture/start', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ projectPath }) }); if (response.ok) { return 'Capture started from VS Code extension'; } else { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } } catch (error) { throw new Error(`Failed to start capture: ${error}`); } } async function stopCaptureFromExtension(projectPath: string): Promise<string> { try { const response = await fetch('http://localhost:8080/api/capture/stop', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ projectPath }) }); if (response.ok) { return 'Capture stopped from VS Code extension'; } else { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } } catch (error) { throw new Error(`Failed to stop capture: ${error}`); } } async function configureExtensionSettings(projectPath: string, settings: Record<string, any>): Promise<string> { const vscodeSettingsPath = path.join(projectPath, '.vscode', 'settings.json'); let existingSettings = {}; try { const existingContent = await fs.readFile(vscodeSettingsPath, 'utf8'); existingSettings = JSON.parse(existingContent); } catch { // File doesn't exist or is invalid, start with empty settings } // Merge DailyDoco settings const updatedSettings = { ...existingSettings, ...Object.fromEntries( Object.entries(settings).map(([key, value]) => [`dailydoco.${key}`, value]) ) }; await fs.mkdir(path.dirname(vscodeSettingsPath), { recursive: true }); await fs.writeFile(vscodeSettingsPath, JSON.stringify(updatedSettings, null, 2)); return `VS Code settings updated with DailyDoco configuration`; } async function showExtensionStatus(projectPath: string): Promise<string> { try { const response = await fetch('http://localhost:8080/api/status'); const status = await response.json(); return `DailyDoco Pro Status: Capture: ${status.capture?.isActive ? 'Active' : 'Inactive'} Processing Queue: ${status.processing?.queueLength || 0} jobs AI Models: ${status.ai?.modelsLoaded?.length || 0} loaded System Health: ${status.system?.networkStatus || 'Unknown'}`; } catch (error) { return `Unable to connect to DailyDoco Pro server: ${error}`; } } async function openDashboardFromExtension(): Promise<string> { // Open dashboard in default browser const dashboardUrl = 'http://localhost:8080/dashboard'; const openCommand = process.platform === 'win32' ? 'start' : process.platform === 'darwin' ? 'open' : 'xdg-open'; return new Promise((resolve, reject) => { cp.exec(`${openCommand} ${dashboardUrl}`, (error) => { if (error) { reject(`Failed to open dashboard: ${error.message}`); } else { resolve(`DailyDoco Pro dashboard opened: ${dashboardUrl}`); } }); }); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aegntic/aegntic-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server