UNPKG

aiwg

Version:

Cognitive architecture for AI-augmented software development with structured memory, ensemble validation, and closed-loop correction. FAIR-aligned artifacts, 84% cost reduction via human-in-the-loop, standards adopted by 100+ organizations.

240 lines (209 loc) 6.88 kB
/** * Channel Manager * * Manages the distribution channel (stable vs edge) for AIWG. * - Stable: Uses the npm-installed package * - Edge: Uses a git clone of the main branch for bleeding-edge updates * * @module src/channel/manager * @version 2024.12.0 */ import fs from 'fs/promises'; import path from 'path'; import { fileURLToPath } from 'url'; import { execSync, spawn } from 'child_process'; import os from 'os'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Configuration paths const CONFIG_DIR = path.join(os.homedir(), '.aiwg'); const CONFIG_FILE = path.join(CONFIG_DIR, 'channel.json'); const EDGE_INSTALL_PATH = path.join(os.homedir(), '.local', 'share', 'ai-writing-guide'); const REPO_URL = 'https://github.com/jmagly/aiwg.git'; /** * Default channel configuration */ const DEFAULT_CONFIG = { channel: 'stable', edgePath: EDGE_INSTALL_PATH, lastUpdateCheck: null, updateCheckInterval: 86400000, // 24 hours in ms }; /** * Get the package root directory * @returns {string} Path to package root */ export function getPackageRoot() { // Go up from src/channel to package root return path.resolve(__dirname, '..', '..'); } /** * Load channel configuration * @returns {Promise<object>} Channel configuration */ export async function loadConfig() { try { const data = await fs.readFile(CONFIG_FILE, 'utf8'); return { ...DEFAULT_CONFIG, ...JSON.parse(data) }; } catch { return { ...DEFAULT_CONFIG }; } } /** * Save channel configuration * @param {object} config - Configuration to save */ export async function saveConfig(config) { await fs.mkdir(CONFIG_DIR, { recursive: true }); await fs.writeFile(CONFIG_FILE, JSON.stringify(config, null, 2)); } /** * Get the current channel * @returns {Promise<string>} 'stable' or 'edge' */ export async function getChannel() { const config = await loadConfig(); return config.channel; } /** * Get the framework root path based on current channel * @returns {Promise<string>} Path to framework root */ export async function getFrameworkRoot() { const config = await loadConfig(); if (config.channel === 'edge') { // Check if edge installation exists try { await fs.access(config.edgePath); return config.edgePath; } catch { // Edge path doesn't exist, fall back to stable console.warn('Edge installation not found, using stable channel'); return getPackageRoot(); } } return getPackageRoot(); } /** * Switch to edge (bleeding edge) channel * Clones or updates the git repository for latest main branch */ export async function switchToEdge() { const config = await loadConfig(); console.log('Switching to edge channel (bleeding edge from main branch)...'); console.log(''); // Check if edge installation exists const edgeExists = await fs.access(config.edgePath).then(() => true).catch(() => false); if (edgeExists) { // Update existing installation console.log(`Updating edge installation at ${config.edgePath}...`); try { execSync('git fetch --all', { cwd: config.edgePath, stdio: 'inherit' }); execSync('git checkout main', { cwd: config.edgePath, stdio: 'inherit' }); execSync('git pull --ff-only', { cwd: config.edgePath, stdio: 'inherit' }); console.log('Edge installation updated successfully.'); } catch (error) { console.error('Failed to update edge installation:', error.message); console.log('Try removing the directory and running again:'); console.log(` rm -rf ${config.edgePath}`); console.log(' aiwg --use-main'); process.exit(1); } } else { // Clone fresh console.log(`Cloning repository to ${config.edgePath}...`); await fs.mkdir(path.dirname(config.edgePath), { recursive: true }); try { execSync(`git clone --branch main ${REPO_URL} "${config.edgePath}"`, { stdio: 'inherit' }); console.log('Edge installation created successfully.'); } catch (error) { console.error('Failed to clone repository:', error.message); process.exit(1); } } // Update config config.channel = 'edge'; await saveConfig(config); console.log(''); console.log('Switched to edge channel.'); console.log('You are now using the latest code from the main branch.'); console.log(''); console.log('To update edge installation: aiwg -update'); console.log('To switch back to stable: aiwg --use-stable'); } /** * Switch to stable (npm) channel */ export async function switchToStable() { const config = await loadConfig(); console.log('Switching to stable channel (npm package)...'); console.log(''); config.channel = 'stable'; await saveConfig(config); console.log('Switched to stable channel.'); console.log('You are now using the npm-installed package.'); console.log(''); console.log('To update: npm update -g aiwg'); console.log('To switch to edge: aiwg --use-main'); } /** * Get version information based on current channel * @returns {Promise<object>} Version info */ export async function getVersionInfo() { const config = await loadConfig(); const packageRoot = getPackageRoot(); // Read package.json version const packageJsonPath = path.join(packageRoot, 'package.json'); const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8')); const info = { version: packageJson.version, channel: config.channel, packageRoot, }; if (config.channel === 'edge') { // Get git info for edge channel try { const gitHash = execSync('git rev-parse --short HEAD', { cwd: config.edgePath, encoding: 'utf8', }).trim(); const gitBranch = execSync('git branch --show-current', { cwd: config.edgePath, encoding: 'utf8', }).trim(); info.edgePath = config.edgePath; info.gitHash = gitHash; info.gitBranch = gitBranch; } catch { // Git info not available } } return info; } /** * Update the edge installation from git */ export async function updateEdge() { const config = await loadConfig(); if (config.channel !== 'edge') { console.log('Not in edge channel. Use npm update -g aiwg for stable channel.'); return; } console.log('Updating edge installation...'); try { execSync('git fetch --all', { cwd: config.edgePath, stdio: 'inherit' }); execSync('git pull --ff-only', { cwd: config.edgePath, stdio: 'inherit' }); console.log(''); console.log('Edge installation updated successfully.'); } catch (error) { console.error('Update failed:', error.message); console.log(''); console.log('If you have local changes, try:'); console.log(` cd ${config.edgePath}`); console.log(' git stash'); console.log(' git pull'); console.log(' git stash pop'); process.exit(1); } }