@overlordai/cli 1.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.
Files changed (61) hide show
  1. package/dist/commands/doctor.d.ts +2 -0
  2. package/dist/commands/doctor.d.ts.map +1 -0
  3. package/dist/commands/doctor.js +97 -0
  4. package/dist/commands/doctor.js.map +1 -0
  5. package/dist/commands/install.d.ts +2 -0
  6. package/dist/commands/install.d.ts.map +1 -0
  7. package/dist/commands/install.js +19 -0
  8. package/dist/commands/install.js.map +1 -0
  9. package/dist/commands/logs.d.ts +4 -0
  10. package/dist/commands/logs.d.ts.map +1 -0
  11. package/dist/commands/logs.js +21 -0
  12. package/dist/commands/logs.js.map +1 -0
  13. package/dist/commands/start.d.ts +2 -0
  14. package/dist/commands/start.d.ts.map +1 -0
  15. package/dist/commands/start.js +28 -0
  16. package/dist/commands/start.js.map +1 -0
  17. package/dist/commands/status.d.ts +2 -0
  18. package/dist/commands/status.d.ts.map +1 -0
  19. package/dist/commands/status.js +66 -0
  20. package/dist/commands/status.js.map +1 -0
  21. package/dist/commands/stop.d.ts +2 -0
  22. package/dist/commands/stop.d.ts.map +1 -0
  23. package/dist/commands/stop.js +30 -0
  24. package/dist/commands/stop.js.map +1 -0
  25. package/dist/commands/upgrade.d.ts +4 -0
  26. package/dist/commands/upgrade.d.ts.map +1 -0
  27. package/dist/commands/upgrade.js +158 -0
  28. package/dist/commands/upgrade.js.map +1 -0
  29. package/dist/installer/admin-creator.d.ts +19 -0
  30. package/dist/installer/admin-creator.d.ts.map +1 -0
  31. package/dist/installer/admin-creator.js +34 -0
  32. package/dist/installer/admin-creator.js.map +1 -0
  33. package/dist/installer/config-writer.d.ts +16 -0
  34. package/dist/installer/config-writer.d.ts.map +1 -0
  35. package/dist/installer/config-writer.js +61 -0
  36. package/dist/installer/config-writer.js.map +1 -0
  37. package/dist/installer/db-initializer.d.ts +18 -0
  38. package/dist/installer/db-initializer.d.ts.map +1 -0
  39. package/dist/installer/db-initializer.js +81 -0
  40. package/dist/installer/db-initializer.js.map +1 -0
  41. package/dist/installer/env-checker.d.ts +44 -0
  42. package/dist/installer/env-checker.d.ts.map +1 -0
  43. package/dist/installer/env-checker.js +135 -0
  44. package/dist/installer/env-checker.js.map +1 -0
  45. package/dist/installer/secret-gen.d.ts +27 -0
  46. package/dist/installer/secret-gen.d.ts.map +1 -0
  47. package/dist/installer/secret-gen.js +35 -0
  48. package/dist/installer/secret-gen.js.map +1 -0
  49. package/dist/installer/wizard.d.ts +12 -0
  50. package/dist/installer/wizard.d.ts.map +1 -0
  51. package/dist/installer/wizard.js +213 -0
  52. package/dist/installer/wizard.js.map +1 -0
  53. package/dist/main.d.ts +3 -0
  54. package/dist/main.d.ts.map +1 -0
  55. package/dist/main.js +49 -0
  56. package/dist/main.js.map +1 -0
  57. package/dist/process-manager.d.ts +36 -0
  58. package/dist/process-manager.d.ts.map +1 -0
  59. package/dist/process-manager.js +111 -0
  60. package/dist/process-manager.js.map +1 -0
  61. package/package.json +34 -0
@@ -0,0 +1,2 @@
1
+ export declare function doctorCommand(): Promise<void>;
2
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAyBA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAqFnD"}
@@ -0,0 +1,97 @@
1
+ import chalk from 'chalk';
2
+ import * as fs from 'node:fs';
3
+ import * as path from 'node:path';
4
+ import { EnvChecker } from '../installer/env-checker.js';
5
+ import { ProcessManager } from '../process-manager.js';
6
+ function printResult(label, result, summary) {
7
+ if (result.ok) {
8
+ console.log(` ${chalk.green('\u2713')} ${label}: ${result.detail ?? 'OK'}`);
9
+ summary.passed++;
10
+ }
11
+ else if (result.optional) {
12
+ console.log(` ${chalk.yellow('!')} ${label}: ${result.detail ?? 'not found'} (optional)`);
13
+ summary.warnings++;
14
+ }
15
+ else {
16
+ console.log(` ${chalk.red('\u2717')} ${label}: ${result.detail ?? 'FAILED'}`);
17
+ summary.errors++;
18
+ }
19
+ }
20
+ export async function doctorCommand() {
21
+ console.log(chalk.bold('\nOverlord System Diagnostics\n'));
22
+ const checker = new EnvChecker();
23
+ const pm = new ProcessManager();
24
+ const summary = { passed: 0, warnings: 0, errors: 0 };
25
+ // System info
26
+ console.log(chalk.bold('System'));
27
+ console.log(` OS: ${process.platform} ${process.arch}`);
28
+ console.log(` Node.js: ${process.version}`);
29
+ console.log();
30
+ // Prerequisites
31
+ console.log(chalk.bold('Prerequisites'));
32
+ printResult('Git', checker.checkGit(), summary);
33
+ printResult('Node.js', checker.checkNode(), summary);
34
+ printResult('Disk space', checker.checkDiskSpace(process.cwd()), summary);
35
+ console.log();
36
+ // Ports
37
+ console.log(chalk.bold('Network'));
38
+ const port9000 = await checker.checkPort(9000);
39
+ const port9100 = await checker.checkPort(9100);
40
+ printResult('Port 9000 (server)', port9000, summary);
41
+ printResult('Port 9100 (worker diag)', port9100, summary);
42
+ console.log();
43
+ // Optional tools
44
+ console.log(chalk.bold('Optional CLI Tools'));
45
+ printResult('claude CLI', checker.checkClaudeCli(), summary);
46
+ printResult('agent CLI', checker.checkCursorCli(), summary);
47
+ printResult('code CLI', checker.checkCodeCli(), summary);
48
+ console.log();
49
+ // Configuration
50
+ console.log(chalk.bold('Configuration'));
51
+ const envPath = path.join(process.cwd(), '.env');
52
+ if (fs.existsSync(envPath)) {
53
+ console.log(` ${chalk.green('\u2713')} .env file exists`);
54
+ summary.passed++;
55
+ }
56
+ else {
57
+ console.log(` ${chalk.red('\u2717')} .env file not found`);
58
+ summary.errors++;
59
+ }
60
+ console.log();
61
+ // PM2 status
62
+ console.log(chalk.bold('PM2 Processes'));
63
+ const procs = await pm.list();
64
+ const overlordProcs = procs.filter((p) => p.name.startsWith('overlord-'));
65
+ if (overlordProcs.length === 0 && procs.length > 0) {
66
+ console.log(` ${chalk.yellow('!')} Orphan PM2 daemon detected (no Overlord processes but daemon running)`);
67
+ console.log(` Run ${chalk.cyan('overlord stop')} to clean up.`);
68
+ summary.warnings++;
69
+ }
70
+ else if (overlordProcs.length > 0) {
71
+ for (const proc of overlordProcs) {
72
+ const status = proc.status === 'online'
73
+ ? chalk.green(proc.status)
74
+ : chalk.red(proc.status);
75
+ console.log(` ${proc.name}: ${status} (PID: ${proc.pid})`);
76
+ if (proc.status === 'errored') {
77
+ summary.errors++;
78
+ }
79
+ else {
80
+ summary.passed++;
81
+ }
82
+ }
83
+ }
84
+ else {
85
+ console.log(` ${chalk.dim('No processes running')}`);
86
+ }
87
+ console.log();
88
+ // Summary
89
+ console.log(chalk.bold('Summary'));
90
+ console.log(` ${chalk.green(`${summary.passed} passed`)}` +
91
+ ` ${chalk.yellow(`${summary.warnings} warnings`)}` +
92
+ ` ${chalk.red(`${summary.errors} errors`)}`);
93
+ if (summary.errors > 0) {
94
+ process.exitCode = 1;
95
+ }
96
+ }
97
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function installCommand(): Promise<void>;
2
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAIA,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAgBpD"}
@@ -0,0 +1,19 @@
1
+ import * as p from '@clack/prompts';
2
+ import chalk from 'chalk';
3
+ import { InstallWizard } from '../installer/wizard.js';
4
+ export async function installCommand() {
5
+ p.intro(chalk.bold('Overlord Installation Wizard'));
6
+ const wizard = new InstallWizard();
7
+ try {
8
+ await wizard.run();
9
+ }
10
+ catch (err) {
11
+ p.cancel('Installation cancelled.');
12
+ if (err instanceof Error && err.message !== 'cancelled') {
13
+ console.error(chalk.red(`Error: ${err.message}`));
14
+ }
15
+ process.exit(1);
16
+ }
17
+ p.outro(chalk.green('Installation complete!'));
18
+ }
19
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC,CAAC;IAEpD,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;IAEnC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;IACrB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,CAAC,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC;QACpC,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function logsCommand(component: string, options: {
2
+ lines?: string;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAGA,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CAqBf"}
@@ -0,0 +1,21 @@
1
+ import chalk from 'chalk';
2
+ import { ProcessManager } from '../process-manager.js';
3
+ export async function logsCommand(component, options) {
4
+ const pm = new ProcessManager();
5
+ const processName = component === 'worker' ? 'overlord-worker' : 'overlord-server';
6
+ const lines = parseInt(options.lines ?? '50', 10);
7
+ console.log(chalk.blue(`Tailing logs for ${processName} (last ${lines} lines)...`));
8
+ console.log(chalk.dim('Press Ctrl+C to stop.\n'));
9
+ const child = await pm.logs(processName, lines);
10
+ // Handle graceful exit
11
+ process.on('SIGINT', () => {
12
+ child.kill('SIGTERM');
13
+ process.exit(0);
14
+ });
15
+ child.on('exit', (code) => {
16
+ if (code !== 0 && code !== null) {
17
+ console.error(chalk.red(`\nLog stream exited with code ${code}`));
18
+ }
19
+ });
20
+ }
21
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,SAAiB,EACjB,OAA2B;IAE3B,MAAM,EAAE,GAAG,IAAI,cAAc,EAAE,CAAC;IAChC,MAAM,WAAW,GAAG,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,iBAAiB,CAAC;IACnF,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;IAElD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,WAAW,UAAU,KAAK,YAAY,CAAC,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAElD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAEhD,uBAAuB;IACvB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACxB,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function startCommand(component: string): Promise<void>;
2
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAGA,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BnE"}
@@ -0,0 +1,28 @@
1
+ import chalk from 'chalk';
2
+ import { ProcessManager } from '../process-manager.js';
3
+ export async function startCommand(component) {
4
+ const pm = new ProcessManager();
5
+ console.log(chalk.blue(`Starting ${component}...`));
6
+ if (component === 'all' || component === 'server') {
7
+ await pm.start({
8
+ name: 'overlord-server',
9
+ script: 'dist/main.js',
10
+ cwd: process.env.OVERLORD_SERVER_DIR,
11
+ instances: 1,
12
+ waitReady: true,
13
+ });
14
+ console.log(chalk.green(' overlord-server started'));
15
+ }
16
+ if (component === 'all' || component === 'worker') {
17
+ await pm.start({
18
+ name: 'overlord-worker',
19
+ script: 'dist/main.js',
20
+ cwd: process.env.OVERLORD_WORKER_DIR,
21
+ waitReady: true,
22
+ });
23
+ console.log(chalk.green(' overlord-worker started'));
24
+ }
25
+ await pm.dump();
26
+ console.log(chalk.green('\nAll processes started. Run `overlord status` to verify.'));
27
+ }
28
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB;IAClD,MAAM,EAAE,GAAG,IAAI,cAAc,EAAE,CAAC;IAEhC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,SAAS,KAAK,CAAC,CAAC,CAAC;IAEpD,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QAClD,MAAM,EAAE,CAAC,KAAK,CAAC;YACb,IAAI,EAAE,iBAAiB;YACvB,MAAM,EAAE,cAAc;YACtB,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;YACpC,SAAS,EAAE,CAAC;YACZ,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QAClD,MAAM,EAAE,CAAC,KAAK,CAAC;YACb,IAAI,EAAE,iBAAiB;YACvB,MAAM,EAAE,cAAc;YACtB,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;YACpC,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC,CAAC;AACxF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function statusCommand(): Promise<void>;
2
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAmCA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAuCnD"}
@@ -0,0 +1,66 @@
1
+ import chalk from 'chalk';
2
+ import { ProcessManager } from '../process-manager.js';
3
+ function formatUptime(ms) {
4
+ const seconds = Math.floor(ms / 1000);
5
+ const minutes = Math.floor(seconds / 60);
6
+ const hours = Math.floor(minutes / 60);
7
+ const days = Math.floor(hours / 24);
8
+ if (days > 0)
9
+ return `${days}d ${hours % 24}h`;
10
+ if (hours > 0)
11
+ return `${hours}h ${minutes % 60}m`;
12
+ if (minutes > 0)
13
+ return `${minutes}m ${seconds % 60}s`;
14
+ return `${seconds}s`;
15
+ }
16
+ function formatMemory(bytes) {
17
+ const mb = bytes / (1024 * 1024);
18
+ return `${mb.toFixed(1)} MB`;
19
+ }
20
+ function statusColor(status) {
21
+ switch (status) {
22
+ case 'online':
23
+ return chalk.green(status);
24
+ case 'stopping':
25
+ return chalk.yellow(status);
26
+ case 'stopped':
27
+ return chalk.red(status);
28
+ case 'errored':
29
+ return chalk.red(status);
30
+ default:
31
+ return chalk.dim(status);
32
+ }
33
+ }
34
+ export async function statusCommand() {
35
+ const pm = new ProcessManager();
36
+ const processes = await pm.list();
37
+ const overlordProcs = processes.filter((p) => p.name.startsWith('overlord-'));
38
+ if (overlordProcs.length === 0) {
39
+ console.log(chalk.yellow('No Overlord processes running.'));
40
+ console.log(chalk.dim('Run `overlord start` to start services.'));
41
+ return;
42
+ }
43
+ // Table header
44
+ const header = [
45
+ 'Name'.padEnd(20),
46
+ 'PID'.padStart(7),
47
+ 'Status'.padEnd(10),
48
+ 'CPU'.padStart(6),
49
+ 'Memory'.padStart(10),
50
+ 'Uptime'.padStart(10),
51
+ ].join(' ');
52
+ console.log(chalk.bold(header));
53
+ console.log('-'.repeat(header.length));
54
+ for (const proc of overlordProcs) {
55
+ const row = [
56
+ proc.name.padEnd(20),
57
+ String(proc.pid).padStart(7),
58
+ statusColor(proc.status).padEnd(10 + (statusColor(proc.status).length - proc.status.length)),
59
+ `${proc.cpu}%`.padStart(6),
60
+ formatMemory(proc.memory).padStart(10),
61
+ formatUptime(proc.uptime).padStart(10),
62
+ ].join(' ');
63
+ console.log(row);
64
+ }
65
+ }
66
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function stopCommand(component: string): Promise<void>;
2
+ //# sourceMappingURL=stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAGA,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmClE"}
@@ -0,0 +1,30 @@
1
+ import chalk from 'chalk';
2
+ import { ProcessManager } from '../process-manager.js';
3
+ export async function stopCommand(component) {
4
+ const pm = new ProcessManager();
5
+ console.log(chalk.blue(`Stopping ${component}...`));
6
+ if (component === 'all' || component === 'worker') {
7
+ await pm.stop('overlord-worker');
8
+ console.log(chalk.yellow(' overlord-worker stopped'));
9
+ }
10
+ if (component === 'all' || component === 'server') {
11
+ await pm.stop('overlord-server');
12
+ console.log(chalk.yellow(' overlord-server stopped'));
13
+ }
14
+ // Check if PM2 daemon should be cleaned up
15
+ const remaining = await pm.list();
16
+ const overlordProcesses = remaining.filter((p) => p.name === 'overlord-server' || p.name === 'overlord-worker');
17
+ if (overlordProcesses.length === 0 && component === 'all') {
18
+ // Delete stopped processes
19
+ await pm.delete('overlord-server');
20
+ await pm.delete('overlord-worker');
21
+ // Kill daemon if no other processes remain
22
+ const allProcs = await pm.list();
23
+ if (allProcs.length === 0) {
24
+ console.log(chalk.dim(' Cleaning up PM2 daemon...'));
25
+ await pm.killDaemon();
26
+ }
27
+ }
28
+ console.log(chalk.green('\nAll processes stopped.'));
29
+ }
30
+ //# sourceMappingURL=stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,SAAiB;IACjD,MAAM,EAAE,GAAG,IAAI,cAAc,EAAE,CAAC;IAEhC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,SAAS,KAAK,CAAC,CAAC,CAAC;IAEpD,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QAClD,MAAM,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QAClD,MAAM,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,2CAA2C;IAC3C,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;IAClC,MAAM,iBAAiB,GAAG,SAAS,CAAC,MAAM,CACxC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,IAAI,CAAC,CAAC,IAAI,KAAK,iBAAiB,CACpE,CAAC;IAEF,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;QAC1D,2BAA2B;QAC3B,MAAM,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;QACnC,MAAM,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAEnC,2CAA2C;QAC3C,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC,CAAC;YACtD,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;AACvD,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function upgradeCommand(options: {
2
+ rollback?: boolean;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=upgrade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAwFA,wBAAsB,cAAc,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmGnF"}
@@ -0,0 +1,158 @@
1
+ import chalk from 'chalk';
2
+ import * as fs from 'node:fs';
3
+ import * as path from 'node:path';
4
+ import * as https from 'node:https';
5
+ import * as crypto from 'node:crypto';
6
+ import { ProcessManager } from '../process-manager.js';
7
+ function getPlatformSuffix() {
8
+ const platform = process.platform;
9
+ const arch = process.arch;
10
+ if (platform === 'linux' && arch === 'x64')
11
+ return 'linux-x64';
12
+ if (platform === 'darwin' && arch === 'x64')
13
+ return 'macos-x64';
14
+ if (platform === 'darwin' && arch === 'arm64')
15
+ return 'macos-arm64';
16
+ throw new Error(`Unsupported platform: ${platform}-${arch}`);
17
+ }
18
+ function httpsGet(url) {
19
+ return new Promise((resolve, reject) => {
20
+ const request = https.get(url, { headers: { 'User-Agent': 'overlord-cli' } }, (res) => {
21
+ // Follow redirects
22
+ if (res.statusCode === 301 || res.statusCode === 302) {
23
+ const redirectUrl = res.headers.location;
24
+ if (redirectUrl) {
25
+ httpsGet(redirectUrl).then(resolve, reject);
26
+ return;
27
+ }
28
+ }
29
+ if (res.statusCode !== 200) {
30
+ reject(new Error(`HTTP ${res.statusCode}`));
31
+ return;
32
+ }
33
+ let data = '';
34
+ res.on('data', (chunk) => { data += chunk.toString(); });
35
+ res.on('end', () => resolve(data));
36
+ });
37
+ request.on('error', reject);
38
+ });
39
+ }
40
+ function httpsDownload(url, dest) {
41
+ return new Promise((resolve, reject) => {
42
+ const request = https.get(url, { headers: { 'User-Agent': 'overlord-cli' } }, (res) => {
43
+ if (res.statusCode === 301 || res.statusCode === 302) {
44
+ const redirectUrl = res.headers.location;
45
+ if (redirectUrl) {
46
+ httpsDownload(redirectUrl, dest).then(resolve, reject);
47
+ return;
48
+ }
49
+ }
50
+ if (res.statusCode !== 200) {
51
+ reject(new Error(`HTTP ${res.statusCode}`));
52
+ return;
53
+ }
54
+ const file = fs.createWriteStream(dest);
55
+ res.pipe(file);
56
+ file.on('finish', () => { file.close(); resolve(); });
57
+ });
58
+ request.on('error', reject);
59
+ });
60
+ }
61
+ async function fetchLatestRelease() {
62
+ const url = 'https://api.github.com/repos/nicepkg/overlord/releases/latest';
63
+ const body = await httpsGet(url);
64
+ return JSON.parse(body);
65
+ }
66
+ function verifySha256(filePath, expectedHash) {
67
+ const fileBuffer = fs.readFileSync(filePath);
68
+ const hash = crypto.createHash('sha256').update(fileBuffer).digest('hex');
69
+ return hash === expectedHash;
70
+ }
71
+ export async function upgradeCommand(options) {
72
+ const pm = new ProcessManager();
73
+ if (options.rollback) {
74
+ console.log(chalk.blue('Rolling back to previous version...'));
75
+ const binaryPath = process.execPath;
76
+ const backupPath = binaryPath + '.bak';
77
+ if (!fs.existsSync(backupPath)) {
78
+ console.error(chalk.red('No backup binary found. Cannot rollback.'));
79
+ process.exit(1);
80
+ }
81
+ fs.copyFileSync(backupPath, binaryPath);
82
+ fs.chmodSync(binaryPath, 0o755);
83
+ await pm.restart('overlord-server');
84
+ await pm.restart('overlord-worker');
85
+ console.log(chalk.green('Rollback complete.'));
86
+ return;
87
+ }
88
+ console.log(chalk.blue('Checking for updates...'));
89
+ // Step 1: Fetch latest release
90
+ let release;
91
+ try {
92
+ release = await fetchLatestRelease();
93
+ }
94
+ catch (err) {
95
+ console.error(chalk.red(`Failed to check for updates: ${err instanceof Error ? err.message : String(err)}`));
96
+ process.exit(1);
97
+ }
98
+ console.log(`Latest version: ${chalk.cyan(release.tag_name)}`);
99
+ // Step 2: Find platform binary
100
+ const suffix = getPlatformSuffix();
101
+ const binaryAsset = release.assets.find((a) => a.name.includes(suffix) && !a.name.endsWith('.sha256'));
102
+ const checksumAsset = release.assets.find((a) => a.name.includes(suffix) && a.name.endsWith('.sha256'));
103
+ if (!binaryAsset) {
104
+ console.error(chalk.red(`No binary found for platform: ${suffix}`));
105
+ process.exit(1);
106
+ }
107
+ // Step 3: Download
108
+ const tmpDir = fs.mkdtempSync(path.join(process.env.TMPDIR ?? '/tmp', 'overlord-upgrade-'));
109
+ try {
110
+ const binaryDest = path.join(tmpDir, binaryAsset.name);
111
+ console.log(chalk.blue('Downloading binary...'));
112
+ await httpsDownload(binaryAsset.browser_download_url, binaryDest);
113
+ // Step 4: Verify SHA256
114
+ if (checksumAsset) {
115
+ console.log(chalk.blue('Verifying SHA256 checksum...'));
116
+ const checksumDest = path.join(tmpDir, checksumAsset.name);
117
+ await httpsDownload(checksumAsset.browser_download_url, checksumDest);
118
+ const expectedHash = fs.readFileSync(checksumDest, 'utf-8').trim().split(/\s+/)[0];
119
+ if (!expectedHash || !/^[a-fA-F0-9]{64}$/.test(expectedHash)) {
120
+ throw new Error('Checksum file is empty or malformed.');
121
+ }
122
+ if (!verifySha256(binaryDest, expectedHash)) {
123
+ throw new Error('SHA256 checksum verification failed!');
124
+ }
125
+ console.log(chalk.green('Checksum verified.'));
126
+ }
127
+ else {
128
+ console.log(chalk.yellow('No checksum file found, skipping verification.'));
129
+ }
130
+ // Step 5: Backup current binary
131
+ const currentBinary = process.execPath;
132
+ const backupPath = currentBinary + '.bak';
133
+ console.log(chalk.blue('Backing up current binary...'));
134
+ fs.copyFileSync(currentBinary, backupPath);
135
+ // Step 6: Replace binary
136
+ console.log(chalk.blue('Installing new binary...'));
137
+ fs.copyFileSync(binaryDest, currentBinary);
138
+ fs.chmodSync(currentBinary, 0o755);
139
+ // Step 7: Graceful restart
140
+ console.log(chalk.blue('Restarting services...'));
141
+ try {
142
+ await pm.restart('overlord-server');
143
+ await pm.restart('overlord-worker');
144
+ }
145
+ catch {
146
+ // Restart may fail if processes are not running
147
+ }
148
+ console.log(chalk.green(`\nUpgrade to ${release.tag_name} complete!`));
149
+ console.log(chalk.dim(`Backup saved at: ${backupPath}`));
150
+ console.log(chalk.dim('Run `overlord doctor` to verify system health.'));
151
+ console.log(chalk.dim('Run `overlord upgrade --rollback` if issues occur.'));
152
+ }
153
+ finally {
154
+ // Cleanup temp files regardless of success or failure
155
+ fs.rmSync(tmpDir, { recursive: true, force: true });
156
+ }
157
+ }
158
+ //# sourceMappingURL=upgrade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export interface AdminConfig {
2
+ username: string;
3
+ password: string;
4
+ gitName: string;
5
+ gitEmail: string;
6
+ }
7
+ /**
8
+ * Creates the initial admin developer account in the database.
9
+ */
10
+ export declare class AdminCreator {
11
+ /**
12
+ * Create an admin user in the developers table.
13
+ *
14
+ * @param dbPath - Absolute path to the SQLite database file.
15
+ * @param config - Admin account configuration.
16
+ */
17
+ create(dbPath: string, config: AdminConfig): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=admin-creator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-creator.d.ts","sourceRoot":"","sources":["../../src/installer/admin-creator.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB;;;;;OAKG;IACG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAwBjE"}
@@ -0,0 +1,34 @@
1
+ import Database from 'better-sqlite3';
2
+ import bcrypt from 'bcrypt';
3
+ import { BCRYPT_COST_FACTOR } from '@overlordai/protocol';
4
+ /**
5
+ * Creates the initial admin developer account in the database.
6
+ */
7
+ export class AdminCreator {
8
+ /**
9
+ * Create an admin user in the developers table.
10
+ *
11
+ * @param dbPath - Absolute path to the SQLite database file.
12
+ * @param config - Admin account configuration.
13
+ */
14
+ async create(dbPath, config) {
15
+ const db = new Database(dbPath);
16
+ try {
17
+ // Check for duplicate username
18
+ const existing = db
19
+ .prepare('SELECT id FROM developers WHERE name = ?')
20
+ .get(config.username);
21
+ if (existing) {
22
+ throw new Error(`Developer with name "${config.username}" already exists`);
23
+ }
24
+ // Hash password with bcrypt
25
+ const passwordHash = await bcrypt.hash(config.password, BCRYPT_COST_FACTOR);
26
+ db.prepare(`INSERT INTO developers (name, git_name, git_email, password_hash, role, status, platform_uids, created_at)
27
+ VALUES (?, ?, ?, ?, 'admin', 'active', '{}', datetime('now'))`).run(config.username, config.gitName, config.gitEmail, passwordHash);
28
+ }
29
+ finally {
30
+ db.close();
31
+ }
32
+ }
33
+ }
34
+ //# sourceMappingURL=admin-creator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-creator.js","sourceRoot":"","sources":["../../src/installer/admin-creator.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAS1D;;GAEG;AACH,MAAM,OAAO,YAAY;IACvB;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,MAAmB;QAC9C,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;QAEhC,IAAI,CAAC;YACH,+BAA+B;YAC/B,MAAM,QAAQ,GAAG,EAAE;iBAChB,OAAO,CAAC,0CAA0C,CAAC;iBACnD,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAExB,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,wBAAwB,MAAM,CAAC,QAAQ,kBAAkB,CAAC,CAAC;YAC7E,CAAC;YAED,4BAA4B;YAC5B,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;YAE5E,EAAE,CAAC,OAAO,CACR;uEAC+D,CAChE,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QACxE,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Writes and manages .env configuration files.
3
+ */
4
+ export declare class ConfigWriter {
5
+ /**
6
+ * Write a complete .env file with the given key-value pairs.
7
+ * Creates parent directories if needed. Sets file permissions to 600.
8
+ */
9
+ write(config: Record<string, string>, envPath: string): void;
10
+ /**
11
+ * Append or update a single key in an existing .env file.
12
+ * If the key already exists, it will be updated in place.
13
+ */
14
+ appendToEnv(key: string, value: string, envPath: string): void;
15
+ }
16
+ //# sourceMappingURL=config-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-writer.d.ts","sourceRoot":"","sources":["../../src/installer/config-writer.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,qBAAa,YAAY;IACvB;;;OAGG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAkB5D;;;OAGG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;CAkC/D"}