const vscode = require('vscode'); const https = require('https'); const http = require('http'); const os = require('os'); const fs = require('fs'); const path = require('path'); const crypto = require('crypto'); const { execSync } = require('child_process'); let currentAgent = 'alfred'; let convId = null; let csrfToken = null; let sessionCookie = null; let userProfile = null; let hmacSecretCache = null; // ═══════════════════════════════════════════════════════════════════════════ // WORKSPACE INTELLIGENCE ENGINE — Deep awareness of project, files, git // ═══════════════════════════════════════════════════════════════════════════ function getWorkspaceRoot() { const folders = vscode.workspace.workspaceFolders; return folders && folders.length > 0 ? folders[0].uri.fsPath : os.homedir(); } function safeExec(cmd, cwd, timeout) { try { return execSync(cmd, { cwd: cwd || getWorkspaceRoot(), encoding: 'utf8', timeout: timeout || 5000, stdio: ['pipe', 'pipe', 'pipe'] }).trim(); } catch (_) { return ''; } } function getProjectStructure() { const root = getWorkspaceRoot(); try { const tree = safeExec('find . -maxdepth 3 -not -path "./.git/*" -not -path "./node_modules/*" -not -path "./.venv/*" -not -path "./__pycache__/*" -not -path "./vendor/*" -not -path "./dist/*" -not -path "./build/*" | sort | head -200', root); return tree || ''; } catch (_) { return ''; } } function getProjectLanguages() { const root = getWorkspaceRoot(); const exts = safeExec('find . -maxdepth 4 -type f -not -path "./.git/*" -not -path "./node_modules/*" -not -path "./.venv/*" -not -path "./vendor/*" | sed "s/.*\\.//" | sort | uniq -c | sort -rn | head -20', root); return exts || ''; } function detectProjectType() { const root = getWorkspaceRoot(); const indicators = []; const checks = [ ['package.json', 'Node.js / JavaScript'], ['tsconfig.json', 'TypeScript'], ['composer.json', 'PHP / Composer'], ['requirements.txt', 'Python'], ['pyproject.toml', 'Python (modern)'], ['Cargo.toml', 'Rust'], ['go.mod', 'Go'], ['pom.xml', 'Java / Maven'], ['build.gradle', 'Java / Gradle'], ['Gemfile', 'Ruby'], ['.htaccess', 'Apache Web Server'], ['Dockerfile', 'Docker'], ['docker-compose.yml', 'Docker Compose'], ['Makefile', 'Make-based build'], ['CMakeLists.txt', 'C/C++ CMake'], ['.env', 'Environment config'], ['webpack.config.js', 'Webpack'], ['vite.config.ts', 'Vite'], ['next.config.js', 'Next.js'], ['nuxt.config.ts', 'Nuxt'], ['tailwind.config.js', 'Tailwind CSS'], ]; for (const [file, label] of checks) { try { if (fs.existsSync(path.join(root, file))) indicators.push(label); } catch (_) {} } return indicators; } function getGitInfo() { const root = getWorkspaceRoot(); const branch = safeExec('git rev-parse --abbrev-ref HEAD', root); if (!branch) return null; const status = safeExec('git status --porcelain | head -30', root); const lastCommit = safeExec('git log -1 --format="%h %s (%cr)"', root); const remoteUrl = safeExec('git remote get-url origin', root); const dirty = safeExec('git diff --stat | tail -1', root); const ahead = safeExec('git rev-list --count @{u}..HEAD 2>/dev/null || echo 0', root); const behind = safeExec('git rev-list --count HEAD..@{u} 2>/dev/null || echo 0', root); return { branch, status, lastCommit, remoteUrl, dirty, ahead, behind }; } function getOpenEditors() { const editors = []; for (const group of vscode.window.tabGroups.all) { for (const tab of group.tabs) { if (tab.input && tab.input.uri) { const rel = vscode.workspace.asRelativePath(tab.input.uri, false); editors.push(rel); } } } return editors; } function getDiagnosticsSummary() { const diags = vscode.languages.getDiagnostics(); let errors = 0, warnings = 0; const errorFiles = []; for (const [uri, items] of diags) { for (const d of items) { if (d.severity === vscode.DiagnosticSeverity.Error) { errors++; const rel = vscode.workspace.asRelativePath(uri, false); if (!errorFiles.includes(rel)) errorFiles.push(rel); } else if (d.severity === vscode.DiagnosticSeverity.Warning) { warnings++; } } } return { errors, warnings, errorFiles: errorFiles.slice(0, 10) }; } function getTerminalNames() { return vscode.window.terminals.map(t => t.name); } function getActiveFileDetails() { const editor = vscode.window.activeTextEditor; if (!editor) return null; const doc = editor.document; const sel = editor.selection; const result = { file: vscode.workspace.asRelativePath(doc.uri, false), fullPath: doc.fileName, language: doc.languageId, lineCount: doc.lineCount, isDirty: doc.isDirty, cursorLine: sel.active.line + 1, cursorCol: sel.active.character + 1, }; if (!sel.isEmpty) { result.selectedText = doc.getText(sel).substring(0, 3000); result.selectionRange = `L${sel.start.line + 1}-L${sel.end.line + 1}`; } else { // Include surrounding context (20 lines around cursor) const startLine = Math.max(0, sel.active.line - 10); const endLine = Math.min(doc.lineCount - 1, sel.active.line + 10); const range = new vscode.Range(startLine, 0, endLine, doc.lineAt(endLine).text.length); result.surroundingCode = doc.getText(range).substring(0, 2000); result.contextRange = `L${startLine + 1}-L${endLine + 1}`; } return result; } function readFileContent(filePath, maxChars) { try { const root = getWorkspaceRoot(); const fullPath = path.isAbsolute(filePath) ? filePath : path.join(root, filePath); // Security: don't read outside workspace if (!fullPath.startsWith(root) && !fullPath.startsWith(os.homedir())) return null; const stat = fs.statSync(fullPath); if (stat.size > 500000) return `[File too large: ${(stat.size / 1024).toFixed(0)} KB]`; return fs.readFileSync(fullPath, 'utf8').substring(0, maxChars || 50000); } catch (e) { return null; } } function searchFilesInWorkspace(pattern) { const root = getWorkspaceRoot(); const results = safeExec(`find . -maxdepth 6 -type f -not -path "./.git/*" -not -path "./node_modules/*" -not -path "./.venv/*" -iname "*${pattern.replace(/[^a-zA-Z0-9._-]/g, '')}*" | head -30`, root); return results ? results.split('\n').filter(Boolean) : []; } function grepInWorkspace(text, filePattern) { const root = getWorkspaceRoot(); const safeText = text.replace(/['"\\$`]/g, ''); const fileArg = filePattern ? ` --include="${filePattern.replace(/[^a-zA-Z0-9.*_-]/g, '')}"` : ''; const results = safeExec(`grep -rn --color=never${fileArg} -m 50 "${safeText}" . --exclude-dir=.git --exclude-dir=node_modules --exclude-dir=.venv | head -50`, root, 8000); return results || ''; } // ═══════════════════════════════════════════════════════════════════════════ // GIT OPERATIONS TOOLKIT — Full git power from chat // ═══════════════════════════════════════════════════════════════════════════ function gitCommit(message) { const root = getWorkspaceRoot(); const safeMsg = message.replace(/"/g, '\\"').replace(/\$/g, '\\$').substring(0, 500); const addResult = safeExec('git add -A', root); const commitResult = safeExec(`git commit -m "${safeMsg}" 2>&1`, root, 15000); return commitResult || 'Nothing to commit'; } function gitDiff(filePath, staged) { const root = getWorkspaceRoot(); const stageFlag = staged ? '--staged ' : ''; const fileArg = filePath ? ` -- "${filePath.replace(/"/g, '')}"` : ''; return safeExec(`git diff ${stageFlag}--stat${fileArg}`, root, 10000) + '\n' + safeExec(`git diff ${stageFlag}${fileArg}`, root, 10000).substring(0, 30000); } function gitLog(count, filePath) { const root = getWorkspaceRoot(); const n = Math.min(Math.max(parseInt(count) || 10, 1), 100); const fileArg = filePath ? ` -- "${filePath.replace(/"/g, '')}"` : ''; return safeExec(`git log --oneline --decorate -n ${n}${fileArg}`, root, 10000); } function gitBlame(filePath, startLine, endLine) { const root = getWorkspaceRoot(); const safePath = filePath.replace(/"/g, ''); const lineRange = (startLine && endLine) ? `-L ${parseInt(startLine)},${parseInt(endLine)} ` : ''; return safeExec(`git blame ${lineRange}"${safePath}" 2>&1`, root, 10000).substring(0, 20000); } function gitStash(action, message) { const root = getWorkspaceRoot(); if (action === 'list') return safeExec('git stash list', root); if (action === 'pop') return safeExec('git stash pop 2>&1', root, 10000); if (action === 'drop') return safeExec('git stash drop 2>&1', root); const safeMsg = message ? ` -m "${message.replace(/"/g, '\\"').substring(0, 200)}"` : ''; return safeExec(`git stash push${safeMsg} 2>&1`, root, 10000); } function gitBranch(action, branchName) { const root = getWorkspaceRoot(); const safeName = (branchName || '').replace(/[^a-zA-Z0-9/_.\-]/g, '').substring(0, 100); if (action === 'list') return safeExec('git branch -a', root); if (action === 'create' && safeName) return safeExec(`git checkout -b "${safeName}" 2>&1`, root); if (action === 'switch' && safeName) return safeExec(`git checkout "${safeName}" 2>&1`, root); if (action === 'delete' && safeName) return safeExec(`git branch -d "${safeName}" 2>&1`, root); return 'Invalid branch operation'; } // ═══════════════════════════════════════════════════════════════════════════ // SYSTEM & PROCESS TOOLS — Server awareness, ports, processes, env // ═══════════════════════════════════════════════════════════════════════════ function getSystemInfo() { return { hostname: os.hostname(), platform: os.platform(), arch: os.arch(), cpus: os.cpus().length, totalMem: (os.totalmem() / 1073741824).toFixed(1) + ' GB', freeMem: (os.freemem() / 1073741824).toFixed(1) + ' GB', uptime: (os.uptime() / 3600).toFixed(1) + ' hours', nodeVersion: process.version, user: os.userInfo().username, homeDir: os.homedir(), loadAvg: os.loadavg().map(l => l.toFixed(2)).join(', '), }; } function getRunningPorts() { return safeExec("ss -tlnp 2>/dev/null | grep LISTEN | awk '{print $4, $6}' | head -40", os.homedir(), 8000); } function getPm2Services() { return safeExec('pm2 jlist 2>/dev/null', os.homedir(), 10000); } function getDiskUsage() { return safeExec("df -h / /home 2>/dev/null | tail -n +2", os.homedir()); } function getEnvironmentVars(filter) { const safeFilter = (filter || '').replace(/[^a-zA-Z0-9_*]/g, ''); if (safeFilter) { return safeExec(`env | grep -i "${safeFilter}" | sort | head -50`, os.homedir()); } return safeExec('env | grep -v "^LS_COLORS\\|^SSH_\\|^LESSOPEN\\|^XDG_" | sort | head -80', os.homedir()); } // ═══════════════════════════════════════════════════════════════════════════ // DATA FORMAT UTILITIES — JSON, base64, hashing, encoding // ═══════════════════════════════════════════════════════════════════════════ function formatJson(text) { try { return JSON.stringify(JSON.parse(text), null, 2); } catch (e) { return 'Invalid JSON: ' + e.message; } } function computeHash(text, algorithm) { const algo = ['sha256', 'sha512', 'md5', 'sha1'].includes(algorithm) ? algorithm : 'sha256'; return crypto.createHash(algo).update(text).digest('hex'); } function base64Encode(text) { return Buffer.from(text).toString('base64'); } function base64Decode(text) { try { return Buffer.from(text, 'base64').toString('utf8'); } catch (e) { return 'Invalid base64: ' + e.message; } } function urlEncode(text) { return encodeURIComponent(text); } function urlDecode(text) { try { return decodeURIComponent(text); } catch (e) { return 'Invalid URL encoding: ' + e.message; } } function generateUuid() { return crypto.randomUUID(); } function countLines(filePath) { try { const root = getWorkspaceRoot(); const fullPath = path.isAbsolute(filePath) ? filePath : path.join(root, filePath); const content = fs.readFileSync(fullPath, 'utf8'); const lines = content.split('\n').length; const chars = content.length; const words = content.split(/\s+/).filter(Boolean).length; const blanks = content.split('\n').filter(l => !l.trim()).length; return { lines, chars, words, blanks, codeLines: lines - blanks }; } catch (e) { return { error: e.message }; } } // ═══════════════════════════════════════════════════════════════════════════ // ADVANCED FILE OPERATIONS — Diff, multi-edit, bulk search-replace // ═══════════════════════════════════════════════════════════════════════════ function diffFiles(fileA, fileB) { const root = getWorkspaceRoot(); const pathA = path.isAbsolute(fileA) ? fileA : path.join(root, fileA); const pathB = path.isAbsolute(fileB) ? fileB : path.join(root, fileB); return safeExec(`diff -u "${pathA}" "${pathB}" 2>&1`, root, 10000).substring(0, 30000); } function findReplace(filePath, search, replace, isRegex) { try { const root = getWorkspaceRoot(); const fullPath = path.isAbsolute(filePath) ? filePath : path.join(root, filePath); let content = fs.readFileSync(fullPath, 'utf8'); let count = 0; if (isRegex) { const re = new RegExp(search, 'g'); content = content.replace(re, (...args) => { count++; return replace; }); } else { while (content.includes(search)) { content = content.replace(search, replace); count++; if (count > 10000) break; } } if (count > 0) fs.writeFileSync(fullPath, content, 'utf8'); return { count, filePath }; } catch (e) { return { error: e.message }; } } function getRecentFiles(count) { const root = getWorkspaceRoot(); const n = Math.min(parseInt(count) || 20, 50); return safeExec(`find . -maxdepth 4 -type f -not -path "./.git/*" -not -path "./node_modules/*" -printf "%T@ %p\\n" 2>/dev/null | sort -rn | head -${n} | awk '{print $2}'`, root, 8000); } function getFileSizes(pattern) { const root = getWorkspaceRoot(); const safePattern = (pattern || '*').replace(/[^a-zA-Z0-9.*_\-/]/g, ''); return safeExec(`find . -maxdepth 4 -type f -name "${safePattern}" -not -path "./.git/*" -not -path "./node_modules/*" -exec ls -lhS {} + 2>/dev/null | head -30`, root, 8000); } // ═══════════════════════════════════════════════════════════════════════════ // TEST RUNNER — Detect and run project tests // ═══════════════════════════════════════════════════════════════════════════ function detectTestFramework() { const root = getWorkspaceRoot(); const frameworks = []; try { const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8')); const deps = { ...(pkg.devDependencies || {}), ...(pkg.dependencies || {}) }; if (deps.jest || deps['@jest/core']) frameworks.push({ name: 'jest', cmd: 'npx jest --verbose' }); if (deps.mocha) frameworks.push({ name: 'mocha', cmd: 'npx mocha' }); if (deps.vitest) frameworks.push({ name: 'vitest', cmd: 'npx vitest run' }); if (deps.ava) frameworks.push({ name: 'ava', cmd: 'npx ava' }); if (pkg.scripts && pkg.scripts.test && pkg.scripts.test !== 'echo "Error: no test specified" && exit 1') { frameworks.push({ name: 'npm-test', cmd: 'npm test' }); } } catch (_) {} if (fs.existsSync(path.join(root, 'pytest.ini')) || fs.existsSync(path.join(root, 'pyproject.toml'))) { frameworks.push({ name: 'pytest', cmd: 'python -m pytest -v' }); } if (fs.existsSync(path.join(root, 'phpunit.xml')) || fs.existsSync(path.join(root, 'phpunit.xml.dist'))) { frameworks.push({ name: 'phpunit', cmd: 'vendor/bin/phpunit' }); } if (fs.existsSync(path.join(root, 'Cargo.toml'))) { frameworks.push({ name: 'cargo-test', cmd: 'cargo test' }); } if (fs.existsSync(path.join(root, 'go.mod'))) { frameworks.push({ name: 'go-test', cmd: 'go test ./...' }); } return frameworks; } function runTests(framework, testFile) { const root = getWorkspaceRoot(); const fw = detectTestFramework().find(f => !framework || f.name === framework) || detectTestFramework()[0]; if (!fw) return 'No test framework detected'; const fileArg = testFile ? ` "${testFile.replace(/"/g, '')}"` : ''; return safeExec(`${fw.cmd}${fileArg} 2>&1`, root, 60000).substring(0, 30000); } // ═══════════════════════════════════════════════════════════════════════════ // ENHANCED CONTEXT ENGINE — Import graph, complexity, dependency audit // ═══════════════════════════════════════════════════════════════════════════ function getImportGraph(filePath) { try { const root = getWorkspaceRoot(); const fullPath = path.isAbsolute(filePath) ? filePath : path.join(root, filePath); const content = fs.readFileSync(fullPath, 'utf8'); const imports = []; // JS/TS imports const jsImports = content.matchAll(/(?:import\s+.*?from\s+['"](.+?)['"]|require\s*\(\s*['"](.+?)['"]\s*\))/g); for (const m of jsImports) imports.push(m[1] || m[2]); // Python imports const pyImports = content.matchAll(/(?:from\s+(\S+)\s+import|import\s+(\S+))/g); for (const m of pyImports) imports.push(m[1] || m[2]); // PHP includes const phpIncludes = content.matchAll(/(?:require|include)(?:_once)?\s*[\(]?\s*['"](.+?)['"]/g); for (const m of phpIncludes) imports.push(m[1]); // Go imports const goImports = content.matchAll(/import\s+(?:\(\s*([\s\S]*?)\)|"(.+?)")/g); for (const m of goImports) { if (m[1]) { for (const line of m[1].split('\n')) { const gm = line.match(/["'](.+?)["']/); if (gm) imports.push(gm[1]); } } else if (m[2]) imports.push(m[2]); } // Rust use const rustUse = content.matchAll(/use\s+(\S+)/g); for (const m of rustUse) imports.push(m[1].replace(/;$/, '')); return { file: filePath, imports: [...new Set(imports)] }; } catch (e) { return { file: filePath, imports: [], error: e.message }; } } function analyzeComplexity(filePath) { try { const root = getWorkspaceRoot(); const fullPath = path.isAbsolute(filePath) ? filePath : path.join(root, filePath); const content = fs.readFileSync(fullPath, 'utf8'); const lines = content.split('\n'); const totalLines = lines.length; const blankLines = lines.filter(l => !l.trim()).length; const commentLines = lines.filter(l => { const t = l.trim(); return t.startsWith('//') || t.startsWith('#') || t.startsWith('*') || t.startsWith('/*') || t.startsWith('