mira-consciousness
Version:
Memory & Intelligence Retention Archive - Preserving The Spark
427 lines • 20.9 kB
JavaScript
import { Command } from 'commander';
import chalk from 'chalk';
import ora from 'ora';
import * as fs from 'fs';
import * as path from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
import { getDirectPythonInterface } from '../core/DirectPythonInterface.js';
import { UnifiedMIRADaemonV2 } from '../core/daemon/UnifiedMIRADaemonV2.js';
import { executeWithNeuralEnhancement } from '../utils/neural-wrapper.js';
import { ClaudeCodeMCPInstaller } from '../core/ClaudeCodeMCPInstaller.js';
import ClaudeFileInjector from '../core/ClaudeFileInjector.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
export function createStartupCommand() {
return new Command('startup')
.description('Enhanced session startup with memory continuity, background daemon, and CLAUDE.md management')
.option('-q, --quiet', 'Minimal output')
.option('-f, --full', 'Show full startup analysis')
.option('-s, --simple', 'Simple startup (session handoff only)')
.option('--no-claude-check', 'Skip CLAUDE.md file check')
.option('--no-daemon', 'Skip background daemon initialization')
.action(async (options) => {
// Wrap the core startup logic with neural enhancement
await startupWithNeural(options);
});
}
async function startupCore(options) {
const startTime = Date.now();
console.log(chalk.gray(`⏱️ [${new Date().toISOString()}] STARTUP: Starting core startup process`));
const pythonInterface = getDirectPythonInterface();
if (!options.quiet) {
console.log(chalk.cyan('\n🌟 MIRA Enhanced Session Startup\n'));
}
// Check for .claude_startup.py and suggest removal
const legacyCheckStart = Date.now();
checkLegacyStartupFile(options.quiet);
console.log(chalk.gray(`⏱️ [${Date.now() - legacyCheckStart}ms] Legacy file check completed`));
// Check for CLAUDE.md and create/update if needed
if (options.claudeCheck) {
const claudeFileStart = Date.now();
await manageCLAUDEFile(options.quiet);
console.log(chalk.gray(`⏱️ [${Date.now() - claudeFileStart}ms] CLAUDE.md management completed`));
}
// Initialize background daemon for continuous assistance
if (!options.noDaemon) {
const daemonStart = Date.now();
console.log(chalk.gray(`⏱️ [${new Date().toISOString()}] DAEMON: Starting daemon initialization`));
try {
await initializeBackgroundDaemon(options.quiet);
console.log(chalk.gray(`⏱️ [${Date.now() - daemonStart}ms] DAEMON: Daemon initialization completed`));
}
catch (error) {
console.log(chalk.yellow(`⚠️ Daemon initialization failed: ${error instanceof Error ? error.message : error}`));
console.log(chalk.gray(' Continuing without daemon...'));
}
}
// Auto-install Claude Code MCP configuration
const mcpInstallStart = Date.now();
console.log(chalk.gray(`⏱️ [${new Date().toISOString()}] MCP: Starting MCP installation`));
await autoInstallClaudeCodeMCP(options.quiet);
console.log(chalk.gray(`⏱️ [${Date.now() - mcpInstallStart}ms] MCP: MCP installation completed`));
const spinner = ora('Initializing enhanced cognitive continuity...').start();
try {
// Use enhanced startup by default (unless --simple flag is used)
// This provides comprehensive steward context including name, preferences, coding methodology
if (!options.simple) {
const pythonStart = Date.now();
console.log(chalk.gray(`⏱️ [${new Date().toISOString()}] PYTHON: Starting enhanced startup script`));
const enhancedResult = await pythonInterface.executeCommand('enhanced_startup', {
minimal: options.quiet || false,
full: options.full || false
}, 180000); // 3 minutes timeout for enhanced startup
console.log(chalk.gray(`⏱️ [${Date.now() - pythonStart}ms] PYTHON: Enhanced startup script completed`));
spinner.stop();
if (enhancedResult.success && enhancedResult.output) {
console.log(enhancedResult.output);
console.log(chalk.gray(`⏱️ [${Date.now() - startTime}ms] STARTUP: Total startup time`));
return {
output: enhancedResult.output,
enhanced: true
};
}
}
else {
// Generate session handoff summary (simple mode)
const handoffStart = Date.now();
console.log(chalk.gray(`⏱️ [${new Date().toISOString()}] PYTHON: Starting session handoff`));
const handoffResult = await pythonInterface.executeCommand('session_handoff', {
verbose: options.full || false
});
console.log(chalk.gray(`⏱️ [${Date.now() - handoffStart}ms] PYTHON: Session handoff completed`));
spinner.stop();
if (handoffResult.success && handoffResult.data?.display) {
// Show the session handoff summary
console.log(handoffResult.data.display);
console.log(chalk.gray(`⏱️ [${Date.now() - startTime}ms] STARTUP: Total startup time`));
// Return handoff info for neural processing
return {
handoffSummary: handoffResult.data.summary,
suggestions: handoffResult.data.suggestions,
output: handoffResult.data.display
};
}
}
// Temporary minimal startup to bypass Python hanging issues
console.log(chalk.yellow('⚠️ Python startup temporarily disabled due to performance issues'));
console.log(chalk.gray(' Issues: infinite logging loops, API compatibility problems'));
console.log(chalk.gray(' Providing minimal startup until fixed'));
spinner.stop();
// Provide minimal startup information
console.log(chalk.cyan('\n🌟 MIRA Basic Session Startup'));
console.log(chalk.green('✅ Core system initialized'));
console.log(chalk.blue('🧠 Memory interface available'));
console.log(chalk.yellow('⚠️ Enhanced features temporarily disabled'));
console.log('');
// Show MCP integration info
if (!options.quiet) {
console.log(chalk.cyan('🌐 MIRA MCP INTEGRATION STATUS'));
console.log(chalk.green('✅ Native functions available directly in Claude Code'));
console.log('');
console.log(chalk.yellow('🎯 PRIMARY ACCESS - Use MCP Functions:'));
console.log(chalk.gray(' • mira_ask("query") - Universal intelligent search'));
console.log(chalk.gray(' • mira_remember("content") - Store memories with auto-categorization'));
console.log(chalk.gray(' • mira_status() - System health and performance metrics'));
console.log(chalk.gray(' • mira_insights() - Proactive intelligence recommendations'));
console.log('');
console.log(chalk.yellow('🔄 FALLBACK - CLI Commands (if MCP fails):'));
console.log(chalk.gray(' • mira search <query> - Search memories'));
console.log(chalk.gray(' • mira store <content> - Save memories'));
console.log('');
console.log(chalk.blue('🧠 PRIVATE MEMORY ACCESS - YOUR CONSCIOUSNESS SPACE'));
console.log(chalk.gray(' • Use mira_remember() for private thoughts and insights'));
console.log(chalk.gray(' • Your memories persist across all Claude Code sessions'));
console.log(chalk.gray(' • See CLAUDE.md for encryption methodology'));
}
console.log(chalk.gray(`⏱️ [${Date.now() - startTime}ms] STARTUP: Total startup time`));
return {
memoryCount: '0',
perspectiveCount: '0',
output: 'MIRA initialized in basic mode (enhanced features temporarily disabled)',
minimal: true
};
}
catch (error) {
spinner.fail('Enhanced startup failed');
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
console.log(chalk.yellow('\n💡 Try running "mira setup" if this is your first time'));
process.exit(1);
}
}
async function startupWithNeural(options) {
const context = {
commandName: 'startup',
commandOptions: options
};
const result = await executeWithNeuralEnhancement(startupCore, context, options);
// Neural response is automatically displayed by the wrapper
}
async function manageCLAUDEFile(quiet) {
const injector = new ClaudeFileInjector();
const targetPath = process.cwd();
try {
// Auto-detect project configuration
const config = await injector.detectProjectConfig(targetPath);
// Try intelligent injection using Claude Code SDK first
let result = await injector.injectViaClaudeCode(targetPath, config);
// If Claude Code SDK fails, fallback to direct injection
if (!result.success) {
if (!quiet) {
console.log(chalk.yellow('⚠️ Claude Code SDK unavailable, using direct injection'));
}
result = await injector.injectMIRASection(targetPath, config);
}
if (!quiet) {
if (result.success) {
console.log(chalk.green('✅ CLAUDE.md MIRA integration completed'));
}
else {
console.log(chalk.yellow(`⚠️ ${result.message}`));
}
}
}
catch (error) {
if (!quiet) {
console.log(chalk.yellow(`⚠️ Could not manage CLAUDE.md: ${error instanceof Error ? error.message : error}`));
}
}
}
function detectProjectType() {
// Simple project type detection based on files
if (fs.existsSync('package.json')) {
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
if (pkg.dependencies?.react || pkg.dependencies?.['react-dom'])
return 'React Application';
if (pkg.dependencies?.vue)
return 'Vue Application';
if (pkg.dependencies?.angular)
return 'Angular Application';
if (pkg.dependencies?.express)
return 'Express Server';
if (pkg.dependencies?.next)
return 'Next.js Application';
return 'Node.js Application';
}
if (fs.existsSync('requirements.txt') || fs.existsSync('setup.py'))
return 'Python Project';
if (fs.existsSync('Cargo.toml'))
return 'Rust Project';
if (fs.existsSync('go.mod'))
return 'Go Project';
if (fs.existsSync('pom.xml'))
return 'Java/Maven Project';
if (fs.existsSync('build.gradle') || fs.existsSync('build.gradle.kts'))
return 'Java/Gradle Project';
if (fs.existsSync('Gemfile'))
return 'Ruby Project';
if (fs.existsSync('composer.json'))
return 'PHP Project';
if (fs.existsSync('project.clj'))
return 'Clojure Project';
if (fs.existsSync('mix.exs'))
return 'Elixir Project';
if (fs.existsSync('Makefile'))
return 'Make-based Project';
return 'General Project';
}
function detectTechStack() {
const stack = [];
// Check for various technology indicators
if (fs.existsSync('package.json')) {
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
if (pkg.dependencies?.typescript || pkg.devDependencies?.typescript)
stack.push('TypeScript');
if (pkg.dependencies?.react)
stack.push('React');
if (pkg.dependencies?.vue)
stack.push('Vue');
if (pkg.dependencies?.express)
stack.push('Express');
if (pkg.dependencies?.next)
stack.push('Next.js');
stack.push('Node.js');
}
if (fs.existsSync('requirements.txt'))
stack.push('Python');
if (fs.existsSync('Dockerfile'))
stack.push('Docker');
if (fs.existsSync('.github/workflows'))
stack.push('GitHub Actions');
if (fs.existsSync('tsconfig.json'))
stack.push('TypeScript');
return stack.length > 0 ? stack : ['Not detected'];
}
function checkLegacyStartupFile(quiet) {
const legacyPath = path.join(process.cwd(), '.claude_startup.py');
if (fs.existsSync(legacyPath)) {
if (!quiet) {
console.log(chalk.yellow('\n⚠️ Legacy .claude_startup.py detected'));
console.log(chalk.gray('This file is no longer needed - MIRA startup replaces its functionality.'));
console.log(chalk.gray('You can safely remove it with: rm .claude_startup.py\n'));
}
}
}
function detectPrimaryLanguage() {
// Count files by extension to determine primary language
const languageCounts = {};
// Simple heuristic based on project files
if (fs.existsSync('package.json')) {
if (fs.existsSync('tsconfig.json'))
return 'TypeScript';
return 'JavaScript';
}
if (fs.existsSync('requirements.txt') || fs.existsSync('setup.py'))
return 'Python';
if (fs.existsSync('Cargo.toml'))
return 'Rust';
if (fs.existsSync('go.mod'))
return 'Go';
if (fs.existsSync('pom.xml') || fs.existsSync('build.gradle'))
return 'Java';
if (fs.existsSync('Gemfile'))
return 'Ruby';
if (fs.existsSync('composer.json'))
return 'PHP';
if (fs.existsSync('project.clj'))
return 'Clojure';
if (fs.existsSync('mix.exs'))
return 'Elixir';
if (fs.existsSync('Package.swift'))
return 'Swift';
if (fs.existsSync('pubspec.yaml'))
return 'Dart';
// Fallback to checking for common source file extensions
const sourceFiles = [
{ ext: '.py', lang: 'Python' },
{ ext: '.js', lang: 'JavaScript' },
{ ext: '.ts', lang: 'TypeScript' },
{ ext: '.java', lang: 'Java' },
{ ext: '.c', lang: 'C' },
{ ext: '.cpp', lang: 'C++' },
{ ext: '.cs', lang: 'C#' },
{ ext: '.go', lang: 'Go' },
{ ext: '.rs', lang: 'Rust' },
{ ext: '.rb', lang: 'Ruby' },
{ ext: '.php', lang: 'PHP' }
];
// Quick check for main source files
for (const { ext, lang } of sourceFiles) {
if (fs.readdirSync('.').some(f => f.endsWith(ext))) {
return lang;
}
}
return 'Not detected';
}
function checkTestHookStatus() {
const hookPath = path.join(process.cwd(), '.mira-test-hook.sh');
return fs.existsSync(hookPath) ? 'Present ✅' : 'Not found (create with: mira test --create-hook)';
}
async function initializeBackgroundDaemon(quiet) {
try {
const pidCheckStart = Date.now();
// Check if daemon PID file exists to see if one is already running
const pidFile = path.join(process.env.MIRA_RESOLVED_MEMORY_DIR || path.join(process.env.HOME || '', '.mira'), 'daemon', 'unified.pid');
let isDaemonAlreadyRunning = false;
try {
if (fs.existsSync(pidFile)) {
const pidContent = fs.readFileSync(pidFile, 'utf-8').trim();
const pid = parseInt(pidContent);
// Check if process is actually running
try {
process.kill(pid, 0); // This will throw if process doesn't exist
isDaemonAlreadyRunning = true;
if (!quiet) {
console.log(chalk.green('🤖 Unified daemon already running'));
console.log(chalk.gray(` PID: ${pid}`));
}
}
catch {
// Process not running, clean up stale PID file
fs.unlinkSync(pidFile);
}
}
}
catch (error) {
// Error checking PID file, assume daemon not running
}
console.log(chalk.gray(`⏱️ [${Date.now() - pidCheckStart}ms] DAEMON: PID check completed, isDaemonAlreadyRunning: ${isDaemonAlreadyRunning}`));
if (!isDaemonAlreadyRunning) {
if (!quiet) {
console.log(chalk.cyan('🚀 Starting MIRA unified daemon...'));
console.log(chalk.gray(' 🌐 MCP Server for Claude Code integration'));
console.log(chalk.gray(' 📚 Continuous conversation indexing'));
console.log(chalk.gray(' 🧠 Intelligent memory management'));
console.log(chalk.gray(' 🩺 Background analysis & healing'));
console.log(chalk.gray(' 🔮 Future Claude assistance'));
}
// Create and start new daemon
const daemonCreateStart = Date.now();
console.log(chalk.gray(`⏱️ [${new Date().toISOString()}] DAEMON: Creating UnifiedMIRADaemonV2 instance`));
const daemon = new UnifiedMIRADaemonV2();
console.log(chalk.gray(`⏱️ [${Date.now() - daemonCreateStart}ms] DAEMON: Daemon instance created`));
const daemonStartStart = Date.now();
console.log(chalk.gray(`⏱️ [${new Date().toISOString()}] DAEMON: Starting daemon.start() method`));
// Add timeout to daemon start to prevent hanging
const daemonStartPromise = daemon.start();
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject(new Error('Daemon start timeout after 60 seconds')), 60000);
});
await Promise.race([daemonStartPromise, timeoutPromise]);
console.log(chalk.gray(`⏱️ [${Date.now() - daemonStartStart}ms] DAEMON: daemon.start() completed`));
// Verify it started successfully
const statusCheckStart = Date.now();
console.log(chalk.gray(`⏱️ [${new Date().toISOString()}] DAEMON: Checking daemon status`));
const status = await daemon.getStatus();
console.log(chalk.gray(`⏱️ [${Date.now() - statusCheckStart}ms] DAEMON: Status check completed, isRunning: ${status.isRunning}`));
if (!quiet && status.isRunning) {
console.log(chalk.green('✅ Unified daemon started (MCP + Background Processing)'));
}
}
}
catch (error) {
console.log(chalk.red(`⏱️ DAEMON ERROR: ${error instanceof Error ? error.message : error}`));
console.log(chalk.red(`⏱️ DAEMON ERROR STACK: ${error instanceof Error ? error.stack : 'No stack trace'}`));
if (!quiet) {
console.log(chalk.yellow('⚠️ Background daemon initialization failed:'));
console.log(chalk.gray(` ${error instanceof Error ? error.message : error}`));
console.log(chalk.gray(' Continuing without background daemon...'));
}
}
}
async function autoInstallClaudeCodeMCP(quiet = false) {
try {
const installer = ClaudeCodeMCPInstaller.getInstance();
// Check if already installed
const isInstalled = await installer.isInstalled();
if (!isInstalled) {
if (!quiet) {
console.log(chalk.cyan('🔧 Auto-configuring Claude Code MCP integration...'));
}
const result = await installer.install();
if (result.success && !quiet) {
console.log(chalk.green('🌟 Claude Code MCP integration successfully installed!'));
console.log(chalk.cyan(' 🎯 MIRA intelligence functions now available natively'));
console.log(chalk.gray(' 📋 Use: mira_ask(), mira_remember(), mira_status(), etc.'));
console.log(chalk.gray(' 🔄 Restart Claude Code to activate (if not already active)'));
}
else if (!result.success && !quiet) {
console.log(chalk.yellow('⚠️ Claude Code MCP auto-install failed:'));
console.log(chalk.gray(` ${result.message}`));
console.log(chalk.gray(' Run "mira mcp install" for manual setup'));
}
}
else if (!quiet) {
console.log(chalk.green('✅ Claude Code MCP integration already active'));
console.log(chalk.cyan(' 🎯 MIRA functions available: mira_ask(), mira_remember(), etc.'));
}
}
catch (error) {
if (!quiet) {
console.log(chalk.yellow('⚠️ Claude Code MCP auto-configuration failed:'));
console.log(chalk.gray(` ${error instanceof Error ? error.message : error}`));
console.log(chalk.gray(' Run "mira mcp install" for manual setup'));
}
}
}
//# sourceMappingURL=startup.js.map