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.
Files changed (57) hide show
  1. package/README.md +154 -215
  2. package/dist/EnvManager-NMS3NMIE.js +15 -0
  3. package/dist/MarketplaceClient-YCFH2VU4.js +1 -0
  4. package/dist/chunk-JHLQ46NG.js +1 -0
  5. package/dist/index.d.ts +4 -0
  6. package/dist/index.js +216 -286
  7. package/dist/tier-table-DQMPQSI2.js +6 -0
  8. package/package.json +26 -10
  9. package/dist/commands/auth/login.js +0 -122
  10. package/dist/commands/auth/logout.js +0 -23
  11. package/dist/commands/auth/whoami.js +0 -36
  12. package/dist/commands/cache/index.js +0 -43
  13. package/dist/commands/config/features.js +0 -1026
  14. package/dist/commands/config/index.js +0 -95
  15. package/dist/commands/index.js +0 -2
  16. package/dist/commands/init/index.js +0 -197
  17. package/dist/commands/init-ci/index.js +0 -153
  18. package/dist/commands/license/index.js +0 -10
  19. package/dist/commands/license/status.js +0 -44
  20. package/dist/commands/license/tier-table.js +0 -46
  21. package/dist/commands/marketplace/browse.js +0 -186
  22. package/dist/commands/marketplace/install.js +0 -263
  23. package/dist/commands/marketplace/list.js +0 -122
  24. package/dist/commands/module/activate.js +0 -206
  25. package/dist/commands/module/add.js +0 -69
  26. package/dist/commands/module/doctor.js +0 -175
  27. package/dist/commands/module/publish.js +0 -258
  28. package/dist/commands/module/remove.js +0 -58
  29. package/dist/commands/telemetry/view.js +0 -27
  30. package/dist/commands/upgrade/check.js +0 -162
  31. package/dist/commands/upgrade/index.js +0 -185
  32. package/dist/core/AuthService.js +0 -222
  33. package/dist/core/CacheManager.js +0 -154
  34. package/dist/core/ConfigManager.js +0 -166
  35. package/dist/core/EnvManager.js +0 -196
  36. package/dist/core/ErrorRecovery.js +0 -192
  37. package/dist/core/LicenseService.js +0 -83
  38. package/dist/core/ManifestParser.js +0 -52
  39. package/dist/core/MarkerService.js +0 -62
  40. package/dist/core/ModuleDoctor.js +0 -451
  41. package/dist/core/ModuleInstaller.js +0 -169
  42. package/dist/core/ProjectInitializer.js +0 -166
  43. package/dist/core/RegistryResolver.js +0 -95
  44. package/dist/core/SchemaActivator.js +0 -270
  45. package/dist/core/ScriptRunner.js +0 -73
  46. package/dist/core/SignatureVerifier.js +0 -75
  47. package/dist/core/index.js +0 -2
  48. package/dist/infrastructure/Container.js +0 -37
  49. package/dist/infrastructure/MarketplaceClient.js +0 -399
  50. package/dist/infrastructure/TelemetryBuffer.js +0 -73
  51. package/dist/infrastructure/TransactionalFileSystem.js +0 -77
  52. package/dist/infrastructure/errors.js +0 -63
  53. package/dist/infrastructure/index.js +0 -2
  54. package/dist/types/auth.js +0 -2
  55. package/dist/types/manifest.js +0 -45
  56. package/dist/types/markers.js +0 -10
  57. package/dist/types/marketplace.js +0 -2
package/README.md CHANGED
@@ -1,48 +1,82 @@
1
1
  # Kaven CLI
2
2
 
3
- > 📖 Versão em Português: [README.pt-BR.md](./README.pt-BR.md)
3
+ > 📖 Portuguese Version: [README.pt-BR.md](./README.pt-BR.md)
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/kaven-cli/alpha.svg)](https://www.npmjs.com/package/kaven-cli)
6
6
  [![npm downloads](https://img.shields.io/npm/dm/kaven-cli.svg)](https://www.npmjs.com/package/kaven-cli)
7
7
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
8
- [![Node](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)](https://nodejs.org)
9
- [![CI](https://github.com/kaven-co/kaven-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/kaven-co/kaven-cli/actions/workflows/ci.yml)
8
+ [![Node](https://img.shields.io/badge/node-%3E%3D22-brightgreen.svg)](https://nodejs.org)
9
+ [![Build Status](https://github.com/kaven-co/kaven-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/kaven-co/kaven-cli/actions/workflows/ci.yml)
10
+ [![Pure ESM](https://img.shields.io/badge/module-Pure%20ESM-yellow.svg)](https://nodejs.org/api/esm.html)
10
11
 
11
- The official command-line tool for the [Kaven](https://kaven.site) SaaS boilerplate framework.
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
- > **Alpha:** APIs and commands may change before v1.0.0.
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
+ - [Architecture Deep Dive](#architecture-deep-dive)
29
+ - [Schema Activation Logic](#schema-activation-logic)
30
+ - [AIOX Squad Integration](#aiox-squad-integration)
31
+ - [Configuration & Environment](#configuration--environment)
32
+ - [Troubleshooting](#troubleshooting)
33
+ - [Contributing](#contributing)
34
+ - [License](#license)
35
+
36
+ ---
37
+
38
+ ## Core Principles
39
+
40
+ - **Pristine Scaffolding**: No more cluttered boilerplates. Kaven starts lean and grows as you add modules.
41
+ - **Transactional Integrity**: The CLI uses a `TransactionalFileSystem` to ensure that failed installations or migrations never leave your project in a broken state.
42
+ - **Agent-Ready**: Native support for **AIOX Squads**, providing a team of specialized AI agents to help build your product.
43
+ - **Type Safety**: Built with strict TypeScript, providing a reliable developer experience.
15
44
 
16
45
  ---
17
46
 
18
47
  ## Installation
19
48
 
49
+ ### Global Install (Recommended)
50
+
20
51
  ```bash
21
52
  npm install -g kaven-cli@alpha
22
53
  # or
23
54
  pnpm add -g kaven-cli@alpha
24
55
  ```
25
56
 
26
- **Requirements:** Node.js >= 20, pnpm (required by `kaven init`)
57
+ ### Requirements
58
+ - **Node.js**: >= 22.0.0 (Pure ESM support required)
59
+ - **PackageManager**: `pnpm` is highly recommended and required for certain internal tasks.
60
+ - **Git**: Installed and configured.
27
61
 
28
62
  ---
29
63
 
30
64
  ## Quick Start
31
65
 
32
66
  ```bash
33
- # 1. Bootstrap a new Kaven project
34
- kaven init my-saas-app
67
+ # 1. Bootstrap a new project with AI Squad support
68
+ kaven init my-unicorn-startup --with-squad
35
69
 
36
- # 2. Authenticate with the marketplace
70
+ # 2. Login to Kaven Marketplace
37
71
  kaven auth login
38
72
 
39
- # 3. Browse available modules
40
- kaven marketplace browse
73
+ # 3. Choose your SaaS tier and features (Interactive TUI)
74
+ kaven config features
41
75
 
42
- # 4. Install a module
43
- kaven marketplace install payments
76
+ # 4. Activate the Billing module in your schema
77
+ kaven module activate billing
44
78
 
45
- # 5. Check project health
79
+ # 5. Verify project health
46
80
  kaven module doctor
47
81
  ```
48
82
 
@@ -50,274 +84,179 @@ kaven module doctor
50
84
 
51
85
  ## Command Reference
52
86
 
53
- ### `kaven init [project-name]`
87
+ ### Project Initialization (`init`)
54
88
 
55
- Bootstrap a new Kaven project from the official template.
89
+ The `init` command clones the official [Kaven Template](https://github.com/kaven-co/kaven-template) and prepares the project environment.
56
90
 
91
+ ```bash
92
+ kaven init [project-name] [options]
57
93
  ```
58
- Options:
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
69
- ```
70
-
71
- ---
72
-
73
- ### `kaven auth`
74
-
75
- Manage authentication with the Kaven Marketplace.
76
94
 
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
- ```
95
+ **Options:**
96
+ - `--with-squad`: Bootstraps the AIOX agent infrastructure in `squads/kaven-squad/`.
97
+ - `--template <path|url>`: Use a custom local directory or Git repository as the source.
98
+ - `--force`: Overwrite existing directory if it exists.
99
+ - `--skip-install`: Skip the automatic `pnpm install`.
100
+ - `--skip-git`: Skip `git init` and initial commit.
83
101
 
84
102
  ---
85
103
 
86
- ### `kaven marketplace`
87
-
88
- Explore and install modules from the Kaven Marketplace.
104
+ ### Schema Activation Engine (`module`)
89
105
 
90
- ```
91
- Commands:
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
108
- ```
106
+ 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.
109
107
 
110
- ---
108
+ ```bash
109
+ # List all available modules and their status
110
+ kaven module list
111
111
 
112
- ### `kaven module`
112
+ # Activate a module (uncomments Prisma models)
113
+ kaven module activate billing
113
114
 
114
- Manage modules installed in the current project.
115
+ # Deactivate a module (comments Prisma models)
116
+ kaven module deactivate billing
115
117
 
118
+ # Verify module integrity and database sync
119
+ kaven module doctor --fix
116
120
  ```
117
- Commands:
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
135
- ```
136
-
137
- > `kaven doctor` is an alias for `kaven module doctor`.
138
121
 
139
122
  ---
140
123
 
141
- ### `kaven upgrade`
124
+ ### Feature Flags & Capabilities (`config features`)
142
125
 
143
- Upgrade your license tier via Paddle checkout.
126
+ Kaven Framework supports over **60+ granular capabilities** (feature flags) that control everything from UI visibility to API limits.
144
127
 
128
+ ```bash
129
+ kaven config features [options]
145
130
  ```
146
- Options:
147
- --no-browser Print checkout URL instead of opening browser
148
131
 
149
- Behavior:
150
- Opens Paddle checkout in browser → polls for payment (every 5s, max 10 min)
151
- updates local license on success
152
- ```
132
+ This command launches an **Interactive TUI** where you can:
133
+ - Select a **Tier Preset** (Starter, Complete, Pro, Enterprise).
134
+ - Customize individual flags (e.g., `TENANCY_CUSTOM_DOMAINS`, `MAX_PROJECTS`).
135
+ - Automatically generate the `packages/database/prisma/seeds/capabilities.seed.ts` file.
153
136
 
154
137
  ---
155
138
 
156
- ### `kaven license`
139
+ ### Marketplace Integration
157
140
 
158
- ```
159
- Commands:
160
- status Show current license tier and expiry
161
- ```
141
+ The `marketplace` command set allows you to extend your SaaS with official and community modules.
162
142
 
163
- ---
164
-
165
- ### `kaven cache`
143
+ ```bash
144
+ # Browse modules in a visual TUI
145
+ kaven marketplace browse
166
146
 
167
- Manage the local API response cache (`~/.kaven/cache`, max 50 MB).
147
+ # Install a specific module
148
+ kaven marketplace install auth-google
168
149
 
169
- ```
170
- Commands:
171
- status Show cache stats (size, entries, age)
172
- clear Delete all cached data
173
-
174
- Cache TTLs:
175
- Module listings 24 hours
176
- Module manifests 7 days
177
- License status 1 hour
150
+ # List available categories
151
+ kaven marketplace list --category auth
178
152
  ```
179
153
 
180
154
  ---
181
155
 
182
- ### `kaven telemetry`
156
+ ## Architecture Deep Dive
183
157
 
184
- ```
185
- Commands:
186
- view Show recent local telemetry events
187
- -l, --limit <n> Number of events (default: 10)
188
- ```
189
-
190
- ---
158
+ ### Schema Activation Logic
191
159
 
192
- ### `kaven config`
160
+ The `SchemaActivator` core targets the `packages/database/prisma/schema.extended.prisma` file. It uses a robust marker system:
193
161
 
194
- ```
195
- Commands:
196
- set <key> <value> Set a configuration value
197
- get <key> Get a configuration value
162
+ ```prisma
163
+ // [KAVEN_MODULE:BILLING BEGIN]
164
+ // model Invoice {
165
+ // id String @id @default(cuid())
166
+ // ...
167
+ // }
168
+ // [KAVEN_MODULE:BILLING END]
198
169
  ```
199
170
 
200
- ---
171
+ When `activate billing` is called, the CLI:
172
+ 1. Validates **Marker Pairing** (BEGIN/END integrity).
173
+ 2. Performs a **Regex-based uncommenting** that preserves your code's indentation.
174
+ 3. Notifies the developer to run `pnpm db:generate && pnpm db:migrate`.
201
175
 
202
- ### `kaven init-ci`
176
+ ### AIOX Squad Integration
203
177
 
204
- Initialize CI/CD configuration in the current project. Generates GitHub Actions workflows tailored for Kaven projects.
178
+ By passing `--with-squad` during `init`, the CLI:
179
+ 1. Injects the `.gemini/` and `.antigravity/` configurations.
180
+ 2. Sets up the specialized agents: **Kai** (Orchestrator), **Dex** (Developer), **Quinn** (QA), and **Gage** (DevOps).
181
+ 3. Configures the repository for an AI-native development workflow.
205
182
 
206
183
  ---
207
184
 
208
- ## Configuration
185
+ ## Configuration & Environment
209
186
 
210
- All configuration lives in `~/.kaven/`:
187
+ All CLI state and cached marketplace data reside in `~/.kaven/`:
211
188
 
212
- ```
213
- ~/.kaven/
214
- auth.json Authentication tokens (chmod 600)
215
- config.json CLI configuration
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
- ```
189
+ - `auth.json`: JWT tokens for marketplace access.
190
+ - `config.json`: CLI preferences (e.g., `apiUrl`, `serviceToken`).
191
+ - `license.json`: Local cache of your framework license.
192
+ - `cache/`: Cached API responses to speed up browsing.
221
193
 
222
194
  ### Environment Variables
223
195
 
224
196
  | Variable | Description |
225
197
  |----------|-------------|
226
- | `KAVEN_API_URL` | Override the marketplace API URL |
227
- | `KAVEN_DEBUG=1` | Enable verbose debug output |
228
- | `KAVEN_OFFLINE=1` | Use cached data only, no network requests |
229
- | `KAVEN_TELEMETRY=0` | Disable telemetry entirely |
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
- ```
198
+ | `KAVEN_API_URL` | Override the production marketplace URL. |
199
+ | `KAVEN_DEBUG=1` | Enable detailed logging of HTTP and FS operations. |
200
+ | `KAVEN_SERVICE_TOKEN` | Token for automated CI/CD or Agent-to-Service auth. |
201
+ | `KAVEN_OFFLINE=1` | Force the CLI to use local cache only. |
251
202
 
252
203
  ---
253
204
 
254
205
  ## Troubleshooting
255
206
 
256
- **"Not authenticated" error**
257
- ```bash
258
- kaven auth login
259
- ```
260
-
261
- **"module.json not found" on publish**
207
+ ### "ReferenceError: module is not defined"
208
+ 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+.
262
209
 
263
- Run `kaven module publish` from inside the module directory (the one containing `module.json`).
210
+ ### "Marker Pairing Failed"
211
+ 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.
264
212
 
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
- ```
279
-
280
- **Cache issues**
281
- ```bash
282
- kaven cache clear
283
- ```
284
-
285
- **Permission denied on `~/.kaven/`**
286
- ```bash
287
- chmod 700 ~/.kaven
288
- chmod 600 ~/.kaven/auth.json ~/.kaven/signing-key.json
289
- ```
213
+ ### "Not Authenticated"
214
+ Run `kaven auth login`. If you are in a CI/CD environment, provide a `KAVEN_SERVICE_TOKEN` via environment variables.
290
215
 
291
216
  ---
292
217
 
293
218
  ## Contributing
294
219
 
220
+ We welcome contributions! Kaven CLI is a high-integrity project with strict quality gates.
221
+
222
+ ### Development Setup
223
+
295
224
  ```bash
225
+ # 1. Clone and install
296
226
  git clone https://github.com/kaven-co/kaven-cli
297
227
  cd kaven-cli
298
228
  pnpm install
299
- pnpm test # 310 tests
300
- pnpm run typecheck
229
+
230
+ # 2. Run the full test suite (318+ tests)
231
+ pnpm test
232
+
233
+ # 3. Run linting and type-checking
301
234
  pnpm run lint
235
+ pnpm run typecheck
236
+
237
+ # 4. Build the Pure ESM bundle
238
+ pnpm run build
302
239
  ```
303
240
 
304
- **Commit convention:** this repo uses [Conventional Commits](https://www.conventionalcommits.org/).
241
+ ### Commit Guidelines
242
+ We use **Conventional Commits**. Every commit must be prefixed with `feat:`, `fix:`, `docs:`, etc. Breaking changes must be flagged.
305
243
 
306
- ```bash
307
- feat: add --with-squad flag to kaven init
308
- fix: resolve cache corruption on concurrent writes
309
- docs: update troubleshooting section
310
- ```
244
+ ### Quality Gates
245
+ - **Tests**: 100% pass rate required.
246
+ - **Lint**: No `any` allowed in core modules.
247
+ - **ESM**: All relative imports must include the `.js` extension.
248
+
249
+ ---
311
250
 
312
- **Release flow:**
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)
251
+ ## Credits & Attribution
316
252
 
317
- Types that trigger a release: `feat` (minor), `fix` / `perf` / `refactor` (patch), `BREAKING CHANGE` (major).
318
- Types that do **not** trigger a release: `chore`, `docs`, `test`, `style`, `ci`.
253
+ Kaven CLI is built with support from the **AIOX Framework**, an agentic development ecosystem by [SynkraAI](https://github.com/synkra).
319
254
 
320
- See [`docs/releasing.md`](./docs/releasing.md) for the full release pipeline documentation.
255
+ Special thanks to the **Kaven Squad** of autonomous agents who helped architect, develop, and validate this tool:
256
+ - **Kai** (Orchestrator)
257
+ - **Dex** (Developer)
258
+ - **Quinn** (QA)
259
+ - **Gage** (DevOps)
321
260
 
322
261
  ---
323
262
 
@@ -327,6 +266,6 @@ Apache 2.0 — see [LICENSE](LICENSE)
327
266
 
328
267
  ---
329
268
 
330
- Documentation: https://docs.kaven.site/cli
331
- GitHub: https://github.com/kaven-co/kaven-cli
332
- npm: https://www.npmjs.com/package/kaven-cli
269
+ **Documentation**: [docs.kaven.site/cli](https://docs.kaven.site/cli)
270
+ **GitHub**: [github.com/kaven-co/kaven-cli](https://github.com/kaven-co/kaven-cli)
271
+ **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};
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ declare const main: () => void;
3
+
4
+ export { main };