Files
Profa 2253d05618 feat: flatten project structure — archive v2, promote v3 to root
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>
2026-03-01 11:35:41 +00:00

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}`);
}
}