kaven-cli 0.4.1-alpha.0 → 0.6.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 (68) hide show
  1. package/README.md +154 -215
  2. package/dist/EnvManager-NMS3NMIE.js +15 -0
  3. package/dist/MarketplaceClient-YCFH2VU4.js +1 -0
  4. package/dist/chunk-JHLQ46NG.js +1 -0
  5. package/dist/index.d.ts +4 -0
  6. package/dist/index.js +224 -301
  7. package/dist/tier-table-DQMPQSI2.js +6 -0
  8. package/package.json +26 -11
  9. package/dist/EnvManager-GQMEZ6NV.js +0 -158
  10. package/dist/MarketplaceClient-IJGRQRC4.js +0 -7
  11. package/dist/chunk-3RG5ZIWI.js +0 -10
  12. package/dist/chunk-GHZX5OAA.js +0 -455
  13. package/dist/commands/aiox/index.js +0 -20
  14. package/dist/commands/auth/login.js +0 -122
  15. package/dist/commands/auth/logout.js +0 -23
  16. package/dist/commands/auth/whoami.js +0 -36
  17. package/dist/commands/cache/index.js +0 -43
  18. package/dist/commands/config/features.js +0 -161
  19. package/dist/commands/config/index.js +0 -95
  20. package/dist/commands/index.js +0 -2
  21. package/dist/commands/init/aiox-bootstrap.js +0 -83
  22. package/dist/commands/init/index.js +0 -210
  23. package/dist/commands/init-ci/index.js +0 -153
  24. package/dist/commands/license/index.js +0 -10
  25. package/dist/commands/license/status.js +0 -44
  26. package/dist/commands/license/tier-table.js +0 -46
  27. package/dist/commands/marketplace/browse.js +0 -186
  28. package/dist/commands/marketplace/install.js +0 -263
  29. package/dist/commands/marketplace/list.js +0 -122
  30. package/dist/commands/module/activate.js +0 -245
  31. package/dist/commands/module/add.js +0 -69
  32. package/dist/commands/module/doctor.js +0 -175
  33. package/dist/commands/module/list.js +0 -51
  34. package/dist/commands/module/publish.js +0 -258
  35. package/dist/commands/module/remove.js +0 -58
  36. package/dist/commands/telemetry/view.js +0 -27
  37. package/dist/commands/upgrade/check.js +0 -162
  38. package/dist/commands/upgrade/index.js +0 -185
  39. package/dist/core/AuthService.js +0 -222
  40. package/dist/core/CacheManager.js +0 -154
  41. package/dist/core/ConfigManager.js +0 -166
  42. package/dist/core/EnvManager.js +0 -196
  43. package/dist/core/ErrorRecovery.js +0 -192
  44. package/dist/core/LicenseService.js +0 -83
  45. package/dist/core/ManifestParser.js +0 -52
  46. package/dist/core/MarkerService.js +0 -62
  47. package/dist/core/ModuleDoctor.js +0 -451
  48. package/dist/core/ModuleInstaller.js +0 -169
  49. package/dist/core/ProjectInitializer.js +0 -183
  50. package/dist/core/RegistryResolver.js +0 -95
  51. package/dist/core/SchemaActivator.js +0 -278
  52. package/dist/core/ScriptRunner.js +0 -73
  53. package/dist/core/SignatureVerifier.js +0 -75
  54. package/dist/core/index.js +0 -2
  55. package/dist/infrastructure/Container.js +0 -37
  56. package/dist/infrastructure/MarketplaceClient.js +0 -425
  57. package/dist/infrastructure/TelemetryBuffer.js +0 -73
  58. package/dist/infrastructure/TransactionalFileSystem.js +0 -77
  59. package/dist/infrastructure/errors.js +0 -63
  60. package/dist/infrastructure/index.js +0 -2
  61. package/dist/lib/capabilities-catalog.js +0 -73
  62. package/dist/lib/module-registry.js +0 -47
  63. package/dist/lib/schema-modifier.js +0 -40
  64. package/dist/tier-table-LAL6PAVW.js +0 -52
  65. package/dist/types/auth.js +0 -2
  66. package/dist/types/manifest.js +0 -45
  67. package/dist/types/markers.js +0 -10
  68. package/dist/types/marketplace.js +0 -2
@@ -1,43 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.cacheStatus = cacheStatus;
7
- exports.cacheClear = cacheClear;
8
- const chalk_1 = __importDefault(require("chalk"));
9
- const CacheManager_1 = require("../../core/CacheManager");
10
- function formatBytes(bytes) {
11
- if (bytes === 0)
12
- return "0 B";
13
- const k = 1024;
14
- const sizes = ["B", "KB", "MB", "GB"];
15
- const i = Math.floor(Math.log(bytes) / Math.log(k));
16
- return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
17
- }
18
- async function cacheStatus() {
19
- const manager = (0, CacheManager_1.getCacheManager)();
20
- const stats = await manager.stats();
21
- console.log(chalk_1.default.bold("\nKaven CLI Cache Status\n"));
22
- console.log(` Cache directory: ${chalk_1.default.cyan(manager.cacheDir)}`);
23
- console.log(` Total size: ${chalk_1.default.cyan(formatBytes(stats.totalSize))}`);
24
- console.log(` Cached entries: ${chalk_1.default.cyan(stats.entries.toString())}`);
25
- if (stats.oldest) {
26
- console.log(` Oldest entry: ${chalk_1.default.gray(stats.oldest.toLocaleString())}`);
27
- }
28
- if (stats.newest) {
29
- console.log(` Newest entry: ${chalk_1.default.gray(stats.newest.toLocaleString())}`);
30
- }
31
- console.log();
32
- console.log(chalk_1.default.gray("Run 'kaven cache clear' to remove all cached data."));
33
- }
34
- async function cacheClear() {
35
- const manager = (0, CacheManager_1.getCacheManager)();
36
- const stats = await manager.stats();
37
- if (stats.entries === 0) {
38
- console.log(chalk_1.default.gray("Cache is already empty."));
39
- return;
40
- }
41
- await manager.clear();
42
- console.log(chalk_1.default.green(`Cache cleared: ${stats.entries} entries (${formatBytes(stats.totalSize)}) removed.`));
43
- }
@@ -1,161 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.configFeatures = configFeatures;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const fs_extra_1 = __importDefault(require("fs-extra"));
9
- const path_1 = __importDefault(require("path"));
10
- const capabilities_catalog_1 = require("../../lib/capabilities-catalog");
11
- async function configFeatures(options) {
12
- const outputPath = options.outputPath ??
13
- path_1.default.join(process.cwd(), "packages", "database", "prisma", "seeds", "capabilities.seed.ts");
14
- if (options.list) {
15
- printList();
16
- return;
17
- }
18
- if (options.tier) {
19
- await applyTierDirect(options.tier, outputPath, options);
20
- return;
21
- }
22
- await runInteractive(outputPath, options);
23
- }
24
- function printList() {
25
- console.log();
26
- console.log(chalk_1.default.bold.underline("Kaven Framework — Capability Catalog"));
27
- console.log(chalk_1.default.gray(`${capabilities_catalog_1.ALL_CAPABILITIES.length} capabilities total\n`));
28
- const categories = [...new Set(capabilities_catalog_1.ALL_CAPABILITIES.map(c => c.category))];
29
- for (const category of categories) {
30
- const caps = capabilities_catalog_1.ALL_CAPABILITIES.filter(c => c.category === category);
31
- console.log(chalk_1.default.bold.cyan(` ${category} (${caps.length})`));
32
- for (const cap of caps) {
33
- console.log(` ${chalk_1.default.white(cap.key.padEnd(30))} ${chalk_1.default.gray(`[${cap.type}]`)}`);
34
- console.log(` ${chalk_1.default.gray(cap.description)}`);
35
- }
36
- console.log();
37
- }
38
- console.log(chalk_1.default.bold("Tier presets:"));
39
- for (const tier of ["starter", "complete", "pro", "enterprise"]) {
40
- console.log(` ${chalk_1.default.white(tier.padEnd(12))}`);
41
- }
42
- console.log();
43
- }
44
- async function applyTierDirect(tier, outputPath, options) {
45
- const defaults = capabilities_catalog_1.TIER_DEFAULTS[tier] || {};
46
- const selections = {};
47
- for (const cap of capabilities_catalog_1.ALL_CAPABILITIES) {
48
- if (tier === "enterprise") {
49
- selections[cap.key] = cap.type === "boolean" ? true : "-1";
50
- }
51
- else {
52
- selections[cap.key] = defaults[cap.key] ?? (cap.type === "boolean" ? false : cap.defaultValue);
53
- }
54
- }
55
- await saveSeedFile(selections, outputPath, options, tier);
56
- }
57
- async function runInteractive(outputPath, options) {
58
- const { select, confirm, input } = await import("@inquirer/prompts");
59
- // eslint-disable-next-line @typescript-eslint/no-require-imports
60
- const prompts = require("@inquirer/prompts");
61
- const checkbox = prompts.checkbox;
62
- console.log();
63
- console.log(chalk_1.default.bold.underline("🛡️ Kaven Feature Flag Configuration"));
64
- const selectedTier = await select({
65
- message: "Select a base tier:",
66
- choices: [
67
- { name: "Starter (Essential SaaS features)", value: "starter" },
68
- { name: "Complete (White-label + Custom Domains)", value: "complete" },
69
- { name: "Pro (Extended API + Limits)", value: "pro" },
70
- { name: "Enterprise (Unlimited everything)", value: "enterprise" },
71
- { name: "Cancel", value: "cancel" },
72
- ],
73
- });
74
- if (selectedTier === "cancel")
75
- return;
76
- const tier = selectedTier;
77
- const defaults = capabilities_catalog_1.TIER_DEFAULTS[tier] || {};
78
- const selections = {};
79
- const customize = await confirm({
80
- message: "Customize individual capabilities?",
81
- default: false,
82
- });
83
- if (!customize) {
84
- return applyTierDirect(tier, outputPath, options);
85
- }
86
- const categories = [...new Set(capabilities_catalog_1.ALL_CAPABILITIES.map(c => c.category))];
87
- for (const category of categories) {
88
- const caps = capabilities_catalog_1.ALL_CAPABILITIES.filter(c => c.category === category);
89
- const boolCaps = caps.filter(c => c.type === "boolean");
90
- const numCaps = caps.filter(c => c.type === "numeric");
91
- if (boolCaps.length > 0) {
92
- const choices = boolCaps.map(c => ({
93
- name: `${c.key.padEnd(30)} — ${c.description}`,
94
- value: c.key,
95
- checked: tier === "enterprise" ? true : (defaults[c.key] === true),
96
- }));
97
- const selected = await checkbox({
98
- message: `${category} features:`,
99
- choices,
100
- });
101
- for (const cap of boolCaps) {
102
- selections[cap.key] = selected.includes(cap.key);
103
- }
104
- }
105
- for (const cap of numCaps) {
106
- const defVal = tier === "enterprise" ? "-1" : (defaults[cap.key] || cap.defaultValue);
107
- const val = await input({
108
- message: `${cap.key} (${cap.description}):`,
109
- default: defVal,
110
- });
111
- selections[cap.key] = val;
112
- }
113
- }
114
- await saveSeedFile(selections, outputPath, options, tier);
115
- }
116
- async function saveSeedFile(selections, outputPath, options, tier) {
117
- const items = capabilities_catalog_1.ALL_CAPABILITIES.map(c => {
118
- const val = selections[c.key];
119
- return ` { key: "${c.key}", type: "${c.type}", defaultValue: "${val}", description: "${c.description}" },`;
120
- }).join("\n");
121
- const content = `// packages/database/prisma/seeds/capabilities.seed.ts
122
- // Generated by kaven config features — ${new Date().toISOString()}
123
- // Tier: ${tier}
124
-
125
- import { PrismaClient } from "@prisma/client";
126
-
127
- export async function seedCapabilities(prisma: PrismaClient) {
128
- const capabilities = [
129
- ${items}
130
- ];
131
-
132
- console.log("🔐 Seeding ${capabilities_catalog_1.ALL_CAPABILITIES.length} Capabilities...");
133
-
134
- for (const cap of capabilities) {
135
- await prisma.capability.upsert({
136
- where: { key: cap.key },
137
- update: cap,
138
- create: cap,
139
- });
140
- }
141
- }
142
- `;
143
- if (options.dryRun) {
144
- console.log(chalk_1.default.bold("\n--- DRY RUN: Generated Content ---"));
145
- console.log(content);
146
- return;
147
- }
148
- if (fs_extra_1.default.existsSync(outputPath) && !options.force) {
149
- const { confirm: confirmOverwrite } = await import("@inquirer/prompts");
150
- const overwrite = await confirmOverwrite({
151
- message: "Seed file already exists. Overwrite?",
152
- default: false,
153
- });
154
- if (!overwrite)
155
- return;
156
- }
157
- await fs_extra_1.default.ensureDir(path_1.default.dirname(outputPath));
158
- await fs_extra_1.default.writeFile(outputPath, content, "utf-8");
159
- console.log(chalk_1.default.green(`\n✅ Seed file written to: ${outputPath}`));
160
- console.log(chalk_1.default.gray("Run pnpm prisma db seed to apply capabilities to your database."));
161
- }
@@ -1,95 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.configSet = configSet;
7
- exports.configGet = configGet;
8
- exports.configView = configView;
9
- exports.configReset = configReset;
10
- const chalk_1 = __importDefault(require("chalk"));
11
- const ConfigManager_1 = require("../../core/ConfigManager");
12
- /**
13
- * C2.4: Config set — Persist value to ~/.kaven/config.json
14
- */
15
- async function configSet(key, value) {
16
- if (!key || !value) {
17
- console.error(chalk_1.default.red("Error: Both key and value are required"));
18
- console.error(chalk_1.default.gray("Usage: kaven config set KEY VALUE"));
19
- process.exit(1);
20
- }
21
- await ConfigManager_1.configManager.initialize();
22
- try {
23
- await ConfigManager_1.configManager.set(key, value);
24
- console.log(chalk_1.default.green(`✅ Set ${chalk_1.default.bold(key)} = ${chalk_1.default.bold(value)}`));
25
- }
26
- catch (error) {
27
- console.error(chalk_1.default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
28
- process.exit(1);
29
- }
30
- }
31
- /**
32
- * C2.4: Config get — Read with defaults
33
- */
34
- async function configGet(key, options) {
35
- if (!key) {
36
- console.error(chalk_1.default.red("Error: Key is required"));
37
- console.error(chalk_1.default.gray("Usage: kaven config get KEY"));
38
- process.exit(1);
39
- }
40
- await ConfigManager_1.configManager.initialize();
41
- try {
42
- const value = ConfigManager_1.configManager.get(key);
43
- if (options.json) {
44
- console.log(JSON.stringify({ [key]: value }, null, 2));
45
- }
46
- else {
47
- console.log(value);
48
- }
49
- }
50
- catch (error) {
51
- console.error(chalk_1.default.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
52
- process.exit(1);
53
- }
54
- }
55
- /**
56
- * C2.4: Config view — Show all configuration
57
- */
58
- async function configView(options) {
59
- await ConfigManager_1.configManager.initialize();
60
- const config = ConfigManager_1.configManager.getAll();
61
- if (options.json) {
62
- console.log(JSON.stringify(config, null, 2));
63
- }
64
- else {
65
- console.log(chalk_1.default.bold("Kaven Configuration:"));
66
- console.log(chalk_1.default.gray(`Location: ${ConfigManager_1.configManager.getConfigDir()}/config.json`));
67
- console.log();
68
- const entries = Object.entries(config);
69
- const maxKeyLen = Math.max(...entries.map(([k]) => k.length));
70
- for (const [key, value] of entries) {
71
- const padding = " ".repeat(maxKeyLen - key.length);
72
- const displayValue = typeof value === "object"
73
- ? JSON.stringify(value, null, 2).replace(/\n/g, "\n" + " ".repeat(maxKeyLen + 3))
74
- : value;
75
- console.log(` ${key}${padding} ${chalk_1.default.cyan(displayValue)}`);
76
- }
77
- }
78
- }
79
- /**
80
- * C2.4: Config reset — Reset to defaults
81
- */
82
- async function configReset() {
83
- const { confirm } = await import("@inquirer/prompts");
84
- const confirmed = await confirm({
85
- message: "Are you sure you want to reset config to defaults?",
86
- default: false,
87
- });
88
- if (!confirmed) {
89
- console.log(chalk_1.default.yellow("Cancelled."));
90
- return;
91
- }
92
- await ConfigManager_1.configManager.initialize();
93
- await ConfigManager_1.configManager.reset();
94
- console.log(chalk_1.default.green("✅ Config reset to defaults"));
95
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,83 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.runEnvironmentBootstrap = runEnvironmentBootstrap;
40
- const node_child_process_1 = require("node:child_process");
41
- const fs = __importStar(require("node:fs"));
42
- const path = __importStar(require("node:path"));
43
- const ora_1 = __importDefault(require("ora"));
44
- const chalk_1 = __importDefault(require("chalk"));
45
- /**
46
- * Runs the AIOX environment bootstrap process.
47
- * This identifies the project stack and generates .aiox/ runtime configs.
48
- */
49
- async function runEnvironmentBootstrap(projectDir, options = {}) {
50
- if (options.skipAiox)
51
- return;
52
- // Check if AIOX Core is installed
53
- const aioxCorePath = path.join(projectDir, ".aiox-core");
54
- if (!fs.existsSync(aioxCorePath)) {
55
- // If not found in .aiox-core, check if it's a symlink (Dev environment)
56
- const isDevLink = fs.existsSync(path.join(projectDir, ".aiox"));
57
- if (!isDevLink) {
58
- return; // Silent skip if AIOX is not present
59
- }
60
- }
61
- const spinner = (0, ora_1.default)("Bootstrapping AIOX environment...").start();
62
- try {
63
- // The AIOX Core exposes a CLI at bin/aiox.js
64
- // We call: node .aiox-core/bin/aiox.js devops environment-bootstrap --quiet
65
- // Determine the bin path
66
- const binPath = fs.existsSync(path.join(projectDir, ".aiox-core/bin/aiox.js"))
67
- ? ".aiox-core/bin/aiox.js"
68
- : ".aiox/bin/aiox.js"; // Fallback for dev symlink
69
- (0, node_child_process_1.execSync)(`node ${binPath} devops environment-bootstrap --quiet`, {
70
- cwd: projectDir,
71
- stdio: "pipe",
72
- timeout: 60000, // 1 minute timeout
73
- });
74
- spinner.succeed("AIOX environment bootstrapped");
75
- }
76
- catch (error) {
77
- spinner.warn("AIOX environment bootstrap failed");
78
- console.log(chalk_1.default.yellow(" ⚠ Run manually inside the project: kaven aiox bootstrap"));
79
- if (process.env.KAVEN_DEBUG) {
80
- console.error(chalk_1.default.gray(` Error: ${error.message}`));
81
- }
82
- }
83
- }
@@ -1,210 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.initProject = initProject;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const ora_1 = __importDefault(require("ora"));
9
- const path_1 = __importDefault(require("path"));
10
- const fs_extra_1 = __importDefault(require("fs-extra"));
11
- const ProjectInitializer_1 = require("../../core/ProjectInitializer");
12
- const ConfigManager_1 = require("../../core/ConfigManager");
13
- const aiox_bootstrap_1 = require("./aiox-bootstrap");
14
- async function promptAnswers(projectName) {
15
- // Dynamic import to keep startup fast and avoid issues if not installed
16
- const { input, select } = await import("@inquirer/prompts");
17
- // Load defaults from config if available
18
- await ConfigManager_1.configManager.initialize();
19
- const existingDefaults = ConfigManager_1.configManager.getAll().projectDefaults || {};
20
- const dbUrl = await input({
21
- message: "Database URL (PostgreSQL):",
22
- default: existingDefaults.dbUrl ||
23
- `postgresql://user:password@localhost:5432/${projectName}`,
24
- });
25
- const emailProvider = await select({
26
- message: "Email provider:",
27
- choices: [
28
- { name: "Postmark", value: "postmark" },
29
- { name: "Resend", value: "resend" },
30
- { name: "AWS SES", value: "ses" },
31
- { name: "SMTP", value: "smtp" },
32
- ],
33
- default: existingDefaults.emailProvider || "postmark",
34
- });
35
- const locale = await input({
36
- message: "Default locale:",
37
- default: existingDefaults.locale || "en-US",
38
- });
39
- const currency = await input({
40
- message: "Default currency:",
41
- default: existingDefaults.currency || "USD",
42
- });
43
- return { dbUrl, emailProvider, locale, currency };
44
- }
45
- async function initProject(projectName, options) {
46
- const initializer = new ProjectInitializer_1.ProjectInitializer();
47
- // Determine project name interactively if not provided
48
- let resolvedName = projectName ?? "";
49
- if (!resolvedName) {
50
- if (options.defaults) {
51
- resolvedName = "my-kaven-app";
52
- }
53
- else {
54
- const { input } = await import("@inquirer/prompts");
55
- resolvedName = await input({
56
- message: "Project name:",
57
- default: "my-kaven-app",
58
- });
59
- }
60
- }
61
- // Validate name
62
- const validation = initializer.validateName(resolvedName);
63
- if (!validation.valid) {
64
- console.error(chalk_1.default.red(`Error: ${validation.reason}`));
65
- console.error(chalk_1.default.gray("Try: kaven init my-project-name (use lowercase letters and hyphens)"));
66
- process.exit(1);
67
- }
68
- const name = resolvedName;
69
- const targetDir = path_1.default.resolve(process.cwd(), name);
70
- // Check if directory already exists
71
- if ((await fs_extra_1.default.pathExists(targetDir)) && !options.force) {
72
- console.error(chalk_1.default.red(`Error: Directory "${name}" already exists. Use --force to overwrite.`));
73
- process.exit(1);
74
- }
75
- // Get prompt answers or use defaults
76
- let answers;
77
- if (options.defaults) {
78
- // Try to load from config, then fallback to options
79
- await ConfigManager_1.configManager.initialize();
80
- const configDefaults = ConfigManager_1.configManager.getAll().projectDefaults || {};
81
- answers = {
82
- dbUrl: options.dbUrl ||
83
- configDefaults.dbUrl ||
84
- `postgresql://user:password@localhost:5432/${name}`,
85
- emailProvider: options.emailProvider || configDefaults.emailProvider || "postmark",
86
- locale: options.locale || configDefaults.locale || "en-US",
87
- currency: options.currency || configDefaults.currency || "USD",
88
- };
89
- }
90
- else {
91
- answers = await promptAnswers(name);
92
- }
93
- console.log();
94
- // Clone template
95
- const cloneSpinner = (0, ora_1.default)("Cloning kaven-template...").start();
96
- try {
97
- await initializer.cloneTemplate(targetDir, options.template);
98
- cloneSpinner.succeed("Template cloned successfully");
99
- }
100
- catch (error) {
101
- cloneSpinner.fail("Failed to clone template");
102
- console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
103
- console.error(chalk_1.default.gray("Try: ensure git is installed and you have internet access"));
104
- process.exit(1);
105
- }
106
- // Remove .git directory
107
- const gitRemoveSpinner = (0, ora_1.default)("Removing .git directory...").start();
108
- await initializer.removeGitDir(targetDir);
109
- gitRemoveSpinner.succeed(".git directory removed");
110
- // Replace placeholders
111
- const placeholderSpinner = (0, ora_1.default)("Configuring project files...").start();
112
- await initializer.replacePlaceholders(targetDir, {
113
- ...answers,
114
- projectName: name,
115
- });
116
- placeholderSpinner.succeed("Project files configured");
117
- // Run pnpm install
118
- if (!options.skipInstall) {
119
- const installSpinner = (0, ora_1.default)("Installing dependencies (pnpm install)...").start();
120
- try {
121
- await initializer.runInstall(targetDir);
122
- installSpinner.succeed("Dependencies installed");
123
- }
124
- catch (error) {
125
- installSpinner.warn("Dependency installation failed — run pnpm install manually");
126
- console.error(chalk_1.default.gray(error instanceof Error ? error.message : String(error)));
127
- }
128
- }
129
- // Init git
130
- if (!options.skipGit) {
131
- const gitSpinner = (0, ora_1.default)("Initializing git repository...").start();
132
- try {
133
- await initializer.initGit(targetDir);
134
- gitSpinner.succeed("Git repository initialized");
135
- }
136
- catch (error) {
137
- gitSpinner.warn("Git init failed — initialize manually");
138
- console.error(chalk_1.default.gray(error instanceof Error ? error.message : String(error)));
139
- }
140
- }
141
- // Install kaven-squad (optional, non-fatal)
142
- if (options.withSquad) {
143
- const squadSpinner = (0, ora_1.default)("Installing kaven-squad...").start();
144
- const squadResult = await initializer.installSquad(targetDir);
145
- if (squadResult.installed) {
146
- squadSpinner.succeed("kaven-squad installed in squads/kaven-squad/");
147
- // Install AIOX Core runtime (non-fatal)
148
- const aioxSpinner = (0, ora_1.default)("Activating AIOX Core...").start();
149
- const aioxResult = await initializer.installAIOXCore(targetDir);
150
- if (aioxResult.installed) {
151
- aioxSpinner.succeed("AIOX Core activated — agents online");
152
- }
153
- else {
154
- aioxSpinner.warn(`AIOX Core not activated automatically (${aioxResult.reason})`);
155
- console.log(chalk_1.default.yellow(` Run inside the project: npx aiox-core install`));
156
- }
157
- }
158
- else if (squadResult.reason === "already-exists") {
159
- squadSpinner.info("kaven-squad already installed — skipping");
160
- }
161
- else {
162
- squadSpinner.warn(`Could not install kaven-squad automatically (${squadResult.reason})`);
163
- console.log(chalk_1.default.yellow(" ⚠ Install manually inside the project: *download-squad kaven-squad"));
164
- }
165
- }
166
- // Health check
167
- const healthCheckSpinner = (0, ora_1.default)("Running health check...").start();
168
- // AIOX Environment Bootstrap
169
- await (0, aiox_bootstrap_1.runEnvironmentBootstrap)(targetDir, { skipAiox: options.skipAiox });
170
- const health = await initializer.healthCheck(targetDir);
171
- if (health.healthy) {
172
- healthCheckSpinner.succeed("Health check passed");
173
- }
174
- else {
175
- healthCheckSpinner.warn("Health check found issues:");
176
- for (const issue of health.issues) {
177
- console.log(chalk_1.default.yellow(` ⚠ ${issue}`));
178
- }
179
- }
180
- // Success message
181
- console.log();
182
- console.log(chalk_1.default.green("✅ Project created successfully!"));
183
- console.log();
184
- console.log(chalk_1.default.bold("Next steps:"));
185
- console.log(chalk_1.default.cyan(` cd ${name}`));
186
- console.log(chalk_1.default.cyan(" cp .env.example .env"));
187
- console.log(chalk_1.default.cyan(" npx prisma migrate dev"));
188
- console.log(chalk_1.default.cyan(" pnpm dev"));
189
- console.log();
190
- console.log(chalk_1.default.gray("For more help, visit: https://docs.kaven.site/getting-started"));
191
- if (options.withSquad) {
192
- console.log();
193
- console.log(chalk_1.default.bold("AIOX Agents:"));
194
- console.log(chalk_1.default.cyan(` cd ${name}`));
195
- console.log(chalk_1.default.cyan(" # Type @dev in Claude Code to start with AI agents"));
196
- }
197
- // Save project defaults to config for future use
198
- await ConfigManager_1.configManager.initialize();
199
- try {
200
- await ConfigManager_1.configManager.set("projectDefaults", {
201
- dbUrl: answers.dbUrl,
202
- emailProvider: answers.emailProvider,
203
- locale: answers.locale,
204
- currency: answers.currency,
205
- });
206
- }
207
- catch {
208
- // Non-critical, continue if config save fails
209
- }
210
- }