@lanonasis/cli
Version:
LanOnasis Enterprise CLI - Memory as a Service, API Key Management, and Infrastructure Orchestration
297 lines (296 loc) ⢠10.9 kB
JavaScript
/**
* Enhanced CLI Entry Point
* Integrates all the enhanced experience components
*/
import { Command } from 'commander';
import chalk from 'chalk';
import { config } from 'dotenv';
import { createCLIArchitecture } from './core/architecture.js';
import { WelcomeExperience } from './core/welcome.js';
import { DashboardCommandCenter } from './core/dashboard.js';
import { ErrorHandler, ErrorBoundary } from './core/error-handler.js';
import { PowerUserMode } from './core/power-mode.js';
import { AchievementSystem } from './core/achievements.js';
import { ProgressIndicator } from './core/progress.js';
import { CLIConfig } from './utils/config.js';
// Load environment variables
config();
// Initialize the enhanced architecture
const architecture = createCLIArchitecture();
const { stateManager, interactionEngine, presentationLayer } = architecture;
// Initialize systems
const errorHandler = new ErrorHandler(stateManager);
const errorBoundary = new ErrorBoundary(errorHandler);
const achievementSystem = new AchievementSystem(stateManager);
const progressIndicator = new ProgressIndicator();
const cliConfig = new CLIConfig();
// Create the main program
const program = new Command();
program
.name('onasis')
.description(chalk.cyan('š§ Onasis Memory Service - Enhanced CLI Experience'))
.version('2.0.0', '-v, --version', 'display version number')
.option('-V, --verbose', 'enable verbose logging')
.option('--api-url <url>', 'override API URL')
.option('--output <format>', 'output format (json, table, yaml, minimal)', 'table')
.option('--no-animations', 'disable animations')
.option('--expert', 'start in expert/power mode')
.option('--offline', 'work offline with cached data');
// Enhanced init command with interactive setup
program
.command('init')
.description('Initialize and configure Onasis CLI')
.action(errorBoundary.wrapAsync(async () => {
const welcome = new WelcomeExperience(stateManager);
await welcome.show();
}));
// Interactive dashboard command
program
.command('dashboard')
.alias('home')
.description('Open the interactive command center')
.action(errorBoundary.wrapAsync(async () => {
const dashboard = new DashboardCommandCenter(stateManager);
await dashboard.show();
}));
// Power mode for expert users
program
.command('power')
.alias('expert')
.description('Enter power user mode for streamlined operations')
.action(errorBoundary.wrapAsync(async () => {
const powerMode = new PowerUserMode(stateManager);
await powerMode.enter();
}));
// Enhanced memory commands with progress and feedback
program
.command('memory')
.alias('m')
.description('Memory operations')
.argument('[action]', 'action to perform (create, search, list, update, delete)')
.option('-t, --title <title>', 'memory title')
.option('-c, --content <content>', 'memory content')
.option('--tags <tags>', 'comma-separated tags')
.option('--type <type>', 'memory type (context, knowledge, reference, project)')
.option('--topic <topic>', 'topic to categorize under')
.option('-q, --query <query>', 'search query')
.option('--limit <n>', 'limit results')
.option('--interactive', 'use interactive mode')
.action(errorBoundary.wrapAsync(async (action, options) => {
const { InteractiveMemoryCreator, InteractiveSearch } = await import('./core/dashboard.js');
// Update stats for achievements
achievementSystem.updateStats({
totalMemories: achievementSystem.userStats.totalMemories + 1
});
switch (action) {
case 'create':
if (options.interactive || (!options.title && !options.content)) {
const creator = new InteractiveMemoryCreator(stateManager);
await creator.create();
}
else {
await progressIndicator.withSpinner(async () => {
// Create memory logic here
console.log(chalk.green('ā Memory created successfully'));
}, 'Creating memory...');
}
break;
case 'search':
const search = new InteractiveSearch(stateManager);
await search.search(options.query || '');
achievementSystem.updateStats({
totalSearches: achievementSystem.userStats.totalSearches + 1
});
break;
case 'list':
await progressIndicator.withSpinner(async () => {
// List memories logic
console.log(chalk.cyan('Memories listed'));
}, 'Loading memories...');
break;
default:
// If no action specified, go to interactive mode
const dashboard = new DashboardCommandCenter(stateManager);
await dashboard.show();
}
}));
// Topic management with visual feedback
program
.command('topic')
.alias('t')
.description('Manage topics')
.argument('[action]', 'action to perform (create, list, delete)')
.argument('[name]', 'topic name')
.action(errorBoundary.wrapAsync(async (action, name) => {
switch (action) {
case 'create':
if (!name) {
const { default: inquirer } = await import('inquirer');
const { topicName } = await inquirer.prompt([
{
type: 'input',
name: 'topicName',
message: 'Topic name:',
validate: (input) => input.length > 0 || 'Topic name is required'
}
]);
name = topicName;
}
console.log(chalk.green(`ā Topic "${name}" created`));
break;
case 'list':
console.log(chalk.bold('š Topics:'));
console.log(' ⢠Architecture');
console.log(' ⢠API Documentation');
console.log(' ⢠Meeting Notes');
break;
case 'delete':
console.log(chalk.red(`ā Topic "${name}" deleted`));
break;
default:
console.log(chalk.yellow('Usage: onasis topic [create|list|delete] [name]'));
}
}));
// Achievement system
program
.command('achievements')
.alias('badges')
.description('View your achievements and progress')
.action(() => {
achievementSystem.showAchievements();
});
// Stats and analytics
program
.command('stats')
.alias('analytics')
.description('View usage statistics and analytics')
.action(errorBoundary.wrapAsync(async () => {
const { AnalyticsView } = await import('./core/dashboard.js');
const analytics = new AnalyticsView(stateManager);
await analytics.show();
}));
// Settings management
program
.command('settings')
.alias('config')
.description('Manage CLI settings and preferences')
.argument('[key]', 'setting key')
.argument('[value]', 'setting value')
.action(errorBoundary.wrapAsync(async (key, value) => {
if (!key) {
// Show all settings
const prefs = stateManager.getPreferences();
console.log(chalk.bold('āļø Settings:\n'));
Object.entries(prefs).forEach(([k, v]) => {
console.log(` ${chalk.cyan(k)}: ${v}`);
});
}
else if (value !== undefined) {
// Set a value
stateManager.updatePreference(key, value);
console.log(chalk.green(`ā ${key} set to ${value}`));
}
else {
// Get a value
const prefs = stateManager.getPreferences();
console.log(`${key}: ${prefs[key]}`);
}
}));
// Help command with enhanced formatting
program
.command('help [command]')
.description('Show help for a specific command')
.action((command) => {
if (command) {
const cmd = program.commands.find(c => c.name() === command);
if (cmd) {
cmd.outputHelp();
}
else {
console.log(chalk.red(`Command "${command}" not found`));
}
}
else {
console.log(chalk.bold.cyan('\nš§ Onasis Memory Service - Enhanced CLI\n'));
console.log('Available commands:\n');
program.commands.forEach(cmd => {
const name = cmd.name().padEnd(15);
const desc = cmd.description();
console.log(` ${chalk.cyan(name)} ${desc}`);
});
console.log('\nFor detailed help: onasis help [command]');
console.log('Interactive mode: onasis (no arguments)');
console.log('Power mode: onasis power');
}
});
// Status command
program
.command('status')
.description('Check service status and connectivity')
.action(errorBoundary.wrapAsync(async () => {
const spinner = progressIndicator;
await spinner.withSpinner(async () => {
// Check API connection
await new Promise(resolve => setTimeout(resolve, 1000));
}, 'Checking service status...');
console.log(chalk.green('ā Service: Online'));
console.log(chalk.green('ā API: Connected'));
console.log(chalk.green('ā Auth: Valid'));
console.log(chalk.cyan(' Endpoint: api.lanonasis.com'));
console.log(chalk.cyan(' Version: 2.0.0'));
}));
// Default action - show interactive dashboard if no command
if (process.argv.length === 2) {
(async () => {
try {
// Check if first run
const isFirstRun = !(await cliConfig.isAuthenticated());
if (isFirstRun) {
const welcome = new WelcomeExperience(stateManager);
await welcome.show();
}
else {
const dashboard = new DashboardCommandCenter(stateManager);
await dashboard.show();
}
}
catch (error) {
errorHandler.handle(error);
process.exit(1);
}
})();
}
else {
// Parse command line arguments
program.parse(process.argv);
}
// Handle global options
const options = program.opts();
if (options.verbose) {
process.env.CLI_VERBOSE = 'true';
console.log(chalk.dim('Verbose mode enabled'));
}
if (options.apiUrl) {
process.env.MEMORY_API_URL = options.apiUrl;
console.log(chalk.dim(`API URL set to: ${options.apiUrl}`));
}
if (options.output) {
stateManager.updatePreference('outputFormat', options.output);
}
if (options.noAnimations) {
stateManager.updatePreference('animations', false);
}
if (options.expert) {
// Start directly in power mode
(async () => {
const powerMode = new PowerUserMode(stateManager);
await powerMode.enter();
})();
}
if (options.offline) {
process.env.CLI_OFFLINE = 'true';
console.log(chalk.yellow('ā Running in offline mode'));
}
// Export for testing and extension
export { architecture, stateManager, errorHandler, achievementSystem, progressIndicator };