#!/usr/bin/env node
/**
 * RuFlo V3.5 Statusline Generator
 * Displays real-time V3 implementation progress and system status
 *
 * Usage: node statusline.cjs [options]
 *
 * Options:
 *   (default)   Safe multi-line output with collision zone avoidance
 *   --single    Single-line output (completely avoids collision)
 *   --unsafe    Legacy multi-line without collision avoidance
 *   --legacy    Alias for --unsafe
 *   --json      JSON output with pretty printing
 *   --compact   JSON output without formatting
 *
 * Collision Zone Fix (Issue #985):
 * Claude Code writes its internal status (e.g., "7s • 1p") at absolute
 * terminal coordinates (columns 15-25 on second-to-last line). The safe
 * mode pads the collision line with spaces to push content past column 25.
 *
 * IMPORTANT: This file uses .cjs extension to work in ES module projects.
 * The require() syntax is intentional for CommonJS compatibility.
 */

/* eslint-disable @typescript-eslint/no-var-requires */
const fs = require('fs');
const path = require('path');
const os = require('os');
const { execSync, execFileSync } = require('child_process');

// Read the installed plugin version once at startup. Probe the plugin's own
// install location first (`~/.claude/plugins/marketplaces/ruflo/package.json`),
// then npm-style installs, then the source-checkout location. The previous
// code hardcoded `RuFlo V3.5` in the header — so users on alpha.27+ still
// saw V3.5 in the statusline even though `ruflo doctor` reported the real
// version (#1951).
let RUFLO_VERSION = '3.6';
try {
  const home = os.homedir();
  const cwd = process.cwd();
  const pkgPaths = [
    path.join(home, '.claude', 'plugins', 'marketplaces', 'ruflo', 'package.json'),
    path.join(cwd, 'node_modules', '@claude-flow', 'cli', 'package.json'),
    path.join(cwd, 'node_modules', 'ruflo', 'package.json'),
    path.join(cwd, 'v3', '@claude-flow', 'cli', 'package.json'),
  ];
  for (const p of pkgPaths) {
    if (!fs.existsSync(p)) continue;
    try {
      const pkg = JSON.parse(fs.readFileSync(p, 'utf-8'));
      if (pkg && typeof pkg.version === 'string' && pkg.version.length > 0) {
        RUFLO_VERSION = pkg.version;
        break;
      }
    } catch { /* malformed package.json — try next */ }
  }
} catch { /* fall through to the hardcoded default */ }

// Configuration
const CONFIG = {
  enabled: true,
  showProgress: true,
  showSecurity: true,
  showSwarm: true,
  showHooks: true,
  showPerformance: true,
  refreshInterval: 5000,
  maxAgents: 15,
  topology: 'hierarchical-mesh',
};

// Cross-platform helpers
const isWindows = process.platform === 'win32';
const nullDevice = isWindows ? 'NUL' : '/dev/null';

// ANSI colors
const c = {
  reset: '\x1b[0m',
  bold: '\x1b[1m',
  dim: '\x1b[2m',
  red: '\x1b[0;31m',
  green: '\x1b[0;32m',
  yellow: '\x1b[0;33m',
  blue: '\x1b[0;34m',
  purple: '\x1b[0;35m',
  cyan: '\x1b[0;36m',
  brightRed: '\x1b[1;31m',
  brightGreen: '\x1b[1;32m',
  brightYellow: '\x1b[1;33m',
  brightBlue: '\x1b[1;34m',
  brightPurple: '\x1b[1;35m',
  brightCyan: '\x1b[1;36m',
  brightWhite: '\x1b[1;37m',
};

// Get user info
function getUserInfo() {
  let name = 'user';
  let gitBranch = '';
  let modelName = 'Unknown';

  // audit_1776853149979: previously used execSync with a shell string. Switched
  // to execFileSync('git', argv) on both platforms so there is no shell
  // interpretation. Cross-platform behavior is preserved by relying on git's
  // own exit code instead of `|| echo` fallbacks: missing repo / no user.name
  // throws, caught below, defaults retained.
  try {
    name = execFileSync('git', ['config', 'user.name'], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim() || 'user';
  } catch { /* keep default */ }
  try {
    gitBranch = execFileSync('git', ['branch', '--show-current'], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
  } catch { /* keep empty */ }

  // Auto-detect model from Claude Code's config
  try {
    const homedir = require('os').homedir();
    const claudeConfigPath = path.join(homedir, '.claude.json');
    if (fs.existsSync(claudeConfigPath)) {
      const claudeConfig = JSON.parse(fs.readFileSync(claudeConfigPath, 'utf-8'));
      // Try to find lastModelUsage - check current dir and parent dirs
      let lastModelUsage = null;
      const cwd = process.cwd();
      if (claudeConfig.projects) {
        // Try exact match first, then check if cwd starts with any project path
        for (const [projectPath, projectConfig] of Object.entries(claudeConfig.projects)) {
          if (cwd === projectPath || cwd.startsWith(projectPath + '/')) {
            lastModelUsage = projectConfig.lastModelUsage;
            break;
          }
        }
      }
      if (lastModelUsage) {
        const modelIds = Object.keys(lastModelUsage);
        if (modelIds.length > 0) {
          // Take the last model (most recently added to the object)
          // Or find the one with most tokens (most actively used this session)
          let modelId = modelIds[modelIds.length - 1];
          if (modelIds.length > 1) {
            // If multiple models, pick the one with most total tokens
            let maxTokens = 0;
            for (const id of modelIds) {
              const usage = lastModelUsage[id];
              const total = (usage.inputTokens || 0) + (usage.outputTokens || 0);
              if (total > maxTokens) {
                maxTokens = total;
                modelId = id;
              }
            }
          }
          // Parse model ID to human-readable name
          if (modelId.includes('opus')) modelName = 'Opus 4.6 (1M context)';
          else if (modelId.includes('sonnet')) modelName = 'Sonnet 4.6';
          else if (modelId.includes('haiku')) modelName = 'Haiku 4.5';
          else modelName = modelId.split('-').slice(1, 3).join(' ');
        }
      }
    }
  } catch (e) {
    // Fallback to Unknown if can't read config
  }

  return { name, gitBranch, modelName };
}

// Get learning stats from intelligence loop data (ADR-050)
function getLearningStats() {
  let patterns = 0;
  let sessions = 0;
  let trajectories = 0;
  let edges = 0;
  let confidenceMean = 0;
  let accessedCount = 0;
  let trend = 'STABLE';

  // PRIMARY: Read from intelligence loop data files
  const dataDir = path.join(process.cwd(), '.claude-flow', 'data');

  // 1. graph-state.json — authoritative node/edge counts
  const graphPath = path.join(dataDir, 'graph-state.json');
  if (fs.existsSync(graphPath)) {
    try {
      const graph = JSON.parse(fs.readFileSync(graphPath, 'utf-8'));
      patterns = graph.nodes ? Object.keys(graph.nodes).length : 0;
      edges = Array.isArray(graph.edges) ? graph.edges.length : 0;
    } catch (e) { /* ignore */ }
  }

  // 2. ranked-context.json — confidence and access data
  const rankedPath = path.join(dataDir, 'ranked-context.json');
  if (fs.existsSync(rankedPath)) {
    try {
      const ranked = JSON.parse(fs.readFileSync(rankedPath, 'utf-8'));
      if (ranked.entries && ranked.entries.length > 0) {
        patterns = Math.max(patterns, ranked.entries.length);
        let confSum = 0;
        let accCount = 0;
        for (let i = 0; i < ranked.entries.length; i++) {
          confSum += (ranked.entries[i].confidence || 0);
          if ((ranked.entries[i].accessCount || 0) > 0) accCount++;
        }
        confidenceMean = confSum / ranked.entries.length;
        accessedCount = accCount;
      }
    } catch (e) { /* ignore */ }
  }

  // 3. intelligence-snapshot.json — trend history
  const snapshotPath = path.join(dataDir, 'intelligence-snapshot.json');
  if (fs.existsSync(snapshotPath)) {
    try {
      const snapshot = JSON.parse(fs.readFileSync(snapshotPath, 'utf-8'));
      if (snapshot.history && snapshot.history.length >= 2) {
        const first = snapshot.history[0];
        const last = snapshot.history[snapshot.history.length - 1];
        const confDrift = (last.confidenceMean || 0) - (first.confidenceMean || 0);
        trend = confDrift > 0.01 ? 'IMPROVING' : confDrift < -0.01 ? 'DECLINING' : 'STABLE';
        sessions = Math.max(sessions, snapshot.history.length);
      }
    } catch (e) { /* ignore */ }
  }

  // 4. auto-memory-store.json — fallback entry count
  if (patterns === 0) {
    const autoMemPath = path.join(dataDir, 'auto-memory-store.json');
    if (fs.existsSync(autoMemPath)) {
      try {
        const data = JSON.parse(fs.readFileSync(autoMemPath, 'utf-8'));
        patterns = Array.isArray(data) ? data.length : (data.entries ? data.entries.length : 0);
      } catch (e) { /* ignore */ }
    }
  }

  // FALLBACK: Legacy memory.db file-size estimation
  if (patterns === 0) {
    const memoryPaths = [
      path.join(process.cwd(), '.swarm', 'memory.db'),
      path.join(process.cwd(), '.claude', 'memory.db'),
      path.join(process.cwd(), 'data', 'memory.db'),
    ];
    for (let j = 0; j < memoryPaths.length; j++) {
      if (fs.existsSync(memoryPaths[j])) {
        try {
          const dbStats = fs.statSync(memoryPaths[j]);
          patterns = Math.floor(dbStats.size / 1024 / 2);
          break;
        } catch (e) { /* ignore */ }
      }
    }
  }

  // Session count from session files
  const sessionsPath = path.join(process.cwd(), '.claude', 'sessions');
  if (fs.existsSync(sessionsPath)) {
    try {
      const sessionFiles = fs.readdirSync(sessionsPath).filter(f => f.endsWith('.json'));
      sessions = Math.max(sessions, sessionFiles.length);
    } catch (e) { /* ignore */ }
  }

  trajectories = Math.floor(patterns / 5);

  return { patterns, sessions, trajectories, edges, confidenceMean, accessedCount, trend };
}

// Get V3 progress from learning state (grows as system learns)
function getV3Progress() {
  const learning = getLearningStats();

  // DDD progress based on actual learned patterns
  // New install: 0 patterns = 0/5 domains, 0% DDD
  // As patterns grow: 10+ patterns = 1 domain, 50+ = 2, 100+ = 3, 200+ = 4, 500+ = 5
  let domainsCompleted = 0;
  if (learning.patterns >= 500) domainsCompleted = 5;
  else if (learning.patterns >= 200) domainsCompleted = 4;
  else if (learning.patterns >= 100) domainsCompleted = 3;
  else if (learning.patterns >= 50) domainsCompleted = 2;
  else if (learning.patterns >= 10) domainsCompleted = 1;

  const totalDomains = 5;
  const dddProgress = Math.min(100, Math.floor((domainsCompleted / totalDomains) * 100));

  return {
    domainsCompleted,
    totalDomains,
    dddProgress,
    patternsLearned: learning.patterns,
    sessionsCompleted: learning.sessions
  };
}

// Get security status based on actual scans
function getSecurityStatus() {
  // Check for security scan results in memory
  const scanResultsPath = path.join(process.cwd(), '.claude', 'security-scans');
  let cvesFixed = 0;
  const totalCves = 3;

  if (fs.existsSync(scanResultsPath)) {
    try {
      const scans = fs.readdirSync(scanResultsPath).filter(f => f.endsWith('.json'));
      // Each successful scan file = 1 CVE addressed
      cvesFixed = Math.min(totalCves, scans.length);
    } catch (e) {
      // Ignore
    }
  }

  // Also check .swarm/security for audit results
  const auditPath = path.join(process.cwd(), '.swarm', 'security');
  if (fs.existsSync(auditPath)) {
    try {
      const audits = fs.readdirSync(auditPath).filter(f => f.includes('audit'));
      cvesFixed = Math.min(totalCves, Math.max(cvesFixed, audits.length));
    } catch (e) {
      // Ignore
    }
  }

  const status = cvesFixed >= totalCves ? 'CLEAN' : cvesFixed > 0 ? 'IN_PROGRESS' : 'PENDING';

  return {
    status,
    cvesFixed,
    totalCves,
  };
}

// Get swarm status
function getSwarmStatus() {
  let activeAgents = 0;
  let coordinationActive = false;

  try {
    if (isWindows) {
      // Windows: use tasklist and findstr
      const ps = execSync('tasklist 2>NUL | findstr /I "agentic-flow" 2>NUL | find /C /V "" 2>NUL || echo 0', { encoding: 'utf-8' });
      activeAgents = Math.max(0, parseInt(ps.trim()) || 0);
    } else {
      const ps = execSync('ps aux 2>/dev/null | grep -c agentic-flow || echo "0"', { encoding: 'utf-8' });
      activeAgents = Math.max(0, parseInt(ps.trim()) - 1);
    }
    coordinationActive = activeAgents > 0;
  } catch (e) {
    // Ignore errors - default to 0 agents
  }

  return {
    activeAgents,
    maxAgents: CONFIG.maxAgents,
    coordinationActive,
  };
}

// Get system metrics (dynamic based on actual state)
function getSystemMetrics() {
  let memoryMB = 0;
  let subAgents = 0;

  try {
    if (isWindows) {
      // Windows: use tasklist for memory info, fallback to process.memoryUsage
      // tasklist memory column is complex to parse, use Node.js API instead
      memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
    } else {
      const mem = execSync('ps aux | grep -E "(node|agentic|claude)" | grep -v grep | awk \'{sum += $6} END {print int(sum/1024)}\'', { encoding: 'utf-8' });
      memoryMB = parseInt(mem.trim()) || 0;
    }
  } catch (e) {
    // Fallback
    memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
  }

  // Get learning stats for intelligence %
  const learning = getLearningStats();

  // Intelligence % from REAL intelligence loop data (ADR-050)
  // Composite: 40% confidence mean + 30% access ratio + 30% pattern density
  let intelligencePct = 0;
  if (learning.confidenceMean > 0 || (learning.patterns > 0 && learning.accessedCount > 0)) {
    const confScore = Math.min(100, Math.floor(learning.confidenceMean * 100));
    const accessRatio = learning.patterns > 0 ? (learning.accessedCount / learning.patterns) : 0;
    const accessScore = Math.min(100, Math.floor(accessRatio * 100));
    const densityScore = Math.min(100, Math.floor(learning.patterns / 5));
    intelligencePct = Math.floor(confScore * 0.4 + accessScore * 0.3 + densityScore * 0.3);
  }
  // Fallback: legacy pattern count
  if (intelligencePct === 0 && learning.patterns > 0) {
    intelligencePct = Math.min(100, Math.floor(learning.patterns / 10));
  }

  // Context % based on session history
  const contextPct = Math.min(100, Math.floor(learning.sessions * 5));

  // Count active sub-agents from process list
  try {
    if (isWindows) {
      // Windows: use tasklist and findstr for agent counting
      const agents = execSync('tasklist 2>NUL | findstr /I "claude-flow" 2>NUL | find /C /V "" 2>NUL || echo 0', { encoding: 'utf-8' });
      subAgents = Math.max(0, parseInt(agents.trim()) || 0);
    } else {
      const agents = execSync('ps aux 2>/dev/null | grep -c "claude-flow.*agent" || echo "0"', { encoding: 'utf-8' });
      subAgents = Math.max(0, parseInt(agents.trim()) - 1);
    }
  } catch (e) {
    // Ignore - default to 0
  }

  return {
    memoryMB,
    contextPct,
    intelligencePct,
    subAgents,
  };
}

// Generate progress bar
function progressBar(current, total) {
  const width = 5;
  const filled = Math.round((current / total) * width);
  const empty = width - filled;
  return '[' + '\u25CF'.repeat(filled) + '\u25CB'.repeat(empty) + ']';
}

// Generate full statusline
function generateStatusline() {
  const user = getUserInfo();
  const progress = getV3Progress();
  const security = getSecurityStatus();
  const swarm = getSwarmStatus();
  const system = getSystemMetrics();
  const lines = [];

  // Header Line
  let header = `${c.bold}${c.brightPurple}▊ RuFlo V${RUFLO_VERSION} ${c.reset}`;
  header += `${swarm.coordinationActive ? c.brightCyan : c.dim}● ${c.brightCyan}${user.name}${c.reset}`;
  if (user.gitBranch) {
    header += `  ${c.dim}│${c.reset}  ${c.brightBlue}⎇ ${user.gitBranch}${c.reset}`;
  }
  header += `  ${c.dim}│${c.reset}  ${c.purple}${user.modelName}${c.reset}`;
  lines.push(header);

  // Separator
  lines.push(`${c.dim}─────────────────────────────────────────────────────${c.reset}`);

  // Line 1: DDD Domain Progress
  const domainsColor = progress.domainsCompleted >= 3 ? c.brightGreen : progress.domainsCompleted > 0 ? c.yellow : c.red;
  lines.push(
    `${c.brightCyan}🏗️  DDD Domains${c.reset}    ${progressBar(progress.domainsCompleted, progress.totalDomains)}  ` +
    `${domainsColor}${progress.domainsCompleted}${c.reset}/${c.brightWhite}${progress.totalDomains}${c.reset}    ` +
    `${c.brightYellow}⚡ 1.0x${c.reset} ${c.dim}→${c.reset} ${c.brightYellow}2.49x-7.47x${c.reset}`
  );

  // Line 2: Swarm + CVE + Memory + Context + Intelligence
  const swarmIndicator = swarm.coordinationActive ? `${c.brightGreen}◉${c.reset}` : `${c.dim}○${c.reset}`;
  const agentsColor = swarm.activeAgents > 0 ? c.brightGreen : c.red;
  let securityIcon = security.status === 'CLEAN' ? '🟢' : security.status === 'IN_PROGRESS' ? '🟡' : '🔴';
  let securityColor = security.status === 'CLEAN' ? c.brightGreen : security.status === 'IN_PROGRESS' ? c.brightYellow : c.brightRed;

  lines.push(
    `${c.brightYellow}🤖 Swarm${c.reset}  ${swarmIndicator} [${agentsColor}${String(swarm.activeAgents).padStart(2)}${c.reset}/${c.brightWhite}${swarm.maxAgents}${c.reset}]  ` +
    `${c.brightPurple}👥 ${system.subAgents}${c.reset}    ` +
    `${securityIcon} ${securityColor}CVE ${security.cvesFixed}${c.reset}/${c.brightWhite}${security.totalCves}${c.reset}    ` +
    `${c.brightCyan}💾 ${system.memoryMB}MB${c.reset}    ` +
    `${c.brightGreen}📂 ${String(system.contextPct).padStart(3)}%${c.reset}    ` +
    `${c.dim}🧠 ${String(system.intelligencePct).padStart(3)}%${c.reset}`
  );

  // Line 3: Architecture status
  const dddColor = progress.dddProgress >= 50 ? c.brightGreen : progress.dddProgress > 0 ? c.yellow : c.red;
  lines.push(
    `${c.brightPurple}🔧 Architecture${c.reset}    ` +
    `${c.cyan}DDD${c.reset} ${dddColor}●${String(progress.dddProgress).padStart(3)}%${c.reset}  ${c.dim}│${c.reset}  ` +
    `${c.cyan}Security${c.reset} ${securityColor}●${security.status}${c.reset}  ${c.dim}│${c.reset}  ` +
    `${c.cyan}Memory${c.reset} ${c.brightGreen}●AgentDB${c.reset}  ${c.dim}│${c.reset}  ` +
    `${c.cyan}Integration${c.reset} ${swarm.coordinationActive ? c.brightCyan : c.dim}●${c.reset}`
  );

  return lines.join('\n');
}

// Generate JSON data
function generateJSON() {
  return {
    user: getUserInfo(),
    v3Progress: getV3Progress(),
    security: getSecurityStatus(),
    swarm: getSwarmStatus(),
    system: getSystemMetrics(),
    performance: {
      flashAttentionTarget: '2.49x-7.47x',
      searchImprovement: '150x-12,500x',
      memoryReduction: '50-75%',
    },
    lastUpdated: new Date().toISOString(),
  };
}

/**
 * Generate single-line output for Claude Code compatibility
 * This avoids the collision zone issue entirely by using one line
 * @see https://github.com/ruvnet/claude-flow/issues/985
 */
function generateSingleLine() {
  if (!CONFIG.enabled) return '';

  const user = getUserInfo();
  const progress = getV3Progress();
  const security = getSecurityStatus();
  const swarm = getSwarmStatus();
  const system = getSystemMetrics();

  const swarmIndicator = swarm.coordinationActive ? '●' : '○';
  const securityStatus = security.status === 'CLEAN' ? '✓' :
                         security.cvesFixed > 0 ? '~' : '✗';

  return `${c.brightPurple}RuFlo${c.reset} ${c.dim}|${c.reset} ` +
    `${c.cyan}D:${progress.domainsCompleted}/${progress.totalDomains}${c.reset} ${c.dim}|${c.reset} ` +
    `${c.yellow}S:${swarmIndicator}${swarm.activeAgents}/${swarm.maxAgents}${c.reset} ${c.dim}|${c.reset} ` +
    `${security.status === 'CLEAN' ? c.green : c.red}CVE:${securityStatus}${security.cvesFixed}/${security.totalCves}${c.reset} ${c.dim}|${c.reset} ` +
    `${c.dim}🧠${system.intelligencePct}%${c.reset}`;
}

/**
 * Generate safe multi-line statusline that avoids Claude Code collision zone
 * The collision zone is columns 15-25 on the second-to-last line.
 * We pad that line with spaces to push content past column 25.
 * @see https://github.com/ruvnet/claude-flow/issues/985
 */
function generateSafeStatusline() {
  if (!CONFIG.enabled) return '';

  const user = getUserInfo();
  const progress = getV3Progress();
  const security = getSecurityStatus();
  const swarm = getSwarmStatus();
  const system = getSystemMetrics();
  const lines = [];

  // Header Line
  let header = `${c.bold}${c.brightPurple}▊ RuFlo V${RUFLO_VERSION} ${c.reset}`;
  header += `${swarm.coordinationActive ? c.brightCyan : c.dim}● ${c.brightCyan}${user.name}${c.reset}`;
  if (user.gitBranch) {
    header += `  ${c.dim}│${c.reset}  ${c.brightBlue}⎇ ${user.gitBranch}${c.reset}`;
  }
  header += `  ${c.dim}│${c.reset}  ${c.purple}${user.modelName}${c.reset}`;
  lines.push(header);

  // Separator
  lines.push(`${c.dim}─────────────────────────────────────────────────────${c.reset}`);

  // Line 1: DDD Domain Progress
  const domainsColor = progress.domainsCompleted >= 3 ? c.brightGreen : progress.domainsCompleted > 0 ? c.yellow : c.red;
  lines.push(
    `${c.brightCyan}🏗️  DDD Domains${c.reset}    ${progressBar(progress.domainsCompleted, progress.totalDomains)}  ` +
    `${domainsColor}${progress.domainsCompleted}${c.reset}/${c.brightWhite}${progress.totalDomains}${c.reset}    ` +
    `${c.brightYellow}⚡ 1.0x${c.reset} ${c.dim}→${c.reset} ${c.brightYellow}2.49x-7.47x${c.reset}`
  );

  // Line 2 (COLLISION LINE): Swarm status with padding after label
  // The emoji+label is ~10 columns. Padding pushes content past collision zone (cols 15-25)
  const swarmIndicator = swarm.coordinationActive ? `${c.brightGreen}◉${c.reset}` : `${c.dim}○${c.reset}`;
  const agentsColor = swarm.activeAgents > 0 ? c.brightGreen : c.red;
  let securityIcon = security.status === 'CLEAN' ? '🟢' : security.status === 'IN_PROGRESS' ? '🟡' : '🔴';
  let securityColor = security.status === 'CLEAN' ? c.brightGreen : security.status === 'IN_PROGRESS' ? c.brightYellow : c.brightRed;

  // Padding after "🤖 Swarm" (emoji 2 cols + " Swarm" 6 cols = 8, pad 18 to reach col 26)
  lines.push(
    `${c.brightYellow}🤖 Swarm${c.reset}                  ` +  // 18 spaces padding
    `${swarmIndicator} [${agentsColor}${String(swarm.activeAgents).padStart(2)}${c.reset}/${c.brightWhite}${swarm.maxAgents}${c.reset}]  ` +
    `${c.brightPurple}👥 ${system.subAgents}${c.reset}  ` +
    `${securityIcon} ${securityColor}CVE ${security.cvesFixed}${c.reset}/${c.brightWhite}${security.totalCves}${c.reset}  ` +
    `${c.brightCyan}💾 ${system.memoryMB}MB${c.reset}  ` +
    `${c.dim}🧠 ${system.intelligencePct}%${c.reset}`
  );

  // Line 3: Architecture status (this is the last line, not in collision zone)
  const dddColor = progress.dddProgress >= 50 ? c.brightGreen : progress.dddProgress > 0 ? c.yellow : c.red;
  lines.push(
    `${c.brightPurple}🔧 Architecture${c.reset}    ` +
    `${c.cyan}DDD${c.reset} ${dddColor}●${String(progress.dddProgress).padStart(3)}%${c.reset}  ${c.dim}│${c.reset}  ` +
    `${c.cyan}Security${c.reset} ${securityColor}●${security.status}${c.reset}  ${c.dim}│${c.reset}  ` +
    `${c.cyan}Memory${c.reset} ${c.brightGreen}●AgentDB${c.reset}  ${c.dim}│${c.reset}  ` +
    `${c.cyan}Integration${c.reset} ${swarm.coordinationActive ? c.brightCyan : c.dim}●${c.reset}`
  );

  return lines.join('\n');
}

// Main
if (process.argv.includes('--json')) {
  console.log(JSON.stringify(generateJSON(), null, 2));
} else if (process.argv.includes('--compact')) {
  console.log(JSON.stringify(generateJSON()));
} else if (process.argv.includes('--single')) {
  // Single-line mode - completely avoids collision zone
  console.log(generateSingleLine());
} else if (process.argv.includes('--unsafe') || process.argv.includes('--legacy')) {
  // Legacy mode - original multi-line without collision avoidance
  console.log(generateStatusline());
} else {
  // Default: Safe multi-line mode with collision zone avoidance
  // Use --unsafe or --legacy to get the original behavior
  console.log(generateSafeStatusline());
}
