zouroboros-cli 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +64 -0
- package/dist/commands/agents.d.ts +2 -0
- package/dist/commands/agents.js +44 -0
- package/dist/commands/backup.d.ts +2 -0
- package/dist/commands/backup.js +122 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.js +52 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +11 -0
- package/dist/commands/heal.d.ts +2 -0
- package/dist/commands/heal.js +51 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +234 -0
- package/dist/commands/memory.d.ts +2 -0
- package/dist/commands/memory.js +32 -0
- package/dist/commands/migrate.d.ts +2 -0
- package/dist/commands/migrate.js +112 -0
- package/dist/commands/persona.d.ts +2 -0
- package/dist/commands/persona.js +45 -0
- package/dist/commands/skills.d.ts +2 -0
- package/dist/commands/skills.js +48 -0
- package/dist/commands/swarm.d.ts +2 -0
- package/dist/commands/swarm.js +32 -0
- package/dist/commands/tui.d.ts +2 -0
- package/dist/commands/tui.js +11 -0
- package/dist/commands/workflow.d.ts +3 -0
- package/dist/commands/workflow.js +87 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +83 -0
- package/dist/utils/doctor.d.ts +6 -0
- package/dist/utils/doctor.js +384 -0
- package/package.json +54 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { Database } from 'bun:sqlite';
|
|
4
|
+
import { existsSync } from 'fs';
|
|
5
|
+
import { loadConfig, createMigrationRunner, MIGRATIONS } from 'zouroboros-core';
|
|
6
|
+
function openDb() {
|
|
7
|
+
const config = loadConfig();
|
|
8
|
+
if (!existsSync(config.memory.dbPath)) {
|
|
9
|
+
console.error(chalk.red(`\n❌ Database not found at ${config.memory.dbPath}`));
|
|
10
|
+
console.error(chalk.gray(' Run "zouroboros init" first to create the database.\n'));
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
return new Database(config.memory.dbPath);
|
|
14
|
+
}
|
|
15
|
+
export const migrateCommand = new Command('migrate')
|
|
16
|
+
.description('Manage database schema migrations')
|
|
17
|
+
.addCommand(new Command('up')
|
|
18
|
+
.description('Apply pending migrations')
|
|
19
|
+
.option('--to <id>', 'Migrate up to a specific migration ID')
|
|
20
|
+
.action((opts) => {
|
|
21
|
+
const db = openDb();
|
|
22
|
+
try {
|
|
23
|
+
const runner = createMigrationRunner(db);
|
|
24
|
+
const targetId = opts.to ? parseInt(opts.to, 10) : undefined;
|
|
25
|
+
const result = runner.migrate(targetId);
|
|
26
|
+
if (result.applied.length === 0 && result.errors.length === 0) {
|
|
27
|
+
console.log(chalk.green('\n✅ Database is up to date — no pending migrations\n'));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (result.applied.length > 0) {
|
|
31
|
+
console.log(chalk.green(`\n✅ Applied ${result.applied.length} migration(s):\n`));
|
|
32
|
+
for (const name of result.applied) {
|
|
33
|
+
console.log(` ${chalk.gray('↑')} ${name}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (result.errors.length > 0) {
|
|
37
|
+
console.log(chalk.red(`\n❌ ${result.errors.length} migration(s) failed:\n`));
|
|
38
|
+
for (const { name, error } of result.errors) {
|
|
39
|
+
console.log(` ${chalk.red('✗')} ${name}: ${error}`);
|
|
40
|
+
}
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
console.log();
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
db.close();
|
|
47
|
+
}
|
|
48
|
+
}))
|
|
49
|
+
.addCommand(new Command('down')
|
|
50
|
+
.description('Rollback migrations to a specific point')
|
|
51
|
+
.argument('<target-id>', 'Roll back to this migration ID (0 to rollback all)')
|
|
52
|
+
.action((targetId) => {
|
|
53
|
+
const id = parseInt(targetId, 10);
|
|
54
|
+
if (isNaN(id) || id < 0) {
|
|
55
|
+
console.error(chalk.red('Target ID must be a non-negative integer'));
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
const db = openDb();
|
|
59
|
+
try {
|
|
60
|
+
const runner = createMigrationRunner(db);
|
|
61
|
+
const result = runner.rollback(id);
|
|
62
|
+
if (result.applied.length === 0) {
|
|
63
|
+
console.log(chalk.yellow('\nNo migrations to rollback\n'));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
console.log(chalk.green(`\n✅ Rolled back ${result.applied.length} migration(s):\n`));
|
|
67
|
+
for (const name of result.applied) {
|
|
68
|
+
console.log(` ${chalk.gray('↓')} ${name}`);
|
|
69
|
+
}
|
|
70
|
+
if (result.errors.length > 0) {
|
|
71
|
+
console.log(chalk.red(`\n❌ ${result.errors.length} rollback(s) failed:\n`));
|
|
72
|
+
for (const { name, error } of result.errors) {
|
|
73
|
+
console.log(` ${chalk.red('✗')} ${name}: ${error}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
console.log();
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
db.close();
|
|
80
|
+
}
|
|
81
|
+
}))
|
|
82
|
+
.addCommand(new Command('status')
|
|
83
|
+
.description('Show migration status')
|
|
84
|
+
.action(() => {
|
|
85
|
+
const db = openDb();
|
|
86
|
+
try {
|
|
87
|
+
const runner = createMigrationRunner(db);
|
|
88
|
+
const status = runner.getStatus();
|
|
89
|
+
console.log(chalk.cyan('\nMigration Status:\n'));
|
|
90
|
+
console.log(` Current version: ${status.current || chalk.gray('(none)')}`);
|
|
91
|
+
console.log(` Applied: ${status.applied.length}`);
|
|
92
|
+
console.log(` Pending: ${status.pending.length}`);
|
|
93
|
+
console.log(` Total available: ${MIGRATIONS.length}\n`);
|
|
94
|
+
if (status.applied.length > 0) {
|
|
95
|
+
console.log(chalk.gray(' Applied:'));
|
|
96
|
+
for (const m of status.applied) {
|
|
97
|
+
const date = new Date(m.applied_at * 1000).toLocaleString();
|
|
98
|
+
console.log(` ${chalk.green('✓')} ${m.name} ${chalk.gray(`(${date})`)}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (status.pending.length > 0) {
|
|
102
|
+
console.log(chalk.gray(' Pending:'));
|
|
103
|
+
for (const m of status.pending) {
|
|
104
|
+
console.log(` ${chalk.yellow('○')} ${m.name}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
console.log();
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
db.close();
|
|
111
|
+
}
|
|
112
|
+
}));
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
export const personaCommand = new Command('persona')
|
|
4
|
+
.description('Persona management commands')
|
|
5
|
+
.addCommand(new Command('create')
|
|
6
|
+
.description('Create a new persona')
|
|
7
|
+
.argument('<name>', 'Persona name')
|
|
8
|
+
.option('--domain <domain>', 'Domain', 'general')
|
|
9
|
+
.option('--interactive', 'Interactive mode', false)
|
|
10
|
+
.action(async (name, options) => {
|
|
11
|
+
const { generatePersona } = await import('zouroboros-personas');
|
|
12
|
+
if (options.interactive) {
|
|
13
|
+
console.log(chalk.cyan(`\n🎭 Creating persona: ${name}\n`));
|
|
14
|
+
// Interactive mode would go here
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
const slug = name.toLowerCase().replace(/\s+/g, '-');
|
|
18
|
+
const config = {
|
|
19
|
+
name,
|
|
20
|
+
slug,
|
|
21
|
+
domain: options.domain,
|
|
22
|
+
description: `${name} persona for ${options.domain} domain`,
|
|
23
|
+
expertise: [],
|
|
24
|
+
requiresApiKey: false,
|
|
25
|
+
safetyRules: [],
|
|
26
|
+
capabilities: [],
|
|
27
|
+
};
|
|
28
|
+
const genOptions = {
|
|
29
|
+
outputDir: process.cwd(),
|
|
30
|
+
};
|
|
31
|
+
const result = await generatePersona(config, genOptions);
|
|
32
|
+
const files = result.filter((r) => r.output).map((r) => r.output);
|
|
33
|
+
console.log(chalk.green(`✅ Persona '${name}' created`));
|
|
34
|
+
console.log(chalk.gray(` Phases: ${result.length} completed`));
|
|
35
|
+
if (files.length > 0) {
|
|
36
|
+
console.log(chalk.gray(` Output: ${files.join(', ')}`));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}))
|
|
40
|
+
.addCommand(new Command('list')
|
|
41
|
+
.description('List all personas')
|
|
42
|
+
.action(() => {
|
|
43
|
+
console.log(chalk.cyan('\nAvailable Personas:\n'));
|
|
44
|
+
console.log('Run with --interactive to create one.\n');
|
|
45
|
+
}));
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { spawn } from 'child_process';
|
|
3
|
+
import { resolve } from 'path';
|
|
4
|
+
const REPO_ROOT = resolve(import.meta.dirname || __dirname, '../../..');
|
|
5
|
+
export const skillsCommand = new Command('skills')
|
|
6
|
+
.description('Manage Zouroboros skills')
|
|
7
|
+
.addCommand(new Command('install')
|
|
8
|
+
.description('Export skills to ~/Skills/ (or custom directory)')
|
|
9
|
+
.option('--dest <dir>', 'Target directory (default: ~/Skills)')
|
|
10
|
+
.option('--skill <name>', 'Install a single skill by name')
|
|
11
|
+
.action((options) => {
|
|
12
|
+
const args = [];
|
|
13
|
+
if (options.dest)
|
|
14
|
+
args.push('--dest', options.dest);
|
|
15
|
+
if (options.skill)
|
|
16
|
+
args.push('--skill', options.skill);
|
|
17
|
+
spawn('bash', [resolve(REPO_ROOT, 'scripts/export-skills.sh'), ...args], {
|
|
18
|
+
stdio: 'inherit',
|
|
19
|
+
});
|
|
20
|
+
}))
|
|
21
|
+
.addCommand(new Command('list')
|
|
22
|
+
.description('List available skills')
|
|
23
|
+
.action(() => {
|
|
24
|
+
console.log(`
|
|
25
|
+
Zouroboros Skills
|
|
26
|
+
═════════════════
|
|
27
|
+
|
|
28
|
+
Workflow Skills (packages/workflow):
|
|
29
|
+
spec-first-interview Socratic interview & seed specification generator
|
|
30
|
+
three-stage-eval Mechanical/semantic/consensus evaluation pipeline
|
|
31
|
+
autoloop Single-metric optimization loop (inspired by autoresearch)
|
|
32
|
+
unstuck-lateral 5 lateral-thinking personas for creative problem solving
|
|
33
|
+
|
|
34
|
+
Self-Enhancement Skills (packages/selfheal):
|
|
35
|
+
zouroboros-introspect 7-metric health scorecard for Zo ecosystem
|
|
36
|
+
zouroboros-prescribe Auto-generate improvement prescriptions from scorecard
|
|
37
|
+
zouroboros-evolve Execute prescriptions with regression detection
|
|
38
|
+
|
|
39
|
+
Core System Skills:
|
|
40
|
+
zo-swarm-orchestrator Multi-agent swarm orchestration with DAG execution
|
|
41
|
+
zo-memory-system Hybrid SQLite + vector memory engine
|
|
42
|
+
|
|
43
|
+
Install:
|
|
44
|
+
zouroboros skills install # Export all to ~/Skills/
|
|
45
|
+
zouroboros skills install --skill autoloop # Export one skill
|
|
46
|
+
zouroboros skills install --dest ./my-skills # Custom directory
|
|
47
|
+
`);
|
|
48
|
+
}));
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
export const swarmCommand = new Command('swarm')
|
|
5
|
+
.description('Swarm orchestration commands')
|
|
6
|
+
.addCommand(new Command('run')
|
|
7
|
+
.description('Run a swarm campaign')
|
|
8
|
+
.argument('<tasks-file>', 'JSON file with tasks')
|
|
9
|
+
.option('--strategy <strategy>', 'Routing strategy', 'balanced')
|
|
10
|
+
.option('--max-concurrent <n>', 'Max concurrent tasks', '8')
|
|
11
|
+
.action(async (tasksFile, options) => {
|
|
12
|
+
if (!existsSync(tasksFile)) {
|
|
13
|
+
console.log(chalk.red(`Error: Tasks file not found: ${tasksFile}`));
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
// Import and run orchestrator
|
|
17
|
+
const { SwarmOrchestrator } = await import('zouroboros-swarm');
|
|
18
|
+
const orchestrator = new SwarmOrchestrator({
|
|
19
|
+
routingStrategy: options.strategy,
|
|
20
|
+
localConcurrency: parseInt(options.maxConcurrent),
|
|
21
|
+
});
|
|
22
|
+
const { readFileSync } = await import('fs');
|
|
23
|
+
const tasks = JSON.parse(readFileSync(tasksFile, 'utf-8'));
|
|
24
|
+
const results = await orchestrator.run(tasks);
|
|
25
|
+
const successCount = results.filter((r) => r.success).length;
|
|
26
|
+
console.log(chalk.green(`\n✅ Campaign complete: ${successCount}/${results.length} tasks succeeded`));
|
|
27
|
+
}))
|
|
28
|
+
.addCommand(new Command('status')
|
|
29
|
+
.description('Check swarm status')
|
|
30
|
+
.action(() => {
|
|
31
|
+
console.log(chalk.cyan('Swarm status: Ready'));
|
|
32
|
+
}));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { spawn } from 'child_process';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
export const tuiCommand = new Command('tui')
|
|
5
|
+
.description('Launch Terminal User Interface dashboard')
|
|
6
|
+
.action(() => {
|
|
7
|
+
// Launch the TUI from the separate tui package
|
|
8
|
+
spawn('bun', [join(__dirname, '../../../tui/src/index.ts')], {
|
|
9
|
+
stdio: 'inherit'
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { spawn } from 'child_process';
|
|
3
|
+
import { join, resolve } from 'path';
|
|
4
|
+
const PACKAGES = resolve(import.meta.dirname || __dirname, '../../../packages');
|
|
5
|
+
function runCli(pkg, cli, args = []) {
|
|
6
|
+
spawn('bun', [join(PACKAGES, pkg, 'src/cli', `${cli}.ts`), ...args], {
|
|
7
|
+
stdio: 'inherit',
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export const workflowCommand = new Command('workflow')
|
|
11
|
+
.description('Workflow tools (interview, evaluate, unstuck, autoloop)')
|
|
12
|
+
.addCommand(new Command('interview')
|
|
13
|
+
.description('Run spec-first interview')
|
|
14
|
+
.option('--topic <topic>', 'Interview topic')
|
|
15
|
+
.action((options) => {
|
|
16
|
+
const args = options.topic ? ['--topic', options.topic] : [];
|
|
17
|
+
runCli('workflow', 'interview', args);
|
|
18
|
+
}))
|
|
19
|
+
.addCommand(new Command('evaluate')
|
|
20
|
+
.description('Run three-stage evaluation')
|
|
21
|
+
.requiredOption('--seed <path>', 'Seed specification file')
|
|
22
|
+
.requiredOption('--artifact <path>', 'Artifact to evaluate')
|
|
23
|
+
.action((options) => {
|
|
24
|
+
runCli('workflow', 'evaluate', ['--seed', options.seed, '--artifact', options.artifact]);
|
|
25
|
+
}))
|
|
26
|
+
.addCommand(new Command('unstuck')
|
|
27
|
+
.description('Run unstuck lateral thinking')
|
|
28
|
+
.argument('<problem>', 'Description of what you are stuck on')
|
|
29
|
+
.action((problem) => {
|
|
30
|
+
runCli('workflow', 'unstuck', [problem]);
|
|
31
|
+
}))
|
|
32
|
+
.addCommand(new Command('autoloop')
|
|
33
|
+
.description('Run autoloop optimization')
|
|
34
|
+
.requiredOption('--program <path>', 'Program.md file')
|
|
35
|
+
.action((options) => {
|
|
36
|
+
runCli('workflow', 'autoloop', ['--program', options.program]);
|
|
37
|
+
}));
|
|
38
|
+
export const selfhealCommand = new Command('selfheal')
|
|
39
|
+
.description('Self-enhancement tools (introspect, prescribe, evolve)')
|
|
40
|
+
.addCommand(new Command('introspect')
|
|
41
|
+
.description('Run 7-metric health scorecard')
|
|
42
|
+
.option('--json', 'Output raw JSON')
|
|
43
|
+
.option('--store', 'Persist scorecard')
|
|
44
|
+
.option('--verbose', 'Print formatted table')
|
|
45
|
+
.action((options) => {
|
|
46
|
+
const args = [];
|
|
47
|
+
if (options.json)
|
|
48
|
+
args.push('--json');
|
|
49
|
+
if (options.store)
|
|
50
|
+
args.push('--store');
|
|
51
|
+
if (options.verbose)
|
|
52
|
+
args.push('--verbose');
|
|
53
|
+
runCli('selfheal', 'introspect', args);
|
|
54
|
+
}))
|
|
55
|
+
.addCommand(new Command('prescribe')
|
|
56
|
+
.description('Generate improvement prescription')
|
|
57
|
+
.option('--scorecard <path>', 'Path to scorecard JSON')
|
|
58
|
+
.option('--target <metric>', 'Target metric name')
|
|
59
|
+
.option('--live', 'Run live introspection')
|
|
60
|
+
.option('--dry-run', 'Preview without writing')
|
|
61
|
+
.action((options) => {
|
|
62
|
+
const args = [];
|
|
63
|
+
if (options.scorecard)
|
|
64
|
+
args.push('--scorecard', options.scorecard);
|
|
65
|
+
if (options.target)
|
|
66
|
+
args.push('--target', options.target);
|
|
67
|
+
if (options.live)
|
|
68
|
+
args.push('--live');
|
|
69
|
+
if (options.dryRun)
|
|
70
|
+
args.push('--dry-run');
|
|
71
|
+
runCli('selfheal', 'prescribe', args);
|
|
72
|
+
}))
|
|
73
|
+
.addCommand(new Command('evolve')
|
|
74
|
+
.description('Execute prescription with regression detection')
|
|
75
|
+
.option('--prescription <path>', 'Path to prescription JSON')
|
|
76
|
+
.option('--dry-run', 'Preview without changes')
|
|
77
|
+
.option('--skip-governor', 'Bypass governor safety gate')
|
|
78
|
+
.action((options) => {
|
|
79
|
+
const args = [];
|
|
80
|
+
if (options.prescription)
|
|
81
|
+
args.push('--prescription', options.prescription);
|
|
82
|
+
if (options.dryRun)
|
|
83
|
+
args.push('--dry-run');
|
|
84
|
+
if (options.skipGovernor)
|
|
85
|
+
args.push('--skip-governor');
|
|
86
|
+
runCli('selfheal', 'evolve', args);
|
|
87
|
+
}));
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Zouroboros CLI
|
|
4
|
+
*
|
|
5
|
+
* Unified command-line interface for all Zouroboros packages.
|
|
6
|
+
*
|
|
7
|
+
* @module zouroboros-cli
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
import chalk from 'chalk';
|
|
11
|
+
import { VERSION } from 'zouroboros-core';
|
|
12
|
+
// Import commands
|
|
13
|
+
import { initCommand } from './commands/init.js';
|
|
14
|
+
import { doctorCommand } from './commands/doctor.js';
|
|
15
|
+
import { configCommand } from './commands/config.js';
|
|
16
|
+
import { memoryCommand } from './commands/memory.js';
|
|
17
|
+
import { swarmCommand } from './commands/swarm.js';
|
|
18
|
+
import { personaCommand } from './commands/persona.js';
|
|
19
|
+
import { workflowCommand, selfhealCommand } from './commands/workflow.js';
|
|
20
|
+
import { healCommand } from './commands/heal.js';
|
|
21
|
+
import { tuiCommand } from './commands/tui.js';
|
|
22
|
+
import { backupCommand } from './commands/backup.js';
|
|
23
|
+
import { migrateCommand } from './commands/migrate.js';
|
|
24
|
+
import { skillsCommand } from './commands/skills.js';
|
|
25
|
+
import { agentsCommand } from './commands/agents.js';
|
|
26
|
+
const program = new Command();
|
|
27
|
+
program
|
|
28
|
+
.name('zouroboros')
|
|
29
|
+
.description('🐍⭕ Zouroboros - Self-enhancing AI memory and orchestration system')
|
|
30
|
+
.version(VERSION, '-v, --version', 'Display version number')
|
|
31
|
+
.helpOption('-h, --help', 'Display help for command')
|
|
32
|
+
.configureOutput({
|
|
33
|
+
writeOut: (str) => process.stdout.write(str),
|
|
34
|
+
writeErr: (str) => process.stderr.write(str),
|
|
35
|
+
});
|
|
36
|
+
// Global options
|
|
37
|
+
program
|
|
38
|
+
.option('--config <path>', 'Path to config file')
|
|
39
|
+
.option('--verbose', 'Enable verbose output')
|
|
40
|
+
.option('--json', 'Output as JSON');
|
|
41
|
+
// Register commands
|
|
42
|
+
program.addCommand(initCommand);
|
|
43
|
+
program.addCommand(doctorCommand);
|
|
44
|
+
program.addCommand(configCommand);
|
|
45
|
+
program.addCommand(memoryCommand);
|
|
46
|
+
program.addCommand(swarmCommand);
|
|
47
|
+
program.addCommand(personaCommand);
|
|
48
|
+
program.addCommand(workflowCommand);
|
|
49
|
+
program.addCommand(selfhealCommand);
|
|
50
|
+
program.addCommand(healCommand);
|
|
51
|
+
program.addCommand(tuiCommand);
|
|
52
|
+
program.addCommand(backupCommand);
|
|
53
|
+
program.addCommand(migrateCommand);
|
|
54
|
+
program.addCommand(skillsCommand);
|
|
55
|
+
program.addCommand(agentsCommand);
|
|
56
|
+
// Default action (no command)
|
|
57
|
+
program.action(() => {
|
|
58
|
+
console.log(chalk.cyan('\n🐍⭕ Zouroboros'));
|
|
59
|
+
console.log(chalk.gray('Self-enhancing AI memory and orchestration system\n'));
|
|
60
|
+
console.log('Run ' + chalk.yellow('zouroboros --help') + ' for available commands\n');
|
|
61
|
+
});
|
|
62
|
+
// Error handling
|
|
63
|
+
program.exitOverride();
|
|
64
|
+
try {
|
|
65
|
+
await program.parseAsync();
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
if (err.code === 'commander.help') {
|
|
69
|
+
process.exit(0);
|
|
70
|
+
}
|
|
71
|
+
if (err.code === 'commander.version') {
|
|
72
|
+
process.exit(0);
|
|
73
|
+
}
|
|
74
|
+
if (err.code === 'commander.unknownOption') {
|
|
75
|
+
console.error(chalk.red(`Error: ${err.message}`));
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
if (err.code === 'commander.missingArgument') {
|
|
79
|
+
console.error(chalk.red(`Error: ${err.message}`));
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
throw err;
|
|
83
|
+
}
|