kaven-cli 0.1.0-alpha.1 → 0.3.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 +221 -45
- package/dist/commands/auth/login.js +97 -19
- package/dist/commands/auth/logout.js +4 -6
- package/dist/commands/auth/whoami.js +12 -11
- package/dist/commands/cache/index.js +43 -0
- package/dist/commands/config/index.js +128 -0
- package/dist/commands/init/index.js +209 -0
- package/dist/commands/init-ci/index.js +153 -0
- package/dist/commands/license/index.js +10 -0
- package/dist/commands/license/status.js +44 -0
- package/dist/commands/license/tier-table.js +46 -0
- package/dist/commands/marketplace/browse.js +219 -0
- package/dist/commands/marketplace/install.js +233 -29
- package/dist/commands/marketplace/list.js +94 -16
- package/dist/commands/module/doctor.js +143 -38
- package/dist/commands/module/publish.js +291 -0
- package/dist/commands/upgrade/check.js +162 -0
- package/dist/commands/upgrade/index.js +218 -0
- package/dist/core/AuthService.js +207 -14
- package/dist/core/CacheManager.js +151 -0
- package/dist/core/ConfigManager.js +165 -0
- package/dist/core/EnvManager.js +196 -0
- package/dist/core/ErrorRecovery.js +191 -0
- package/dist/core/LicenseService.js +118 -0
- package/dist/core/ModuleDoctor.js +286 -0
- package/dist/core/ModuleInstaller.js +136 -2
- package/dist/core/ProjectInitializer.js +117 -0
- package/dist/core/RegistryResolver.js +94 -0
- package/dist/core/ScriptRunner.js +72 -0
- package/dist/core/SignatureVerifier.js +72 -0
- package/dist/index.js +265 -20
- package/dist/infrastructure/MarketplaceClient.js +388 -64
- package/dist/infrastructure/errors.js +61 -0
- package/dist/types/auth.js +2 -0
- package/dist/types/marketplace.js +2 -0
- package/package.json +15 -2
package/README.md
CHANGED
|
@@ -1,93 +1,269 @@
|
|
|
1
|
-
# Kaven CLI
|
|
1
|
+
# Kaven CLI
|
|
2
2
|
|
|
3
3
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
4
|
-
[](https://semver.org)
|
|
5
|
+
[](https://nodejs.org)
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
The official command-line tool for the **Kaven** SaaS boilerplate ecosystem.
|
|
8
|
+
Bootstrap projects, manage modules, and interact with the Kaven Marketplace.
|
|
7
9
|
|
|
8
|
-
> **
|
|
10
|
+
> **Alpha**: APIs and commands are subject to change before v1.0.0.
|
|
9
11
|
|
|
10
12
|
---
|
|
11
13
|
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
A CLI pode ser instalada globalmente via npm ou pnpm:
|
|
14
|
+
## Installation
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
17
|
npm install -g kaven-cli@alpha
|
|
18
|
-
#
|
|
18
|
+
# or
|
|
19
19
|
pnpm add -g kaven-cli@alpha
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
**Requirements:** Node.js >= 20, pnpm (for `kaven init`)
|
|
23
|
+
|
|
24
|
+
---
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
Five commands to get productive with Kaven:
|
|
25
29
|
|
|
26
30
|
```bash
|
|
27
|
-
# 1.
|
|
31
|
+
# 1. Bootstrap a new project
|
|
32
|
+
kaven init my-saas-app
|
|
33
|
+
|
|
34
|
+
# 2. Authenticate with the marketplace
|
|
28
35
|
kaven auth login
|
|
29
36
|
|
|
30
|
-
#
|
|
31
|
-
kaven marketplace
|
|
37
|
+
# 3. Browse available modules
|
|
38
|
+
kaven marketplace browse
|
|
32
39
|
|
|
33
|
-
#
|
|
40
|
+
# 4. Install a module
|
|
34
41
|
kaven marketplace install payments
|
|
35
42
|
|
|
36
|
-
#
|
|
43
|
+
# 5. Check project health
|
|
37
44
|
kaven module doctor
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Command Reference
|
|
50
|
+
|
|
51
|
+
### `kaven init [project-name]`
|
|
38
52
|
|
|
39
|
-
|
|
40
|
-
|
|
53
|
+
Bootstrap a new Kaven project from the official template.
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
Options:
|
|
57
|
+
--defaults Skip interactive prompts and use default values
|
|
58
|
+
--skip-install Skip running pnpm install after setup
|
|
59
|
+
--skip-git Skip git init and initial commit
|
|
60
|
+
--force Overwrite existing directory
|
|
61
|
+
|
|
62
|
+
Examples:
|
|
63
|
+
kaven init my-app
|
|
64
|
+
kaven init my-app --defaults
|
|
65
|
+
kaven init my-app --skip-git --skip-install
|
|
41
66
|
```
|
|
42
67
|
|
|
43
|
-
|
|
68
|
+
### `kaven auth`
|
|
44
69
|
|
|
45
|
-
|
|
70
|
+
Manage authentication and session tokens.
|
|
46
71
|
|
|
47
|
-
|
|
72
|
+
```
|
|
73
|
+
Commands:
|
|
74
|
+
login Start device code authentication flow (RFC 8628)
|
|
75
|
+
logout Clear the local authentication session
|
|
76
|
+
whoami Display info about the authenticated user
|
|
77
|
+
```
|
|
48
78
|
|
|
49
|
-
|
|
79
|
+
### `kaven marketplace`
|
|
50
80
|
|
|
51
|
-
|
|
52
|
-
- `kaven module remove <name>`: Remove um módulo e limpa as injeções de código.
|
|
53
|
-
- `kaven module doctor`: Verifica a integridade dos markers, âncoras e dependências.
|
|
81
|
+
Explore and install modules from the Kaven Marketplace.
|
|
54
82
|
|
|
55
|
-
|
|
83
|
+
```
|
|
84
|
+
Commands:
|
|
85
|
+
list List available modules
|
|
86
|
+
install Install a module
|
|
87
|
+
browse Interactive TUI module browser
|
|
88
|
+
|
|
89
|
+
Options for list:
|
|
90
|
+
--category <cat> Filter by category
|
|
91
|
+
--sort <field> Sort: newest (default), popular, name
|
|
92
|
+
--page <n> Page number
|
|
93
|
+
--limit <n> Results per page (max: 100)
|
|
94
|
+
--json Output raw JSON
|
|
95
|
+
|
|
96
|
+
Options for install:
|
|
97
|
+
--version <ver> Install specific version
|
|
98
|
+
--force Skip overwrite confirmation
|
|
99
|
+
--skip-env Skip .env injection
|
|
100
|
+
--env-file <path> Target .env file
|
|
101
|
+
```
|
|
56
102
|
|
|
57
|
-
|
|
103
|
+
### `kaven module`
|
|
58
104
|
|
|
59
|
-
|
|
60
|
-
- `kaven auth logout`: Remove as credenciais locais.
|
|
61
|
-
- `kaven auth whoami`: Exibe informações do usuário atual.
|
|
105
|
+
Manage installed modules.
|
|
62
106
|
|
|
63
|
-
|
|
107
|
+
```
|
|
108
|
+
Commands:
|
|
109
|
+
doctor Run health checks on the project and modules
|
|
110
|
+
add Install a module from a local manifest
|
|
111
|
+
remove Remove an installed module
|
|
112
|
+
publish Publish a module to the marketplace
|
|
113
|
+
|
|
114
|
+
Options for doctor:
|
|
115
|
+
--fix Auto-fix detected issues (pnpm install, prisma generate, env vars)
|
|
116
|
+
--json Output machine-readable JSON
|
|
117
|
+
|
|
118
|
+
Exit codes for doctor:
|
|
119
|
+
0 All checks passed
|
|
120
|
+
1 One or more errors found
|
|
121
|
+
2 Warnings only (no errors)
|
|
122
|
+
|
|
123
|
+
Options for publish:
|
|
124
|
+
--dry-run Validate and package without uploading
|
|
125
|
+
--changelog <text> Release notes for this version
|
|
126
|
+
```
|
|
64
127
|
|
|
65
|
-
|
|
128
|
+
### `kaven upgrade`
|
|
66
129
|
|
|
67
|
-
|
|
68
|
-
- `kaven marketplace install <id>`: Baixa e instala um módulo automaticamente.
|
|
130
|
+
Upgrade your Kaven license tier via Paddle checkout.
|
|
69
131
|
|
|
70
|
-
|
|
132
|
+
```
|
|
133
|
+
Options:
|
|
134
|
+
--no-browser Print checkout URL instead of opening browser
|
|
71
135
|
|
|
72
|
-
|
|
136
|
+
Behavior:
|
|
137
|
+
- Opens a Paddle checkout in your browser
|
|
138
|
+
- Polls for payment confirmation (every 5s, max 10 min)
|
|
139
|
+
- Updates local license on success
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### `kaven license`
|
|
143
|
+
|
|
144
|
+
Manage your Kaven license.
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
Commands:
|
|
148
|
+
status Show current license status and tier
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### `kaven cache`
|
|
152
|
+
|
|
153
|
+
Manage the local API response cache (~/.kaven/cache, max 50 MB).
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
Commands:
|
|
157
|
+
status Show cache statistics (size, entries, age)
|
|
158
|
+
clear Delete all cached data
|
|
159
|
+
|
|
160
|
+
Cache TTLs:
|
|
161
|
+
Module listings: 24 hours
|
|
162
|
+
Module manifests: 7 days
|
|
163
|
+
License status: 1 hour
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### `kaven telemetry`
|
|
73
167
|
|
|
74
|
-
|
|
168
|
+
View observability and audit logs.
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
Commands:
|
|
172
|
+
view Display the most recent local telemetry events
|
|
173
|
+
-l, --limit <n> Number of events to show (default: 10)
|
|
174
|
+
```
|
|
75
175
|
|
|
76
176
|
---
|
|
77
177
|
|
|
78
|
-
##
|
|
178
|
+
## Configuration
|
|
179
|
+
|
|
180
|
+
Kaven CLI stores configuration in `~/.kaven/`:
|
|
79
181
|
|
|
80
|
-
|
|
182
|
+
```
|
|
183
|
+
~/.kaven/
|
|
184
|
+
auth.json Authentication tokens (chmod 600)
|
|
185
|
+
config.json CLI configuration (apiUrl override)
|
|
186
|
+
license.json License key and tier
|
|
187
|
+
signing-key.json Module signing key pair (chmod 600)
|
|
188
|
+
cache/ API response cache (max 50 MB)
|
|
189
|
+
telemetry.log Local telemetry events
|
|
190
|
+
```
|
|
81
191
|
|
|
82
|
-
|
|
83
|
-
|
|
192
|
+
### Overriding the API URL
|
|
193
|
+
|
|
194
|
+
Set `KAVEN_API_URL` environment variable or add to `~/.kaven/config.json`:
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"apiUrl": "https://api.your-kaven-instance.com"
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Debug Mode
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
KAVEN_DEBUG=1 kaven marketplace list
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Offline Mode
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
KAVEN_OFFLINE=1 kaven marketplace list # Uses cached data only
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Troubleshooting
|
|
217
|
+
|
|
218
|
+
### "Not authenticated" error
|
|
219
|
+
|
|
220
|
+
Run `kaven auth login` and complete the device code flow in your browser.
|
|
221
|
+
|
|
222
|
+
### "module.json not found" on publish
|
|
223
|
+
|
|
224
|
+
Run `kaven module publish` from inside the module directory
|
|
225
|
+
(the directory containing `module.json`).
|
|
226
|
+
|
|
227
|
+
### pnpm install fails on kaven init
|
|
228
|
+
|
|
229
|
+
Install pnpm globally: `npm install -g pnpm`
|
|
230
|
+
Or use `kaven init --skip-install` and run `pnpm install` manually.
|
|
231
|
+
|
|
232
|
+
### Prisma client out of sync
|
|
233
|
+
|
|
234
|
+
Run `kaven module doctor --fix` or manually: `npx prisma generate`
|
|
235
|
+
|
|
236
|
+
### Cache issues
|
|
237
|
+
|
|
238
|
+
Clear the cache: `kaven cache clear`
|
|
239
|
+
|
|
240
|
+
### Permission denied on ~/.kaven/
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
chmod 700 ~/.kaven
|
|
244
|
+
chmod 600 ~/.kaven/auth.json
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Development
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
git clone https://github.com/kaven-co/kaven-cli
|
|
253
|
+
cd kaven-cli
|
|
254
|
+
pnpm install # or: npm install (with legacy-peer-deps)
|
|
255
|
+
pnpm test # Run test suite
|
|
256
|
+
pnpm run typecheck # TypeScript check
|
|
257
|
+
pnpm run lint # ESLint
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
84
261
|
|
|
85
|
-
##
|
|
262
|
+
## License
|
|
86
263
|
|
|
87
|
-
|
|
264
|
+
Apache 2.0 — see [LICENSE](LICENSE)
|
|
88
265
|
|
|
89
266
|
---
|
|
90
267
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
</p>
|
|
268
|
+
Documentation: https://docs.kaven.sh/cli
|
|
269
|
+
GitHub: https://github.com/kaven-co/kaven-cli
|
|
@@ -6,39 +6,117 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.authLogin = authLogin;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
8
|
const ora_1 = __importDefault(require("ora"));
|
|
9
|
+
const open_1 = __importDefault(require("open"));
|
|
9
10
|
const AuthService_1 = require("../../core/AuthService");
|
|
11
|
+
const MarketplaceClient_1 = require("../../infrastructure/MarketplaceClient");
|
|
10
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
|
+
*/
|
|
11
81
|
async function authLogin() {
|
|
12
82
|
const telemetry = TelemetryBuffer_1.TelemetryBuffer.getInstance();
|
|
13
83
|
const startTime = Date.now();
|
|
14
84
|
telemetry.capture("cli.auth.login.start");
|
|
85
|
+
const client = new MarketplaceClient_1.MarketplaceClient();
|
|
15
86
|
const authService = new AuthService_1.AuthService();
|
|
16
|
-
console.log(chalk_1.default.blue("🔐
|
|
17
|
-
const spinner = (0, ora_1.default)("
|
|
87
|
+
console.log(chalk_1.default.blue("🔐 Starting authentication flow...\n"));
|
|
88
|
+
const spinner = (0, ora_1.default)("Requesting device code from marketplace...").start();
|
|
18
89
|
try {
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
const deviceCode = "KAVEN-777-BINGO";
|
|
22
|
-
const verificationUrl = "https://kaven.sh/device";
|
|
90
|
+
// Step 1: Request device code
|
|
91
|
+
const { device_code, user_code, verification_uri, expires_in, interval } = await client.requestDeviceCode();
|
|
23
92
|
spinner.stop();
|
|
24
|
-
|
|
25
|
-
console.log(chalk_1.default.
|
|
26
|
-
console.log(chalk_1.default.bold(`
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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);
|
|
35
113
|
await telemetry.flush();
|
|
36
114
|
}
|
|
37
115
|
catch (error) {
|
|
38
116
|
telemetry.capture("cli.auth.login.error", { error: error.message }, Date.now() - startTime);
|
|
39
117
|
await telemetry.flush();
|
|
40
|
-
spinner.fail(chalk_1.default.red("
|
|
41
|
-
console.error(error);
|
|
118
|
+
spinner.fail(chalk_1.default.red("Authentication failed"));
|
|
119
|
+
console.error(chalk_1.default.red(`\n Error: ${error.message}\n`));
|
|
42
120
|
process.exit(1);
|
|
43
121
|
}
|
|
44
122
|
}
|
|
@@ -5,21 +5,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.authLogout = authLogout;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
-
const ora_1 = __importDefault(require("ora"));
|
|
9
8
|
const AuthService_1 = require("../../core/AuthService");
|
|
10
9
|
async function authLogout() {
|
|
11
10
|
const authService = new AuthService_1.AuthService();
|
|
12
|
-
const spinner = (0, ora_1.default)("Encerrando sessão...").start();
|
|
13
11
|
try {
|
|
14
12
|
if (!(await authService.isAuthenticated())) {
|
|
15
|
-
|
|
13
|
+
console.log(chalk_1.default.yellow("You are not authenticated."));
|
|
16
14
|
return;
|
|
17
15
|
}
|
|
18
|
-
await authService.
|
|
19
|
-
|
|
16
|
+
await authService.logout();
|
|
17
|
+
console.log(chalk_1.default.green("Logged out successfully."));
|
|
20
18
|
}
|
|
21
19
|
catch {
|
|
22
|
-
|
|
20
|
+
console.error(chalk_1.default.red("Error during logout."));
|
|
23
21
|
process.exit(1);
|
|
24
22
|
}
|
|
25
23
|
}
|
|
@@ -12,24 +12,25 @@ async function authWhoami() {
|
|
|
12
12
|
telemetry.capture("cli.auth.whoami.start");
|
|
13
13
|
const authService = new AuthService_1.AuthService();
|
|
14
14
|
try {
|
|
15
|
-
const
|
|
16
|
-
if (!
|
|
17
|
-
console.log(chalk_1.default.yellow("
|
|
18
|
-
console.log(chalk_1.default.gray("Use 'kaven auth login'
|
|
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
19
|
telemetry.capture("cli.auth.whoami.not_authenticated");
|
|
20
20
|
await telemetry.flush();
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
23
|
telemetry.capture("cli.auth.whoami.authenticated");
|
|
24
|
-
console.log(
|
|
25
|
-
console.log(
|
|
26
|
-
console.log(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
30
|
}
|
|
31
31
|
catch {
|
|
32
|
-
console.error(chalk_1.default.red("
|
|
32
|
+
console.error(chalk_1.default.red("Error checking authentication status."));
|
|
33
33
|
process.exit(1);
|
|
34
34
|
}
|
|
35
|
+
await telemetry.flush();
|
|
35
36
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
}
|