kaven-cli 0.4.1-alpha.0 → 0.5.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/README.md +154 -215
- package/dist/EnvManager-NMS3NMIE.js +15 -0
- package/dist/MarketplaceClient-YCFH2VU4.js +1 -0
- package/dist/chunk-JHLQ46NG.js +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +215 -301
- package/dist/tier-table-DQMPQSI2.js +6 -0
- package/package.json +26 -11
- package/dist/EnvManager-GQMEZ6NV.js +0 -158
- package/dist/MarketplaceClient-IJGRQRC4.js +0 -7
- package/dist/chunk-3RG5ZIWI.js +0 -10
- package/dist/chunk-GHZX5OAA.js +0 -455
- package/dist/commands/aiox/index.js +0 -20
- package/dist/commands/auth/login.js +0 -122
- package/dist/commands/auth/logout.js +0 -23
- package/dist/commands/auth/whoami.js +0 -36
- package/dist/commands/cache/index.js +0 -43
- package/dist/commands/config/features.js +0 -161
- package/dist/commands/config/index.js +0 -95
- package/dist/commands/index.js +0 -2
- package/dist/commands/init/aiox-bootstrap.js +0 -83
- package/dist/commands/init/index.js +0 -210
- package/dist/commands/init-ci/index.js +0 -153
- package/dist/commands/license/index.js +0 -10
- package/dist/commands/license/status.js +0 -44
- package/dist/commands/license/tier-table.js +0 -46
- package/dist/commands/marketplace/browse.js +0 -186
- package/dist/commands/marketplace/install.js +0 -263
- package/dist/commands/marketplace/list.js +0 -122
- package/dist/commands/module/activate.js +0 -245
- package/dist/commands/module/add.js +0 -69
- package/dist/commands/module/doctor.js +0 -175
- package/dist/commands/module/list.js +0 -51
- package/dist/commands/module/publish.js +0 -258
- package/dist/commands/module/remove.js +0 -58
- package/dist/commands/telemetry/view.js +0 -27
- package/dist/commands/upgrade/check.js +0 -162
- package/dist/commands/upgrade/index.js +0 -185
- package/dist/core/AuthService.js +0 -222
- package/dist/core/CacheManager.js +0 -154
- package/dist/core/ConfigManager.js +0 -166
- package/dist/core/EnvManager.js +0 -196
- package/dist/core/ErrorRecovery.js +0 -192
- package/dist/core/LicenseService.js +0 -83
- package/dist/core/ManifestParser.js +0 -52
- package/dist/core/MarkerService.js +0 -62
- package/dist/core/ModuleDoctor.js +0 -451
- package/dist/core/ModuleInstaller.js +0 -169
- package/dist/core/ProjectInitializer.js +0 -183
- package/dist/core/RegistryResolver.js +0 -95
- package/dist/core/SchemaActivator.js +0 -278
- package/dist/core/ScriptRunner.js +0 -73
- package/dist/core/SignatureVerifier.js +0 -75
- package/dist/core/index.js +0 -2
- package/dist/infrastructure/Container.js +0 -37
- package/dist/infrastructure/MarketplaceClient.js +0 -425
- package/dist/infrastructure/TelemetryBuffer.js +0 -73
- package/dist/infrastructure/TransactionalFileSystem.js +0 -77
- package/dist/infrastructure/errors.js +0 -63
- package/dist/infrastructure/index.js +0 -2
- package/dist/lib/capabilities-catalog.js +0 -73
- package/dist/lib/module-registry.js +0 -47
- package/dist/lib/schema-modifier.js +0 -40
- package/dist/tier-table-LAL6PAVW.js +0 -52
- package/dist/types/auth.js +0 -2
- package/dist/types/manifest.js +0 -45
- package/dist/types/markers.js +0 -10
- package/dist/types/marketplace.js +0 -2
|
@@ -1,263 +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.marketplaceInstall = marketplaceInstall;
|
|
40
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
41
|
-
const ora_1 = __importDefault(require("ora"));
|
|
42
|
-
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
43
|
-
const path_1 = __importDefault(require("path"));
|
|
44
|
-
const os_1 = __importDefault(require("os"));
|
|
45
|
-
const tar = __importStar(require("tar"));
|
|
46
|
-
const MarketplaceClient_1 = require("../../infrastructure/MarketplaceClient");
|
|
47
|
-
const AuthService_1 = require("../../core/AuthService");
|
|
48
|
-
const ModuleInstaller_1 = require("../../core/ModuleInstaller");
|
|
49
|
-
const MarkerService_1 = require("../../core/MarkerService");
|
|
50
|
-
const TelemetryBuffer_1 = require("../../infrastructure/TelemetryBuffer");
|
|
51
|
-
const errors_1 = require("../../infrastructure/errors");
|
|
52
|
-
const SignatureVerifier_1 = require("../../core/SignatureVerifier");
|
|
53
|
-
/** Create a unique temp directory for this install session. */
|
|
54
|
-
async function makeTempDir() {
|
|
55
|
-
const base = path_1.default.join(os_1.default.tmpdir(), "kaven-install-");
|
|
56
|
-
return fs_extra_1.default.mkdtemp(base);
|
|
57
|
-
}
|
|
58
|
-
/** Format bytes into a human-readable string like "245 KB". */
|
|
59
|
-
function formatBytes(bytes) {
|
|
60
|
-
if (bytes < 1024)
|
|
61
|
-
return `${bytes} B`;
|
|
62
|
-
if (bytes < 1024 * 1024)
|
|
63
|
-
return `${Math.round(bytes / 1024)} KB`;
|
|
64
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
65
|
-
}
|
|
66
|
-
async function marketplaceInstall(slug, options = {}) {
|
|
67
|
-
const telemetry = TelemetryBuffer_1.TelemetryBuffer.getInstance();
|
|
68
|
-
const startTime = Date.now();
|
|
69
|
-
telemetry.capture("cli.marketplace.install.start", { slug });
|
|
70
|
-
const authService = new AuthService_1.AuthService();
|
|
71
|
-
const client = new MarketplaceClient_1.MarketplaceClient(authService);
|
|
72
|
-
const projectRoot = process.cwd();
|
|
73
|
-
// 1. Verify authentication — required for downloads
|
|
74
|
-
let accessToken;
|
|
75
|
-
try {
|
|
76
|
-
accessToken = await authService.getValidToken();
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
console.error(chalk_1.default.red("Authentication required. Run: kaven auth login"));
|
|
80
|
-
telemetry.capture("cli.marketplace.install.error", { slug, error: "not_authenticated" }, Date.now() - startTime);
|
|
81
|
-
await telemetry.flush();
|
|
82
|
-
process.exit(1);
|
|
83
|
-
return; // Unreachable but satisfies TS control flow
|
|
84
|
-
}
|
|
85
|
-
void accessToken; // used implicitly via authService in client
|
|
86
|
-
const spinner = (0, ora_1.default)(`Preparing installation of '${slug}'...`).start();
|
|
87
|
-
let tempDir = null;
|
|
88
|
-
try {
|
|
89
|
-
// 2. Get module metadata
|
|
90
|
-
spinner.text = `Fetching module '${slug}' from Marketplace...`;
|
|
91
|
-
let moduleData;
|
|
92
|
-
try {
|
|
93
|
-
moduleData = await client.getModule(slug);
|
|
94
|
-
}
|
|
95
|
-
catch (error) {
|
|
96
|
-
if (error instanceof errors_1.NotFoundError) {
|
|
97
|
-
spinner.fail(chalk_1.default.red(`Module '${slug}' not found in Marketplace.`));
|
|
98
|
-
process.exit(1);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
throw error;
|
|
102
|
-
}
|
|
103
|
-
const latestVersion = moduleData.latestVersion
|
|
104
|
-
?? moduleData.releases?.[0]?.version;
|
|
105
|
-
const installVersion = options.version ?? latestVersion;
|
|
106
|
-
if (!installVersion) {
|
|
107
|
-
spinner.fail(chalk_1.default.red(`No published version found for '${slug}'.`));
|
|
108
|
-
process.exit(1);
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
// 3. Check for conflict before downloading
|
|
112
|
-
const markerService = new MarkerService_1.MarkerService();
|
|
113
|
-
const installer = new ModuleInstaller_1.ModuleInstaller(projectRoot, markerService);
|
|
114
|
-
// Check if already installed by looking at marker files
|
|
115
|
-
const isInstalled = await installer.isModuleInstalled(slug);
|
|
116
|
-
if (isInstalled && !options.force) {
|
|
117
|
-
spinner.stop();
|
|
118
|
-
console.log(chalk_1.default.yellow(`Module '${slug}' is already installed. Use --force to overwrite.`));
|
|
119
|
-
telemetry.capture("cli.marketplace.install.skipped", { slug, reason: "already_installed" }, Date.now() - startTime);
|
|
120
|
-
await telemetry.flush();
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
// 4. Create download token
|
|
124
|
-
spinner.text = `Creating download token for '${slug}@${installVersion}'...`;
|
|
125
|
-
const downloadToken = await client.createDownloadToken(slug, installVersion);
|
|
126
|
-
// 5. Download the tarball to a temp directory
|
|
127
|
-
tempDir = await makeTempDir();
|
|
128
|
-
const tarPath = path_1.default.join(tempDir, "module.tar.gz");
|
|
129
|
-
const extractDir = path_1.default.join(tempDir, "extracted");
|
|
130
|
-
await fs_extra_1.default.ensureDir(extractDir);
|
|
131
|
-
// Fetch with size reporting
|
|
132
|
-
spinner.text = `Downloading ${slug} v${installVersion}...`;
|
|
133
|
-
const absoluteUrl = await client.resolveUrl(downloadToken.downloadUrl);
|
|
134
|
-
const response = await fetch(absoluteUrl);
|
|
135
|
-
if (!response.ok) {
|
|
136
|
-
throw new Error(`Download failed: ${response.status} ${response.statusText}`);
|
|
137
|
-
}
|
|
138
|
-
const contentLength = response.headers.get("content-length");
|
|
139
|
-
const sizeStr = contentLength
|
|
140
|
-
? ` (${formatBytes(parseInt(contentLength, 10))})`
|
|
141
|
-
: "";
|
|
142
|
-
spinner.text = `Downloading ${slug} v${installVersion}${sizeStr}...`;
|
|
143
|
-
if (!response.body) {
|
|
144
|
-
throw new Error("No response body received for download");
|
|
145
|
-
}
|
|
146
|
-
// Stream download to file
|
|
147
|
-
const fileStream = fs_extra_1.default.createWriteStream(tarPath);
|
|
148
|
-
const reader = response.body.getReader();
|
|
149
|
-
await new Promise((resolve, reject) => {
|
|
150
|
-
const pump = async () => {
|
|
151
|
-
try {
|
|
152
|
-
let reading = true;
|
|
153
|
-
while (reading) {
|
|
154
|
-
const { done, value } = await reader.read();
|
|
155
|
-
if (done) {
|
|
156
|
-
fileStream.end();
|
|
157
|
-
reading = false;
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
if (!fileStream.write(value)) {
|
|
161
|
-
await new Promise((r) => fileStream.once("drain", r));
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
fileStream.once("finish", resolve);
|
|
166
|
-
fileStream.once("error", reject);
|
|
167
|
-
}
|
|
168
|
-
catch (err) {
|
|
169
|
-
reject(err);
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
pump();
|
|
173
|
-
});
|
|
174
|
-
// 6. Verify Ed25519 signature and SHA-256 checksum
|
|
175
|
-
const stat = await fs_extra_1.default.stat(tarPath);
|
|
176
|
-
if (stat.size === 0) {
|
|
177
|
-
throw new Error("Downloaded file is empty");
|
|
178
|
-
}
|
|
179
|
-
if (!options.skipVerify) {
|
|
180
|
-
spinner.text = `Verifying signature for ${slug} v${installVersion}...`;
|
|
181
|
-
const releaseInfo = await client.getReleaseInfo(slug, installVersion);
|
|
182
|
-
if (releaseInfo.checksum &&
|
|
183
|
-
releaseInfo.signature &&
|
|
184
|
-
releaseInfo.publicKey) {
|
|
185
|
-
await (0, SignatureVerifier_1.verifyDownload)({
|
|
186
|
-
filePath: tarPath,
|
|
187
|
-
expectedChecksum: releaseInfo.checksum,
|
|
188
|
-
signature: releaseInfo.signature,
|
|
189
|
-
publicKeyBase64: releaseInfo.publicKey,
|
|
190
|
-
});
|
|
191
|
-
spinner.text = `Signature verified for ${slug} v${installVersion}`;
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
spinner.text = `No signature data for ${slug} v${installVersion} — skipping verification`;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
// 7. Extract tarball
|
|
198
|
-
spinner.text = `Extracting ${slug} v${installVersion}...`;
|
|
199
|
-
await tar.x({ file: tarPath, cwd: extractDir });
|
|
200
|
-
// 8. Read module.json manifest from extracted dir
|
|
201
|
-
const manifestPath = path_1.default.join(extractDir, "module.json");
|
|
202
|
-
const manifestExists = await fs_extra_1.default.pathExists(manifestPath);
|
|
203
|
-
if (!manifestExists) {
|
|
204
|
-
throw new Error(`module.json not found in extracted archive for '${slug}'`);
|
|
205
|
-
}
|
|
206
|
-
const manifest = await fs_extra_1.default.readJson(manifestPath);
|
|
207
|
-
// 9. Delegate to ModuleInstaller
|
|
208
|
-
spinner.text = `Installing ${slug} v${installVersion}...`;
|
|
209
|
-
await installer.install(manifest);
|
|
210
|
-
spinner.succeed(chalk_1.default.green(`Module '${slug}@${installVersion}' installed successfully.`));
|
|
211
|
-
console.log(chalk_1.default.gray(`Use 'kaven module doctor' to verify the installation.`));
|
|
212
|
-
telemetry.capture("cli.marketplace.install.success", { slug, version: installVersion }, Date.now() - startTime);
|
|
213
|
-
await telemetry.flush();
|
|
214
|
-
}
|
|
215
|
-
catch (error) {
|
|
216
|
-
spinner.stop();
|
|
217
|
-
if (error instanceof errors_1.SignatureVerificationError) {
|
|
218
|
-
console.error(chalk_1.default.red(`Signature verification failed for '${slug}': ${error.message}`));
|
|
219
|
-
console.error(chalk_1.default.yellow("Use --skip-verify to bypass (not recommended)."));
|
|
220
|
-
telemetry.capture("cli.marketplace.install.error", { slug, error: "signature_verification_failed" }, Date.now() - startTime);
|
|
221
|
-
await telemetry.flush();
|
|
222
|
-
process.exit(1);
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
if (error instanceof errors_1.LicenseRequiredError) {
|
|
226
|
-
console.error(chalk_1.default.red(`License required: '${slug}' requires a '${error.requiredTier}' license.`));
|
|
227
|
-
console.error(chalk_1.default.yellow(`Run: kaven upgrade ${error.requiredTier}`));
|
|
228
|
-
telemetry.capture("cli.marketplace.install.error", { slug, error: "license_required", tier: error.requiredTier }, Date.now() - startTime);
|
|
229
|
-
await telemetry.flush();
|
|
230
|
-
process.exit(1);
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
if (error instanceof errors_1.AuthenticationError ||
|
|
234
|
-
(error instanceof Error &&
|
|
235
|
-
error.message.includes("Not authenticated"))) {
|
|
236
|
-
console.error(chalk_1.default.red("Authentication required. Run: kaven auth login"));
|
|
237
|
-
telemetry.capture("cli.marketplace.install.error", { slug, error: "auth_error" }, Date.now() - startTime);
|
|
238
|
-
await telemetry.flush();
|
|
239
|
-
process.exit(1);
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
if (error instanceof errors_1.NetworkError) {
|
|
243
|
-
console.error(chalk_1.default.red("Could not reach marketplace. Check your connection."));
|
|
244
|
-
telemetry.capture("cli.marketplace.install.error", { slug, error: "network_error" }, Date.now() - startTime);
|
|
245
|
-
await telemetry.flush();
|
|
246
|
-
process.exit(1);
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
telemetry.capture("cli.marketplace.install.error", { slug, error: error.message }, Date.now() - startTime);
|
|
250
|
-
await telemetry.flush();
|
|
251
|
-
spinner.fail(chalk_1.default.red(`Failed to install module '${slug}'.`));
|
|
252
|
-
console.error(error);
|
|
253
|
-
process.exit(1);
|
|
254
|
-
}
|
|
255
|
-
finally {
|
|
256
|
-
// 10. Always cleanup temp dir
|
|
257
|
-
if (tempDir) {
|
|
258
|
-
await fs_extra_1.default.remove(tempDir).catch(() => {
|
|
259
|
-
// Ignore cleanup errors
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
@@ -1,122 +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.marketplaceList = marketplaceList;
|
|
7
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
-
const ora_1 = __importDefault(require("ora"));
|
|
9
|
-
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
10
|
-
const MarketplaceClient_1 = require("../../infrastructure/MarketplaceClient");
|
|
11
|
-
const AuthService_1 = require("../../core/AuthService");
|
|
12
|
-
const errors_1 = require("../../infrastructure/errors");
|
|
13
|
-
const TelemetryBuffer_1 = require("../../infrastructure/TelemetryBuffer");
|
|
14
|
-
function colorTier(tier) {
|
|
15
|
-
switch (tier.toLowerCase()) {
|
|
16
|
-
case "starter":
|
|
17
|
-
return chalk_1.default.green(tier.toLowerCase());
|
|
18
|
-
case "complete":
|
|
19
|
-
return chalk_1.default.yellow(tier.toLowerCase());
|
|
20
|
-
case "pro":
|
|
21
|
-
return chalk_1.default.magenta(tier.toLowerCase());
|
|
22
|
-
case "enterprise":
|
|
23
|
-
return chalk_1.default.blue(tier.toLowerCase());
|
|
24
|
-
default:
|
|
25
|
-
return tier;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
async function marketplaceList(options = {}) {
|
|
29
|
-
const telemetry = TelemetryBuffer_1.TelemetryBuffer.getInstance();
|
|
30
|
-
const startTime = Date.now();
|
|
31
|
-
telemetry.capture("cli.marketplace.list.start");
|
|
32
|
-
const authService = new AuthService_1.AuthService();
|
|
33
|
-
const client = new MarketplaceClient_1.MarketplaceClient(authService);
|
|
34
|
-
const page = options.page ?? 1;
|
|
35
|
-
const pageSize = Math.min(options.limit ?? 20, 100);
|
|
36
|
-
const sort = options.sort ?? "newest";
|
|
37
|
-
// Check auth — warn but don't block
|
|
38
|
-
const isAuth = await authService.isAuthenticated();
|
|
39
|
-
if (!isAuth) {
|
|
40
|
-
console.log(chalk_1.default.yellow("Warning: Not authenticated. Only public modules will be shown. Run: kaven auth login"));
|
|
41
|
-
}
|
|
42
|
-
const spinner = (0, ora_1.default)("Fetching modules from Marketplace...").start();
|
|
43
|
-
try {
|
|
44
|
-
const result = await client.listModules({
|
|
45
|
-
category: options.category,
|
|
46
|
-
page,
|
|
47
|
-
pageSize,
|
|
48
|
-
q: sort === "newest" ? undefined : undefined,
|
|
49
|
-
});
|
|
50
|
-
spinner.stop();
|
|
51
|
-
const modules = result.data;
|
|
52
|
-
const meta = result.meta;
|
|
53
|
-
const total = result.total ?? meta?.total ?? modules.length;
|
|
54
|
-
if (options.json) {
|
|
55
|
-
console.log(JSON.stringify(result, null, 2));
|
|
56
|
-
telemetry.capture("cli.marketplace.list.success", { count: modules.length, json: true }, Date.now() - startTime);
|
|
57
|
-
await telemetry.flush();
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
if (modules.length === 0) {
|
|
61
|
-
console.log(chalk_1.default.yellow("No modules found matching your criteria."));
|
|
62
|
-
telemetry.capture("cli.marketplace.list.success", { count: 0 }, Date.now() - startTime);
|
|
63
|
-
await telemetry.flush();
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const table = new cli_table3_1.default({
|
|
67
|
-
head: [
|
|
68
|
-
chalk_1.default.white.bold("Slug"),
|
|
69
|
-
chalk_1.default.white.bold("Name"),
|
|
70
|
-
chalk_1.default.white.bold("Version"),
|
|
71
|
-
chalk_1.default.white.bold("Tier"),
|
|
72
|
-
chalk_1.default.white.bold("Installs"),
|
|
73
|
-
],
|
|
74
|
-
style: {
|
|
75
|
-
head: [],
|
|
76
|
-
border: ["gray"],
|
|
77
|
-
},
|
|
78
|
-
});
|
|
79
|
-
// Sort modules client-side based on sort option
|
|
80
|
-
const sorted = [...modules];
|
|
81
|
-
if (sort === "popular") {
|
|
82
|
-
sorted.sort((a, b) => b.installCount - a.installCount);
|
|
83
|
-
}
|
|
84
|
-
else if (sort === "name") {
|
|
85
|
-
sorted.sort((a, b) => a.name.localeCompare(b.name));
|
|
86
|
-
}
|
|
87
|
-
// newest = default server-side order
|
|
88
|
-
for (const mod of sorted) {
|
|
89
|
-
table.push([
|
|
90
|
-
chalk_1.default.cyan(mod.slug),
|
|
91
|
-
chalk_1.default.white(mod.name),
|
|
92
|
-
chalk_1.default.green(mod.latestVersion ?? "—"),
|
|
93
|
-
colorTier(mod.requiredTier ?? mod.tier ?? ""),
|
|
94
|
-
chalk_1.default.gray(String(mod.installCount)),
|
|
95
|
-
]);
|
|
96
|
-
}
|
|
97
|
-
console.log(chalk_1.default.blue.bold("\nAvailable Marketplace Modules:\n"));
|
|
98
|
-
console.log(table.toString());
|
|
99
|
-
// Pagination footer
|
|
100
|
-
const totalPages = Math.ceil(total / pageSize);
|
|
101
|
-
const startItem = (page - 1) * pageSize + 1;
|
|
102
|
-
const endItem = Math.min(page * pageSize, total);
|
|
103
|
-
console.log(chalk_1.default.gray(`\nShowing ${startItem}-${endItem} of ${total} modules (page ${page}/${totalPages})`));
|
|
104
|
-
console.log(chalk_1.default.gray("Use 'kaven marketplace install <slug>' to install a module."));
|
|
105
|
-
telemetry.capture("cli.marketplace.list.success", { count: modules.length, total }, Date.now() - startTime);
|
|
106
|
-
await telemetry.flush();
|
|
107
|
-
}
|
|
108
|
-
catch (error) {
|
|
109
|
-
spinner.stop();
|
|
110
|
-
if (error instanceof errors_1.NetworkError) {
|
|
111
|
-
console.error(chalk_1.default.red("Could not reach marketplace. Check your connection."));
|
|
112
|
-
telemetry.capture("cli.marketplace.list.error", { error: "network_error" }, Date.now() - startTime);
|
|
113
|
-
await telemetry.flush();
|
|
114
|
-
process.exit(1);
|
|
115
|
-
}
|
|
116
|
-
telemetry.capture("cli.marketplace.list.error", { error: error.message }, Date.now() - startTime);
|
|
117
|
-
await telemetry.flush();
|
|
118
|
-
console.error(chalk_1.default.red("Error fetching modules from Marketplace."));
|
|
119
|
-
console.error(error);
|
|
120
|
-
process.exit(1);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
@@ -1,245 +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.moduleActivate = moduleActivate;
|
|
7
|
-
exports.moduleDeactivate = moduleDeactivate;
|
|
8
|
-
exports.moduleListActivation = moduleListActivation;
|
|
9
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
-
const ora_1 = __importDefault(require("ora"));
|
|
11
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
-
const prompts_1 = require("@inquirer/prompts");
|
|
13
|
-
const SchemaActivator_1 = require("../../core/SchemaActivator");
|
|
14
|
-
const TelemetryBuffer_1 = require("../../infrastructure/TelemetryBuffer");
|
|
15
|
-
// ============================================================
|
|
16
|
-
// Helpers
|
|
17
|
-
// ============================================================
|
|
18
|
-
function findModuleDef(moduleId) {
|
|
19
|
-
return SchemaActivator_1.KAVEN_MODULES.find((m) => m.id === moduleId.toLowerCase());
|
|
20
|
-
}
|
|
21
|
-
function assertSchemaExists(exists, root) {
|
|
22
|
-
if (!exists) {
|
|
23
|
-
const fullPath = node_path_1.default.join(root, "packages", "database", "prisma", "schema.extended.prisma");
|
|
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."));
|
|
26
|
-
process.exit(1);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
// ============================================================
|
|
30
|
-
// kaven module activate <name>
|
|
31
|
-
// ============================================================
|
|
32
|
-
async function moduleActivate(moduleName, projectRoot, options = {}) {
|
|
33
|
-
const telemetry = TelemetryBuffer_1.TelemetryBuffer.getInstance();
|
|
34
|
-
const startTime = Date.now();
|
|
35
|
-
telemetry.capture("cli.module.activate.start", { moduleName });
|
|
36
|
-
const root = projectRoot ?? process.cwd();
|
|
37
|
-
const activator = new SchemaActivator_1.SchemaActivator(root);
|
|
38
|
-
const spinner = (0, ora_1.default)(`Activating module ${moduleName}...`).start();
|
|
39
|
-
try {
|
|
40
|
-
// 1. Validate schema exists
|
|
41
|
-
const exists = await activator.exists();
|
|
42
|
-
spinner.stop();
|
|
43
|
-
assertSchemaExists(exists, root);
|
|
44
|
-
// 2. Validate module is known
|
|
45
|
-
const def = findModuleDef(moduleName);
|
|
46
|
-
if (!def) {
|
|
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(", ")}`));
|
|
49
|
-
process.exit(1);
|
|
50
|
-
}
|
|
51
|
-
// 3. Check dependencies
|
|
52
|
-
if (def.dependsOn.length > 0) {
|
|
53
|
-
spinner.start("Checking dependencies...");
|
|
54
|
-
const depStatuses = [];
|
|
55
|
-
for (const depId of def.dependsOn) {
|
|
56
|
-
const depDef = findModuleDef(depId);
|
|
57
|
-
if (!depDef)
|
|
58
|
-
continue;
|
|
59
|
-
const status = await activator.getModuleStatus(depDef);
|
|
60
|
-
depStatuses.push(status);
|
|
61
|
-
}
|
|
62
|
-
const missing = depStatuses.filter((s) => !s.active);
|
|
63
|
-
if (missing.length > 0) {
|
|
64
|
-
spinner.stop();
|
|
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
|
-
}
|
|
77
|
-
}
|
|
78
|
-
spinner.stop();
|
|
79
|
-
}
|
|
80
|
-
// 4. Check if already active
|
|
81
|
-
const current = await activator.getModuleStatus(def);
|
|
82
|
-
if (current.active) {
|
|
83
|
-
console.log(chalk_1.default.yellow(`\nModule "${def.label}" is already active.`));
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
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...`);
|
|
108
|
-
await activator.activateModule(def);
|
|
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
|
-
}
|
|
113
|
-
telemetry.capture("cli.module.activate.success", { moduleName: def.id, models: def.models.length }, Date.now() - startTime);
|
|
114
|
-
await telemetry.flush();
|
|
115
|
-
}
|
|
116
|
-
catch (error) {
|
|
117
|
-
spinner.fail(chalk_1.default.red(`Failed to activate module: ${error instanceof Error ? error.message : String(error)}`));
|
|
118
|
-
telemetry.capture("cli.module.activate.error", { moduleName, error: error.message }, Date.now() - startTime);
|
|
119
|
-
await telemetry.flush();
|
|
120
|
-
process.exit(1);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
// ============================================================
|
|
124
|
-
// kaven module deactivate <name>
|
|
125
|
-
// ============================================================
|
|
126
|
-
async function moduleDeactivate(moduleName, projectRoot, options = {}) {
|
|
127
|
-
const telemetry = TelemetryBuffer_1.TelemetryBuffer.getInstance();
|
|
128
|
-
const startTime = Date.now();
|
|
129
|
-
telemetry.capture("cli.module.deactivate.start", { moduleName });
|
|
130
|
-
const root = projectRoot ?? process.cwd();
|
|
131
|
-
const activator = new SchemaActivator_1.SchemaActivator(root);
|
|
132
|
-
const spinner = (0, ora_1.default)(`Deactivating module ${moduleName}...`).start();
|
|
133
|
-
try {
|
|
134
|
-
// 1. Validate schema exists
|
|
135
|
-
const exists = await activator.exists();
|
|
136
|
-
spinner.stop();
|
|
137
|
-
assertSchemaExists(exists, root);
|
|
138
|
-
// 2. Validate module
|
|
139
|
-
const def = findModuleDef(moduleName);
|
|
140
|
-
if (!def) {
|
|
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(", ")}`));
|
|
143
|
-
process.exit(1);
|
|
144
|
-
}
|
|
145
|
-
// 3. Check for active dependents
|
|
146
|
-
spinner.start("Checking reverse dependencies...");
|
|
147
|
-
const dependents = [];
|
|
148
|
-
for (const candidate of SchemaActivator_1.KAVEN_MODULES) {
|
|
149
|
-
if (candidate.id === def.id)
|
|
150
|
-
continue;
|
|
151
|
-
if (!candidate.dependsOn.includes(def.id))
|
|
152
|
-
continue;
|
|
153
|
-
const status = await activator.getModuleStatus(candidate);
|
|
154
|
-
if (status.active) {
|
|
155
|
-
dependents.push(candidate.id);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
if (dependents.length > 0) {
|
|
159
|
-
spinner.stop();
|
|
160
|
-
console.error(chalk_1.default.red(`\nCannot deactivate "${moduleName}": the following active modules depend on it:`));
|
|
161
|
-
console.error(chalk_1.default.gray(` ${dependents.join(", ")}`));
|
|
162
|
-
console.error(chalk_1.default.gray(`Deactivate them first:\n${dependents.map((d) => ` kaven module deactivate ${d}`).join("\n")}`));
|
|
163
|
-
process.exit(1);
|
|
164
|
-
}
|
|
165
|
-
// 4. Check if already inactive
|
|
166
|
-
const current = await activator.getModuleStatus(def);
|
|
167
|
-
if (!current.active) {
|
|
168
|
-
spinner.stop();
|
|
169
|
-
console.log(chalk_1.default.yellow(`\nModule "${def.label}" is already inactive.`));
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
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...`);
|
|
181
|
-
await activator.deactivateModule(def);
|
|
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
|
-
}
|
|
186
|
-
telemetry.capture("cli.module.deactivate.success", { moduleName: def.id }, Date.now() - startTime);
|
|
187
|
-
await telemetry.flush();
|
|
188
|
-
}
|
|
189
|
-
catch (error) {
|
|
190
|
-
spinner.fail(chalk_1.default.red(`Failed to deactivate module: ${error instanceof Error ? error.message : String(error)}`));
|
|
191
|
-
telemetry.capture("cli.module.deactivate.error", { moduleName, error: error.message }, Date.now() - startTime);
|
|
192
|
-
await telemetry.flush();
|
|
193
|
-
process.exit(1);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
// ============================================================
|
|
197
|
-
// kaven module list
|
|
198
|
-
// ============================================================
|
|
199
|
-
async function moduleListActivation(projectRoot) {
|
|
200
|
-
const root = projectRoot ?? process.cwd();
|
|
201
|
-
const activator = new SchemaActivator_1.SchemaActivator(root);
|
|
202
|
-
const schemaExists = await activator.exists();
|
|
203
|
-
// Table header
|
|
204
|
-
const COL = {
|
|
205
|
-
module: 18,
|
|
206
|
-
status: 10,
|
|
207
|
-
models: 44,
|
|
208
|
-
deps: 20,
|
|
209
|
-
};
|
|
210
|
-
const header = chalk_1.default.bold("Module".padEnd(COL.module)) +
|
|
211
|
-
chalk_1.default.bold("Status".padEnd(COL.status)) +
|
|
212
|
-
chalk_1.default.bold("Models".padEnd(COL.models)) +
|
|
213
|
-
chalk_1.default.bold("Depends on");
|
|
214
|
-
const divider = "─".repeat(COL.module + COL.status + COL.models + COL.deps);
|
|
215
|
-
console.log();
|
|
216
|
-
console.log(chalk_1.default.blue("Kaven Schema Modules\n"));
|
|
217
|
-
console.log(header);
|
|
218
|
-
console.log(chalk_1.default.gray(divider));
|
|
219
|
-
if (!schemaExists) {
|
|
220
|
-
for (const def of SchemaActivator_1.KAVEN_MODULES) {
|
|
221
|
-
const modCol = def.id.padEnd(COL.module);
|
|
222
|
-
const statusCol = chalk_1.default.gray("unknown".padEnd(COL.status));
|
|
223
|
-
const modelsCol = def.models.join(", ").padEnd(COL.models);
|
|
224
|
-
const depsCol = def.dependsOn.length > 0 ? def.dependsOn.join(", ") : "—";
|
|
225
|
-
console.log(`${modCol}${statusCol}${modelsCol}${depsCol}`);
|
|
226
|
-
}
|
|
227
|
-
console.log();
|
|
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."));
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
for (const def of SchemaActivator_1.KAVEN_MODULES) {
|
|
233
|
-
const status = await activator.getModuleStatus(def);
|
|
234
|
-
const modCol = def.id.padEnd(COL.module);
|
|
235
|
-
const statusText = status.active ? "active" : "inactive";
|
|
236
|
-
const statusColored = status.active
|
|
237
|
-
? chalk_1.default.green(statusText.padEnd(COL.status))
|
|
238
|
-
: chalk_1.default.gray(statusText.padEnd(COL.status));
|
|
239
|
-
const modelsCol = def.models.join(", ").padEnd(COL.models);
|
|
240
|
-
const depsCol = def.dependsOn.length > 0 ? def.dependsOn.join(", ") : "—";
|
|
241
|
-
console.log(`${modCol}${statusColored}${modelsCol}${depsCol}`);
|
|
242
|
-
}
|
|
243
|
-
console.log();
|
|
244
|
-
console.log(chalk_1.default.gray("To activate: kaven module activate <name> | To deactivate: kaven module deactivate <name>"));
|
|
245
|
-
}
|