kaven-cli 0.4.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 +216 -286
- package/dist/tier-table-DQMPQSI2.js +6 -0
- package/package.json +26 -10
- 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 -1026
- package/dist/commands/config/index.js +0 -95
- package/dist/commands/index.js +0 -2
- package/dist/commands/init/index.js +0 -197
- 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 -206
- package/dist/commands/module/add.js +0 -69
- package/dist/commands/module/doctor.js +0 -175
- 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 -166
- package/dist/core/RegistryResolver.js +0 -95
- package/dist/core/SchemaActivator.js +0 -270
- 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 -399
- 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/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
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import i from"cli-table3";import e from"chalk";var l=[{name:"STARTER",price:"$149",projects:"1",tenants:"10",marketplace:!1},{name:"COMPLETE",price:"$399",projects:"1",tenants:"Unlimited",marketplace:!1},{name:"PRO",price:"$799",projects:"5",tenants:"Unlimited",marketplace:!0},{name:"ENTERPRISE",price:"Custom",projects:"Unlimited",tenants:"Unlimited",marketplace:!0}];function r(n){switch(n.toUpperCase()){case"STARTER":return e.green(n);case"COMPLETE":return e.yellow(n);case"PRO":return e.magenta(n);case"ENTERPRISE":return e.cyan(n);default:return n}}function R(n,a){console.log(e.red(`
|
|
2
|
+
\u2717 License tier insufficient
|
|
3
|
+
`)),console.log(` Your tier: ${r(n)}`),console.log(` Required tier: ${r(a)}
|
|
4
|
+
`);let o=new i({head:["Tier","Price","Projects","Tenants","Marketplace"],style:{head:["cyan"]}});for(let t of l){let s=t.name===n.toUpperCase(),c=t.name===a.toUpperCase()?e.yellow(" \u2190 required"):s?e.dim(" \u2190 you"):"";o.push([r(t.name)+c,t.price,t.projects,t.tenants,t.marketplace?e.green("\u2713"):e.dim("\u2717")])}console.log(o.toString()),console.log(e.dim(`
|
|
5
|
+
Upgrade at: https://kaven.dev/pricing
|
|
6
|
+
`))}export{R as printTierComparisonTable};
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kaven-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "Kaven CLI - The official command line tool for Kaven",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"bin": {
|
|
@@ -11,13 +12,14 @@
|
|
|
11
12
|
"README.md"
|
|
12
13
|
],
|
|
13
14
|
"scripts": {
|
|
14
|
-
"build": "
|
|
15
|
+
"build": "tsup src/index.ts --format esm --clean --minify --shims --dts",
|
|
16
|
+
"dev": "tsup src/index.ts --format esm --watch --silent",
|
|
15
17
|
"prepublishOnly": "pnpm run build",
|
|
16
18
|
"lint": "eslint 'src/**/*.{ts,tsx}' --max-warnings 0",
|
|
17
19
|
"lint:fix": "eslint 'src/**/*.{ts,tsx}' --fix",
|
|
18
|
-
"test": "
|
|
19
|
-
"test:watch": "
|
|
20
|
-
"test:coverage": "
|
|
20
|
+
"test": "node scripts/run-tests.mjs",
|
|
21
|
+
"test:watch": "node --import tsx --test --watch 'src/**/*.test.ts' 'tests/**/*.test.ts'",
|
|
22
|
+
"test:coverage": "node --import tsx --test --experimental-test-coverage 'src/**/*.test.ts' 'tests/**/*.test.ts'",
|
|
21
23
|
"typecheck": "tsc --noEmit",
|
|
22
24
|
"quality": "pnpm run lint && pnpm run typecheck && pnpm run test",
|
|
23
25
|
"quality:gate": "./.agent/scripts/quality-gate.sh",
|
|
@@ -48,7 +50,8 @@
|
|
|
48
50
|
"@semantic-release/npm": "^13.1.5",
|
|
49
51
|
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
50
52
|
"@types/fs-extra": "^11.0.4",
|
|
51
|
-
"@types/
|
|
53
|
+
"@types/js-yaml": "^4.0.9",
|
|
54
|
+
"@types/node": "^25.6.0",
|
|
52
55
|
"@types/tar": "^6.1.13",
|
|
53
56
|
"@typescript-eslint/eslint-plugin": "^8.53.1",
|
|
54
57
|
"@typescript-eslint/parser": "^8.53.1",
|
|
@@ -56,29 +59,42 @@
|
|
|
56
59
|
"msw": "^2.12.10",
|
|
57
60
|
"semantic-release": "^25.0.3",
|
|
58
61
|
"tsup": "^8.5.1",
|
|
59
|
-
"
|
|
60
|
-
"
|
|
62
|
+
"tsx": "^4.21.0",
|
|
63
|
+
"typescript": "^5.0.0"
|
|
61
64
|
},
|
|
62
65
|
"engines": {
|
|
63
66
|
"node": ">=20"
|
|
64
67
|
},
|
|
65
68
|
"dependencies": {
|
|
69
|
+
"@clack/prompts": "^1.2.0",
|
|
66
70
|
"@inquirer/prompts": "^7.5.2",
|
|
67
71
|
"chalk": "^5.6.2",
|
|
68
72
|
"cli-table3": "^0.6.5",
|
|
69
73
|
"commander": "^14.0.2",
|
|
70
74
|
"fs-extra": "^11.3.3",
|
|
71
75
|
"glob": "^13.0.0",
|
|
76
|
+
"i18next": "^26.0.6",
|
|
77
|
+
"js-yaml": "^4.1.1",
|
|
72
78
|
"open": "^10.1.0",
|
|
73
79
|
"ora": "^9.1.0",
|
|
80
|
+
"picocolors": "^1.1.1",
|
|
74
81
|
"tar": "^7.5.9",
|
|
75
82
|
"zod": "^4.3.6"
|
|
76
83
|
},
|
|
77
84
|
"pnpm": {
|
|
78
85
|
"overrides": {
|
|
79
|
-
"minimatch@<10.2.
|
|
86
|
+
"minimatch@<10.2.3": ">=10.2.3",
|
|
80
87
|
"@isaacs/brace-expansion@<=5.0.0": ">=5.0.1",
|
|
81
|
-
"esbuild@<=0.24.2": ">=0.25.0"
|
|
88
|
+
"esbuild@<=0.24.2": ">=0.25.0",
|
|
89
|
+
"handlebars@<=4.7.8": ">=4.7.9",
|
|
90
|
+
"tar@<=7.5.10": ">=7.5.11",
|
|
91
|
+
"lodash@<=4.17.23": ">=4.18.0",
|
|
92
|
+
"lodash-es@<=4.17.23": ">=4.18.0",
|
|
93
|
+
"rollup@<4.59.0": ">=4.59.0",
|
|
94
|
+
"vite@<=6.4.1": ">=6.4.2",
|
|
95
|
+
"flatted@<=3.4.1": ">=3.4.2",
|
|
96
|
+
"picomatch@<2.3.2": ">=2.3.2",
|
|
97
|
+
"picomatch@>=4.0.0 <4.0.4": ">=4.0.4"
|
|
82
98
|
}
|
|
83
99
|
}
|
|
84
100
|
}
|
|
@@ -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.authLogin = authLogin;
|
|
7
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
-
const ora_1 = __importDefault(require("ora"));
|
|
9
|
-
const open_1 = __importDefault(require("open"));
|
|
10
|
-
const AuthService_1 = require("../../core/AuthService");
|
|
11
|
-
const MarketplaceClient_1 = require("../../infrastructure/MarketplaceClient");
|
|
12
|
-
const TelemetryBuffer_1 = require("../../infrastructure/TelemetryBuffer");
|
|
13
|
-
/**
|
|
14
|
-
* Sleep helper for polling delays
|
|
15
|
-
*/
|
|
16
|
-
function sleep(ms) {
|
|
17
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Poll for access token with exponential backoff
|
|
21
|
-
*/
|
|
22
|
-
async function pollForToken(client, deviceCode, expiresIn, initialInterval, spinner) {
|
|
23
|
-
const deadline = Date.now() + expiresIn * 1000;
|
|
24
|
-
const backoffIntervals = [5, 10, 15, 20]; // seconds - exponential backoff
|
|
25
|
-
let backoffIndex = 0;
|
|
26
|
-
let interval = initialInterval;
|
|
27
|
-
while (Date.now() < deadline) {
|
|
28
|
-
// Update countdown spinner
|
|
29
|
-
const remaining = Math.ceil((deadline - Date.now()) / 1000);
|
|
30
|
-
const mm = Math.floor(remaining / 60);
|
|
31
|
-
const ss = String(remaining % 60).padStart(2, '0');
|
|
32
|
-
spinner.text = `Waiting for authorization... (expires in ${mm}:${ss})`;
|
|
33
|
-
// Wait for next poll
|
|
34
|
-
await sleep(interval * 1000);
|
|
35
|
-
try {
|
|
36
|
-
const result = await client.pollDeviceToken(deviceCode);
|
|
37
|
-
// Success - return tokens
|
|
38
|
-
if (result.status === 'success' && result.tokens) {
|
|
39
|
-
return result.tokens;
|
|
40
|
-
}
|
|
41
|
-
// Handle different status codes
|
|
42
|
-
switch (result.status) {
|
|
43
|
-
case 'slow_down':
|
|
44
|
-
// Increase interval by 5s as requested by server
|
|
45
|
-
interval += 5;
|
|
46
|
-
break;
|
|
47
|
-
case 'access_denied':
|
|
48
|
-
throw new Error('Authorization denied by user. Try again with \'kaven auth login\'.');
|
|
49
|
-
case 'expired_token':
|
|
50
|
-
throw new Error('Device code expired. Run \'kaven auth login\' again.');
|
|
51
|
-
case 'authorization_pending':
|
|
52
|
-
// Continue polling - apply exponential backoff
|
|
53
|
-
if (backoffIndex < backoffIntervals.length - 1) {
|
|
54
|
-
backoffIndex++;
|
|
55
|
-
interval = backoffIntervals[backoffIndex];
|
|
56
|
-
}
|
|
57
|
-
break;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
catch (error) {
|
|
61
|
-
// Re-throw our custom errors
|
|
62
|
-
if (error.message.includes('denied') ||
|
|
63
|
-
error.message.includes('expired')) {
|
|
64
|
-
throw error;
|
|
65
|
-
}
|
|
66
|
-
// Network errors
|
|
67
|
-
const nodeError = error;
|
|
68
|
-
if (nodeError.code === 'ECONNREFUSED' || nodeError.code === 'ENOTFOUND') {
|
|
69
|
-
throw new Error('Network error. Check your connection and try again.');
|
|
70
|
-
}
|
|
71
|
-
// Unknown error
|
|
72
|
-
throw error;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
// Timeout - device code expired
|
|
76
|
-
throw new Error('Device code expired. Run \'kaven auth login\' again.');
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Main login command - OAuth 2.0 Device Authorization Grant (RFC 8628)
|
|
80
|
-
*/
|
|
81
|
-
async function authLogin() {
|
|
82
|
-
const telemetry = TelemetryBuffer_1.TelemetryBuffer.getInstance();
|
|
83
|
-
const startTime = Date.now();
|
|
84
|
-
telemetry.capture("cli.auth.login.start");
|
|
85
|
-
const client = new MarketplaceClient_1.MarketplaceClient();
|
|
86
|
-
const authService = new AuthService_1.AuthService();
|
|
87
|
-
console.log(chalk_1.default.blue("🔐 Starting authentication flow...\n"));
|
|
88
|
-
const spinner = (0, ora_1.default)("Requesting device code from marketplace...").start();
|
|
89
|
-
try {
|
|
90
|
-
// Step 1: Request device code
|
|
91
|
-
const { device_code, user_code, verification_uri, expires_in, interval } = await client.requestDeviceCode();
|
|
92
|
-
spinner.stop();
|
|
93
|
-
// Step 2: Display code and open browser
|
|
94
|
-
console.log(chalk_1.default.yellow("To complete login, follow these steps:\n"));
|
|
95
|
-
console.log(chalk_1.default.bold(` Your verification code: ${chalk_1.default.cyan(user_code)}\n`));
|
|
96
|
-
try {
|
|
97
|
-
await (0, open_1.default)(verification_uri);
|
|
98
|
-
console.log(chalk_1.default.dim(" ✓ Browser opened automatically"));
|
|
99
|
-
}
|
|
100
|
-
catch {
|
|
101
|
-
console.log(chalk_1.default.yellow(` Open this URL in your browser:`));
|
|
102
|
-
console.log(chalk_1.default.underline(` ${verification_uri}\n`));
|
|
103
|
-
}
|
|
104
|
-
// Step 3: Poll for token with exponential backoff
|
|
105
|
-
const pollSpinner = (0, ora_1.default)('Waiting for authorization...').start();
|
|
106
|
-
const tokens = await pollForToken(client, device_code, expires_in, interval, pollSpinner);
|
|
107
|
-
// Step 4: Store tokens securely
|
|
108
|
-
await authService.saveTokens(tokens);
|
|
109
|
-
pollSpinner.succeed(chalk_1.default.green(`Logged in as ${chalk_1.default.bold(tokens.user.email)}`));
|
|
110
|
-
console.log(chalk_1.default.dim(` Tier: ${tokens.user.tier}`));
|
|
111
|
-
console.log(chalk_1.default.gray("\n Your credentials were saved securely in ~/.kaven/auth.json\n"));
|
|
112
|
-
telemetry.capture("cli.auth.login.success", { tier: tokens.user.tier }, Date.now() - startTime);
|
|
113
|
-
await telemetry.flush();
|
|
114
|
-
}
|
|
115
|
-
catch (error) {
|
|
116
|
-
telemetry.capture("cli.auth.login.error", { error: error.message }, Date.now() - startTime);
|
|
117
|
-
await telemetry.flush();
|
|
118
|
-
spinner.fail(chalk_1.default.red("Authentication failed"));
|
|
119
|
-
console.error(chalk_1.default.red(`\n Error: ${error.message}\n`));
|
|
120
|
-
process.exit(1);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
@@ -1,23 +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.authLogout = authLogout;
|
|
7
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
-
const AuthService_1 = require("../../core/AuthService");
|
|
9
|
-
async function authLogout() {
|
|
10
|
-
const authService = new AuthService_1.AuthService();
|
|
11
|
-
try {
|
|
12
|
-
if (!(await authService.isAuthenticated())) {
|
|
13
|
-
console.log(chalk_1.default.yellow("You are not authenticated."));
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
await authService.logout();
|
|
17
|
-
console.log(chalk_1.default.green("Logged out successfully."));
|
|
18
|
-
}
|
|
19
|
-
catch {
|
|
20
|
-
console.error(chalk_1.default.red("Error during logout."));
|
|
21
|
-
process.exit(1);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
@@ -1,36 +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.authWhoami = authWhoami;
|
|
7
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
-
const AuthService_1 = require("../../core/AuthService");
|
|
9
|
-
const TelemetryBuffer_1 = require("../../infrastructure/TelemetryBuffer");
|
|
10
|
-
async function authWhoami() {
|
|
11
|
-
const telemetry = TelemetryBuffer_1.TelemetryBuffer.getInstance();
|
|
12
|
-
telemetry.capture("cli.auth.whoami.start");
|
|
13
|
-
const authService = new AuthService_1.AuthService();
|
|
14
|
-
try {
|
|
15
|
-
const info = await authService.getWhoamiInfo();
|
|
16
|
-
if (!info) {
|
|
17
|
-
console.log(chalk_1.default.yellow("You are not authenticated."));
|
|
18
|
-
console.log(chalk_1.default.gray("Use 'kaven auth login' to sign in."));
|
|
19
|
-
telemetry.capture("cli.auth.whoami.not_authenticated");
|
|
20
|
-
await telemetry.flush();
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
telemetry.capture("cli.auth.whoami.authenticated");
|
|
24
|
-
console.log();
|
|
25
|
-
console.log(` ${chalk_1.default.bold("Email:")} ${info.email}`);
|
|
26
|
-
console.log(` ${chalk_1.default.bold("GitHub:")} ${info.githubId}`);
|
|
27
|
-
console.log(` ${chalk_1.default.bold("Tier:")} ${info.tier}`);
|
|
28
|
-
console.log(` ${chalk_1.default.bold("Session:")} ${info.sessionExpiry}`);
|
|
29
|
-
console.log();
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
console.error(chalk_1.default.red("Error checking authentication status."));
|
|
33
|
-
process.exit(1);
|
|
34
|
-
}
|
|
35
|
-
await telemetry.flush();
|
|
36
|
-
}
|
|
@@ -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
|
-
}
|