@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,61 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ /**
4
+ * Writes and manages .env configuration files.
5
+ */
6
+ export class ConfigWriter {
7
+ /**
8
+ * Write a complete .env file with the given key-value pairs.
9
+ * Creates parent directories if needed. Sets file permissions to 600.
10
+ */
11
+ write(config, envPath) {
12
+ const dir = path.dirname(envPath);
13
+ if (!fs.existsSync(dir)) {
14
+ fs.mkdirSync(dir, { recursive: true });
15
+ }
16
+ const lines = [];
17
+ for (const [key, value] of Object.entries(config)) {
18
+ // Quote values that contain special characters
19
+ const needsQuoting = /[\s#"'\\$`!]/.test(value);
20
+ const escapedValue = needsQuoting ? `"${value.replace(/["\\$`]/g, '\\$&')}"` : value;
21
+ lines.push(`${key}=${escapedValue}`);
22
+ }
23
+ fs.writeFileSync(envPath, lines.join('\n') + '\n', { encoding: 'utf-8' });
24
+ fs.chmodSync(envPath, 0o600);
25
+ }
26
+ /**
27
+ * Append or update a single key in an existing .env file.
28
+ * If the key already exists, it will be updated in place.
29
+ */
30
+ appendToEnv(key, value, envPath) {
31
+ const needsQuoting = /[\s#"'\\$`!]/.test(value);
32
+ const escapedValue = needsQuoting ? `"${value.replace(/["\\$`]/g, '\\$&')}"` : value;
33
+ const newLine = `${key}=${escapedValue}`;
34
+ if (!fs.existsSync(envPath)) {
35
+ fs.writeFileSync(envPath, newLine + '\n', { encoding: 'utf-8' });
36
+ fs.chmodSync(envPath, 0o600);
37
+ return;
38
+ }
39
+ const content = fs.readFileSync(envPath, 'utf-8');
40
+ const lines = content.split('\n');
41
+ const regex = new RegExp(`^${key}=`);
42
+ let found = false;
43
+ const updatedLines = lines.map((line) => {
44
+ if (regex.test(line)) {
45
+ found = true;
46
+ return newLine;
47
+ }
48
+ return line;
49
+ });
50
+ if (!found) {
51
+ // Append to end, ensuring there's a trailing newline
52
+ const trimmed = content.trimEnd();
53
+ fs.writeFileSync(envPath, trimmed + '\n' + newLine + '\n', { encoding: 'utf-8' });
54
+ }
55
+ else {
56
+ fs.writeFileSync(envPath, updatedLines.join('\n') + '\n', { encoding: 'utf-8' });
57
+ }
58
+ fs.chmodSync(envPath, 0o600);
59
+ }
60
+ }
61
+ //# sourceMappingURL=config-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-writer.js","sourceRoot":"","sources":["../../src/installer/config-writer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Initializes the SQLite database and runs migrations.
3
+ *
4
+ * Re-uses the same MigrationRunner logic from the server:
5
+ * creates a schema_version table and applies numbered .sql migration files.
6
+ */
7
+ export declare class DbInitializer {
8
+ /**
9
+ * Open (or create) the SQLite database at the given path,
10
+ * apply recommended PRAGMAs, and run all pending migrations.
11
+ *
12
+ * @param dbPath - Absolute path to the SQLite database file.
13
+ * @param migrationsDir - Absolute path to the directory containing .sql migration files.
14
+ */
15
+ initialize(dbPath: string, migrationsDir: string): void;
16
+ private runMigrations;
17
+ }
18
+ //# sourceMappingURL=db-initializer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-initializer.d.ts","sourceRoot":"","sources":["../../src/installer/db-initializer.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,qBAAa,aAAa;IACxB;;;;;;OAMG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI;IAwBvD,OAAO,CAAC,aAAa;CAsDtB"}
@@ -0,0 +1,81 @@
1
+ import Database from 'better-sqlite3';
2
+ import * as path from 'node:path';
3
+ import * as fs from 'node:fs';
4
+ /**
5
+ * Initializes the SQLite database and runs migrations.
6
+ *
7
+ * Re-uses the same MigrationRunner logic from the server:
8
+ * creates a schema_version table and applies numbered .sql migration files.
9
+ */
10
+ export class DbInitializer {
11
+ /**
12
+ * Open (or create) the SQLite database at the given path,
13
+ * apply recommended PRAGMAs, and run all pending migrations.
14
+ *
15
+ * @param dbPath - Absolute path to the SQLite database file.
16
+ * @param migrationsDir - Absolute path to the directory containing .sql migration files.
17
+ */
18
+ initialize(dbPath, migrationsDir) {
19
+ // Ensure the parent directory exists
20
+ const dir = path.dirname(dbPath);
21
+ if (!fs.existsSync(dir)) {
22
+ fs.mkdirSync(dir, { recursive: true });
23
+ }
24
+ const db = new Database(dbPath);
25
+ try {
26
+ // Apply recommended PRAGMAs for performance and safety
27
+ db.pragma('journal_mode = WAL');
28
+ db.pragma('busy_timeout = 5000');
29
+ db.pragma('synchronous = NORMAL');
30
+ db.pragma('cache_size = -64000'); // 64MB
31
+ db.pragma('foreign_keys = ON');
32
+ // Run migrations using the same pattern as server's MigrationRunner
33
+ this.runMigrations(db, migrationsDir);
34
+ }
35
+ finally {
36
+ db.close();
37
+ }
38
+ }
39
+ runMigrations(db, migrationsDir) {
40
+ db.exec(`
41
+ CREATE TABLE IF NOT EXISTS schema_version (
42
+ version INTEGER PRIMARY KEY,
43
+ filename TEXT NOT NULL,
44
+ applied_at TEXT NOT NULL DEFAULT (datetime('now'))
45
+ )
46
+ `);
47
+ if (!fs.existsSync(migrationsDir)) {
48
+ throw new Error(`Migrations directory not found: ${migrationsDir}`);
49
+ }
50
+ const files = fs
51
+ .readdirSync(migrationsDir)
52
+ .filter((f) => f.endsWith('.sql'))
53
+ .sort((a, b) => {
54
+ const numA = parseInt(a.split('-')[0], 10);
55
+ const numB = parseInt(b.split('-')[0], 10);
56
+ return numA - numB;
57
+ });
58
+ const applied = new Set(db
59
+ .prepare('SELECT version FROM schema_version')
60
+ .all()
61
+ .map((row) => row.version));
62
+ for (const file of files) {
63
+ const version = parseInt(file.split('-')[0], 10);
64
+ if (applied.has(version)) {
65
+ continue;
66
+ }
67
+ const sql = fs.readFileSync(path.join(migrationsDir, file), 'utf-8');
68
+ const runMigration = db.transaction(() => {
69
+ db.exec(sql);
70
+ db.prepare('INSERT INTO schema_version (version, filename) VALUES (?, ?)').run(version, file);
71
+ });
72
+ try {
73
+ runMigration();
74
+ }
75
+ catch (err) {
76
+ throw new Error(`Migration ${file} failed: ${err instanceof Error ? err.message : String(err)}`);
77
+ }
78
+ }
79
+ }
80
+ }
81
+ //# sourceMappingURL=db-initializer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-initializer.js","sourceRoot":"","sources":["../../src/installer/db-initializer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ export interface CheckResult {
2
+ ok: boolean;
3
+ detail?: string;
4
+ optional?: boolean;
5
+ }
6
+ /**
7
+ * Checks system prerequisites for Overlord installation.
8
+ */
9
+ export declare class EnvChecker {
10
+ /**
11
+ * Check Git is installed and version >= 2.20.
12
+ */
13
+ checkGit(): CheckResult;
14
+ /**
15
+ * Check Node.js version >= 20.
16
+ */
17
+ checkNode(): CheckResult;
18
+ /**
19
+ * Check Redis is reachable and version >= 6.2.
20
+ */
21
+ checkRedis(url: string): Promise<CheckResult>;
22
+ /**
23
+ * Check claude CLI is available (optional).
24
+ */
25
+ checkClaudeCli(): CheckResult;
26
+ /**
27
+ * Check Cursor agent CLI is available (optional).
28
+ */
29
+ checkCursorCli(): CheckResult;
30
+ /**
31
+ * Check VS Code CLI is available (optional).
32
+ */
33
+ checkCodeCli(): CheckResult;
34
+ /**
35
+ * Check available disk space at a given path (warn if < 1 GB).
36
+ */
37
+ checkDiskSpace(dirPath: string): CheckResult;
38
+ /**
39
+ * Check if a TCP port is available.
40
+ */
41
+ checkPort(port: number): Promise<CheckResult>;
42
+ private checkOptionalBinary;
43
+ }
44
+ //# sourceMappingURL=env-checker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-checker.d.ts","sourceRoot":"","sources":["../../src/installer/env-checker.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB;;OAEG;IACH,QAAQ,IAAI,WAAW;IAqBvB;;OAEG;IACH,SAAS,IAAI,WAAW;IAcxB;;OAEG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA0BnD;;OAEG;IACH,cAAc,IAAI,WAAW;IAI7B;;OAEG;IACH,cAAc,IAAI,WAAW;IAI7B;;OAEG;IACH,YAAY,IAAI,WAAW;IAI3B;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW;IAgB5C;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAsB7C,OAAO,CAAC,mBAAmB;CAQ5B"}
@@ -0,0 +1,135 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import * as net from 'node:net';
3
+ import * as fs from 'node:fs';
4
+ /**
5
+ * Checks system prerequisites for Overlord installation.
6
+ */
7
+ export class EnvChecker {
8
+ /**
9
+ * Check Git is installed and version >= 2.20.
10
+ */
11
+ checkGit() {
12
+ try {
13
+ const output = execFileSync('git', ['--version'], { encoding: 'utf-8' }).trim();
14
+ const match = output.match(/git version (\d+)\.(\d+)/);
15
+ if (!match) {
16
+ return { ok: false, detail: 'Could not parse Git version' };
17
+ }
18
+ const major = parseInt(match[1], 10);
19
+ const minor = parseInt(match[2], 10);
20
+ if (major < 2 || (major === 2 && minor < 20)) {
21
+ return { ok: false, detail: `Git ${major}.${minor} found, requires >= 2.20` };
22
+ }
23
+ return { ok: true, detail: `Git ${major}.${minor}` };
24
+ }
25
+ catch {
26
+ return { ok: false, detail: 'Git not found' };
27
+ }
28
+ }
29
+ /**
30
+ * Check Node.js version >= 20.
31
+ */
32
+ checkNode() {
33
+ const match = process.version.match(/v(\d+)/);
34
+ if (!match) {
35
+ return { ok: false, detail: 'Could not parse Node.js version' };
36
+ }
37
+ const major = parseInt(match[1], 10);
38
+ if (major < 20) {
39
+ return { ok: false, detail: `Node.js ${process.version} found, requires >= 20` };
40
+ }
41
+ return { ok: true, detail: `Node.js ${process.version}` };
42
+ }
43
+ /**
44
+ * Check Redis is reachable and version >= 6.2.
45
+ */
46
+ async checkRedis(url) {
47
+ try {
48
+ const output = execFileSync('redis-cli', ['-u', url, 'INFO', 'server'], {
49
+ encoding: 'utf-8',
50
+ stdio: ['pipe', 'pipe', 'pipe'],
51
+ timeout: 5000,
52
+ });
53
+ const versionMatch = output.match(/redis_version:(\d+)\.(\d+)/);
54
+ if (!versionMatch) {
55
+ return { ok: false, detail: 'Could not parse Redis version' };
56
+ }
57
+ const major = parseInt(versionMatch[1], 10);
58
+ const minor = parseInt(versionMatch[2], 10);
59
+ if (major < 6 || (major === 6 && minor < 2)) {
60
+ return { ok: false, detail: `Redis ${major}.${minor} found, requires >= 6.2` };
61
+ }
62
+ return { ok: true, detail: `Redis ${major}.${minor}` };
63
+ }
64
+ catch {
65
+ return { ok: false, detail: 'Redis not reachable' };
66
+ }
67
+ }
68
+ /**
69
+ * Check claude CLI is available (optional).
70
+ */
71
+ checkClaudeCli() {
72
+ return this.checkOptionalBinary('claude', 'claude');
73
+ }
74
+ /**
75
+ * Check Cursor agent CLI is available (optional).
76
+ */
77
+ checkCursorCli() {
78
+ return this.checkOptionalBinary('agent', 'agent');
79
+ }
80
+ /**
81
+ * Check VS Code CLI is available (optional).
82
+ */
83
+ checkCodeCli() {
84
+ return this.checkOptionalBinary('code', 'code');
85
+ }
86
+ /**
87
+ * Check available disk space at a given path (warn if < 1 GB).
88
+ */
89
+ checkDiskSpace(dirPath) {
90
+ try {
91
+ const stat = fs.statfsSync(dirPath);
92
+ const availableBytes = stat.bavail * stat.bsize;
93
+ const availableGB = availableBytes / (1024 * 1024 * 1024);
94
+ if (availableGB < 1) {
95
+ return { ok: false, detail: `Only ${availableGB.toFixed(1)} GB available, requires >= 1 GB` };
96
+ }
97
+ return { ok: true, detail: `${availableGB.toFixed(1)} GB available` };
98
+ }
99
+ catch {
100
+ return { ok: false, detail: 'Could not check disk space' };
101
+ }
102
+ }
103
+ /**
104
+ * Check if a TCP port is available.
105
+ */
106
+ checkPort(port) {
107
+ return new Promise((resolve) => {
108
+ const server = net.createServer();
109
+ server.once('error', (err) => {
110
+ if (err.code === 'EADDRINUSE') {
111
+ resolve({ ok: false, detail: `Port ${port} is in use` });
112
+ }
113
+ else {
114
+ resolve({ ok: false, detail: `Port ${port} check failed: ${err.message}` });
115
+ }
116
+ });
117
+ server.once('listening', () => {
118
+ server.close(() => {
119
+ resolve({ ok: true, detail: `Port ${port} available` });
120
+ });
121
+ });
122
+ server.listen(port, '127.0.0.1');
123
+ });
124
+ }
125
+ checkOptionalBinary(command, label) {
126
+ try {
127
+ execFileSync('which', [command], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
128
+ return { ok: true, detail: `${label} found`, optional: true };
129
+ }
130
+ catch {
131
+ return { ok: false, detail: `${label} not found`, optional: true };
132
+ }
133
+ }
134
+ }
135
+ //# sourceMappingURL=env-checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-checker.js","sourceRoot":"","sources":["../../src/installer/env-checker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export interface GeneratedSecrets {
2
+ jwtSecret: string;
3
+ workerJwtSecret: string;
4
+ encryptionKey: string;
5
+ }
6
+ /**
7
+ * Generates cryptographically secure secrets for Overlord configuration.
8
+ */
9
+ export declare class SecretGenerator {
10
+ /**
11
+ * Generate a 64-byte hex JWT secret for user authentication.
12
+ */
13
+ generateJwtSecret(): string;
14
+ /**
15
+ * Generate a 64-byte hex JWT secret for worker authentication and channel tokens.
16
+ */
17
+ generateWorkerJwtSecret(): string;
18
+ /**
19
+ * Generate a 32-byte hex encryption key for AES-256-GCM.
20
+ */
21
+ generateEncryptionKey(): string;
22
+ /**
23
+ * Generate all three secrets at once.
24
+ */
25
+ generateAll(): GeneratedSecrets;
26
+ }
27
+ //# sourceMappingURL=secret-gen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-gen.d.ts","sourceRoot":"","sources":["../../src/installer/secret-gen.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAI3B;;OAEG;IACH,uBAAuB,IAAI,MAAM;IAIjC;;OAEG;IACH,qBAAqB,IAAI,MAAM;IAI/B;;OAEG;IACH,WAAW,IAAI,gBAAgB;CAOhC"}
@@ -0,0 +1,35 @@
1
+ import * as crypto from 'node:crypto';
2
+ /**
3
+ * Generates cryptographically secure secrets for Overlord configuration.
4
+ */
5
+ export class SecretGenerator {
6
+ /**
7
+ * Generate a 64-byte hex JWT secret for user authentication.
8
+ */
9
+ generateJwtSecret() {
10
+ return crypto.randomBytes(64).toString('hex');
11
+ }
12
+ /**
13
+ * Generate a 64-byte hex JWT secret for worker authentication and channel tokens.
14
+ */
15
+ generateWorkerJwtSecret() {
16
+ return crypto.randomBytes(64).toString('hex');
17
+ }
18
+ /**
19
+ * Generate a 32-byte hex encryption key for AES-256-GCM.
20
+ */
21
+ generateEncryptionKey() {
22
+ return crypto.randomBytes(32).toString('hex');
23
+ }
24
+ /**
25
+ * Generate all three secrets at once.
26
+ */
27
+ generateAll() {
28
+ return {
29
+ jwtSecret: this.generateJwtSecret(),
30
+ workerJwtSecret: this.generateWorkerJwtSecret(),
31
+ encryptionKey: this.generateEncryptionKey(),
32
+ };
33
+ }
34
+ }
35
+ //# sourceMappingURL=secret-gen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-gen.js","sourceRoot":"","sources":["../../src/installer/secret-gen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAQtC;;GAEG;AACH,MAAM,OAAO,eAAe;IAC1B;;OAEG;IACH,iBAAiB;QACf,OAAO,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,uBAAuB;QACrB,OAAO,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,qBAAqB;QACnB,OAAO,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE;YACnC,eAAe,EAAE,IAAI,CAAC,uBAAuB,EAAE;YAC/C,aAAa,EAAE,IAAI,CAAC,qBAAqB,EAAE;SAC5C,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * 10-step interactive installation wizard using @clack/prompts.
3
+ */
4
+ export declare class InstallWizard {
5
+ private checker;
6
+ private secretGen;
7
+ private configWriter;
8
+ private dbInit;
9
+ private adminCreator;
10
+ run(): Promise<void>;
11
+ }
12
+ //# sourceMappingURL=wizard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../../src/installer/wizard.ts"],"names":[],"mappings":"AAUA;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,YAAY,CAAsB;IAEpC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAgN3B"}