kaven-cli 0.4.0 → 0.4.1-alpha.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/dist/EnvManager-GQMEZ6NV.js +158 -0
- package/dist/MarketplaceClient-IJGRQRC4.js +7 -0
- package/dist/chunk-3RG5ZIWI.js +10 -0
- package/dist/chunk-GHZX5OAA.js +455 -0
- package/dist/commands/aiox/index.js +20 -0
- package/dist/commands/config/features.js +110 -975
- package/dist/commands/init/aiox-bootstrap.js +83 -0
- package/dist/commands/init/index.js +16 -3
- package/dist/commands/module/activate.js +84 -45
- package/dist/commands/module/list.js +51 -0
- package/dist/core/ProjectInitializer.js +17 -0
- package/dist/core/SchemaActivator.js +8 -0
- package/dist/index.js +20 -4
- package/dist/infrastructure/MarketplaceClient.js +26 -0
- package/dist/lib/capabilities-catalog.js +73 -0
- package/dist/lib/module-registry.js +47 -0
- package/dist/lib/schema-modifier.js +40 -0
- package/dist/tier-table-LAL6PAVW.js +52 -0
- package/package.json +2 -1
|
@@ -0,0 +1,83 @@
|
|
|
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
|
+
}
|
|
@@ -10,6 +10,7 @@ const path_1 = __importDefault(require("path"));
|
|
|
10
10
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
11
11
|
const ProjectInitializer_1 = require("../../core/ProjectInitializer");
|
|
12
12
|
const ConfigManager_1 = require("../../core/ConfigManager");
|
|
13
|
+
const aiox_bootstrap_1 = require("./aiox-bootstrap");
|
|
13
14
|
async function promptAnswers(projectName) {
|
|
14
15
|
// Dynamic import to keep startup fast and avoid issues if not installed
|
|
15
16
|
const { input, select } = await import("@inquirer/prompts");
|
|
@@ -143,6 +144,16 @@ async function initProject(projectName, options) {
|
|
|
143
144
|
const squadResult = await initializer.installSquad(targetDir);
|
|
144
145
|
if (squadResult.installed) {
|
|
145
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
|
+
}
|
|
146
157
|
}
|
|
147
158
|
else if (squadResult.reason === "already-exists") {
|
|
148
159
|
squadSpinner.info("kaven-squad already installed — skipping");
|
|
@@ -154,6 +165,8 @@ async function initProject(projectName, options) {
|
|
|
154
165
|
}
|
|
155
166
|
// Health check
|
|
156
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 });
|
|
157
170
|
const health = await initializer.healthCheck(targetDir);
|
|
158
171
|
if (health.healthy) {
|
|
159
172
|
healthCheckSpinner.succeed("Health check passed");
|
|
@@ -177,9 +190,9 @@ async function initProject(projectName, options) {
|
|
|
177
190
|
console.log(chalk_1.default.gray("For more help, visit: https://docs.kaven.site/getting-started"));
|
|
178
191
|
if (options.withSquad) {
|
|
179
192
|
console.log();
|
|
180
|
-
console.log(chalk_1.default.bold("AIOX
|
|
181
|
-
console.log(chalk_1.default.cyan(
|
|
182
|
-
console.log(chalk_1.default.
|
|
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"));
|
|
183
196
|
}
|
|
184
197
|
// Save project defaults to config for future use
|
|
185
198
|
await ConfigManager_1.configManager.initialize();
|
|
@@ -9,6 +9,7 @@ exports.moduleListActivation = moduleListActivation;
|
|
|
9
9
|
const chalk_1 = __importDefault(require("chalk"));
|
|
10
10
|
const ora_1 = __importDefault(require("ora"));
|
|
11
11
|
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
const prompts_1 = require("@inquirer/prompts");
|
|
12
13
|
const SchemaActivator_1 = require("../../core/SchemaActivator");
|
|
13
14
|
const TelemetryBuffer_1 = require("../../infrastructure/TelemetryBuffer");
|
|
14
15
|
// ============================================================
|
|
@@ -20,36 +21,36 @@ function findModuleDef(moduleId) {
|
|
|
20
21
|
function assertSchemaExists(exists, root) {
|
|
21
22
|
if (!exists) {
|
|
22
23
|
const fullPath = node_path_1.default.join(root, "packages", "database", "prisma", "schema.extended.prisma");
|
|
23
|
-
console.error(chalk_1.default.red(`\
|
|
24
|
-
console.error(chalk_1.default.gray("
|
|
24
|
+
console.error(chalk_1.default.red(`\nError: Schema not found at: ${fullPath}`));
|
|
25
|
+
console.error(chalk_1.default.gray("Make sure you are in the root of a valid Kaven project."));
|
|
25
26
|
process.exit(1);
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
// ============================================================
|
|
29
30
|
// kaven module activate <name>
|
|
30
31
|
// ============================================================
|
|
31
|
-
async function moduleActivate(moduleName, projectRoot) {
|
|
32
|
+
async function moduleActivate(moduleName, projectRoot, options = {}) {
|
|
32
33
|
const telemetry = TelemetryBuffer_1.TelemetryBuffer.getInstance();
|
|
33
34
|
const startTime = Date.now();
|
|
34
35
|
telemetry.capture("cli.module.activate.start", { moduleName });
|
|
35
36
|
const root = projectRoot ?? process.cwd();
|
|
36
37
|
const activator = new SchemaActivator_1.SchemaActivator(root);
|
|
37
|
-
const spinner = (0, ora_1.default)(`
|
|
38
|
+
const spinner = (0, ora_1.default)(`Activating module ${moduleName}...`).start();
|
|
38
39
|
try {
|
|
39
|
-
// 1.
|
|
40
|
+
// 1. Validate schema exists
|
|
40
41
|
const exists = await activator.exists();
|
|
41
42
|
spinner.stop();
|
|
42
43
|
assertSchemaExists(exists, root);
|
|
43
|
-
// 2.
|
|
44
|
+
// 2. Validate module is known
|
|
44
45
|
const def = findModuleDef(moduleName);
|
|
45
46
|
if (!def) {
|
|
46
|
-
console.error(chalk_1.default.red(`\
|
|
47
|
-
console.error(chalk_1.default.gray(`
|
|
47
|
+
console.error(chalk_1.default.red(`\nUnknown module: "${moduleName}".`));
|
|
48
|
+
console.error(chalk_1.default.gray(`Available modules: ${SchemaActivator_1.KAVEN_MODULES.map((m) => m.id).join(", ")}`));
|
|
48
49
|
process.exit(1);
|
|
49
50
|
}
|
|
50
|
-
// 3.
|
|
51
|
+
// 3. Check dependencies
|
|
51
52
|
if (def.dependsOn.length > 0) {
|
|
52
|
-
spinner.start("
|
|
53
|
+
spinner.start("Checking dependencies...");
|
|
53
54
|
const depStatuses = [];
|
|
54
55
|
for (const depId of def.dependsOn) {
|
|
55
56
|
const depDef = findModuleDef(depId);
|
|
@@ -61,28 +62,59 @@ async function moduleActivate(moduleName, projectRoot) {
|
|
|
61
62
|
const missing = depStatuses.filter((s) => !s.active);
|
|
62
63
|
if (missing.length > 0) {
|
|
63
64
|
spinner.stop();
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
// Auto-activate deps if --with-deps
|
|
66
|
+
if (options.withDeps) {
|
|
67
|
+
for (const dep of missing) {
|
|
68
|
+
await moduleActivate(dep.id, projectRoot, { ...options, withDeps: true });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
console.error(chalk_1.default.red(`\nInactive dependencies for "${moduleName}": ${missing.map((m) => m.id).join(", ")}`));
|
|
73
|
+
console.error(chalk_1.default.gray(`Activate them first:\n${missing.map((m) => ` kaven module activate ${m.id}`).join("\n")}`));
|
|
74
|
+
console.log(chalk_1.default.gray("\nOr use --with-deps to activate them automatically."));
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
67
77
|
}
|
|
68
78
|
spinner.stop();
|
|
69
79
|
}
|
|
70
|
-
// 4.
|
|
80
|
+
// 4. Check if already active
|
|
71
81
|
const current = await activator.getModuleStatus(def);
|
|
72
82
|
if (current.active) {
|
|
73
|
-
console.log(chalk_1.default.yellow(`\
|
|
83
|
+
console.log(chalk_1.default.yellow(`\nModule "${def.label}" is already active.`));
|
|
74
84
|
return;
|
|
75
85
|
}
|
|
76
|
-
// 5.
|
|
77
|
-
|
|
86
|
+
// 5. Confirm if not --yes
|
|
87
|
+
if (!options.yes) {
|
|
88
|
+
const ok = await (0, prompts_1.confirm)({
|
|
89
|
+
message: `Activate module "${def.label}"? This will uncomment ${def.models.length} model(s) in the schema.`,
|
|
90
|
+
default: true,
|
|
91
|
+
});
|
|
92
|
+
if (!ok) {
|
|
93
|
+
console.log(chalk_1.default.gray("\nActivation aborted."));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// 6. Dry run
|
|
98
|
+
if (options.dryRun) {
|
|
99
|
+
console.log(chalk_1.default.bold(`\n--- DRY RUN: Activating ${def.label} ---`));
|
|
100
|
+
console.log(`Models to uncomment: ${def.models.join(", ")}`);
|
|
101
|
+
if (def.enums.length > 0) {
|
|
102
|
+
console.log(`Enums to uncomment: ${def.enums.join(", ")}`);
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
// 7. Activate
|
|
107
|
+
spinner.start(`Uncommenting ${def.label} models in schema...`);
|
|
78
108
|
await activator.activateModule(def);
|
|
79
|
-
spinner.succeed(chalk_1.default.green(`\
|
|
80
|
-
|
|
109
|
+
spinner.succeed(chalk_1.default.green(`\nModule ${def.label} activated. ${def.models.length} models added: ${def.models.join(", ")}`));
|
|
110
|
+
if (!options.skipMigrate) {
|
|
111
|
+
console.log(chalk_1.default.cyan("\nNext step: Run `pnpm db:generate && pnpm db:migrate` to apply changes."));
|
|
112
|
+
}
|
|
81
113
|
telemetry.capture("cli.module.activate.success", { moduleName: def.id, models: def.models.length }, Date.now() - startTime);
|
|
82
114
|
await telemetry.flush();
|
|
83
115
|
}
|
|
84
116
|
catch (error) {
|
|
85
|
-
spinner.fail(chalk_1.default.red(`
|
|
117
|
+
spinner.fail(chalk_1.default.red(`Failed to activate module: ${error instanceof Error ? error.message : String(error)}`));
|
|
86
118
|
telemetry.capture("cli.module.activate.error", { moduleName, error: error.message }, Date.now() - startTime);
|
|
87
119
|
await telemetry.flush();
|
|
88
120
|
process.exit(1);
|
|
@@ -91,27 +123,27 @@ async function moduleActivate(moduleName, projectRoot) {
|
|
|
91
123
|
// ============================================================
|
|
92
124
|
// kaven module deactivate <name>
|
|
93
125
|
// ============================================================
|
|
94
|
-
async function moduleDeactivate(moduleName, projectRoot) {
|
|
126
|
+
async function moduleDeactivate(moduleName, projectRoot, options = {}) {
|
|
95
127
|
const telemetry = TelemetryBuffer_1.TelemetryBuffer.getInstance();
|
|
96
128
|
const startTime = Date.now();
|
|
97
129
|
telemetry.capture("cli.module.deactivate.start", { moduleName });
|
|
98
130
|
const root = projectRoot ?? process.cwd();
|
|
99
131
|
const activator = new SchemaActivator_1.SchemaActivator(root);
|
|
100
|
-
const spinner = (0, ora_1.default)(`
|
|
132
|
+
const spinner = (0, ora_1.default)(`Deactivating module ${moduleName}...`).start();
|
|
101
133
|
try {
|
|
102
|
-
// 1.
|
|
134
|
+
// 1. Validate schema exists
|
|
103
135
|
const exists = await activator.exists();
|
|
104
136
|
spinner.stop();
|
|
105
137
|
assertSchemaExists(exists, root);
|
|
106
|
-
// 2.
|
|
138
|
+
// 2. Validate module
|
|
107
139
|
const def = findModuleDef(moduleName);
|
|
108
140
|
if (!def) {
|
|
109
|
-
console.error(chalk_1.default.red(`\
|
|
110
|
-
console.error(chalk_1.default.gray(`
|
|
141
|
+
console.error(chalk_1.default.red(`\nUnknown module: "${moduleName}".`));
|
|
142
|
+
console.error(chalk_1.default.gray(`Available modules: ${SchemaActivator_1.KAVEN_MODULES.map((m) => m.id).join(", ")}`));
|
|
111
143
|
process.exit(1);
|
|
112
144
|
}
|
|
113
|
-
// 3.
|
|
114
|
-
spinner.start("
|
|
145
|
+
// 3. Check for active dependents
|
|
146
|
+
spinner.start("Checking reverse dependencies...");
|
|
115
147
|
const dependents = [];
|
|
116
148
|
for (const candidate of SchemaActivator_1.KAVEN_MODULES) {
|
|
117
149
|
if (candidate.id === def.id)
|
|
@@ -125,28 +157,37 @@ async function moduleDeactivate(moduleName, projectRoot) {
|
|
|
125
157
|
}
|
|
126
158
|
if (dependents.length > 0) {
|
|
127
159
|
spinner.stop();
|
|
128
|
-
console.error(chalk_1.default.red(`\
|
|
160
|
+
console.error(chalk_1.default.red(`\nCannot deactivate "${moduleName}": the following active modules depend on it:`));
|
|
129
161
|
console.error(chalk_1.default.gray(` ${dependents.join(", ")}`));
|
|
130
|
-
console.error(chalk_1.default.gray(`
|
|
162
|
+
console.error(chalk_1.default.gray(`Deactivate them first:\n${dependents.map((d) => ` kaven module deactivate ${d}`).join("\n")}`));
|
|
131
163
|
process.exit(1);
|
|
132
164
|
}
|
|
133
|
-
// 4.
|
|
165
|
+
// 4. Check if already inactive
|
|
134
166
|
const current = await activator.getModuleStatus(def);
|
|
135
167
|
if (!current.active) {
|
|
136
168
|
spinner.stop();
|
|
137
|
-
console.log(chalk_1.default.yellow(`\
|
|
169
|
+
console.log(chalk_1.default.yellow(`\nModule "${def.label}" is already inactive.`));
|
|
138
170
|
return;
|
|
139
171
|
}
|
|
140
|
-
// 5.
|
|
141
|
-
|
|
172
|
+
// 5. Dry run
|
|
173
|
+
if (options.dryRun) {
|
|
174
|
+
spinner.stop();
|
|
175
|
+
console.log(chalk_1.default.bold(`\n--- DRY RUN: Deactivating ${def.label} ---`));
|
|
176
|
+
console.log(`Models to comment: ${def.models.join(", ")}`);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
// 6. Deactivate
|
|
180
|
+
spinner.start(`Commenting ${def.label} models in schema...`);
|
|
142
181
|
await activator.deactivateModule(def);
|
|
143
|
-
spinner.succeed(chalk_1.default.green(`\
|
|
144
|
-
|
|
182
|
+
spinner.succeed(chalk_1.default.green(`\nModule ${def.label} deactivated successfully.`));
|
|
183
|
+
if (!options.skipMigrate) {
|
|
184
|
+
console.log(chalk_1.default.cyan("\nNext step: Run `pnpm db:generate && pnpm db:migrate` to apply changes."));
|
|
185
|
+
}
|
|
145
186
|
telemetry.capture("cli.module.deactivate.success", { moduleName: def.id }, Date.now() - startTime);
|
|
146
187
|
await telemetry.flush();
|
|
147
188
|
}
|
|
148
189
|
catch (error) {
|
|
149
|
-
spinner.fail(chalk_1.default.red(`
|
|
190
|
+
spinner.fail(chalk_1.default.red(`Failed to deactivate module: ${error instanceof Error ? error.message : String(error)}`));
|
|
150
191
|
telemetry.capture("cli.module.deactivate.error", { moduleName, error: error.message }, Date.now() - startTime);
|
|
151
192
|
await telemetry.flush();
|
|
152
193
|
process.exit(1);
|
|
@@ -159,9 +200,9 @@ async function moduleListActivation(projectRoot) {
|
|
|
159
200
|
const root = projectRoot ?? process.cwd();
|
|
160
201
|
const activator = new SchemaActivator_1.SchemaActivator(root);
|
|
161
202
|
const schemaExists = await activator.exists();
|
|
162
|
-
//
|
|
203
|
+
// Table header
|
|
163
204
|
const COL = {
|
|
164
|
-
module:
|
|
205
|
+
module: 18,
|
|
165
206
|
status: 10,
|
|
166
207
|
models: 44,
|
|
167
208
|
deps: 20,
|
|
@@ -172,7 +213,7 @@ async function moduleListActivation(projectRoot) {
|
|
|
172
213
|
chalk_1.default.bold("Depends on");
|
|
173
214
|
const divider = "─".repeat(COL.module + COL.status + COL.models + COL.deps);
|
|
174
215
|
console.log();
|
|
175
|
-
console.log(chalk_1.default.blue("
|
|
216
|
+
console.log(chalk_1.default.blue("Kaven Schema Modules\n"));
|
|
176
217
|
console.log(header);
|
|
177
218
|
console.log(chalk_1.default.gray(divider));
|
|
178
219
|
if (!schemaExists) {
|
|
@@ -184,8 +225,8 @@ async function moduleListActivation(projectRoot) {
|
|
|
184
225
|
console.log(`${modCol}${statusCol}${modelsCol}${depsCol}`);
|
|
185
226
|
}
|
|
186
227
|
console.log();
|
|
187
|
-
console.log(chalk_1.default.yellow("
|
|
188
|
-
console.log(chalk_1.default.gray("
|
|
228
|
+
console.log(chalk_1.default.yellow("Warning: schema.extended.prisma not found. Status cannot be determined."));
|
|
229
|
+
console.log(chalk_1.default.gray("Run this command in the root of a Kaven project to see real status."));
|
|
189
230
|
return;
|
|
190
231
|
}
|
|
191
232
|
for (const def of SchemaActivator_1.KAVEN_MODULES) {
|
|
@@ -200,7 +241,5 @@ async function moduleListActivation(projectRoot) {
|
|
|
200
241
|
console.log(`${modCol}${statusColored}${modelsCol}${depsCol}`);
|
|
201
242
|
}
|
|
202
243
|
console.log();
|
|
203
|
-
console.log(chalk_1.default.gray("
|
|
204
|
-
console.log();
|
|
205
|
-
console.log(chalk_1.default.gray("Para ativar: kaven module activate <name> | Para desativar: kaven module deactivate <name>"));
|
|
244
|
+
console.log(chalk_1.default.gray("To activate: kaven module activate <name> | To deactivate: kaven module deactivate <name>"));
|
|
206
245
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
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.marketplaceList = marketplaceList;
|
|
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 module_registry_1 = require("../../lib/module-registry");
|
|
11
|
+
const schema_modifier_1 = require("../../lib/schema-modifier");
|
|
12
|
+
/**
|
|
13
|
+
* Finds the Prisma schema file in the project
|
|
14
|
+
*/
|
|
15
|
+
function findSchemaPath(root) {
|
|
16
|
+
const searchPath = root || process.cwd();
|
|
17
|
+
const paths = [
|
|
18
|
+
path_1.default.join(searchPath, "packages/database/prisma/schema.extended.prisma"),
|
|
19
|
+
path_1.default.join(searchPath, "prisma/schema.prisma"),
|
|
20
|
+
];
|
|
21
|
+
for (const p of paths) {
|
|
22
|
+
if (fs_extra_1.default.existsSync(p))
|
|
23
|
+
return p;
|
|
24
|
+
}
|
|
25
|
+
throw new Error("Prisma schema file not found.");
|
|
26
|
+
}
|
|
27
|
+
async function marketplaceList(root) {
|
|
28
|
+
try {
|
|
29
|
+
const schemaPath = findSchemaPath(root);
|
|
30
|
+
const content = await fs_extra_1.default.readFile(schemaPath, "utf-8");
|
|
31
|
+
console.log(`\n ${chalk_1.default.bold.underline("Kaven Schema Modules")}\n`);
|
|
32
|
+
const active = module_registry_1.MODULE_REGISTRY.filter(m => (0, schema_modifier_1.isModuleActive)(content, m.models));
|
|
33
|
+
const inactive = module_registry_1.MODULE_REGISTRY.filter(m => !(0, schema_modifier_1.isModuleActive)(content, m.models));
|
|
34
|
+
console.log(chalk_1.default.green(" ACTIVE"));
|
|
35
|
+
active.forEach(m => {
|
|
36
|
+
const suffix = m.id === "core" ? chalk_1.default.gray(" (always active)") : "";
|
|
37
|
+
console.log(` ${chalk_1.default.green("✓")} ${m.id.padEnd(15)} ${m.name} (${m.models.length} models)${suffix}`);
|
|
38
|
+
});
|
|
39
|
+
if (inactive.length > 0) {
|
|
40
|
+
console.log(`\\n ${chalk_1.default.yellow("INACTIVE")}`);
|
|
41
|
+
inactive.forEach(m => {
|
|
42
|
+
const deps = m.dependsOn.length > 0 ? chalk_1.default.gray(` (requires: ${m.dependsOn.join(", ")})`) : "";
|
|
43
|
+
console.log(` ${chalk_1.default.gray("○")} ${m.id.padEnd(15)} ${m.name} (${m.models.length} models)${deps}`);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
console.log();
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
console.error(chalk_1.default.red(`Error: ${error.message}`));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -81,6 +81,9 @@ class ProjectInitializer {
|
|
|
81
81
|
"apps/api/package.json",
|
|
82
82
|
"apps/admin/package.json",
|
|
83
83
|
"apps/tenant/package.json",
|
|
84
|
+
"docs/architecture/tech-stack.md",
|
|
85
|
+
"docs/architecture/source-tree.md",
|
|
86
|
+
"docs/architecture/coding-standards.md",
|
|
84
87
|
];
|
|
85
88
|
for (const relFile of filesToProcess) {
|
|
86
89
|
const filePath = path_1.default.join(targetDir, relFile);
|
|
@@ -142,6 +145,20 @@ class ProjectInitializer {
|
|
|
142
145
|
}
|
|
143
146
|
return { installed: true };
|
|
144
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* Install AIOX Core runtime into the project via npx.
|
|
150
|
+
* Non-fatal — if it fails, user gets instructions to run manually.
|
|
151
|
+
*/
|
|
152
|
+
async installAIOXCore(targetDir) {
|
|
153
|
+
const exitCode = await runCommand('npx', ['aiox-core@5.0.3', 'install', '--quiet'], targetDir);
|
|
154
|
+
if (exitCode !== 0) {
|
|
155
|
+
return {
|
|
156
|
+
installed: false,
|
|
157
|
+
reason: `npx aiox-core exited with code ${exitCode}`,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return { installed: true };
|
|
161
|
+
}
|
|
145
162
|
/** Health check after project initialization. */
|
|
146
163
|
async healthCheck(targetDir) {
|
|
147
164
|
const issues = [];
|
|
@@ -47,6 +47,14 @@ exports.KAVEN_MODULES = [
|
|
|
47
47
|
enums: ["TrackingSource"],
|
|
48
48
|
dependsOn: [],
|
|
49
49
|
},
|
|
50
|
+
{
|
|
51
|
+
id: "service-tokens",
|
|
52
|
+
label: "Service Tokens",
|
|
53
|
+
description: "Agent authentication tokens for AIOX integration",
|
|
54
|
+
models: ["ServiceToken"],
|
|
55
|
+
enums: [],
|
|
56
|
+
dependsOn: [],
|
|
57
|
+
},
|
|
50
58
|
];
|
|
51
59
|
// ============================================================
|
|
52
60
|
// Marcadores de seção no schema
|
package/dist/index.js
CHANGED
|
@@ -22,12 +22,13 @@ const index_3 = require("./commands/cache/index");
|
|
|
22
22
|
const index_4 = require("./commands/config/index");
|
|
23
23
|
const features_1 = require("./commands/config/features");
|
|
24
24
|
const index_5 = require("./commands/init-ci/index");
|
|
25
|
+
const aiox_1 = require("./commands/aiox");
|
|
25
26
|
const main = () => {
|
|
26
27
|
const program = new commander_1.Command();
|
|
27
28
|
program
|
|
28
29
|
.name("kaven")
|
|
29
30
|
.description("The official CLI for the Kaven SaaS boilerplate ecosystem")
|
|
30
|
-
.version("0.
|
|
31
|
+
.version("0.4.1-alpha.0")
|
|
31
32
|
.addHelpText("after", `
|
|
32
33
|
Examples:
|
|
33
34
|
$ kaven init my-saas-app Bootstrap a new Kaven project
|
|
@@ -52,6 +53,7 @@ Support: https://github.com/kaven-co/kaven-cli/issues
|
|
|
52
53
|
.option("--force", "Overwrite existing directory if it exists")
|
|
53
54
|
.option("--template <path>", "Path to a local template or custom git repository URL")
|
|
54
55
|
.option("--with-squad", "Install kaven-squad (AIOX) into squads/kaven-squad/ after scaffold")
|
|
56
|
+
.option("--skip-aiox", "Skip AIOX environment bootstrap")
|
|
55
57
|
.addHelpText("after", `
|
|
56
58
|
Examples:
|
|
57
59
|
$ kaven init my-app Interactive setup
|
|
@@ -66,6 +68,7 @@ Examples:
|
|
|
66
68
|
force: opts.force,
|
|
67
69
|
template: opts.template,
|
|
68
70
|
withSquad: opts.withSquad,
|
|
71
|
+
skipAiox: opts.skipAiox,
|
|
69
72
|
}));
|
|
70
73
|
/**
|
|
71
74
|
* Modules Group
|
|
@@ -142,6 +145,10 @@ Examples:
|
|
|
142
145
|
moduleCommand
|
|
143
146
|
.command("activate <name> [root]")
|
|
144
147
|
.description("Activate a Kaven schema module by uncommenting its models in schema.extended.prisma")
|
|
148
|
+
.option("--with-deps", "Automatically activate required dependencies")
|
|
149
|
+
.option("--skip-migrate", "Skip db:generate and db:migrate after activation")
|
|
150
|
+
.option("--dry-run", "Show affected models without modifying schema")
|
|
151
|
+
.option("--yes", "Skip confirmation prompt")
|
|
145
152
|
.addHelpText("after", `
|
|
146
153
|
Modules: billing, projects, notifications
|
|
147
154
|
|
|
@@ -149,11 +156,15 @@ Examples:
|
|
|
149
156
|
$ kaven module activate billing
|
|
150
157
|
$ kaven module activate projects
|
|
151
158
|
$ kaven module activate projects ./my-app
|
|
159
|
+
$ kaven module activate billing --with-deps
|
|
152
160
|
`)
|
|
153
|
-
.action((name, root) => (0, activate_1.moduleActivate)(name, root));
|
|
161
|
+
.action((name, root, opts) => (0, activate_1.moduleActivate)(name, root, opts));
|
|
154
162
|
moduleCommand
|
|
155
163
|
.command("deactivate <name> [root]")
|
|
156
164
|
.description("Deactivate a Kaven schema module by commenting its models in schema.extended.prisma")
|
|
165
|
+
.option("--skip-migrate", "Skip db:generate and db:migrate")
|
|
166
|
+
.option("--dry-run", "Show affected models without modifying schema")
|
|
167
|
+
.option("--yes", "Skip confirmation prompt")
|
|
157
168
|
.addHelpText("after", `
|
|
158
169
|
Modules: billing, projects, notifications
|
|
159
170
|
|
|
@@ -162,7 +173,7 @@ Examples:
|
|
|
162
173
|
$ kaven module deactivate projects
|
|
163
174
|
$ kaven module deactivate projects ./my-app
|
|
164
175
|
`)
|
|
165
|
-
.action((name, root) => (0, activate_1.moduleDeactivate)(name, root));
|
|
176
|
+
.action((name, root, opts) => (0, activate_1.moduleDeactivate)(name, root, opts));
|
|
166
177
|
moduleCommand
|
|
167
178
|
.command("list [root]")
|
|
168
179
|
.description("List available Kaven schema modules with their status, models, and dependencies")
|
|
@@ -395,9 +406,14 @@ Examples:
|
|
|
395
406
|
$ kaven init-ci --dry-run Show what would be created
|
|
396
407
|
`)
|
|
397
408
|
.action((opts) => (0, index_5.initCi)({ dryRun: opts.dryRun }));
|
|
398
|
-
|
|
409
|
+
/**
|
|
410
|
+
* AIOX Commands
|
|
411
|
+
*/
|
|
412
|
+
(0, aiox_1.registerAioxCommand)(program);
|
|
413
|
+
program.parse(process.argv);
|
|
399
414
|
};
|
|
400
415
|
exports.main = main;
|
|
416
|
+
// Execute main if this is the entry point
|
|
401
417
|
if (require.main === module) {
|
|
402
418
|
(0, exports.main)();
|
|
403
419
|
}
|
|
@@ -33,6 +33,28 @@ async function loadConfigApiUrl() {
|
|
|
33
33
|
}
|
|
34
34
|
return null;
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Load a service token for agent-to-service auth.
|
|
38
|
+
* Resolution order: KAVEN_SERVICE_TOKEN env → ~/.kaven/config.json#serviceToken
|
|
39
|
+
*/
|
|
40
|
+
async function loadServiceToken() {
|
|
41
|
+
if (process.env.KAVEN_SERVICE_TOKEN) {
|
|
42
|
+
return process.env.KAVEN_SERVICE_TOKEN;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const configPath = path_1.default.join(os_1.default.homedir(), ".kaven", "config.json");
|
|
46
|
+
if (await fs_extra_1.default.pathExists(configPath)) {
|
|
47
|
+
const config = await fs_extra_1.default.readJson(configPath);
|
|
48
|
+
if (typeof config.serviceToken === "string" && config.serviceToken) {
|
|
49
|
+
return config.serviceToken;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Ignore config read errors
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
36
58
|
/** Resolve base URL from env → config file → default. */
|
|
37
59
|
async function resolveBaseUrl() {
|
|
38
60
|
if (process.env.KAVEN_API_URL) {
|
|
@@ -91,6 +113,10 @@ class MarketplaceClient {
|
|
|
91
113
|
const token = await this.authService.getValidToken();
|
|
92
114
|
headers["Authorization"] = `Bearer ${token}`;
|
|
93
115
|
}
|
|
116
|
+
const serviceToken = await loadServiceToken();
|
|
117
|
+
if (serviceToken) {
|
|
118
|
+
headers["X-Service-Token"] = serviceToken;
|
|
119
|
+
}
|
|
94
120
|
debug(`${method} ${url}`);
|
|
95
121
|
const controller = new AbortController();
|
|
96
122
|
const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|