pilot-agent-cli
Version:
GitHub Copilot automation tool with configuration-driven file management
132 lines (116 loc) • 5.12 kB
JavaScript
/**
* Standalone Copilot Server Detector for global installation
* Self-contained version that doesn't depend on src/ directory
*/
const { promisify } = require('util');
const exec = promisify(require('child_process').exec);
const fs = require('fs');
const path = require('path');
class StandaloneCopilotServerDetector {
/**
* Detect copilot-language-server using multiple methods
* @returns {Promise<{found: boolean, method: string, path?: string}>}
*/
async detect() {
console.log('🔧 Searching for copilot-language-server...');
const detectionMethods = [
// Method 1: Try npx which works on all platforms
async () => {
try {
await exec('npx copilot-language-server --version', { timeout: 5000 });
return { found: true, method: 'npx' };
} catch (error) {
return { found: false };
}
},
// Method 2: Try direct command (works if in PATH)
async () => {
try {
await exec('copilot-language-server --version', { timeout: 5000 });
return { found: true, method: 'PATH' };
} catch (error) {
return { found: false };
}
},
// Method 3: Try where command on Windows / which on Unix
async () => {
try {
const command = process.platform === 'win32' ? 'where copilot-language-server' : 'which copilot-language-server';
const { stdout } = await exec(command, { timeout: 5000 });
const serverPath = stdout.trim();
return { found: true, method: 'system-command', path: serverPath };
} catch (error) {
return { found: false };
}
},
// Method 4: Check npm global directory
async () => {
try {
const { stdout } = await exec('npm root -g', { timeout: 5000 });
const globalNodeModules = stdout.trim();
const expectedPath = path.join(globalNodeModules, '@github', 'copilot-language-server');
if (fs.existsSync(expectedPath)) {
const binPath = path.join(expectedPath, 'bin', 'copilot-language-server');
if (fs.existsSync(binPath)) {
return { found: true, method: 'npm-global', path: binPath };
}
}
return { found: false };
} catch (error) {
return { found: false };
}
}
];
for (const method of detectionMethods) {
const result = await method();
if (result.found) {
console.log(`✅ copilot-language-server found via ${result.method}`);
return result;
}
}
console.error('❌ copilot-language-server not found');
console.log('📦 Installation required:');
console.log(' npm install -g @github/copilot-language-server');
console.log('');
console.log('🔍 Troubleshooting:');
console.log(' 1. Verify installation: npx copilot-language-server --version');
console.log(' 2. Check npm global path: npm root -g');
console.log(' 3. Restart terminal after installation');
return { found: false };
}
/**
* Get spawn command and args based on detection method
*/
getSpawnCommand(method, path = null) {
switch (method) {
case 'npx':
return { command: 'npx', args: ['copilot-language-server', '--stdio'] };
case 'PATH':
return { command: 'copilot-language-server', args: ['--stdio'] };
case 'system-command':
return path ?
{ command: path, args: ['--stdio'] } :
{ command: 'copilot-language-server', args: ['--stdio'] };
case 'npm-global':
return path ?
{ command: 'node', args: [path, '--stdio'] } :
{ command: 'copilot-language-server', args: ['--stdio'] };
default:
return { command: 'npx', args: ['copilot-language-server', '--stdio'] };
}
}
/**
* Get recommended spawn options for the detected server
*/
getSpawnOptions(method) {
const baseOptions = {
stdio: ['pipe', 'pipe', 'pipe']
};
// Use shell on Windows for npm-based commands
if (process.platform === 'win32' && (method === 'npx' || method === 'system-command')) {
return { ...baseOptions, shell: true };
}
return baseOptions;
}
}
module.exports = StandaloneCopilotServerDetector;