kaven-cli 0.4.0 → 0.4.2-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/README.md +181 -207
- 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 +243 -289
- 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
package/README.md
CHANGED
|
@@ -1,48 +1,83 @@
|
|
|
1
1
|
# Kaven CLI
|
|
2
2
|
|
|
3
|
-
> 📖
|
|
3
|
+
> 📖 Portuguese Version: [README.pt-BR.md](./README.pt-BR.md)
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/kaven-cli)
|
|
6
6
|
[](https://www.npmjs.com/package/kaven-cli)
|
|
7
7
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
8
|
-
[](https://nodejs.org)
|
|
9
|
+
[](https://github.com/kaven-co/kaven-cli/actions/workflows/ci.yml)
|
|
10
|
+
[](https://nodejs.org/api/esm.html)
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
Bootstrap projects, manage modules, and interact with the Kaven Marketplace — all from your terminal.
|
|
12
|
+
**Kaven CLI** is the central orchestrator for the [Kaven Framework](https://kaven.site). It automates the entire lifecycle of a high-performance SaaS boilerplate, from initial scaffolding and Prisma schema orchestration to marketplace module installation and advanced capability management.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Built for precision and speed, it is now a **Pure ESM** tool optimized for modern Node.js environments.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Table of Contents
|
|
19
|
+
|
|
20
|
+
- [Core Principles](#core-principles)
|
|
21
|
+
- [Installation](#installation)
|
|
22
|
+
- [Quick Start](#quick-start)
|
|
23
|
+
- [Command Reference](#command-reference)
|
|
24
|
+
- [Project Initialization (`init`)](#project-initialization-init)
|
|
25
|
+
- [Schema Activation Engine (`module`)](#schema-activation-engine-module)
|
|
26
|
+
- [Feature Flags & Capabilities (`config features`)](#feature-flags--capabilities-config-features)
|
|
27
|
+
- [Marketplace Integration](#marketplace-integration)
|
|
28
|
+
- [Update & Upgrade](#update--upgrade)
|
|
29
|
+
- [Architecture Deep Dive](#architecture-deep-dive)
|
|
30
|
+
- [Schema Activation Logic](#schema-activation-logic)
|
|
31
|
+
- [AIOX Squad Integration](#aiox-squad-integration)
|
|
32
|
+
- [Configuration & Environment](#configuration--environment)
|
|
33
|
+
- [Troubleshooting](#troubleshooting)
|
|
34
|
+
- [Contributing](#contributing)
|
|
35
|
+
- [License](#license)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Core Principles
|
|
40
|
+
|
|
41
|
+
- **Pristine Scaffolding**: No more cluttered boilerplates. Kaven starts lean and grows as you add modules.
|
|
42
|
+
- **Transactional Integrity**: The CLI uses a `TransactionalFileSystem` to ensure that failed installations or migrations never leave your project in a broken state.
|
|
43
|
+
- **Agent-Ready**: Native support for **AIOX Squads**, providing a team of specialized AI agents to help build your product.
|
|
44
|
+
- **Type Safety**: Built with strict TypeScript, providing a reliable developer experience.
|
|
15
45
|
|
|
16
46
|
---
|
|
17
47
|
|
|
18
48
|
## Installation
|
|
19
49
|
|
|
50
|
+
### Global Install (Recommended)
|
|
51
|
+
|
|
20
52
|
```bash
|
|
21
53
|
npm install -g kaven-cli@alpha
|
|
22
54
|
# or
|
|
23
55
|
pnpm add -g kaven-cli@alpha
|
|
24
56
|
```
|
|
25
57
|
|
|
26
|
-
|
|
58
|
+
### Requirements
|
|
59
|
+
- **Node.js**: >= 22.0.0 (Pure ESM support required)
|
|
60
|
+
- **PackageManager**: `pnpm` is highly recommended and required for certain internal tasks.
|
|
61
|
+
- **Git**: Installed and configured.
|
|
27
62
|
|
|
28
63
|
---
|
|
29
64
|
|
|
30
65
|
## Quick Start
|
|
31
66
|
|
|
32
67
|
```bash
|
|
33
|
-
# 1. Bootstrap a new
|
|
34
|
-
kaven init my-
|
|
68
|
+
# 1. Bootstrap a new project with AI Squad support
|
|
69
|
+
kaven init my-unicorn-startup --with-squad
|
|
35
70
|
|
|
36
|
-
# 2.
|
|
71
|
+
# 2. Login to Kaven Marketplace
|
|
37
72
|
kaven auth login
|
|
38
73
|
|
|
39
|
-
# 3.
|
|
40
|
-
kaven
|
|
74
|
+
# 3. Choose your SaaS tier and features (Interactive TUI)
|
|
75
|
+
kaven config features
|
|
41
76
|
|
|
42
|
-
# 4.
|
|
43
|
-
kaven
|
|
77
|
+
# 4. Activate the Billing module in your schema
|
|
78
|
+
kaven module activate billing
|
|
44
79
|
|
|
45
|
-
# 5.
|
|
80
|
+
# 5. Verify project health
|
|
46
81
|
kaven module doctor
|
|
47
82
|
```
|
|
48
83
|
|
|
@@ -50,274 +85,213 @@ kaven module doctor
|
|
|
50
85
|
|
|
51
86
|
## Command Reference
|
|
52
87
|
|
|
53
|
-
###
|
|
88
|
+
### Project Initialization (`init`)
|
|
54
89
|
|
|
55
|
-
|
|
90
|
+
The `init` command clones the official [Kaven Template](https://github.com/kaven-co/kaven-template) and prepares the project environment.
|
|
56
91
|
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
--defaults Skip interactive prompts, use defaults
|
|
60
|
-
--skip-install Skip pnpm install after setup
|
|
61
|
-
--skip-git Skip git init and initial commit
|
|
62
|
-
--force Overwrite existing directory
|
|
63
|
-
--with-squad Initialize AIOX squad in the project
|
|
64
|
-
|
|
65
|
-
Examples:
|
|
66
|
-
kaven init my-app
|
|
67
|
-
kaven init my-app --defaults
|
|
68
|
-
kaven init my-app --skip-git --skip-install
|
|
92
|
+
```bash
|
|
93
|
+
kaven init [project-name] [options]
|
|
69
94
|
```
|
|
70
95
|
|
|
71
|
-
|
|
96
|
+
**Options:**
|
|
97
|
+
- `--with-squad`: Bootstraps the AIOX agent infrastructure in `squads/kaven-squad/`.
|
|
98
|
+
- `--template <path|url>`: Use a custom local directory or Git repository as the source.
|
|
99
|
+
- `--force`: Overwrite existing directory if it exists.
|
|
100
|
+
- `--skip-install`: Skip the automatic `pnpm install`.
|
|
101
|
+
- `--skip-git`: Skip `git init` and initial commit.
|
|
72
102
|
|
|
73
|
-
|
|
103
|
+
---
|
|
74
104
|
|
|
75
|
-
|
|
105
|
+
### Schema Activation Engine (`module`)
|
|
76
106
|
|
|
77
|
-
|
|
78
|
-
Commands:
|
|
79
|
-
login Start device code flow (RFC 8628) — opens browser to confirm
|
|
80
|
-
logout Clear the local session
|
|
81
|
-
whoami Display the authenticated user info
|
|
82
|
-
```
|
|
107
|
+
Kaven's **Schema Activation Engine** solves the "Boilerplate Bloat" problem. Instead of having dozens of inactive tables in your database, Kaven keeps modules commented out in your Prisma schema until you need them.
|
|
83
108
|
|
|
84
|
-
|
|
109
|
+
```bash
|
|
110
|
+
# List all available modules and their status
|
|
111
|
+
kaven module list
|
|
85
112
|
|
|
86
|
-
|
|
113
|
+
# Activate a module (uncomments Prisma models)
|
|
114
|
+
kaven module activate billing
|
|
87
115
|
|
|
88
|
-
|
|
116
|
+
# Deactivate a module (comments Prisma models)
|
|
117
|
+
kaven module deactivate billing
|
|
89
118
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
list List available modules
|
|
93
|
-
install Download and apply a module to the current project
|
|
94
|
-
browse Interactive TUI browser
|
|
95
|
-
|
|
96
|
-
Options (list):
|
|
97
|
-
--category <cat> Filter by category
|
|
98
|
-
--sort <field> newest (default) | popular | name
|
|
99
|
-
--page <n> Page number
|
|
100
|
-
--limit <n> Results per page (max 100)
|
|
101
|
-
--json Raw JSON output
|
|
102
|
-
|
|
103
|
-
Options (install):
|
|
104
|
-
--version <ver> Install a specific version
|
|
105
|
-
--force Skip overwrite confirmation
|
|
106
|
-
--skip-env Skip .env injection
|
|
107
|
-
--env-file <path> Target .env file path
|
|
119
|
+
# Verify module integrity and database sync
|
|
120
|
+
kaven module doctor --fix
|
|
108
121
|
```
|
|
109
122
|
|
|
110
123
|
---
|
|
111
124
|
|
|
112
|
-
### `
|
|
125
|
+
### Feature Flags & Capabilities (`config features`)
|
|
113
126
|
|
|
114
|
-
|
|
127
|
+
Kaven Framework supports over **60+ granular capabilities** (feature flags) that control everything from UI visibility to API limits.
|
|
115
128
|
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
doctor Run health checks on the project and installed modules
|
|
119
|
-
add Install a module from a local manifest
|
|
120
|
-
remove Uninstall an installed module
|
|
121
|
-
publish Publish a module to the marketplace
|
|
122
|
-
|
|
123
|
-
Options (doctor):
|
|
124
|
-
--fix Auto-fix detected issues (runs pnpm install, prisma generate, patches env)
|
|
125
|
-
--json Machine-readable JSON output
|
|
126
|
-
|
|
127
|
-
Exit codes (doctor):
|
|
128
|
-
0 All checks passed
|
|
129
|
-
1 One or more errors
|
|
130
|
-
2 Warnings only
|
|
131
|
-
|
|
132
|
-
Options (publish):
|
|
133
|
-
--dry-run Validate and package without uploading
|
|
134
|
-
--changelog <msg> Release notes for this version
|
|
129
|
+
```bash
|
|
130
|
+
kaven config features [options]
|
|
135
131
|
```
|
|
136
132
|
|
|
137
|
-
|
|
133
|
+
This command launches an **Interactive TUI** where you can:
|
|
134
|
+
- Select a **Tier Preset** (Starter, Complete, Pro, Enterprise).
|
|
135
|
+
- Customize individual flags (e.g., `TENANCY_CUSTOM_DOMAINS`, `MAX_PROJECTS`).
|
|
136
|
+
- Automatically generate the `packages/database/prisma/seeds/capabilities.seed.ts` file.
|
|
138
137
|
|
|
139
138
|
---
|
|
140
139
|
|
|
141
|
-
###
|
|
142
|
-
|
|
143
|
-
Upgrade your license tier via Paddle checkout.
|
|
140
|
+
### Marketplace Integration
|
|
144
141
|
|
|
145
|
-
|
|
146
|
-
Options:
|
|
147
|
-
--no-browser Print checkout URL instead of opening browser
|
|
148
|
-
|
|
149
|
-
Behavior:
|
|
150
|
-
Opens Paddle checkout in browser → polls for payment (every 5s, max 10 min)
|
|
151
|
-
→ updates local license on success
|
|
152
|
-
```
|
|
142
|
+
The `marketplace` command set allows you to extend your SaaS with official and community modules.
|
|
153
143
|
|
|
154
|
-
|
|
144
|
+
```bash
|
|
145
|
+
# Browse modules in a visual TUI
|
|
146
|
+
kaven marketplace browse
|
|
155
147
|
|
|
156
|
-
|
|
148
|
+
# Install a specific module
|
|
149
|
+
kaven marketplace install auth-google
|
|
157
150
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
status Show current license tier and expiry
|
|
151
|
+
# List available categories
|
|
152
|
+
kaven marketplace list --category auth
|
|
161
153
|
```
|
|
162
154
|
|
|
163
155
|
---
|
|
164
156
|
|
|
165
|
-
###
|
|
157
|
+
### Update & Upgrade
|
|
166
158
|
|
|
167
|
-
|
|
159
|
+
Kaven follows the Linux `apt` convention — **update** manages software versions, **upgrade** manages your plan.
|
|
168
160
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
License status 1 hour
|
|
161
|
+
#### `kaven update` — Update CLI and modules
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
kaven update # check for updates: CLI + all installed modules
|
|
165
|
+
kaven update --core # check and update CLI only
|
|
166
|
+
kaven update --module X # update a specific installed module
|
|
167
|
+
kaven update --all # apply all available updates
|
|
168
|
+
kaven update --check # check without applying (dry run)
|
|
178
169
|
```
|
|
179
170
|
|
|
180
|
-
|
|
171
|
+
> Works offline: uses local MSW handlers when marketplace is unreachable.
|
|
181
172
|
|
|
182
|
-
|
|
173
|
+
#### `kaven module update` — Update a specific module (C4.1)
|
|
183
174
|
|
|
175
|
+
```bash
|
|
176
|
+
kaven module update payments # update to latest
|
|
177
|
+
kaven module update payments@1.0.3 # update to specific version
|
|
184
178
|
```
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
179
|
+
|
|
180
|
+
#### `kaven upgrade` — License plan upgrade only
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
kaven upgrade # opens Stripe checkout to upgrade your plan tier
|
|
184
|
+
kaven upgrade check # check if a newer CLI version is on npm
|
|
188
185
|
```
|
|
189
186
|
|
|
187
|
+
> `kaven upgrade` is **not** for updating software. It is exclusively for moving between Starter → Complete → Pro license tiers via Stripe.
|
|
188
|
+
|
|
190
189
|
---
|
|
191
190
|
|
|
192
|
-
|
|
191
|
+
## Architecture Deep Dive
|
|
193
192
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
193
|
+
### Schema Activation Logic
|
|
194
|
+
|
|
195
|
+
The `SchemaActivator` core targets the `packages/database/prisma/schema.extended.prisma` file. It uses a robust marker system:
|
|
196
|
+
|
|
197
|
+
```prisma
|
|
198
|
+
// [KAVEN_MODULE:BILLING BEGIN]
|
|
199
|
+
// model Invoice {
|
|
200
|
+
// id String @id @default(cuid())
|
|
201
|
+
// ...
|
|
202
|
+
// }
|
|
203
|
+
// [KAVEN_MODULE:BILLING END]
|
|
198
204
|
```
|
|
199
205
|
|
|
200
|
-
|
|
206
|
+
When `activate billing` is called, the CLI:
|
|
207
|
+
1. Validates **Marker Pairing** (BEGIN/END integrity).
|
|
208
|
+
2. Performs a **Regex-based uncommenting** that preserves your code's indentation.
|
|
209
|
+
3. Notifies the developer to run `pnpm db:generate && pnpm db:migrate`.
|
|
201
210
|
|
|
202
|
-
###
|
|
211
|
+
### AIOX Squad Integration
|
|
203
212
|
|
|
204
|
-
|
|
213
|
+
By passing `--with-squad` during `init`, the CLI:
|
|
214
|
+
1. Injects the `.gemini/` and `.antigravity/` configurations.
|
|
215
|
+
2. Sets up the specialized agents: **Kai** (Orchestrator), **Dex** (Developer), **Quinn** (QA), and **Gage** (DevOps).
|
|
216
|
+
3. Configures the repository for an AI-native development workflow.
|
|
205
217
|
|
|
206
218
|
---
|
|
207
219
|
|
|
208
|
-
## Configuration
|
|
220
|
+
## Configuration & Environment
|
|
209
221
|
|
|
210
|
-
All
|
|
222
|
+
All CLI state and cached marketplace data reside in `~/.kaven/`:
|
|
211
223
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
license.json License key and tier
|
|
217
|
-
signing-key.json Module Ed25519 signing key (chmod 600)
|
|
218
|
-
cache/ API response cache (max 50 MB)
|
|
219
|
-
telemetry.log Local telemetry events
|
|
220
|
-
```
|
|
224
|
+
- `auth.json`: JWT tokens for marketplace access.
|
|
225
|
+
- `config.json`: CLI preferences (e.g., `apiUrl`, `serviceToken`).
|
|
226
|
+
- `license.json`: Local cache of your framework license.
|
|
227
|
+
- `cache/`: Cached API responses to speed up browsing.
|
|
221
228
|
|
|
222
229
|
### Environment Variables
|
|
223
230
|
|
|
224
231
|
| Variable | Description |
|
|
225
232
|
|----------|-------------|
|
|
226
|
-
| `KAVEN_API_URL` | Override the marketplace
|
|
227
|
-
| `KAVEN_DEBUG=1` | Enable
|
|
228
|
-
| `
|
|
229
|
-
| `
|
|
230
|
-
|
|
231
|
-
### API URL Override (config file)
|
|
232
|
-
|
|
233
|
-
```json
|
|
234
|
-
// ~/.kaven/config.json
|
|
235
|
-
{
|
|
236
|
-
"apiUrl": "https://api.your-kaven-instance.com"
|
|
237
|
-
}
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
### Debug Mode
|
|
241
|
-
|
|
242
|
-
```bash
|
|
243
|
-
KAVEN_DEBUG=1 kaven marketplace list
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### Offline Mode
|
|
247
|
-
|
|
248
|
-
```bash
|
|
249
|
-
KAVEN_OFFLINE=1 kaven marketplace list
|
|
250
|
-
```
|
|
233
|
+
| `KAVEN_API_URL` | Override the production marketplace URL. |
|
|
234
|
+
| `KAVEN_DEBUG=1` | Enable detailed logging of HTTP and FS operations. |
|
|
235
|
+
| `KAVEN_SERVICE_TOKEN` | Token for automated CI/CD or Agent-to-Service auth. |
|
|
236
|
+
| `KAVEN_OFFLINE=1` | Force the CLI to use local cache only. |
|
|
251
237
|
|
|
252
238
|
---
|
|
253
239
|
|
|
254
240
|
## Troubleshooting
|
|
255
241
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
kaven auth login
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
**"module.json not found" on publish**
|
|
262
|
-
|
|
263
|
-
Run `kaven module publish` from inside the module directory (the one containing `module.json`).
|
|
264
|
-
|
|
265
|
-
**pnpm install fails on `kaven init`**
|
|
266
|
-
```bash
|
|
267
|
-
npm install -g pnpm # install pnpm globally
|
|
268
|
-
# or skip it and install later:
|
|
269
|
-
kaven init my-app --skip-install
|
|
270
|
-
cd my-app && pnpm install
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
**Prisma client out of sync**
|
|
274
|
-
```bash
|
|
275
|
-
kaven module doctor --fix
|
|
276
|
-
# or manually:
|
|
277
|
-
npx prisma generate
|
|
278
|
-
```
|
|
242
|
+
### "ReferenceError: module is not defined"
|
|
243
|
+
Kaven CLI is **Pure ESM**. If you are trying to extend the CLI or run it in an environment that expects CommonJS, ensure your `package.json` contains `"type": "module"` and you are using Node.js 22+.
|
|
279
244
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
kaven cache clear
|
|
283
|
-
```
|
|
245
|
+
### "Marker Pairing Failed"
|
|
246
|
+
This error occurs if you manually edited the Prisma file and deleted or duplicated a `// [KAVEN_MODULE:...]` marker. Run `kaven module doctor` to identify the broken section.
|
|
284
247
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
chmod 700 ~/.kaven
|
|
288
|
-
chmod 600 ~/.kaven/auth.json ~/.kaven/signing-key.json
|
|
289
|
-
```
|
|
248
|
+
### "Not Authenticated"
|
|
249
|
+
Run `kaven auth login`. If you are in a CI/CD environment, provide a `KAVEN_SERVICE_TOKEN` via environment variables.
|
|
290
250
|
|
|
291
251
|
---
|
|
292
252
|
|
|
293
253
|
## Contributing
|
|
294
254
|
|
|
255
|
+
We welcome contributions! Kaven CLI is a high-integrity project with strict quality gates.
|
|
256
|
+
|
|
257
|
+
### Development Setup
|
|
258
|
+
|
|
295
259
|
```bash
|
|
260
|
+
# 1. Clone and install
|
|
296
261
|
git clone https://github.com/kaven-co/kaven-cli
|
|
297
262
|
cd kaven-cli
|
|
298
263
|
pnpm install
|
|
299
|
-
|
|
300
|
-
|
|
264
|
+
|
|
265
|
+
# 2. Run the full test suite (334 tests)
|
|
266
|
+
pnpm test
|
|
267
|
+
|
|
268
|
+
# 3. Run linting and type-checking
|
|
301
269
|
pnpm run lint
|
|
270
|
+
pnpm run typecheck
|
|
271
|
+
|
|
272
|
+
# 4. Build the Pure ESM bundle
|
|
273
|
+
pnpm run build
|
|
302
274
|
```
|
|
303
275
|
|
|
304
|
-
|
|
276
|
+
### Commit Guidelines
|
|
277
|
+
We use **Conventional Commits**. Every commit must be prefixed with `feat:`, `fix:`, `docs:`, etc. Breaking changes must be flagged.
|
|
305
278
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
279
|
+
### Quality Gates
|
|
280
|
+
- **Tests**: 100% pass rate required.
|
|
281
|
+
- **Lint**: No `any` allowed in core modules.
|
|
282
|
+
- **ESM**: All relative imports must include the `.js` extension.
|
|
283
|
+
|
|
284
|
+
---
|
|
311
285
|
|
|
312
|
-
|
|
313
|
-
1. Open a PR against `main`
|
|
314
|
-
2. PR requires CI green (lint + typecheck + tests + build)
|
|
315
|
-
3. Merge → Semantic Release automatically bumps version and publishes to npm (`@alpha` tag)
|
|
286
|
+
## Credits & Attribution
|
|
316
287
|
|
|
317
|
-
|
|
318
|
-
Types that do **not** trigger a release: `chore`, `docs`, `test`, `style`, `ci`.
|
|
288
|
+
Kaven CLI is built with support from the **AIOX Framework**, an agentic development ecosystem by [SynkraAI](https://github.com/synkra).
|
|
319
289
|
|
|
320
|
-
|
|
290
|
+
Special thanks to the **Kaven Squad** of autonomous agents who helped architect, develop, and validate this tool:
|
|
291
|
+
- **Kai** (Orchestrator)
|
|
292
|
+
- **Dex** (Developer)
|
|
293
|
+
- **Quinn** (QA)
|
|
294
|
+
- **Gage** (DevOps)
|
|
321
295
|
|
|
322
296
|
---
|
|
323
297
|
|
|
@@ -327,6 +301,6 @@ Apache 2.0 — see [LICENSE](LICENSE)
|
|
|
327
301
|
|
|
328
302
|
---
|
|
329
303
|
|
|
330
|
-
Documentation
|
|
331
|
-
GitHub
|
|
332
|
-
|
|
304
|
+
**Documentation**: [docs.kaven.site/cli](https://docs.kaven.site/cli)
|
|
305
|
+
**GitHub**: [github.com/kaven-co/kaven-cli](https://github.com/kaven-co/kaven-cli)
|
|
306
|
+
**NPM**: [npmjs.com/package/kaven-cli](https://www.npmjs.com/package/kaven-cli)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import*as l from"fs";import*as f from"path";import*as m from"readline";import d from"chalk";var h=class{async injectEnvVars(n,t,r){if(r.skipEnv||!t||t.length===0)return{added:0,skipped:0};let s=f.join(r.projectDir,r.envFile??".env"),a=this.readEnvFile(s),c=this.parseEnvFile(a),i=[],p=0;console.log(d.bold(`
|
|
2
|
+
Environment variables for '${n}':
|
|
3
|
+
`));for(let e of t){if(c.has(e.name)){console.log(d.dim(` ${e.name} \u2014 already set, skipping`)),p++;continue}let o;if(e.sensitive)o=await this.promptPassword(` ${e.name} (${e.description})${e.default?" [****]":""}: `),!o&&e.default&&(o=e.default);else{let g=e.default?` [${e.default}]`:"";o=await this.promptInput(` ${e.name} (${e.description})${g}: `,e.default)}if(e.required&&!o&&(console.log(d.yellow(` ${e.name} is required.`)),o=e.sensitive?await this.promptPassword(` ${e.name}: `):await this.promptInput(` ${e.name}: `),!o)){console.log(d.yellow(` Skipping ${e.name} \u2014 set it manually in .env`)),p++;continue}i.push({name:e.name,value:o})}if(i.length===0)return console.log(d.dim(" No new environment variables to add.")),{added:0,skipped:p};let u=this.buildMarkerBlock(n,i);return this.appendToEnvFile(s,a,u),console.log(d.green(`
|
|
4
|
+
Added ${i.length} environment variable(s) to ${r.envFile??".env"}`)),{added:i.length,skipped:p}}removeEnvVars(n,t){let r=[".env",".env.local",".env.development",".env.production"];t.envFile&&r.unshift(t.envFile);let s=0;for(let a of r){let c=f.join(t.projectDir,a);if(!l.existsSync(c))continue;let i=l.readFileSync(c,"utf-8"),p=`# [KAVEN_MODULE:${n} BEGIN]`,u=`# [KAVEN_MODULE:${n} END]`,e=i.indexOf(p),o=i.indexOf(u);if(e===-1||o===-1)continue;let v=i.substring(e,o+u.length).split(`
|
|
5
|
+
`).filter(w=>/^[A-Z_]+=/.test(w)).length,E=i.substring(0,e).replace(/\n+$/,`
|
|
6
|
+
`),$=i.substring(o+u.length+1);l.writeFileSync(c,E+$),s+=v,v>0&&console.log(d.dim(` Removed ${v} env var(s) from ${a}`))}return s}readEnvFile(n){try{return l.readFileSync(n,"utf-8")}catch{return""}}parseEnvFile(n){let t=new Map;for(let r of n.split(`
|
|
7
|
+
`)){let s=r.match(/^([A-Z_][A-Z0-9_]*)=(.*)$/);s&&t.set(s[1],s[2])}return t}buildMarkerBlock(n,t){return[`# [KAVEN_MODULE:${n} BEGIN]`,...t.map(r=>`${r.name}=${r.value}`),`# [KAVEN_MODULE:${n} END]`].join(`
|
|
8
|
+
`)}appendToEnvFile(n,t,r){l.mkdirSync(f.dirname(n),{recursive:!0});let s=t.endsWith(`
|
|
9
|
+
`)||t===""?`
|
|
10
|
+
`:`
|
|
11
|
+
|
|
12
|
+
`;l.writeFileSync(n,t+s+r+`
|
|
13
|
+
`)}promptInput(n,t){return new Promise(r=>{let s=m.createInterface({input:process.stdin,output:process.stdout});s.question(n,a=>{s.close(),r(a||t||"")})})}promptPassword(n){return new Promise(t=>{let r=m.createInterface({input:process.stdin,output:process.stdout});process.stdout.write(n),process.stdin.setRawMode?.(!0),process.stdin.resume();let s="",a=c=>{let i=c.toString();i==="\r"||i===`
|
|
14
|
+
`?(process.stdin.setRawMode?.(!1),process.stdin.pause(),process.stdin.removeListener("data",a),process.stdout.write(`
|
|
15
|
+
`),r.close(),t(s)):i===""?process.exit():i==="\x7F"?(s=s.slice(0,-1),process.stdout.clearLine(0),process.stdout.cursorTo(0),process.stdout.write(n+"*".repeat(s.length))):(s+=i,process.stdout.write("*"))};process.stdin.on("data",a)})}};export{h as EnvManager};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{g as a}from"./chunk-JHLQ46NG.js";export{a as MarketplaceClient};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import v from"fs-extra";import q from"path";import x from"os";var c=class extends Error{constructor(e){super(e),this.name="MarketplaceError"}},T=class extends c{constructor(e){super(e),this.name="AuthenticationError"}},E=class extends c{constructor(t,s){super(s);this.requiredTier=t;this.name="LicenseRequiredError"}},p=class extends c{constructor(e){super(e),this.name="NotFoundError"}},R=class extends c{constructor(t){super(`Rate limited. Try again in ${t}s`);this.retryAfter=t;this.name="RateLimitError"}},m=class extends c{constructor(e){super(e),this.name="ServerError"}},y=class extends c{constructor(e){super(e),this.name="NetworkError"}},A=class extends c{constructor(e){super(e),this.name="SignatureVerificationError"}};function S(r){if(r instanceof Error)return r;if(typeof r=="string")return new Error(r);try{return new Error(JSON.stringify(r))}catch{return new Error(String(r))}}var O="https://marketplace.kaven.site",_=3e4,P=3,C=1e3;function b(r){process.env.KAVEN_DEBUG==="1"&&console.debug(`[kaven:debug] ${r}`)}async function D(){try{let r=q.join(x.homedir(),".kaven","config.json");if(await v.pathExists(r)){let e=await v.readJson(r);if(typeof e.apiUrl=="string"&&e.apiUrl)return e.apiUrl}}catch{}return null}async function I(){if(process.env.KAVEN_SERVICE_TOKEN)return process.env.KAVEN_SERVICE_TOKEN;try{let r=q.join(x.homedir(),".kaven","config.json");if(await v.pathExists(r)){let e=await v.readJson(r);if(typeof e.serviceToken=="string"&&e.serviceToken)return e.serviceToken}}catch{}return null}async function j(){if(process.env.KAVEN_API_URL)return process.env.KAVEN_API_URL.replace(/\/$/,"");let r=await D();return r?r.replace(/\/$/,""):O}function K(r){return new Promise(e=>setTimeout(e,r))}function G(r){return r>=500}var $=class{baseURLPromise;authService;constructor(e){this.authService=e??null,this.baseURLPromise=j()}async resolveUrl(e){return`${await this.baseURLPromise}${e}`}async request(e,t,s={}){let k=`${await this.baseURLPromise}${t}`,{body:d,authenticated:U=!1}=s,g=null;for(let u=0;u<=P;u++){if(u>0){let l=C*Math.pow(2,u-1);b(`Retry attempt ${u} for ${e} ${t} (delay ${l}ms)`),await K(l)}try{let l={"Content-Type":"application/json",Accept:"application/json"};if(U&&this.authService){let h=await this.authService.getValidToken();l.Authorization=`Bearer ${h}`}let n=await I();n&&(l["X-Service-Token"]=n),b(`${e} ${k}`);let w=new AbortController,M=setTimeout(()=>w.abort(),_),o;try{o=await fetch(k,{method:e,headers:l,body:d!==void 0?JSON.stringify(d):void 0,signal:w.signal})}finally{clearTimeout(M)}if(b(`Response: ${o.status} ${o.statusText}`),!o.ok){let h=await o.text().catch(()=>""),f=h;try{let a=JSON.parse(h);f=a.message||a.error||h}catch{}switch(o.status){case 401:throw new T(f||"Authentication required");case 403:{let a="pro";try{a=JSON.parse(h).requiredTier||a}catch{}throw new E(a,f||"License required")}case 404:throw new p(f||"Resource not found");case 429:{let a=parseInt(o.headers.get("retry-after")??"60",10);throw new R(isNaN(a)?60:a)}default:if(G(o.status)){g=new m(f||`Server error: ${o.status}`);continue}throw new m(f||`Server error: ${o.status}`)}}return(o.headers.get("content-type")??"").includes("application/json")?await o.json():{}}catch(l){let n=S(l);if(n instanceof T||n instanceof E||n instanceof p||n instanceof R)throw n;if(n instanceof TypeError||n.name==="AbortError"){let w=new y(n.name==="AbortError"?"Request timed out after 30s":`Network error: ${n.message}`);if(g=w,u<P)continue;throw w}if(n instanceof m){if(g=n,u<P)continue;throw n}throw n}}throw g??new y("Request failed after retries")}async requestDeviceCode(){return this.request("POST","/auth/device-code",{body:{client_id:"kaven-cli"},authenticated:!1})}async pollDeviceToken(e){try{let s=`${await this.baseURLPromise}/auth/token`,i=new AbortController,k=setTimeout(()=>i.abort(),_),d;try{d=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({device_code:e,grant_type:"urn:ietf:params:oauth:grant-type:device_code"}),signal:i.signal})}finally{clearTimeout(k)}if(d.ok)return{status:"success",tokens:await d.json()};let g=(await d.json().catch(()=>({}))).error??"unknown_error";switch(g){case"authorization_pending":return{status:"authorization_pending"};case"slow_down":return{status:"slow_down"};case"access_denied":return{status:"access_denied"};case"expired_token":return{status:"expired_token"};default:throw new Error(`Unexpected error: ${g}`)}}catch(t){let s=S(t),i=s;throw i.code==="ECONNREFUSED"||i.code==="ENOTFOUND"?new y("Network error. Check your connection and try again."):s}}async refreshToken(e){return this.request("POST","/auth/refresh",{body:{refresh_token:e},authenticated:!1})}async listModules(e){let t=new URLSearchParams;e?.category&&t.set("category",e.category),e?.tier&&t.set("tier",e.tier),e?.q&&t.set("q",e.q),e?.page&&t.set("page",String(e.page)),e?.pageSize&&t.set("pageSize",String(e.pageSize));let s=t.toString(),i=`/modules${s?`?${s}`:""}`;return this.request("GET",i)}async getModule(e){return this.request("GET",`/modules/${e}`)}async getManifest(e,t){return this.request("GET",`/modules/${e}/versions/${t}/manifest`)}async createDownloadToken(e,t){return this.request("POST","/download-tokens",{body:{moduleSlug:e,version:t},authenticated:!0})}async validateLicense(e,t){return await this.request("POST","/licenses/validate",{body:{licenseKey:e,requiredTier:t}})}async getLicenseStatus(e){return this.request("GET",`/licenses/status?key=${encodeURIComponent(e)}`)}async getModuleManifest(e){try{return await this.getManifest(e,"latest")}catch(t){if(t instanceof p)return null;throw t}}async getReleaseInfo(e,t){return this.request("GET",`/modules/${e}/versions/${t}`)}async getUploadUrl(e,t,s){return this.request("POST","/releases/upload-url",{body:{moduleSlug:e,version:t,size:s},authenticated:!0})}async createRelease(e){return this.request("POST","/releases",{body:e,authenticated:!0})}async createCheckoutSession(e,t){return this.request("POST","/checkout/session",{body:{tier:e,licenseKey:t},authenticated:!0})}async getCheckoutStatus(e){return this.request("GET",`/checkout/session/${e}/status`,{authenticated:!0})}async getCategories(){try{let e=await this.request("GET","/categories",{authenticated:!1});return Array.isArray(e)?e:e.categories??[]}catch(e){if(e instanceof p){let s=(await this.request("GET","/search?q=",{authenticated:!1})).facets?.categories?.map(i=>i.category).filter(Boolean)??[];return[...new Set(s)].sort()}throw e}}};export{T as a,E as b,p as c,y as d,A as e,S as f,$ as g};
|
package/dist/index.d.ts
ADDED