mirror of
https://github.com/proffesor-for-testing/agentic-qe.git
synced 2026-09-19 08:45:47 +08:00
2253d05618
Remove the nested v3/ subdirectory by moving all active source code, tests, configs, and assets directly to the project root. Archive v2/ (dead code, 847MB) to v2-archive.tar.gz. Key changes: - Move v3/src/ → src/, v3/tests/ → tests/, v3/packages/ → packages/ - Move v3/tsconfig.json, v3/vitest.config.ts to root - Merge v3/package.json into root package.json (ESM, scripts, deps, exports) - Merge v3/scripts/ into scripts/, v3/implementation/ into docs/implementation/ - Update all CI workflows to remove "cd v3 &&" and v3/ path prefixes - Fix all init installer path resolution (3-level-up → 2-level-up) - Fix hooks to use "node ./dist/cli/bundle.js" instead of bare "aqe" - Update settings.json ADR/DDD directories to docs/implementation/ - Fix helper scripts (statusline, adr-compliance, ddd-tracker, guidance-hooks) - Update 58 agent definitions: aqe/v3/ → aqe/ memory namespaces - Update 15 guidance shards: v3/src/ → src/ path references - Fix sync interfaces: remove v3/ and v2/ path references - Fix test path calculations (process.cwd() + '..' no longer needed) - Fix flaky perf test threshold (500ms → 1000ms for CI environments) - Fix complexity-analyzer test to match ADR-051 keyword-based eligibility Build passes, 17,901 tests pass, CLI and MCP bundles verified. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
261 lines
8.1 KiB
JavaScript
261 lines
8.1 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Preinstall script for agentic-qe
|
|
* Detects and handles conflicts from:
|
|
* - agentic-qe v2 (old package)
|
|
* - @agentic-qe/v3 (alpha package)
|
|
*
|
|
* Uses CommonJS for maximum Node.js compatibility
|
|
*/
|
|
|
|
const { execSync, spawnSync } = require('child_process');
|
|
const { existsSync, unlinkSync, lstatSync } = require('fs');
|
|
const { join } = require('path');
|
|
|
|
const RESET = '\x1b[0m';
|
|
const BOLD = '\x1b[1m';
|
|
const YELLOW = '\x1b[33m';
|
|
const GREEN = '\x1b[32m';
|
|
const CYAN = '\x1b[36m';
|
|
const RED = '\x1b[31m';
|
|
|
|
function log(msg) {
|
|
console.log(`${CYAN}[agentic-qe]${RESET} ${msg}`);
|
|
}
|
|
|
|
function warn(msg) {
|
|
console.log(`${YELLOW}[agentic-qe]${RESET} ${msg}`);
|
|
}
|
|
|
|
function error(msg) {
|
|
console.log(`${RED}[agentic-qe]${RESET} ${msg}`);
|
|
}
|
|
|
|
function success(msg) {
|
|
console.log(`${GREEN}[agentic-qe]${RESET} ${msg}`);
|
|
}
|
|
|
|
function findExistingAqeBinary() {
|
|
// Try 'which' command first
|
|
try {
|
|
const result = spawnSync('which', ['aqe'], { encoding: 'utf-8' });
|
|
if (result.status === 0 && result.stdout.trim()) {
|
|
return result.stdout.trim();
|
|
}
|
|
} catch {
|
|
// which command failed
|
|
}
|
|
|
|
// Try to find via npm prefix
|
|
try {
|
|
const prefix = execSync('npm config get prefix', { encoding: 'utf-8' }).trim();
|
|
const binPath = join(prefix, 'bin', 'aqe');
|
|
if (existsSync(binPath)) {
|
|
return binPath;
|
|
}
|
|
} catch {
|
|
// Ignore
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function checkPackageInstalled(packageName) {
|
|
try {
|
|
const result = execSync(`npm list -g ${packageName} --depth=0 2>/dev/null`, {
|
|
encoding: 'utf-8',
|
|
stdio: ['pipe', 'pipe', 'pipe']
|
|
});
|
|
return result.includes(`${packageName}@`);
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function getPackageVersion(packageName) {
|
|
try {
|
|
const result = execSync(`npm list -g ${packageName} --depth=0 2>/dev/null`, {
|
|
encoding: 'utf-8',
|
|
stdio: ['pipe', 'pipe', 'pipe']
|
|
});
|
|
const regex = new RegExp(`${packageName.replace('/', '\\/')}@([\\d\\.\\-a-z]+)`);
|
|
const match = result.match(regex);
|
|
return match ? match[1] : null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function uninstallPackage(packageName) {
|
|
try {
|
|
log(`Uninstalling ${packageName}...`);
|
|
execSync(`npm uninstall -g ${packageName}`, {
|
|
encoding: 'utf-8',
|
|
stdio: 'inherit'
|
|
});
|
|
success(`Successfully uninstalled ${packageName}`);
|
|
return true;
|
|
} catch (err) {
|
|
error(`Failed to uninstall ${packageName}: ${err.message}`);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function removeStaleSymlink(binaryPath) {
|
|
try {
|
|
const stats = lstatSync(binaryPath);
|
|
if (stats.isSymbolicLink()) {
|
|
unlinkSync(binaryPath);
|
|
success(`Removed stale symlink: ${binaryPath}`);
|
|
return true;
|
|
}
|
|
} catch {
|
|
// Not a symlink or can't remove
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function main() {
|
|
// Skip in CI environments unless explicitly requested
|
|
if (process.env.CI && !process.env.AQE_PREINSTALL_CHECK) {
|
|
return;
|
|
}
|
|
|
|
const aqeBinary = findExistingAqeBinary();
|
|
|
|
// Check for both old package names
|
|
const v2Installed = checkPackageInstalled('agentic-qe');
|
|
const alphaInstalled = checkPackageInstalled('@agentic-qe/v3');
|
|
|
|
const v2Version = v2Installed ? getPackageVersion('agentic-qe') : null;
|
|
const alphaVersion = alphaInstalled ? getPackageVersion('@agentic-qe/v3') : null;
|
|
|
|
// If the currently installed agentic-qe is version 3.x, we're good (user is upgrading within v3)
|
|
if (v2Version && v2Version.startsWith('3.')) {
|
|
// User is upgrading from 3.x to newer 3.x - this should work normally
|
|
return;
|
|
}
|
|
|
|
if (!aqeBinary && !v2Installed && !alphaInstalled) {
|
|
// Clean install, nothing to do
|
|
return;
|
|
}
|
|
|
|
console.log('');
|
|
log(`${BOLD}Checking for existing agentic-qe installation...${RESET}`);
|
|
|
|
// Handle alpha package conflict
|
|
if (alphaInstalled) {
|
|
warn(`Found @agentic-qe/v3@${alphaVersion || 'alpha'} installed globally`);
|
|
warn('The alpha package uses the same "aqe" binary name as the released version');
|
|
console.log('');
|
|
|
|
// Check if we can auto-migrate
|
|
const autoMigrate = process.env.AQE_AUTO_MIGRATE === 'true' ||
|
|
process.env.npm_config_yes === 'true';
|
|
|
|
if (autoMigrate) {
|
|
log('Auto-migrating from alpha to release...');
|
|
if (uninstallPackage('@agentic-qe/v3')) {
|
|
success('Migration complete. Continuing with install...');
|
|
return;
|
|
} else {
|
|
error('Auto-migration failed. Please run manually:');
|
|
console.log(` ${CYAN}npm uninstall -g @agentic-qe/v3 && npm install -g agentic-qe@latest${RESET}`);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Interactive mode
|
|
console.log(`${YELLOW}To upgrade from alpha to release:${RESET}`);
|
|
console.log('');
|
|
console.log(` ${BOLD}Option 1: Auto-migrate (recommended)${RESET}`);
|
|
console.log(` ${CYAN}AQE_AUTO_MIGRATE=true npm install -g agentic-qe@latest${RESET}`);
|
|
console.log('');
|
|
console.log(` ${BOLD}Option 2: Manual uninstall first${RESET}`);
|
|
console.log(` ${CYAN}npm uninstall -g @agentic-qe/v3${RESET}`);
|
|
console.log(` ${CYAN}npm install -g agentic-qe@latest${RESET}`);
|
|
console.log('');
|
|
console.log(` ${BOLD}Option 3: Force overwrite${RESET}`);
|
|
console.log(` ${CYAN}npm install -g agentic-qe@latest --force${RESET}`);
|
|
console.log('');
|
|
|
|
process.exit(1);
|
|
}
|
|
|
|
// Handle v2 package conflict
|
|
if (v2Installed && !v2Version?.startsWith('3.')) {
|
|
warn(`Found agentic-qe v${v2Version || '2.x'} installed globally`);
|
|
warn('The v2 package uses the same "aqe" binary name as v3');
|
|
console.log('');
|
|
|
|
const autoMigrate = process.env.AQE_AUTO_MIGRATE === 'true' ||
|
|
process.env.npm_config_yes === 'true';
|
|
|
|
if (autoMigrate) {
|
|
log('Auto-migrating from v2 to v3...');
|
|
if (uninstallPackage('agentic-qe')) {
|
|
success('Migration complete. Continuing with v3 install...');
|
|
return;
|
|
} else {
|
|
error('Auto-migration failed. Please run manually:');
|
|
console.log(` ${CYAN}npm uninstall -g agentic-qe && npm install -g agentic-qe@latest${RESET}`);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
console.log(`${YELLOW}To upgrade from v2 to v3:${RESET}`);
|
|
console.log('');
|
|
console.log(` ${BOLD}Option 1: Auto-migrate (recommended)${RESET}`);
|
|
console.log(` ${CYAN}AQE_AUTO_MIGRATE=true npm install -g agentic-qe@latest${RESET}`);
|
|
console.log('');
|
|
console.log(` ${BOLD}Option 2: Manual uninstall first${RESET}`);
|
|
console.log(` ${CYAN}npm uninstall -g agentic-qe${RESET}`);
|
|
console.log(` ${CYAN}npm install -g agentic-qe@latest${RESET}`);
|
|
console.log('');
|
|
console.log(` ${BOLD}Option 3: Force overwrite${RESET}`);
|
|
console.log(` ${CYAN}npm install -g agentic-qe@latest --force${RESET}`);
|
|
console.log('');
|
|
|
|
process.exit(1);
|
|
|
|
} else if (aqeBinary && !v2Installed && !alphaInstalled) {
|
|
// Binary exists but no known package found - stale symlink or different package
|
|
warn(`Found existing 'aqe' binary at: ${aqeBinary}`);
|
|
|
|
// Try to identify what it's from
|
|
try {
|
|
const realpath = require('fs').realpathSync(aqeBinary);
|
|
if (realpath.includes('agentic-qe')) {
|
|
warn('This appears to be from a previous agentic-qe installation.');
|
|
}
|
|
} catch {
|
|
// Can't resolve realpath
|
|
}
|
|
|
|
console.log('');
|
|
console.log(`${YELLOW}To resolve the conflict:${RESET}`);
|
|
console.log('');
|
|
console.log(` ${BOLD}Option 1: Remove existing binary${RESET}`);
|
|
console.log(` ${CYAN}rm ${aqeBinary}${RESET}`);
|
|
console.log(` ${CYAN}npm install -g agentic-qe@latest${RESET}`);
|
|
console.log('');
|
|
console.log(` ${BOLD}Option 2: Force overwrite${RESET}`);
|
|
console.log(` ${CYAN}npm install -g agentic-qe@latest --force${RESET}`);
|
|
console.log('');
|
|
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
try {
|
|
main();
|
|
} catch (err) {
|
|
// Don't let preinstall failures block installation
|
|
// Just log and continue
|
|
if (process.env.DEBUG) {
|
|
error(`Preinstall check error: ${err.message}`);
|
|
}
|
|
}
|