@jawkit.cc/cli 0.1.0 → 0.1.1
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 +42 -328
- package/content/claude-code/free.tar.gz +0 -0
- package/content/claude-code/professional.tar.gz +0 -0
- package/content/github-copilot/free.tar.gz +0 -0
- package/content/manifest.json +6 -6
- package/dist/{chunk-V3HNAAHL.js → chunk-3QQ6HWDH.js} +2 -2
- package/dist/{chunk-V3HNAAHL.js.map → chunk-3QQ6HWDH.js.map} +1 -1
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,359 +5,73 @@ CLI toolkit for installing AI coding assistant configurations (Claude Code, GitH
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **Multi-agent support**: Claude Code, GitHub Copilot
|
|
8
|
-
- **Tiered content**: Free and Professional
|
|
9
|
-
- **
|
|
10
|
-
- **Offline support**: Free tier bundled in npm package
|
|
8
|
+
- **Tiered content**: Free and Professional tiers
|
|
9
|
+
- **Easy setup**: One command to install prompts, skills, and configurations
|
|
11
10
|
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
# Install globally
|
|
16
|
-
npm install -g @jawkit/cli
|
|
17
|
-
|
|
18
|
-
# Initialize in your project (free tier - no auth needed)
|
|
19
|
-
jawkit init
|
|
20
|
-
|
|
21
|
-
# For premium content, purchase at jawkit.dev and activate:
|
|
22
|
-
jawkit auth activate JAWKIT_YOUR_LICENSE_KEY
|
|
23
|
-
|
|
24
|
-
# Check license status
|
|
25
|
-
jawkit auth status
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
## Technical Stack
|
|
31
|
-
|
|
32
|
-
### CLI (Node.js)
|
|
33
|
-
|
|
34
|
-
| Component | Technology | Purpose |
|
|
35
|
-
|-----------|------------|---------|
|
|
36
|
-
| **Runtime** | Node.js 18+ | ES Modules |
|
|
37
|
-
| **CLI Framework** | Commander.js | Command parsing |
|
|
38
|
-
| **Build** | tsup | ES Module bundling |
|
|
39
|
-
| **HTTP Client** | ofetch | API requests |
|
|
40
|
-
| **Prompts** | @inquirer/prompts | Interactive CLI |
|
|
41
|
-
| **Archive** | tar (+ built-in zlib) | tar.gz extraction |
|
|
42
|
-
| **Logging** | chalk + ora | Colors, spinners |
|
|
43
|
-
| **Secure Storage** | keytar | OS keychain for tokens |
|
|
44
|
-
|
|
45
|
-
### Backend Services
|
|
46
|
-
|
|
47
|
-
| Service | Technology | Purpose |
|
|
48
|
-
|---------|------------|---------|
|
|
49
|
-
| **Payments** | Paddle | Checkout, subscriptions |
|
|
50
|
-
| **License Data** | Cloudflare D1 | License keys, payments, invitations |
|
|
51
|
-
| **Content Storage** | Cloudflare R2 | Content bundles (tar.gz) |
|
|
52
|
-
| **API Gateway** | Cloudflare Workers | License validation, signed URLs, webhooks |
|
|
53
|
-
| **Email** | Resend | License delivery emails |
|
|
54
|
-
|
|
55
|
-
### Architecture Overview
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
59
|
-
│ JawKit CLI System │
|
|
60
|
-
├─────────────────────────────────────────────────────────────────────────────┤
|
|
61
|
-
│ │
|
|
62
|
-
│ User's Machine Cloud Infrastructure │
|
|
63
|
-
│ ┌─────────────────┐ ┌─────────────────────────────┐ │
|
|
64
|
-
│ │ jawkit CLI │ │ Paddle │ │
|
|
65
|
-
│ │ (@jawkit/cli) │ │ ┌───────────────────────┐ │ │
|
|
66
|
-
│ │ │ │ │ • Checkout │ │ │
|
|
67
|
-
│ │ • init │ │ │ • Payment processing │ │ │
|
|
68
|
-
│ │ • auth activate│ │ └───────────┬───────────┘ │ │
|
|
69
|
-
│ │ • upgrade │ │ │ Webhook │ │
|
|
70
|
-
│ │ • version │ └──────────────┼──────────────┘ │
|
|
71
|
-
│ └────────┬────────┘ ▼ │
|
|
72
|
-
│ │ ┌─────────────────────────────┐ │
|
|
73
|
-
│ │ Validate license │ Cloudflare Workers │ │
|
|
74
|
-
│ │◄────────────────────────────────┤ ┌───────────────────────┐ │ │
|
|
75
|
-
│ │ Download content │ │ • Paddle webhook │ │ │
|
|
76
|
-
│ │ (signed URLs for premium) │ │ • License validation │ │ │
|
|
77
|
-
│ │ │ │ • Signed URL gen │ │ │
|
|
78
|
-
│ │ │ │ • D1 Database │ │ │
|
|
79
|
-
│ │ │ └───────────────────────┘ │ │
|
|
80
|
-
│ │ └──────────────┬──────────────┘ │
|
|
81
|
-
│ │ │ │ │
|
|
82
|
-
│ │ ▼ ▼ │
|
|
83
|
-
│ │ ┌─────────┐ ┌─────────────────┐ │
|
|
84
|
-
│ └─────────────────────────────────┤ R2 │ │ D1 │ │
|
|
85
|
-
│ Direct download (free tier) │ Content │ │ license_keys │ │
|
|
86
|
-
│ └─────────┘ │ payments │ │
|
|
87
|
-
│ ┌─────────────────┐ │ invitations │ │
|
|
88
|
-
│ │ Local Storage │ └─────────────────┘ │
|
|
89
|
-
│ │ ~/.jawkit/ │ ┌─────────────────────────────┐ │
|
|
90
|
-
│ │ • license │◄───────────────────────│ Resend │ │
|
|
91
|
-
│ │ • config.json │ │ License delivery email │ │
|
|
92
|
-
│ │ • cache/ │ └─────────────────────────────┘ │
|
|
93
|
-
│ └─────────────────┘ │
|
|
94
|
-
└─────────────────────────────────────────────────────────────────────────────┘
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
## Project Structure
|
|
100
|
-
|
|
101
|
-
```
|
|
102
|
-
jawkit-cli/
|
|
103
|
-
├── src/ # CLI source code
|
|
104
|
-
│ ├── cli.ts # Entry point (Commander setup)
|
|
105
|
-
│ ├── index.ts # Library exports
|
|
106
|
-
│ ├── commands/ # CLI commands
|
|
107
|
-
│ │ ├── auth.ts # auth activate/redeem/deactivate/status
|
|
108
|
-
│ │ ├── init.ts # Initialize content
|
|
109
|
-
│ │ ├── upgrade.ts # Upgrade content
|
|
110
|
-
│ │ └── version.ts # Show versions
|
|
111
|
-
│ ├── auth/ # Authentication module
|
|
112
|
-
│ │ ├── auth.service.ts # License activation, validation
|
|
113
|
-
│ │ ├── license-storage.ts # Keytar + file fallback for license
|
|
114
|
-
│ │ └── types.ts # TierLevel, StoredLicense, etc.
|
|
115
|
-
│ ├── content/ # Content management module
|
|
116
|
-
│ │ ├── content.service.ts # Download orchestration
|
|
117
|
-
│ │ ├── remote-provider.ts # R2 + Worker API client
|
|
118
|
-
│ │ ├── cache-manager.ts # Local disk cache
|
|
119
|
-
│ │ ├── bundled-content.ts # Offline fallback
|
|
120
|
-
│ │ └── extractor.ts # tar.gz extraction
|
|
121
|
-
│ ├── agents/ # Agent adapters
|
|
122
|
-
│ │ ├── base-agent.ts # Abstract base class
|
|
123
|
-
│ │ ├── registry.ts # Agent registry
|
|
124
|
-
│ │ ├── claude-code/ # Claude Code adapter
|
|
125
|
-
│ │ └── github-copilot/ # GitHub Copilot adapter
|
|
126
|
-
│ └── lib/ # Utilities
|
|
127
|
-
│ ├── config.ts # Configuration persistence
|
|
128
|
-
│ ├── errors.ts # Error classes
|
|
129
|
-
│ ├── promo.ts # Promotional messages
|
|
130
|
-
│ └── logger.ts # Console output
|
|
131
|
-
├── cloudflare/
|
|
132
|
-
│ └── workers/
|
|
133
|
-
│ └── jawkit-api/ # Cloudflare Worker
|
|
134
|
-
│ ├── src/
|
|
135
|
-
│ │ ├── index.ts # Router
|
|
136
|
-
│ │ ├── db/ # D1 repositories
|
|
137
|
-
│ │ │ ├── license-repository.ts
|
|
138
|
-
│ │ │ ├── payment-repository.ts
|
|
139
|
-
│ │ │ └── invitation-repository.ts
|
|
140
|
-
│ │ └── routes/
|
|
141
|
-
│ │ ├── license.ts # License validation
|
|
142
|
-
│ │ ├── invitation.ts # Invitation management
|
|
143
|
-
│ │ ├── paddle-webhook.ts # Paddle webhooks
|
|
144
|
-
│ │ └── download.ts # Signed URL generation
|
|
145
|
-
│ ├── migrations/ # D1 schema migrations
|
|
146
|
-
│ └── public/ # Pricing page static files
|
|
147
|
-
├── content-source/ # Source content by tier
|
|
148
|
-
├── content/ # Built bundles (generated)
|
|
149
|
-
├── scripts/
|
|
150
|
-
│ ├── bundle-content.ts # Build content bundles
|
|
151
|
-
│ ├── migrate-to-d1.ts # Data migration helper
|
|
152
|
-
│ └── local-r2-server.ts # Local development server
|
|
153
|
-
└── docs/
|
|
154
|
-
├── PRD.md # Product Requirements
|
|
155
|
-
├── PRP-*.md # Technical specifications
|
|
156
|
-
└── setup/ # Setup guides
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
---
|
|
160
|
-
|
|
161
|
-
## Development Setup
|
|
162
|
-
|
|
163
|
-
### Prerequisites
|
|
164
|
-
|
|
165
|
-
- Node.js 18+
|
|
166
|
-
- Cloudflare account (Workers paid plan for D1)
|
|
167
|
-
- npm or pnpm
|
|
168
|
-
|
|
169
|
-
### Step 1: Clone and Install
|
|
170
|
-
|
|
171
|
-
```bash
|
|
172
|
-
git clone https://github.com/jawkit/cli.git
|
|
173
|
-
cd jawkit-cli
|
|
174
|
-
npm install
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### Step 2: Set Up Cloudflare D1 Database
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
cd cloudflare/workers/jawkit-api
|
|
181
|
-
|
|
182
|
-
# Create D1 database
|
|
183
|
-
npx wrangler d1 create jawkit-licenses
|
|
184
|
-
# Copy the database_id to wrangler.toml
|
|
185
|
-
|
|
186
|
-
# Apply migrations
|
|
187
|
-
npx wrangler d1 migrations apply jawkit-licenses --local
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### Step 3: Configure Cloudflare Worker
|
|
191
|
-
|
|
192
|
-
Create `.dev.vars` in `cloudflare/workers/jawkit-api/`:
|
|
11
|
+
## Installation
|
|
193
12
|
|
|
194
13
|
```bash
|
|
195
|
-
|
|
196
|
-
PADDLE_WEBHOOK_SECRET=pdl_xxx
|
|
197
|
-
PADDLE_API_KEY=your-paddle-api-key
|
|
198
|
-
RESEND_API_KEY=re_xxx
|
|
199
|
-
ADMIN_KEY=local-admin-key
|
|
14
|
+
npm install -g @jawkit.cc/cli
|
|
200
15
|
```
|
|
201
16
|
|
|
202
|
-
|
|
17
|
+
## Quick Start
|
|
203
18
|
|
|
204
19
|
```bash
|
|
205
|
-
#
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
# Test CLI commands
|
|
209
|
-
node dist/cli.js version
|
|
210
|
-
node dist/cli.js init --dry-run
|
|
211
|
-
```
|
|
20
|
+
# Initialize in your project (free tier - no license needed)
|
|
21
|
+
jawkit init
|
|
212
22
|
|
|
213
|
-
|
|
23
|
+
# Check available content
|
|
24
|
+
jawkit version
|
|
214
25
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
npx wrangler dev
|
|
218
|
-
# Worker runs at http://localhost:8787
|
|
26
|
+
# Upgrade to latest content
|
|
27
|
+
jawkit upgrade
|
|
219
28
|
```
|
|
220
29
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
## Available Scripts
|
|
30
|
+
## Professional Tier
|
|
224
31
|
|
|
225
|
-
|
|
32
|
+
Get access to premium prompts, skills, and configurations:
|
|
226
33
|
|
|
227
34
|
```bash
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
npm run serve:local # Start local R2 simulation server
|
|
232
|
-
npm run test # Run tests (watch)
|
|
233
|
-
npm run test:run # Run tests (single)
|
|
234
|
-
npm run typecheck # Type checking only
|
|
235
|
-
npm run lint # ESLint
|
|
236
|
-
```
|
|
35
|
+
# Purchase at jawkit.cc
|
|
36
|
+
# Then activate your license:
|
|
37
|
+
jawkit auth activate YOUR_LICENSE_KEY
|
|
237
38
|
|
|
238
|
-
|
|
39
|
+
# Check license status
|
|
40
|
+
jawkit auth status
|
|
239
41
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
npx wrangler dev # Start dev server (localhost:8787)
|
|
243
|
-
npx wrangler deploy # Deploy to Cloudflare
|
|
244
|
-
npx wrangler d1 migrations apply jawkit-licenses --local # Apply migrations locally
|
|
245
|
-
npx wrangler d1 migrations apply jawkit-licenses --remote # Apply to production
|
|
42
|
+
# Re-run init to get professional content
|
|
43
|
+
jawkit init
|
|
246
44
|
```
|
|
247
45
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
## Environment Variables
|
|
251
|
-
|
|
252
|
-
### CLI (built-in defaults for production)
|
|
253
|
-
|
|
254
|
-
| Variable | Description | Default |
|
|
255
|
-
|----------|-------------|---------|
|
|
256
|
-
| `JAWKIT_API_URL` | API URL for license validation | `https://jawkit-api.xxx.workers.dev` |
|
|
257
|
-
| `R2_PUBLIC_URL` | Content CDN URL | `https://content.jawkit.dev` |
|
|
258
|
-
|
|
259
|
-
### Cloudflare Worker Secrets
|
|
46
|
+
## Commands
|
|
260
47
|
|
|
261
|
-
|
|
|
262
|
-
|
|
263
|
-
| `
|
|
264
|
-
| `
|
|
265
|
-
| `
|
|
266
|
-
| `
|
|
267
|
-
| `
|
|
48
|
+
| Command | Description |
|
|
49
|
+
|---------|-------------|
|
|
50
|
+
| `jawkit init` | Install content for detected AI assistant |
|
|
51
|
+
| `jawkit upgrade` | Update to latest content |
|
|
52
|
+
| `jawkit auth activate <key>` | Activate a license key |
|
|
53
|
+
| `jawkit auth status` | Show current license status |
|
|
54
|
+
| `jawkit auth deactivate` | Remove license from this machine |
|
|
55
|
+
| `jawkit version` | Show CLI and content versions |
|
|
56
|
+
| `jawkit --help` | Show all commands |
|
|
268
57
|
|
|
269
|
-
|
|
58
|
+
## Supported Agents
|
|
270
59
|
|
|
271
|
-
|
|
60
|
+
- **Claude Code** - Anthropic's AI coding assistant
|
|
61
|
+
- **GitHub Copilot** - GitHub's AI pair programmer
|
|
272
62
|
|
|
273
|
-
|
|
274
|
-
|------|-------|-------|---------|
|
|
275
|
-
| `free` | 0 | $0 | Basic commands and skills (no auth required) |
|
|
276
|
-
| `professional` | 1 | $99 one-time | All content including agents, advanced commands, skills |
|
|
63
|
+
## Requirements
|
|
277
64
|
|
|
278
|
-
|
|
65
|
+
- Node.js 18 or higher
|
|
279
66
|
|
|
280
|
-
|
|
67
|
+
## Links
|
|
281
68
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
| Method | Endpoint | Description |
|
|
287
|
-
|--------|----------|-------------|
|
|
288
|
-
| GET | `/health` | Health check |
|
|
289
|
-
| POST | `/license/validate` | Validate license key, returns tier info |
|
|
290
|
-
| POST | `/invitation/create` | Create invitation (admin) |
|
|
291
|
-
| POST | `/invitation/redeem` | Redeem invitation code |
|
|
292
|
-
| GET | `/invitation/check/:code` | Check invitation validity |
|
|
293
|
-
| GET | `/invitation/list` | List invitations (admin) |
|
|
294
|
-
| POST | `/webhook/paddle` | Paddle payment webhook handler |
|
|
295
|
-
| GET | `/manifests/latest.json` | Get content manifest |
|
|
296
|
-
| GET | `/bundles/:agent/:version/free.tar.gz` | Download free bundle |
|
|
297
|
-
| POST | `/get-download-url` | Get signed URL for premium bundle |
|
|
298
|
-
| GET | `/download/:path` | Download with signature verification |
|
|
299
|
-
| GET | `/` | Pricing page (static) |
|
|
300
|
-
| GET | `/success.html` | Post-purchase success page |
|
|
301
|
-
|
|
302
|
-
---
|
|
303
|
-
|
|
304
|
-
## Documentation
|
|
305
|
-
|
|
306
|
-
### Setup Guides
|
|
307
|
-
|
|
308
|
-
| Guide | Description |
|
|
309
|
-
|-------|-------------|
|
|
310
|
-
| [Cloudflare Setup](docs/setup/01-cloudflare-setup.md) | D1, Worker, and R2 deployment |
|
|
311
|
-
| [Development Workflow](docs/setup/02-development-workflow.md) | Day-to-day development |
|
|
312
|
-
| [Content Authoring](docs/setup/03-content-authoring.md) | Creating content bundles |
|
|
313
|
-
| [Content Pipeline](docs/setup/04-content-pipeline.md) | End-to-end content flow |
|
|
314
|
-
| [Init Command Flow](docs/setup/05-init-command-flow.md) | Detailed init flow |
|
|
315
|
-
| [Tier Management](docs/setup/06-tier-management.md) | Adding/modifying tiers |
|
|
316
|
-
| [CLI Reference](docs/setup/07-cli-reference.md) | Complete workflow reference |
|
|
317
|
-
| [Local Testing](docs/setup/08-local-testing.md) | Testing without cloud |
|
|
318
|
-
|
|
319
|
-
### Technical Specifications
|
|
320
|
-
|
|
321
|
-
| Document | Description |
|
|
322
|
-
|----------|-------------|
|
|
323
|
-
| [PRD.md](docs/PRD.md) | Product Requirements Document |
|
|
324
|
-
| [PRP-001](docs/PRP-001-CLI-Core.md) | CLI Core Architecture |
|
|
325
|
-
| [PRP-002](docs/PRP-002-Authentication.md) | Authentication System |
|
|
326
|
-
| [PRP-003](docs/PRP-003-Agent-Adapters.md) | Agent Adapter System |
|
|
327
|
-
| [PRP-004](docs/PRP-004-Content-Management.md) | Content Management |
|
|
328
|
-
| [PRP-005](docs/PRP-005-Version-Management.md) | Version Management |
|
|
329
|
-
|
|
330
|
-
---
|
|
331
|
-
|
|
332
|
-
## Maintainer Guide
|
|
333
|
-
|
|
334
|
-
### Key Files for Common Changes
|
|
335
|
-
|
|
336
|
-
| Task | Files to Modify |
|
|
337
|
-
|------|-----------------|
|
|
338
|
-
| Add CLI command | `src/commands/`, `src/cli.ts` |
|
|
339
|
-
| Add agent adapter | `src/agents/`, `src/agents/registry.ts` |
|
|
340
|
-
| Modify auth flow | `src/auth/auth.service.ts`, Worker `/routes/license.ts` |
|
|
341
|
-
| Change tier system | `src/auth/types.ts`, Worker, D1 migrations |
|
|
342
|
-
| Update content schema | `src/content/types.ts`, `scripts/bundle-content.ts` |
|
|
343
|
-
|
|
344
|
-
### Security Notes
|
|
345
|
-
|
|
346
|
-
1. **License Keys**: Stored in OS keychain (keytar) with file fallback (0600 permissions)
|
|
347
|
-
2. **Signed URLs**: HMAC-SHA256, 1-hour expiry, served through Worker
|
|
348
|
-
3. **Webhook Security**: Paddle signature verification (HMAC-SHA256)
|
|
349
|
-
4. **Tier Access**: Server-side license validation in Cloudflare Worker
|
|
350
|
-
|
|
351
|
-
### Testing Checklist
|
|
352
|
-
|
|
353
|
-
- [ ] `npm run typecheck` - No type errors
|
|
354
|
-
- [ ] `npm run lint` - No lint errors
|
|
355
|
-
- [ ] `npm run test:run` - All tests pass
|
|
356
|
-
- [ ] `npm run build` - Builds successfully
|
|
357
|
-
- [ ] Manual test: `jawkit init --dry-run` works
|
|
358
|
-
|
|
359
|
-
---
|
|
69
|
+
- Website: https://jawkit.cc
|
|
70
|
+
- Purchase: https://jawkit.cc/pro
|
|
71
|
+
- Documentation: https://jawkit.cc/docs
|
|
360
72
|
|
|
361
73
|
## License
|
|
362
74
|
|
|
363
|
-
Proprietary -
|
|
75
|
+
Proprietary - See [LICENSE](LICENSE) for details.
|
|
76
|
+
|
|
77
|
+
**Important**: The content installed by JawKit (prompts, skills, configurations) is for your personal or internal business use only. Sharing content with others is not permitted.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/content/manifest.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "2.0",
|
|
3
3
|
"version": "1.0.0",
|
|
4
|
-
"publishedAt": "2026-01-28T08:
|
|
4
|
+
"publishedAt": "2026-01-28T08:45:20.342Z",
|
|
5
5
|
"minCliVersion": "1.0.0",
|
|
6
6
|
"agents": {
|
|
7
7
|
"claude-code": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"bundles": {
|
|
10
10
|
"free": {
|
|
11
11
|
"filename": "free.tar.gz",
|
|
12
|
-
"checksum": "sha256:
|
|
12
|
+
"checksum": "sha256:497c14d48dc4a41a70ae8ca40c311e08a6fd6bcb40cffd9125a6a2018a860ebf",
|
|
13
13
|
"size": 2774,
|
|
14
14
|
"fileCount": 6,
|
|
15
15
|
"contentTypes": [
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
},
|
|
20
20
|
"professional": {
|
|
21
21
|
"filename": "professional.tar.gz",
|
|
22
|
-
"checksum": "sha256:
|
|
23
|
-
"size":
|
|
22
|
+
"checksum": "sha256:325d95500206c047b60f2e6dee87854a693710cba8bf1d042279de240e346be1",
|
|
23
|
+
"size": 4438,
|
|
24
24
|
"fileCount": 8,
|
|
25
25
|
"contentTypes": [
|
|
26
26
|
"agents",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"bundles": {
|
|
36
36
|
"free": {
|
|
37
37
|
"filename": "free.tar.gz",
|
|
38
|
-
"checksum": "sha256:
|
|
39
|
-
"size":
|
|
38
|
+
"checksum": "sha256:02433d0aedb0b5aa72635d11e7f13ca20c62f31197886a7bfd2dc1456a9ee0d0",
|
|
39
|
+
"size": 1050,
|
|
40
40
|
"fileCount": 2,
|
|
41
41
|
"contentTypes": [
|
|
42
42
|
"commands",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// package.json
|
|
4
|
-
var version = "0.1.
|
|
4
|
+
var version = "0.1.1";
|
|
5
5
|
var description = "CLI toolkit for installing AI coding assistant configurations";
|
|
6
6
|
|
|
7
7
|
// src/lib/logger.ts
|
|
@@ -1366,4 +1366,4 @@ export {
|
|
|
1366
1366
|
isNewerVersion,
|
|
1367
1367
|
checkContentUpdates
|
|
1368
1368
|
};
|
|
1369
|
-
//# sourceMappingURL=chunk-
|
|
1369
|
+
//# sourceMappingURL=chunk-3QQ6HWDH.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/lib/logger.ts","../src/lib/errors.ts","../src/lib/config.ts","../src/auth/types.ts","../src/auth/auth.service.ts","../src/auth/license-storage.ts","../src/content/content.service.ts","../src/content/remote-provider.ts","../src/content/cache-manager.ts","../src/content/bundled-content.ts","../src/content/extractor.ts","../src/services/cli-version.ts","../src/services/content-version.ts"],"sourcesContent":["{\n \"name\": \"@jawkit.cc/cli\",\n \"version\": \"0.1.0\",\n \"description\": \"CLI toolkit for installing AI coding assistant configurations\",\n \"type\": \"module\",\n \"bin\": {\n \"jawkit\": \"./dist/cli.js\"\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\"\n }\n },\n \"files\": [\n \"dist\",\n \"content\"\n ],\n \"scripts\": {\n \"dev\": \"tsup --watch\",\n \"build\": \"tsup\",\n \"start\": \"node dist/cli.js\",\n \"lint\": \"eslint src --ext .ts\",\n \"lint:fix\": \"eslint src --ext .ts --fix\",\n \"test\": \"vitest\",\n \"test:run\": \"vitest run\",\n \"typecheck\": \"tsc --noEmit\",\n \"bundle-content\": \"tsx scripts/bundle-content.ts\",\n \"upload-content\": \"node scripts/upload-content.js\",\n \"deploy\": \"node scripts/deploy.js\",\n \"publish-content\": \"npm run bundle-content && npm run upload-content\",\n \"serve:local\": \"tsx scripts/local-r2-server.ts\",\n \"prebuild\": \"npm run bundle-content || true\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"cli\",\n \"ai\",\n \"claude\",\n \"copilot\",\n \"coding-assistant\",\n \"developer-tools\"\n ],\n \"author\": \"JawKit\",\n \"license\": \"SEE LICENSE IN LICENSE\",\n \"private\": false,\n \"engines\": {\n \"node\": \">=18.0.0\"\n },\n \"dependencies\": {\n \"@inquirer/prompts\": \"^7.2.1\",\n \"chalk\": \"^5.4.1\",\n \"commander\": \"^13.0.0\",\n \"ofetch\": \"^1.4.1\",\n \"ora\": \"^8.1.1\",\n \"tar\": \"^7.4.3\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.10.7\",\n \"eslint\": \"^9.18.0\",\n \"tsup\": \"^8.3.5\",\n \"tsx\": \"^4.7.0\",\n \"typescript\": \"^5.7.3\",\n \"vitest\": \"^2.1.8\"\n }\n}\n","import chalk from 'chalk';\nimport ora, { type Ora } from 'ora';\n\nexport interface LoggerOptions {\n quiet?: boolean;\n verbose?: boolean;\n json?: boolean;\n}\n\nexport class Logger {\n private options: LoggerOptions;\n private currentSpinner: Ora | null = null;\n\n constructor(options: LoggerOptions = {}) {\n this.options = options;\n }\n\n info(message: string): void {\n if (this.options.quiet) return;\n console.log(message);\n }\n\n success(message: string): void {\n if (this.options.quiet) return;\n console.log(chalk.green('✓'), message);\n }\n\n warn(message: string): void {\n console.log(chalk.yellow('⚠'), message);\n }\n\n error(message: string): void {\n console.error(chalk.red('✖'), message);\n }\n\n debug(message: string): void {\n if (!this.options.verbose) return;\n console.log(chalk.gray(`[debug] ${message}`));\n }\n\n newline(): void {\n if (this.options.quiet) return;\n console.log();\n }\n\n divider(char = '─', length = 40): void {\n if (this.options.quiet) return;\n console.log(chalk.gray(char.repeat(length)));\n }\n\n spinner(text: string): Ora {\n this.currentSpinner = ora({\n text,\n spinner: 'dots',\n });\n return this.currentSpinner;\n }\n\n stopSpinner(): void {\n if (this.currentSpinner) {\n this.currentSpinner.stop();\n this.currentSpinner = null;\n }\n }\n\n progress(percentage: number, text?: string): void {\n if (this.options.quiet) return;\n\n const width = 30;\n const filled = Math.round((percentage / 100) * width);\n const empty = width - filled;\n const bar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));\n\n process.stdout.write(`\\r${bar} ${percentage}%${text ? ` ${text}` : ''}`);\n\n if (percentage >= 100) {\n console.log();\n }\n }\n\n table(data: Record<string, string>[]): void {\n if (this.options.quiet) return;\n console.table(data);\n }\n\n json(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n }\n}\n\n// Default logger instance\nexport const logger = new Logger();\n","import chalk from 'chalk';\nimport { Logger } from './logger.js';\n\nexport abstract class JawKitError extends Error {\n abstract code: string;\n suggestion?: string;\n cause?: Error;\n\n constructor(message: string, options?: { cause?: Error }) {\n super(message);\n this.name = this.constructor.name;\n this.cause = options?.cause;\n }\n}\n\nexport class AuthError extends JawKitError {\n code = 'AUTH_ERROR';\n\n static notAuthenticated(): AuthError {\n const error = new AuthError('No license key activated');\n error.suggestion = \"Run 'jawkit auth activate <license-key>' to activate your license\";\n return error;\n }\n\n static licenseExpired(): AuthError {\n const error = new AuthError('License has expired');\n error.suggestion = \"Visit https://jawkit.cc/pro to renew your license\";\n return error;\n }\n\n static activationFailed(reason?: string): AuthError {\n const error = new AuthError(`License activation failed${reason ? `: ${reason}` : ''}`);\n error.suggestion = 'Check your license key and try again';\n return error;\n }\n\n static licenseRevoked(): AuthError {\n const error = new AuthError('License has been revoked');\n error.suggestion = 'Contact support at support@jawkit.cc';\n return error;\n }\n\n static licenseNotFound(): AuthError {\n const error = new AuthError('License key not found');\n error.suggestion = 'Check your license key and try again';\n return error;\n }\n}\n\nexport class ContentError extends JawKitError {\n code = 'CONTENT_ERROR';\n\n static manifestNotFound(): ContentError {\n const error = new ContentError('Content manifest not found');\n error.suggestion = 'Check your internet connection and try again';\n return error;\n }\n\n static checksumMismatch(bundle: string): ContentError {\n const error = new ContentError(\n `Bundle checksum verification failed: ${bundle}`\n );\n error.suggestion =\n 'Try running the command again. The download may have been corrupted.';\n return error;\n }\n\n static downloadFailed(bundle: string, status?: number): ContentError {\n const error = new ContentError(\n `Failed to download bundle: ${bundle}${status ? ` (HTTP ${status})` : ''}`\n );\n error.suggestion = 'Check your internet connection and try again';\n return error;\n }\n\n static extractionFailed(bundle: string): ContentError {\n const error = new ContentError(`Failed to extract bundle: ${bundle}`);\n error.suggestion =\n 'The bundle may be corrupted. Try running jawkit init again to re-download.';\n return error;\n }\n\n static tierAccessDenied(tier: string): ContentError {\n const error = new ContentError(`Access denied for tier: ${tier}`);\n error.suggestion = 'Upgrade to Professional at https://jawkit.cc/pro';\n return error;\n }\n\n static signedUrlFailed(): ContentError {\n const error = new ContentError('Failed to get download authorization');\n error.suggestion = \"Check your license status with: jawkit auth status\";\n return error;\n }\n}\n\nexport class AgentError extends JawKitError {\n code = 'AGENT_ERROR';\n\n static notFound(agentId: string): AgentError {\n const error = new AgentError(`Agent not found: ${agentId}`);\n error.suggestion = \"Run 'jawkit init --help' to see available agents\";\n return error;\n }\n\n static installFailed(agentId: string, reason?: string): AgentError {\n const error = new AgentError(\n `Failed to install ${agentId}${reason ? `: ${reason}` : ''}`\n );\n return error;\n }\n\n static alreadyInstalled(agentId: string, path: string): AgentError {\n const error = new AgentError(`${agentId} is already installed at ${path}`);\n error.suggestion = \"Run 'jawkit init' again to update (existing content will be backed up)\";\n return error;\n }\n}\n\nexport class ConfigError extends JawKitError {\n code = 'CONFIG_ERROR';\n\n static readFailed(path: string): ConfigError {\n const error = new ConfigError(`Failed to read config file: ${path}`);\n return error;\n }\n\n static writeFailed(path: string): ConfigError {\n const error = new ConfigError(`Failed to write config file: ${path}`);\n return error;\n }\n}\n\n/**\n * Handle and display error to user\n */\nexport function handleError(error: unknown, logger: Logger): void {\n if (error instanceof JawKitError) {\n logger.error(error.message);\n\n if (error.suggestion) {\n logger.info(chalk.dim(` Suggestion: ${error.suggestion}`));\n }\n\n if (error.cause) {\n logger.debug(`Caused by: ${error.cause.message}`);\n }\n } else if (error instanceof Error) {\n logger.error(error.message);\n\n if (error.stack) {\n logger.debug(error.stack);\n }\n } else {\n logger.error(String(error));\n }\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\n\nconst CONFIG_DIR = path.join(os.homedir(), '.jawkit');\nconst CONFIG_FILE = 'config.json';\n\nexport interface JawKitConfig {\n contentVersions?: Record<string, string>;\n lastUpdateCheck?: string;\n installations?: Installation[];\n}\n\nexport interface Installation {\n path: string;\n agent: string;\n contentVersion: string;\n installedAt: string;\n files: string[];\n tier?: string; // Tier used when content was installed (free, professional)\n checksum?: string; // Bundle checksum for detecting content changes\n}\n\nexport class ConfigService {\n private configDir: string;\n private configPath: string;\n private config: JawKitConfig | null = null;\n\n constructor(configDir: string = CONFIG_DIR) {\n this.configDir = configDir;\n this.configPath = path.join(configDir, CONFIG_FILE);\n }\n\n async initialize(): Promise<void> {\n await fs.mkdir(this.configDir, { recursive: true });\n }\n\n async load(): Promise<JawKitConfig> {\n if (this.config) {\n return this.config;\n }\n\n try {\n const content = await fs.readFile(this.configPath, 'utf-8');\n this.config = JSON.parse(content);\n return this.config!;\n } catch {\n this.config = {};\n return this.config;\n }\n }\n\n async save(): Promise<void> {\n await this.initialize();\n await fs.writeFile(\n this.configPath,\n JSON.stringify(this.config ?? {}, null, 2)\n );\n }\n\n async get<K extends keyof JawKitConfig>(key: K): Promise<JawKitConfig[K]> {\n const config = await this.load();\n return config[key];\n }\n\n async set<K extends keyof JawKitConfig>(\n key: K,\n value: JawKitConfig[K]\n ): Promise<void> {\n await this.load();\n this.config = { ...this.config, [key]: value };\n await this.save();\n }\n\n async getInstallations(): Promise<Installation[]> {\n return (await this.get('installations')) ?? [];\n }\n\n async addInstallation(installation: Installation): Promise<void> {\n const installations = await this.getInstallations();\n const existingIndex = installations.findIndex(\n (i) => i.path === installation.path && i.agent === installation.agent\n );\n\n if (existingIndex >= 0) {\n installations[existingIndex] = installation;\n } else {\n installations.push(installation);\n }\n\n await this.set('installations', installations);\n }\n\n async updateInstallation(\n installPath: string,\n updates: Partial<Installation>\n ): Promise<void> {\n const installations = await this.getInstallations();\n const index = installations.findIndex((i) => i.path === installPath);\n\n if (index >= 0) {\n installations[index] = { ...installations[index]!, ...updates };\n await this.set('installations', installations);\n }\n }\n\n getConfigDir(): string {\n return this.configDir;\n }\n}\n","/**\n * User tier levels\n */\nexport type TierLevel = 'free' | 'professional';\n\n/**\n * Stored license data (re-export from license-storage for convenience)\n */\nexport type { StoredLicense } from './license-storage.js';\n\n/**\n * User profile derived from license\n */\nexport interface UserProfile {\n email: string;\n tier: TierLevel;\n tierExpiresAt: string | null;\n}\n\n/**\n * License activation result\n */\nexport interface ActivationResult {\n success: boolean;\n user: UserProfile | null;\n error?: string;\n}\n\n/**\n * License validation response from server\n */\nexport interface LicenseValidationResponse {\n valid: boolean;\n email: string;\n tier: string;\n tierExpiresAt: string | null;\n}\n\n/**\n * Tier level utilities\n */\nexport const TIER_LEVELS: Record<TierLevel, number> = {\n 'free': 0,\n 'professional': 1,\n};\n\nexport function getTierLevel(tier: TierLevel): number {\n return TIER_LEVELS[tier] ?? 0;\n}\n\nexport function hasTierAccess(userTier: TierLevel, requiredTier: TierLevel): boolean {\n return getTierLevel(userTier) >= getTierLevel(requiredTier);\n}\n\nexport function getTierDisplayName(tier: TierLevel): string {\n switch (tier) {\n case 'free':\n return 'Free';\n case 'professional':\n return 'Professional ($99)';\n default:\n return 'Unknown';\n }\n}\n","import { ofetch } from 'ofetch';\nimport { LicenseStorage, type StoredLicense } from './license-storage.js';\nimport type {\n UserProfile,\n TierLevel,\n ActivationResult,\n LicenseValidationResponse,\n} from './types.js';\n\n// API endpoint for license validation\n// Set JAWKIT_API_URL environment variable to override\nconst API_URL = process.env.JAWKIT_API_URL || 'https://api.jawkit.cc';\n\n/**\n * Authentication Service\n * Handles license key activation, validation, and storage\n */\nexport class AuthService {\n private licenseStorage: LicenseStorage;\n\n constructor() {\n this.licenseStorage = new LicenseStorage();\n }\n\n /**\n * Activate a license key\n * Validates against server and stores locally\n */\n async activate(licenseKey: string): Promise<ActivationResult> {\n // Basic format validation\n if (!licenseKey.startsWith('JAWKIT_')) {\n return {\n success: false,\n user: null,\n error: 'Invalid license key format. License keys start with JAWKIT_',\n };\n }\n\n try {\n // Validate against server\n const response = await ofetch<LicenseValidationResponse>(\n `${API_URL}/license/validate`,\n {\n method: 'POST',\n body: { licenseKey },\n }\n );\n\n if (!response.valid) {\n return {\n success: false,\n user: null,\n error: 'License key validation failed',\n };\n }\n\n // Store license locally\n const storedLicense: StoredLicense = {\n licenseKey,\n email: response.email,\n tier: response.tier,\n tierExpiresAt: response.tierExpiresAt,\n validatedAt: Date.now(),\n };\n\n await this.licenseStorage.store(storedLicense);\n\n return {\n success: true,\n user: {\n email: response.email,\n tier: response.tier as TierLevel,\n tierExpiresAt: response.tierExpiresAt,\n },\n };\n } catch (error) {\n // Handle specific HTTP errors\n if (error instanceof Error && 'statusCode' in error) {\n const statusCode = (error as { statusCode: number }).statusCode;\n if (statusCode === 404) {\n return {\n success: false,\n user: null,\n error: 'License key not found',\n };\n }\n if (statusCode === 403) {\n return {\n success: false,\n user: null,\n error: 'License has been revoked',\n };\n }\n }\n\n return {\n success: false,\n user: null,\n error: error instanceof Error ? error.message : 'Failed to validate license',\n };\n }\n }\n\n /**\n * Deactivate (remove) stored license\n */\n async deactivate(): Promise<void> {\n await this.licenseStorage.clear();\n }\n\n /**\n * Check if user has a valid license stored\n */\n async isAuthenticated(): Promise<boolean> {\n const license = await this.licenseStorage.retrieve();\n if (!license) {\n return false;\n }\n\n // Check if tier has expired\n if (license.tierExpiresAt) {\n const expiresAt = new Date(license.tierExpiresAt);\n if (expiresAt < new Date()) {\n // Tier expired, but license still valid (falls back to free)\n return true;\n }\n }\n\n return true;\n }\n\n /**\n * Get current user profile from stored license\n */\n async getCurrentUser(): Promise<UserProfile | null> {\n const license = await this.licenseStorage.retrieve();\n if (!license) {\n return null;\n }\n\n // Determine effective tier (check expiration)\n let effectiveTier: TierLevel = license.tier as TierLevel;\n if (license.tierExpiresAt) {\n const expiresAt = new Date(license.tierExpiresAt);\n if (expiresAt < new Date()) {\n effectiveTier = 'free';\n }\n }\n\n return {\n email: license.email,\n tier: effectiveTier,\n tierExpiresAt: license.tierExpiresAt,\n };\n }\n\n /**\n * Get user's tier level\n * Returns 'free' if no license or expired\n */\n async getUserTier(): Promise<TierLevel> {\n const user = await this.getCurrentUser();\n return user?.tier ?? 'free';\n }\n\n /**\n * Get stored license key for API requests\n */\n async getLicenseKey(): Promise<string | null> {\n const license = await this.licenseStorage.retrieve();\n return license?.licenseKey ?? null;\n }\n\n /**\n * Redeem an invitation code\n * Calls API to exchange invite code for license key, then activates it\n */\n async redeem(inviteCode: string, email: string): Promise<ActivationResult> {\n // Basic format validation\n if (!inviteCode.startsWith('JAWKIT_INV_')) {\n return {\n success: false,\n user: null,\n error: 'Invalid invitation code format. Invitation codes start with JAWKIT_INV_',\n };\n }\n\n try {\n // Call redeem API\n const response = await ofetch<{\n success: boolean;\n licenseKey: string;\n email: string;\n tier: string;\n tierExpiresAt: string | null;\n }>(`${API_URL}/invitation/redeem`, {\n method: 'POST',\n body: { inviteCode, email },\n });\n\n if (!response.success || !response.licenseKey) {\n return {\n success: false,\n user: null,\n error: 'Failed to redeem invitation',\n };\n }\n\n // Store the new license locally\n const storedLicense: StoredLicense = {\n licenseKey: response.licenseKey,\n email: response.email,\n tier: response.tier,\n tierExpiresAt: response.tierExpiresAt,\n validatedAt: Date.now(),\n };\n\n await this.licenseStorage.store(storedLicense);\n\n return {\n success: true,\n user: {\n email: response.email,\n tier: response.tier as TierLevel,\n tierExpiresAt: response.tierExpiresAt,\n },\n };\n } catch (error) {\n // Handle specific HTTP errors\n if (error instanceof Error && 'data' in error) {\n const data = (error as { data?: { error?: string } }).data;\n if (data?.error) {\n return {\n success: false,\n user: null,\n error: data.error,\n };\n }\n }\n\n return {\n success: false,\n user: null,\n error: error instanceof Error ? error.message : 'Failed to redeem invitation',\n };\n }\n }\n\n /**\n * Re-validate stored license against server\n * Useful for refreshing tier status\n */\n async revalidate(): Promise<ActivationResult> {\n const license = await this.licenseStorage.retrieve();\n if (!license) {\n return {\n success: false,\n user: null,\n error: 'No license key stored',\n };\n }\n\n return this.activate(license.licenseKey);\n }\n\n}\n\n// Singleton instance\nlet authServiceInstance: AuthService | null = null;\n\n/**\n * Get the AuthService singleton instance\n */\nexport function getAuthService(): AuthService {\n if (!authServiceInstance) {\n authServiceInstance = new AuthService();\n }\n return authServiceInstance;\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\n\nconst STORAGE_DIR = path.join(os.homedir(), '.jawkit');\nconst LICENSE_FILE = 'license.json';\n\n/**\n * Stored license data\n */\nexport interface StoredLicense {\n licenseKey: string;\n email: string;\n tier: string;\n tierExpiresAt: string | null;\n validatedAt: number; // Unix timestamp in milliseconds\n}\n\n/**\n * File-based license storage with restricted permissions\n */\nexport class LicenseStorage {\n private getFilePath(): string {\n return path.join(STORAGE_DIR, LICENSE_FILE);\n }\n\n /**\n * Store license data\n */\n async store(license: StoredLicense): Promise<void> {\n await fs.mkdir(STORAGE_DIR, { recursive: true });\n const filePath = this.getFilePath();\n\n // Store with restricted permissions (owner read/write only)\n await fs.writeFile(filePath, JSON.stringify(license, null, 2), {\n mode: 0o600,\n });\n }\n\n /**\n * Retrieve stored license\n */\n async retrieve(): Promise<StoredLicense | null> {\n try {\n const filePath = this.getFilePath();\n const data = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(data) as StoredLicense;\n } catch {\n return null;\n }\n }\n\n /**\n * Clear stored license\n */\n async clear(): Promise<void> {\n try {\n const filePath = this.getFilePath();\n await fs.unlink(filePath);\n } catch {\n // File doesn't exist, ignore\n }\n }\n\n /**\n * Check if license is stored\n */\n async hasLicense(): Promise<boolean> {\n const license = await this.retrieve();\n return license !== null;\n }\n}\n","import fs from 'fs/promises';\nimport type {\n ContentManifest,\n BundleManifest,\n ExtractResult,\n UpdateInfo,\n ProgressCallback,\n} from './types.js';\nimport type { TierLevel } from '../auth/types.js';\nimport { RemoteProvider, getRemoteProvider } from './remote-provider.js';\nimport { CacheManager, getCacheManager } from './cache-manager.js';\nimport { BundledContent, getBundledContent } from './bundled-content.js';\nimport { extractBundle, verifyChecksum } from './extractor.js';\nimport { getAuthService } from '../auth/index.js';\nimport { ContentError } from '../lib/errors.js';\n\n/**\n * Main content service for downloading and managing JawKit content\n */\nexport class ContentService {\n private remote: RemoteProvider;\n private cache: CacheManager;\n private bundled: BundledContent;\n\n constructor(\n remote?: RemoteProvider,\n cache?: CacheManager,\n bundled?: BundledContent\n ) {\n this.remote = remote || getRemoteProvider();\n this.cache = cache || getCacheManager();\n this.bundled = bundled || getBundledContent();\n }\n\n /**\n * Get the content manifest\n * Falls back: remote → cache → bundled\n */\n async getManifest(version: string = 'latest'): Promise<ContentManifest> {\n // Try remote first\n try {\n const manifest = await this.remote.fetchManifest(version);\n await this.cache.saveManifest(manifest);\n return manifest;\n } catch {\n // Fall back to cached manifest\n const cached = await this.cache.getManifest();\n if (cached) {\n return cached;\n }\n\n // Fall back to bundled manifest\n const bundledManifest = this.bundled.getManifestOrNull();\n if (bundledManifest) {\n return bundledManifest;\n }\n\n throw ContentError.manifestNotFound();\n }\n }\n\n /**\n * Get bundle info for a user's tier\n */\n async getBundleInfo(agentId: string, tier: TierLevel): Promise<BundleManifest> {\n const manifest = await this.getManifest();\n const agentManifest = manifest.agents[agentId];\n\n if (!agentManifest) {\n throw new ContentError(`Agent not found in manifest: ${agentId}`);\n }\n\n // Try the requested tier, fall back to free\n const bundleInfo = agentManifest.bundles[tier] || agentManifest.bundles['free'];\n\n if (!bundleInfo) {\n throw new ContentError(`No bundle available for agent: ${agentId}`);\n }\n\n return bundleInfo;\n }\n\n /**\n * Download and extract a content bundle\n */\n async downloadAndExtractBundle(\n agentId: string,\n tier: TierLevel,\n targetDir: string,\n onProgress?: ProgressCallback\n ): Promise<ExtractResult> {\n const manifest = await this.getManifest();\n const agentManifest = manifest.agents[agentId];\n\n if (!agentManifest) {\n throw new ContentError(`Agent not found: ${agentId}`);\n }\n\n // Get best available bundle for tier\n const effectiveTier = agentManifest.bundles[tier] ? tier : 'free';\n const bundleInfo = agentManifest.bundles[effectiveTier];\n\n if (!bundleInfo) {\n throw new ContentError(`No bundle available for agent: ${agentId}`);\n }\n\n const version = agentManifest.version;\n\n // Check cache first\n const cachedBundle = await this.cache.getBundle(agentId, version, effectiveTier);\n let bundlePath: string;\n\n if (cachedBundle && (await verifyChecksum(cachedBundle, bundleInfo.checksum))) {\n bundlePath = cachedBundle;\n } else {\n // Download bundle\n bundlePath = await this.downloadBundle(\n agentId,\n version,\n effectiveTier,\n bundleInfo,\n onProgress\n );\n }\n\n // Extract bundle\n const result = await extractBundle(bundlePath, targetDir, onProgress);\n\n // Clean up old versions\n await this.cache.clearOldVersions(agentId, version);\n\n return {\n ...result,\n version,\n };\n }\n\n /**\n * Download a bundle to cache\n */\n private async downloadBundle(\n agentId: string,\n version: string,\n tier: TierLevel | 'free',\n bundleInfo: BundleManifest,\n onProgress?: ProgressCallback\n ): Promise<string> {\n // Get license key for premium tiers\n let licenseKey: string | null = null;\n if (tier !== 'free') {\n const authService = getAuthService();\n licenseKey = await authService.getLicenseKey();\n }\n\n // Get download URL\n const downloadUrl = await this.remote.getBundleUrl(\n agentId,\n version,\n tier as TierLevel,\n licenseKey\n );\n\n // Create temp file path\n const tempPath = await this.cache.getTempPath(`${agentId}-${version}-${tier}.tar.gz`);\n\n // Download with progress\n await this.remote.downloadToFile(downloadUrl, tempPath, bundleInfo.size, (downloaded) => {\n onProgress?.({\n phase: 'downloading',\n totalBytes: bundleInfo.size,\n processedBytes: downloaded,\n percentage: Math.round((downloaded / bundleInfo.size) * 100),\n });\n });\n\n // Verify checksum\n if (!(await verifyChecksum(tempPath, bundleInfo.checksum))) {\n await fs.unlink(tempPath);\n throw ContentError.checksumMismatch(bundleInfo.filename);\n }\n\n // Move to cache\n const cachePath = await this.cache.saveBundle(agentId, version, tier, tempPath);\n\n return cachePath;\n }\n\n /**\n * Check for content updates\n * Returns null if no update available or if check fails\n * Use verbose logging to see failure details\n */\n async checkForUpdates(\n agentId: string,\n currentVersion: string,\n verbose: boolean = false\n ): Promise<UpdateInfo | null> {\n try {\n const manifest = await this.remote.fetchManifest('latest');\n const agentManifest = manifest.agents[agentId];\n\n if (!agentManifest) {\n if (verbose) {\n console.error(`Update check: agent \"${agentId}\" not found in manifest`);\n }\n return null;\n }\n\n if (this.isNewerVersion(agentManifest.version, currentVersion)) {\n // Get bundle info for display (use largest available tier)\n const professional = agentManifest.bundles['professional'];\n const free = agentManifest.bundles['free'];\n const displayBundle = professional || free;\n\n if (!displayBundle) {\n return null;\n }\n\n return {\n currentVersion,\n latestVersion: agentManifest.version,\n changelog: manifest.changelog,\n publishedAt: new Date(manifest.publishedAt),\n bundleSize: displayBundle.size,\n fileCount: displayBundle.fileCount,\n };\n }\n\n return null;\n } catch (error) {\n // Log failure in verbose mode so users can diagnose issues\n if (verbose) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`Update check failed: ${message}`);\n }\n return null;\n }\n }\n\n /**\n * Extract bundled fallback content (free tier only)\n */\n async extractFallbackContent(\n agentId: string,\n targetDir: string,\n onProgress?: ProgressCallback\n ): Promise<ExtractResult> {\n const bundlePath = this.bundled.getBundlePath(agentId);\n\n if (!bundlePath) {\n throw new ContentError('No bundled fallback content available');\n }\n\n const result = await extractBundle(bundlePath, targetDir, onProgress);\n const manifest = this.bundled.getManifestOrNull();\n\n return {\n ...result,\n version: manifest?.version || 'bundled',\n };\n }\n\n /**\n * Check if bundled fallback is available for an agent\n */\n hasFallbackContent(agentId: string): boolean {\n return this.bundled.hasBundle(agentId);\n }\n\n /**\n * Compare semantic versions\n */\n private isNewerVersion(latest: string, current: string): boolean {\n const latestParts = latest.split('.').map(Number);\n const currentParts = current.split('.').map(Number);\n\n for (let i = 0; i < 3; i++) {\n const l = latestParts[i] || 0;\n const c = currentParts[i] || 0;\n if (l > c) return true;\n if (l < c) return false;\n }\n\n return false;\n }\n}\n\n// Singleton instance\nlet contentServiceInstance: ContentService | null = null;\n\n/**\n * Get the ContentService singleton instance\n */\nexport function getContentService(): ContentService {\n if (!contentServiceInstance) {\n contentServiceInstance = new ContentService();\n }\n return contentServiceInstance;\n}\n","import { ofetch, FetchError } from 'ofetch';\nimport { createWriteStream } from 'fs';\nimport { pipeline } from 'stream/promises';\nimport { Readable } from 'stream';\nimport type { ContentManifest, SignedUrlResponse } from './types.js';\nimport type { TierLevel } from '../auth/types.js';\nimport { ContentError } from '../lib/errors.js';\n\n// Cloudflare Worker URL (handles manifest + signed URLs)\n// Set JAWKIT_WORKER_URL environment variable to override\nconst WORKER_URL = process.env.JAWKIT_WORKER_URL || 'https://api.jawkit.cc';\n\n// R2 public URL for content downloads\n// Set R2_PUBLIC_URL environment variable to override\nconst R2_PUBLIC_URL = process.env.R2_PUBLIC_URL || 'https://content.jawkit.cc';\n\n/**\n * Remote content provider using R2 Cloudflare and Cloudflare Worker\n */\nexport class RemoteProvider {\n private r2BaseUrl: string;\n private workerUrl: string;\n\n constructor(r2BaseUrl?: string, workerUrl?: string) {\n this.r2BaseUrl = r2BaseUrl || R2_PUBLIC_URL;\n this.workerUrl = workerUrl || WORKER_URL;\n }\n\n /**\n * Fetch content manifest from R2\n * @param version - 'latest' or specific version (e.g., '1.0.0')\n */\n async fetchManifest(version: string = 'latest'): Promise<ContentManifest> {\n const url =\n version === 'latest'\n ? `${this.r2BaseUrl}/manifests/latest.json`\n : `${this.r2BaseUrl}/manifests/${version}.json`;\n\n try {\n const response = await ofetch<ContentManifest>(url, {\n timeout: 10000,\n retry: 2,\n });\n\n return response;\n } catch (error) {\n if (error instanceof FetchError) {\n if (error.status === 404) {\n throw ContentError.manifestNotFound();\n }\n throw ContentError.downloadFailed('manifest', error.status);\n }\n throw error;\n }\n }\n\n /**\n * Get bundle download URL\n * - Free tier: Direct public R2 URL\n * - Premium tiers: Signed URL via Cloudflare Worker\n */\n async getBundleUrl(\n agentId: string,\n version: string,\n tier: TierLevel,\n licenseKey?: string | null\n ): Promise<string> {\n // Free tier - direct public URL\n if (tier === 'free') {\n return `${this.r2BaseUrl}/bundles/${agentId}/${version}/free.tar.gz`;\n }\n\n // Premium tiers - get signed URL from Cloudflare Worker\n if (!licenseKey) {\n throw ContentError.tierAccessDenied(tier);\n }\n\n try {\n const response = await ofetch<SignedUrlResponse>(\n `${this.workerUrl}/get-download-url`,\n {\n method: 'POST',\n headers: {\n Authorization: `License ${licenseKey}`,\n 'Content-Type': 'application/json',\n },\n body: {\n agent: agentId,\n version,\n tier,\n },\n timeout: 10000,\n }\n );\n\n return response.url;\n } catch (error) {\n if (error instanceof FetchError) {\n if (error.status === 401) {\n throw ContentError.tierAccessDenied(tier);\n }\n if (error.status === 403) {\n throw ContentError.tierAccessDenied(tier);\n }\n throw ContentError.signedUrlFailed();\n }\n throw error;\n }\n }\n\n /**\n * Download file to disk with progress callback and retry logic\n */\n async downloadToFile(\n url: string,\n destPath: string,\n _expectedSize: number,\n onProgress?: (downloaded: number) => void,\n maxRetries: number = 3\n ): Promise<void> {\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw ContentError.downloadFailed(destPath, response.status);\n }\n\n if (!response.body) {\n throw ContentError.downloadFailed(destPath);\n }\n\n const reader = response.body.getReader();\n const writer = createWriteStream(destPath);\n let downloaded = 0;\n\n // Create a readable stream from the web stream reader\n const readable = new Readable({\n async read() {\n try {\n const { done, value } = await reader.read();\n if (done) {\n this.push(null);\n } else {\n downloaded += value.length;\n onProgress?.(downloaded);\n this.push(value);\n }\n } catch (error) {\n this.destroy(error instanceof Error ? error : new Error(String(error)));\n }\n },\n });\n\n await pipeline(readable, writer);\n return; // Success - exit retry loop\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Don't retry on 4xx errors (client errors)\n if (error instanceof ContentError) {\n throw error;\n }\n\n if (attempt < maxRetries) {\n // Exponential backoff: 1s, 2s, 4s\n const delay = Math.pow(2, attempt - 1) * 1000;\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n }\n\n throw lastError || ContentError.downloadFailed(destPath);\n }\n\n /**\n * Check if a bundle exists on the remote server\n */\n async checkBundleExists(\n agentId: string,\n version: string,\n tier: TierLevel\n ): Promise<boolean> {\n const url = `${this.r2BaseUrl}/bundles/${agentId}/${version}/${tier}.tar.gz`;\n\n try {\n const response = await fetch(url, { method: 'HEAD' });\n return response.ok;\n } catch {\n return false;\n }\n }\n\n /**\n * Get the R2 base URL\n */\n getR2BaseUrl(): string {\n return this.r2BaseUrl;\n }\n\n /**\n * Get the Worker URL\n */\n getWorkerUrl(): string {\n return this.workerUrl;\n }\n}\n\n// Singleton instance\nlet remoteProviderInstance: RemoteProvider | null = null;\n\n/**\n * Get the RemoteProvider singleton instance\n */\nexport function getRemoteProvider(): RemoteProvider {\n if (!remoteProviderInstance) {\n remoteProviderInstance = new RemoteProvider();\n }\n return remoteProviderInstance;\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\nimport type { ContentManifest, CacheInfo } from './types.js';\n\nconst DEFAULT_CACHE_DIR = path.join(os.homedir(), '.jawkit', 'cache');\nconst MANIFEST_FILE = 'manifest.json';\nconst BUNDLES_DIR = 'bundles';\nconst TEMP_DIR = 'temp';\n\n/**\n * Manages local caching of content bundles and manifests\n */\nexport class CacheManager {\n private cacheDir: string;\n private initialized: boolean = false;\n\n constructor(cacheDir: string = DEFAULT_CACHE_DIR) {\n this.cacheDir = cacheDir;\n }\n\n /**\n * Initialize cache directories\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n await fs.mkdir(this.cacheDir, { recursive: true });\n await fs.mkdir(path.join(this.cacheDir, BUNDLES_DIR), { recursive: true });\n await fs.mkdir(path.join(this.cacheDir, TEMP_DIR), { recursive: true });\n this.initialized = true;\n }\n\n // Manifest caching\n\n /**\n * Save manifest to cache\n */\n async saveManifest(manifest: ContentManifest): Promise<void> {\n await this.initialize();\n const filePath = path.join(this.cacheDir, MANIFEST_FILE);\n await fs.writeFile(filePath, JSON.stringify(manifest, null, 2), 'utf-8');\n }\n\n /**\n * Get cached manifest\n */\n async getManifest(): Promise<ContentManifest | null> {\n try {\n const filePath = path.join(this.cacheDir, MANIFEST_FILE);\n const content = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(content) as ContentManifest;\n } catch {\n return null;\n }\n }\n\n // Bundle caching\n\n /**\n * Save downloaded bundle to cache\n * @param agentId - Agent identifier\n * @param version - Content version\n * @param tier - Tier level\n * @param sourcePath - Path to the downloaded file (will be moved)\n * @returns Path to cached bundle\n */\n async saveBundle(\n agentId: string,\n version: string,\n tier: string,\n sourcePath: string\n ): Promise<string> {\n await this.initialize();\n\n const bundleDir = path.join(this.cacheDir, BUNDLES_DIR, agentId, version);\n await fs.mkdir(bundleDir, { recursive: true });\n\n const destPath = path.join(bundleDir, `${tier}.tar.gz`);\n\n // Move from temp to cache\n await fs.rename(sourcePath, destPath);\n\n return destPath;\n }\n\n /**\n * Get cached bundle path if exists\n */\n async getBundle(\n agentId: string,\n version: string,\n tier: string\n ): Promise<string | null> {\n const bundlePath = path.join(\n this.cacheDir,\n BUNDLES_DIR,\n agentId,\n version,\n `${tier}.tar.gz`\n );\n\n try {\n await fs.access(bundlePath);\n return bundlePath;\n } catch {\n return null;\n }\n }\n\n /**\n * Check if a bundle exists in cache\n */\n async hasBundle(agentId: string, version: string, tier: string): Promise<boolean> {\n const bundlePath = await this.getBundle(agentId, version, tier);\n return bundlePath !== null;\n }\n\n // Temp file management\n\n /**\n * Get a path in the temp directory for downloads\n */\n async getTempPath(filename: string): Promise<string> {\n await this.initialize();\n return path.join(this.cacheDir, TEMP_DIR, filename);\n }\n\n /**\n * Clean temporary files\n */\n async cleanTemp(): Promise<void> {\n const tempDir = path.join(this.cacheDir, TEMP_DIR);\n try {\n await fs.rm(tempDir, { recursive: true, force: true });\n await fs.mkdir(tempDir, { recursive: true });\n } catch {\n // Ignore errors\n }\n }\n\n // Cache management\n\n /**\n * Clear all cached data\n */\n async clearCache(): Promise<void> {\n await fs.rm(this.cacheDir, { recursive: true, force: true });\n this.initialized = false;\n await this.initialize();\n }\n\n /**\n * Clear cache for a specific agent\n */\n async clearAgentCache(agentId: string): Promise<void> {\n const agentDir = path.join(this.cacheDir, BUNDLES_DIR, agentId);\n try {\n await fs.rm(agentDir, { recursive: true, force: true });\n } catch {\n // Directory doesn't exist\n }\n }\n\n /**\n * Clear old versions, keeping only the specified version\n */\n async clearOldVersions(agentId: string, keepVersion: string): Promise<number> {\n const agentDir = path.join(this.cacheDir, BUNDLES_DIR, agentId);\n let removedCount = 0;\n\n try {\n const versions = await fs.readdir(agentDir);\n\n for (const version of versions) {\n if (version !== keepVersion) {\n await fs.rm(path.join(agentDir, version), { recursive: true, force: true });\n removedCount++;\n }\n }\n } catch {\n // Directory doesn't exist, nothing to clean\n }\n\n return removedCount;\n }\n\n /**\n * Get total cache size in bytes\n */\n async getCacheSize(): Promise<number> {\n let totalSize = 0;\n\n async function calculateSize(dirPath: string): Promise<void> {\n try {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const entryPath = path.join(dirPath, entry.name);\n if (entry.isDirectory()) {\n await calculateSize(entryPath);\n } else {\n const stats = await fs.stat(entryPath);\n totalSize += stats.size;\n }\n }\n } catch {\n // Ignore errors\n }\n }\n\n await calculateSize(this.cacheDir);\n return totalSize;\n }\n\n /**\n * Get detailed cache information\n */\n async getCacheInfo(): Promise<CacheInfo> {\n const size = await this.getCacheSize();\n const bundlesDir = path.join(this.cacheDir, BUNDLES_DIR);\n const agents: Record<string, string[]> = {};\n\n try {\n const agentDirs = await fs.readdir(bundlesDir);\n\n for (const agent of agentDirs) {\n const agentPath = path.join(bundlesDir, agent);\n try {\n const stat = await fs.stat(agentPath);\n if (stat.isDirectory()) {\n const versions = await fs.readdir(agentPath);\n // Filter to only directories (await each stat check)\n const versionDirs: string[] = [];\n for (const v of versions) {\n const vPath = path.join(agentPath, v);\n try {\n const vStat = await fs.stat(vPath);\n if (vStat.isDirectory()) {\n versionDirs.push(v);\n }\n } catch {\n // Skip invalid entries\n }\n }\n agents[agent] = versionDirs;\n }\n } catch {\n // Skip invalid entries\n }\n }\n } catch {\n // No cache\n }\n\n return { size, agents };\n }\n\n /**\n * Get the cache directory path\n */\n getCacheDir(): string {\n return this.cacheDir;\n }\n}\n\n// Singleton instance\nlet cacheManagerInstance: CacheManager | null = null;\n\n/**\n * Get the CacheManager singleton instance\n */\nexport function getCacheManager(): CacheManager {\n if (!cacheManagerInstance) {\n cacheManagerInstance = new CacheManager();\n }\n return cacheManagerInstance;\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport type { ContentManifest } from './types.js';\n\n// Get the directory of the current module\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// Bundled content is included in the npm package at the root level\n// After build: dist/ and content/ are siblings\nconst BUNDLED_DIR = path.join(__dirname, '../../content');\n\n/**\n * Provides access to bundled fallback content included in the npm package\n * This allows the CLI to work offline with free tier content\n */\nexport class BundledContent {\n private bundledDir: string;\n\n constructor(bundledDir: string = BUNDLED_DIR) {\n this.bundledDir = bundledDir;\n }\n\n /**\n * Check if bundled content exists\n */\n isAvailable(): boolean {\n try {\n const manifestPath = path.join(this.bundledDir, 'manifest.json');\n fs.accessSync(manifestPath);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Get bundled manifest (free tier info)\n */\n getManifest(): ContentManifest {\n const manifestPath = path.join(this.bundledDir, 'manifest.json');\n const content = fs.readFileSync(manifestPath, 'utf-8');\n return JSON.parse(content) as ContentManifest;\n }\n\n /**\n * Get bundled manifest or null if not available\n */\n getManifestOrNull(): ContentManifest | null {\n try {\n return this.getManifest();\n } catch {\n return null;\n }\n }\n\n /**\n * Get path to bundled tar.gz file for an agent\n * Only 'free' tier is bundled\n */\n getBundlePath(agentId: string, tier: 'free' = 'free'): string | null {\n const bundlePath = path.join(this.bundledDir, agentId, `${tier}.tar.gz`);\n\n try {\n fs.accessSync(bundlePath);\n return bundlePath;\n } catch {\n return null;\n }\n }\n\n /**\n * Check if bundled content exists for an agent\n */\n hasBundle(agentId: string): boolean {\n return this.getBundlePath(agentId) !== null;\n }\n\n /**\n * List available bundled agents\n */\n listAgents(): string[] {\n try {\n const entries = fs.readdirSync(this.bundledDir, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .filter((e) => {\n // Check if the directory contains a free.tar.gz\n const bundlePath = path.join(this.bundledDir, e.name, 'free.tar.gz');\n try {\n fs.accessSync(bundlePath);\n return true;\n } catch {\n return false;\n }\n })\n .map((e) => e.name);\n } catch {\n return [];\n }\n }\n\n /**\n * Get the version of bundled content\n */\n getVersion(): string | null {\n const manifest = this.getManifestOrNull();\n return manifest?.version ?? null;\n }\n\n /**\n * Get the bundled directory path (for debugging)\n */\n getBundledDir(): string {\n return this.bundledDir;\n }\n}\n\n// Singleton instance\nlet bundledContentInstance: BundledContent | null = null;\n\n/**\n * Get the BundledContent singleton instance\n */\nexport function getBundledContent(): BundledContent {\n if (!bundledContentInstance) {\n bundledContentInstance = new BundledContent();\n }\n return bundledContentInstance;\n}\n","import { createGunzip } from 'zlib';\nimport { extract as tarExtract, type ReadEntry } from 'tar';\nimport { createReadStream } from 'fs';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport crypto from 'crypto';\nimport type { ExtractResult, ProgressCallback } from './types.js';\nimport { ContentError } from '../lib/errors.js';\n\n/**\n * Extract a tar.gz bundle to a target directory\n */\nexport async function extractBundle(\n bundlePath: string,\n targetDir: string,\n onProgress?: ProgressCallback\n): Promise<Omit<ExtractResult, 'version'>> {\n const filesExtracted: string[] = [];\n let totalSize = 0;\n const errors: string[] = [];\n\n try {\n // Ensure target directory exists\n await fs.mkdir(targetDir, { recursive: true });\n\n // Create extraction pipeline\n await new Promise<void>((resolve, reject) => {\n const readStream = createReadStream(bundlePath);\n const gunzip = createGunzip();\n\n const extractor = tarExtract({\n cwd: targetDir,\n strip: 0, // Don't strip leading path components\n filter: (entryPath: string) => {\n // Skip manifest.json - we don't need it in target\n return !entryPath.endsWith('manifest.json');\n },\n onentry: (entry: ReadEntry) => {\n filesExtracted.push(entry.path);\n totalSize += entry.size || 0;\n\n onProgress?.({\n phase: 'extracting',\n totalBytes: totalSize,\n processedBytes: totalSize,\n percentage: 100, // We don't know total until done\n currentFile: entry.path,\n });\n },\n });\n\n readStream\n .on('error', reject)\n .pipe(gunzip)\n .on('error', reject)\n .pipe(extractor)\n .on('error', reject)\n .on('finish', resolve);\n });\n\n return {\n success: true,\n filesExtracted,\n totalSize,\n errors,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown extraction error';\n errors.push(errorMessage);\n return {\n success: false,\n filesExtracted,\n totalSize,\n errors,\n };\n }\n}\n\n/**\n * Verify checksum of a file\n * @param filePath - Path to the file\n * @param expectedChecksum - Expected checksum in format \"sha256:abc123...\"\n */\nexport async function verifyChecksum(\n filePath: string,\n expectedChecksum: string\n): Promise<boolean> {\n const hash = crypto.createHash('sha256');\n const stream = createReadStream(filePath);\n\n for await (const chunk of stream) {\n hash.update(chunk);\n }\n\n const actualChecksum = `sha256:${hash.digest('hex')}`;\n return actualChecksum === expectedChecksum;\n}\n\n/**\n * Calculate SHA256 checksum of a file\n * @param filePath - Path to the file\n * @returns Checksum in format \"sha256:abc123...\"\n */\nexport async function calculateChecksum(filePath: string): Promise<string> {\n const hash = crypto.createHash('sha256');\n const stream = createReadStream(filePath);\n\n for await (const chunk of stream) {\n hash.update(chunk);\n }\n\n return `sha256:${hash.digest('hex')}`;\n}\n\n/**\n * Get file size in bytes\n */\nexport async function getFileSize(filePath: string): Promise<number> {\n const stats = await fs.stat(filePath);\n return stats.size;\n}\n\n/**\n * List files in a tar.gz archive (without extracting)\n */\nexport async function listBundleContents(bundlePath: string): Promise<string[]> {\n const files: string[] = [];\n\n await new Promise<void>((resolve, reject) => {\n const readStream = createReadStream(bundlePath);\n const gunzip = createGunzip();\n\n const extractor = tarExtract({\n onentry: (entry: ReadEntry) => {\n files.push(entry.path);\n entry.resume(); // Skip actual extraction\n },\n });\n\n readStream\n .on('error', reject)\n .pipe(gunzip)\n .on('error', reject)\n .pipe(extractor)\n .on('error', reject)\n .on('finish', resolve);\n });\n\n return files;\n}\n\n/**\n * Extract and verify a bundle\n * Combines extraction with checksum verification\n */\nexport async function extractAndVerifyBundle(\n bundlePath: string,\n targetDir: string,\n expectedChecksum: string,\n onProgress?: ProgressCallback\n): Promise<ExtractResult> {\n // First verify the bundle checksum\n onProgress?.({\n phase: 'verifying',\n totalBytes: 0,\n processedBytes: 0,\n percentage: 0,\n });\n\n const isValid = await verifyChecksum(bundlePath, expectedChecksum);\n if (!isValid) {\n throw ContentError.checksumMismatch(path.basename(bundlePath));\n }\n\n // Then extract\n const result = await extractBundle(bundlePath, targetDir, onProgress);\n\n return {\n ...result,\n version: '', // Will be filled in by ContentService\n };\n}\n","import { ofetch } from 'ofetch';\nimport { version as packageVersion } from '../../package.json';\n\nconst NPM_REGISTRY = 'https://registry.npmjs.org';\nconst PACKAGE_NAME = '@jawkit/cli';\n\n/**\n * Get current CLI version from package.json\n */\nexport function getCliVersion(): string {\n return packageVersion;\n}\n\n/**\n * Check npm registry for latest CLI version\n */\nexport async function checkCliUpdate(): Promise<string | null> {\n try {\n const response = await ofetch<{ 'dist-tags': { latest: string } }>(\n `${NPM_REGISTRY}/${encodeURIComponent(PACKAGE_NAME)}`,\n {\n timeout: 5000,\n headers: {\n Accept: 'application/json',\n },\n }\n );\n\n return response['dist-tags'].latest;\n } catch {\n // Silently fail - update check is non-critical\n return null;\n }\n}\n\n/**\n * Compare versions (semver)\n * Returns true if latest is newer than current\n */\nexport function isNewerVersion(latest: string, current: string): boolean {\n const latestParts = latest.split('.').map(Number);\n const currentParts = current.split('.').map(Number);\n\n for (let i = 0; i < 3; i++) {\n const l = latestParts[i] || 0;\n const c = currentParts[i] || 0;\n\n if (l > c) return true;\n if (l < c) return false;\n }\n\n return false;\n}\n\n/**\n * Check if current CLI version is compatible with content\n */\nexport function isCompatibleVersion(\n cliVersion: string,\n minCliVersion: string\n): boolean {\n return !isNewerVersion(minCliVersion, cliVersion);\n}\n","import { ConfigService } from '../lib/config.js';\nimport { ContentService } from '../content/content.service.js';\nimport { isNewerVersion } from './cli-version.js';\n\n/**\n * Get installed content versions from config\n */\nexport async function getContentVersions(): Promise<Record<string, string>> {\n const config = new ConfigService();\n return (await config.get('contentVersions')) ?? {};\n}\n\n/**\n * Check for content updates\n * Returns a map of agentId -> latest version for agents with updates available\n */\nexport async function checkContentUpdates(\n currentVersions: Record<string, string>\n): Promise<Record<string, string>> {\n const contentService = new ContentService();\n const updates: Record<string, string> = {};\n\n try {\n const manifest = await contentService.getManifest('latest');\n\n for (const [agentId, agentManifest] of Object.entries(manifest.agents)) {\n const current = currentVersions[agentId];\n const latest = agentManifest.version;\n\n // If not installed or newer version available\n if (!current || isNewerVersion(latest, current)) {\n updates[agentId] = latest;\n }\n }\n } catch {\n // Silently fail - update check is non-critical\n }\n\n return updates;\n}\n\n/**\n * Update content version in config\n */\nexport async function updateContentVersion(\n agentId: string,\n version: string\n): Promise<void> {\n const config = new ConfigService();\n const versions = await getContentVersions();\n\n await config.set('contentVersions', {\n ...versions,\n [agentId]: version,\n });\n}\n\n/**\n * Get all installed content versions with update info\n */\nexport async function getContentVersionsWithUpdates(): Promise<\n Array<{\n agentId: string;\n current: string;\n latest: string | null;\n updateAvailable: boolean;\n }>\n> {\n const currentVersions = await getContentVersions();\n const updates = await checkContentUpdates(currentVersions);\n\n const result: Array<{\n agentId: string;\n current: string;\n latest: string | null;\n updateAvailable: boolean;\n }> = [];\n\n for (const [agentId, current] of Object.entries(currentVersions)) {\n const latest = updates[agentId] ?? null;\n result.push({\n agentId,\n current,\n latest: latest ?? current,\n updateAvailable: latest !== null,\n });\n }\n\n return result;\n}\n"],"mappings":"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","names":["chalk","path","logger","fs","path","os","fs","ofetch","version","ofetch","fs","path","os","version","fs","path","__filename","__dirname","fs","fs","version","fs","ofetch","ofetch"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/lib/logger.ts","../src/lib/errors.ts","../src/lib/config.ts","../src/auth/types.ts","../src/auth/auth.service.ts","../src/auth/license-storage.ts","../src/content/content.service.ts","../src/content/remote-provider.ts","../src/content/cache-manager.ts","../src/content/bundled-content.ts","../src/content/extractor.ts","../src/services/cli-version.ts","../src/services/content-version.ts"],"sourcesContent":["{\n \"name\": \"@jawkit.cc/cli\",\n \"version\": \"0.1.1\",\n \"description\": \"CLI toolkit for installing AI coding assistant configurations\",\n \"type\": \"module\",\n \"bin\": {\n \"jawkit\": \"./dist/cli.js\"\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\"\n }\n },\n \"files\": [\n \"dist\",\n \"content\"\n ],\n \"scripts\": {\n \"dev\": \"tsup --watch\",\n \"build\": \"tsup\",\n \"start\": \"node dist/cli.js\",\n \"lint\": \"eslint src --ext .ts\",\n \"lint:fix\": \"eslint src --ext .ts --fix\",\n \"test\": \"vitest\",\n \"test:run\": \"vitest run\",\n \"typecheck\": \"tsc --noEmit\",\n \"bundle-content\": \"tsx scripts/bundle-content.ts\",\n \"upload-content\": \"node scripts/upload-content.js\",\n \"deploy\": \"node scripts/deploy.js\",\n \"publish-content\": \"npm run bundle-content && npm run upload-content\",\n \"serve:local\": \"tsx scripts/local-r2-server.ts\",\n \"prebuild\": \"npm run bundle-content || true\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"cli\",\n \"ai\",\n \"claude\",\n \"copilot\",\n \"coding-assistant\",\n \"developer-tools\"\n ],\n \"author\": \"JawKit\",\n \"license\": \"SEE LICENSE IN LICENSE\",\n \"private\": false,\n \"engines\": {\n \"node\": \">=18.0.0\"\n },\n \"dependencies\": {\n \"@inquirer/prompts\": \"^7.2.1\",\n \"chalk\": \"^5.4.1\",\n \"commander\": \"^13.0.0\",\n \"ofetch\": \"^1.4.1\",\n \"ora\": \"^8.1.1\",\n \"tar\": \"^7.4.3\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.10.7\",\n \"eslint\": \"^9.18.0\",\n \"tsup\": \"^8.3.5\",\n \"tsx\": \"^4.7.0\",\n \"typescript\": \"^5.7.3\",\n \"vitest\": \"^2.1.8\"\n }\n}\n","import chalk from 'chalk';\nimport ora, { type Ora } from 'ora';\n\nexport interface LoggerOptions {\n quiet?: boolean;\n verbose?: boolean;\n json?: boolean;\n}\n\nexport class Logger {\n private options: LoggerOptions;\n private currentSpinner: Ora | null = null;\n\n constructor(options: LoggerOptions = {}) {\n this.options = options;\n }\n\n info(message: string): void {\n if (this.options.quiet) return;\n console.log(message);\n }\n\n success(message: string): void {\n if (this.options.quiet) return;\n console.log(chalk.green('✓'), message);\n }\n\n warn(message: string): void {\n console.log(chalk.yellow('⚠'), message);\n }\n\n error(message: string): void {\n console.error(chalk.red('✖'), message);\n }\n\n debug(message: string): void {\n if (!this.options.verbose) return;\n console.log(chalk.gray(`[debug] ${message}`));\n }\n\n newline(): void {\n if (this.options.quiet) return;\n console.log();\n }\n\n divider(char = '─', length = 40): void {\n if (this.options.quiet) return;\n console.log(chalk.gray(char.repeat(length)));\n }\n\n spinner(text: string): Ora {\n this.currentSpinner = ora({\n text,\n spinner: 'dots',\n });\n return this.currentSpinner;\n }\n\n stopSpinner(): void {\n if (this.currentSpinner) {\n this.currentSpinner.stop();\n this.currentSpinner = null;\n }\n }\n\n progress(percentage: number, text?: string): void {\n if (this.options.quiet) return;\n\n const width = 30;\n const filled = Math.round((percentage / 100) * width);\n const empty = width - filled;\n const bar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));\n\n process.stdout.write(`\\r${bar} ${percentage}%${text ? ` ${text}` : ''}`);\n\n if (percentage >= 100) {\n console.log();\n }\n }\n\n table(data: Record<string, string>[]): void {\n if (this.options.quiet) return;\n console.table(data);\n }\n\n json(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n }\n}\n\n// Default logger instance\nexport const logger = new Logger();\n","import chalk from 'chalk';\nimport { Logger } from './logger.js';\n\nexport abstract class JawKitError extends Error {\n abstract code: string;\n suggestion?: string;\n cause?: Error;\n\n constructor(message: string, options?: { cause?: Error }) {\n super(message);\n this.name = this.constructor.name;\n this.cause = options?.cause;\n }\n}\n\nexport class AuthError extends JawKitError {\n code = 'AUTH_ERROR';\n\n static notAuthenticated(): AuthError {\n const error = new AuthError('No license key activated');\n error.suggestion = \"Run 'jawkit auth activate <license-key>' to activate your license\";\n return error;\n }\n\n static licenseExpired(): AuthError {\n const error = new AuthError('License has expired');\n error.suggestion = \"Visit https://jawkit.cc/pro to renew your license\";\n return error;\n }\n\n static activationFailed(reason?: string): AuthError {\n const error = new AuthError(`License activation failed${reason ? `: ${reason}` : ''}`);\n error.suggestion = 'Check your license key and try again';\n return error;\n }\n\n static licenseRevoked(): AuthError {\n const error = new AuthError('License has been revoked');\n error.suggestion = 'Contact support at support@jawkit.cc';\n return error;\n }\n\n static licenseNotFound(): AuthError {\n const error = new AuthError('License key not found');\n error.suggestion = 'Check your license key and try again';\n return error;\n }\n}\n\nexport class ContentError extends JawKitError {\n code = 'CONTENT_ERROR';\n\n static manifestNotFound(): ContentError {\n const error = new ContentError('Content manifest not found');\n error.suggestion = 'Check your internet connection and try again';\n return error;\n }\n\n static checksumMismatch(bundle: string): ContentError {\n const error = new ContentError(\n `Bundle checksum verification failed: ${bundle}`\n );\n error.suggestion =\n 'Try running the command again. The download may have been corrupted.';\n return error;\n }\n\n static downloadFailed(bundle: string, status?: number): ContentError {\n const error = new ContentError(\n `Failed to download bundle: ${bundle}${status ? ` (HTTP ${status})` : ''}`\n );\n error.suggestion = 'Check your internet connection and try again';\n return error;\n }\n\n static extractionFailed(bundle: string): ContentError {\n const error = new ContentError(`Failed to extract bundle: ${bundle}`);\n error.suggestion =\n 'The bundle may be corrupted. Try running jawkit init again to re-download.';\n return error;\n }\n\n static tierAccessDenied(tier: string): ContentError {\n const error = new ContentError(`Access denied for tier: ${tier}`);\n error.suggestion = 'Upgrade to Professional at https://jawkit.cc/pro';\n return error;\n }\n\n static signedUrlFailed(): ContentError {\n const error = new ContentError('Failed to get download authorization');\n error.suggestion = \"Check your license status with: jawkit auth status\";\n return error;\n }\n}\n\nexport class AgentError extends JawKitError {\n code = 'AGENT_ERROR';\n\n static notFound(agentId: string): AgentError {\n const error = new AgentError(`Agent not found: ${agentId}`);\n error.suggestion = \"Run 'jawkit init --help' to see available agents\";\n return error;\n }\n\n static installFailed(agentId: string, reason?: string): AgentError {\n const error = new AgentError(\n `Failed to install ${agentId}${reason ? `: ${reason}` : ''}`\n );\n return error;\n }\n\n static alreadyInstalled(agentId: string, path: string): AgentError {\n const error = new AgentError(`${agentId} is already installed at ${path}`);\n error.suggestion = \"Run 'jawkit init' again to update (existing content will be backed up)\";\n return error;\n }\n}\n\nexport class ConfigError extends JawKitError {\n code = 'CONFIG_ERROR';\n\n static readFailed(path: string): ConfigError {\n const error = new ConfigError(`Failed to read config file: ${path}`);\n return error;\n }\n\n static writeFailed(path: string): ConfigError {\n const error = new ConfigError(`Failed to write config file: ${path}`);\n return error;\n }\n}\n\n/**\n * Handle and display error to user\n */\nexport function handleError(error: unknown, logger: Logger): void {\n if (error instanceof JawKitError) {\n logger.error(error.message);\n\n if (error.suggestion) {\n logger.info(chalk.dim(` Suggestion: ${error.suggestion}`));\n }\n\n if (error.cause) {\n logger.debug(`Caused by: ${error.cause.message}`);\n }\n } else if (error instanceof Error) {\n logger.error(error.message);\n\n if (error.stack) {\n logger.debug(error.stack);\n }\n } else {\n logger.error(String(error));\n }\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\n\nconst CONFIG_DIR = path.join(os.homedir(), '.jawkit');\nconst CONFIG_FILE = 'config.json';\n\nexport interface JawKitConfig {\n contentVersions?: Record<string, string>;\n lastUpdateCheck?: string;\n installations?: Installation[];\n}\n\nexport interface Installation {\n path: string;\n agent: string;\n contentVersion: string;\n installedAt: string;\n files: string[];\n tier?: string; // Tier used when content was installed (free, professional)\n checksum?: string; // Bundle checksum for detecting content changes\n}\n\nexport class ConfigService {\n private configDir: string;\n private configPath: string;\n private config: JawKitConfig | null = null;\n\n constructor(configDir: string = CONFIG_DIR) {\n this.configDir = configDir;\n this.configPath = path.join(configDir, CONFIG_FILE);\n }\n\n async initialize(): Promise<void> {\n await fs.mkdir(this.configDir, { recursive: true });\n }\n\n async load(): Promise<JawKitConfig> {\n if (this.config) {\n return this.config;\n }\n\n try {\n const content = await fs.readFile(this.configPath, 'utf-8');\n this.config = JSON.parse(content);\n return this.config!;\n } catch {\n this.config = {};\n return this.config;\n }\n }\n\n async save(): Promise<void> {\n await this.initialize();\n await fs.writeFile(\n this.configPath,\n JSON.stringify(this.config ?? {}, null, 2)\n );\n }\n\n async get<K extends keyof JawKitConfig>(key: K): Promise<JawKitConfig[K]> {\n const config = await this.load();\n return config[key];\n }\n\n async set<K extends keyof JawKitConfig>(\n key: K,\n value: JawKitConfig[K]\n ): Promise<void> {\n await this.load();\n this.config = { ...this.config, [key]: value };\n await this.save();\n }\n\n async getInstallations(): Promise<Installation[]> {\n return (await this.get('installations')) ?? [];\n }\n\n async addInstallation(installation: Installation): Promise<void> {\n const installations = await this.getInstallations();\n const existingIndex = installations.findIndex(\n (i) => i.path === installation.path && i.agent === installation.agent\n );\n\n if (existingIndex >= 0) {\n installations[existingIndex] = installation;\n } else {\n installations.push(installation);\n }\n\n await this.set('installations', installations);\n }\n\n async updateInstallation(\n installPath: string,\n updates: Partial<Installation>\n ): Promise<void> {\n const installations = await this.getInstallations();\n const index = installations.findIndex((i) => i.path === installPath);\n\n if (index >= 0) {\n installations[index] = { ...installations[index]!, ...updates };\n await this.set('installations', installations);\n }\n }\n\n getConfigDir(): string {\n return this.configDir;\n }\n}\n","/**\n * User tier levels\n */\nexport type TierLevel = 'free' | 'professional';\n\n/**\n * Stored license data (re-export from license-storage for convenience)\n */\nexport type { StoredLicense } from './license-storage.js';\n\n/**\n * User profile derived from license\n */\nexport interface UserProfile {\n email: string;\n tier: TierLevel;\n tierExpiresAt: string | null;\n}\n\n/**\n * License activation result\n */\nexport interface ActivationResult {\n success: boolean;\n user: UserProfile | null;\n error?: string;\n}\n\n/**\n * License validation response from server\n */\nexport interface LicenseValidationResponse {\n valid: boolean;\n email: string;\n tier: string;\n tierExpiresAt: string | null;\n}\n\n/**\n * Tier level utilities\n */\nexport const TIER_LEVELS: Record<TierLevel, number> = {\n 'free': 0,\n 'professional': 1,\n};\n\nexport function getTierLevel(tier: TierLevel): number {\n return TIER_LEVELS[tier] ?? 0;\n}\n\nexport function hasTierAccess(userTier: TierLevel, requiredTier: TierLevel): boolean {\n return getTierLevel(userTier) >= getTierLevel(requiredTier);\n}\n\nexport function getTierDisplayName(tier: TierLevel): string {\n switch (tier) {\n case 'free':\n return 'Free';\n case 'professional':\n return 'Professional ($99)';\n default:\n return 'Unknown';\n }\n}\n","import { ofetch } from 'ofetch';\nimport { LicenseStorage, type StoredLicense } from './license-storage.js';\nimport type {\n UserProfile,\n TierLevel,\n ActivationResult,\n LicenseValidationResponse,\n} from './types.js';\n\n// API endpoint for license validation\n// Set JAWKIT_API_URL environment variable to override\nconst API_URL = process.env.JAWKIT_API_URL || 'https://api.jawkit.cc';\n\n/**\n * Authentication Service\n * Handles license key activation, validation, and storage\n */\nexport class AuthService {\n private licenseStorage: LicenseStorage;\n\n constructor() {\n this.licenseStorage = new LicenseStorage();\n }\n\n /**\n * Activate a license key\n * Validates against server and stores locally\n */\n async activate(licenseKey: string): Promise<ActivationResult> {\n // Basic format validation\n if (!licenseKey.startsWith('JAWKIT_')) {\n return {\n success: false,\n user: null,\n error: 'Invalid license key format. License keys start with JAWKIT_',\n };\n }\n\n try {\n // Validate against server\n const response = await ofetch<LicenseValidationResponse>(\n `${API_URL}/license/validate`,\n {\n method: 'POST',\n body: { licenseKey },\n }\n );\n\n if (!response.valid) {\n return {\n success: false,\n user: null,\n error: 'License key validation failed',\n };\n }\n\n // Store license locally\n const storedLicense: StoredLicense = {\n licenseKey,\n email: response.email,\n tier: response.tier,\n tierExpiresAt: response.tierExpiresAt,\n validatedAt: Date.now(),\n };\n\n await this.licenseStorage.store(storedLicense);\n\n return {\n success: true,\n user: {\n email: response.email,\n tier: response.tier as TierLevel,\n tierExpiresAt: response.tierExpiresAt,\n },\n };\n } catch (error) {\n // Handle specific HTTP errors\n if (error instanceof Error && 'statusCode' in error) {\n const statusCode = (error as { statusCode: number }).statusCode;\n if (statusCode === 404) {\n return {\n success: false,\n user: null,\n error: 'License key not found',\n };\n }\n if (statusCode === 403) {\n return {\n success: false,\n user: null,\n error: 'License has been revoked',\n };\n }\n }\n\n return {\n success: false,\n user: null,\n error: error instanceof Error ? error.message : 'Failed to validate license',\n };\n }\n }\n\n /**\n * Deactivate (remove) stored license\n */\n async deactivate(): Promise<void> {\n await this.licenseStorage.clear();\n }\n\n /**\n * Check if user has a valid license stored\n */\n async isAuthenticated(): Promise<boolean> {\n const license = await this.licenseStorage.retrieve();\n if (!license) {\n return false;\n }\n\n // Check if tier has expired\n if (license.tierExpiresAt) {\n const expiresAt = new Date(license.tierExpiresAt);\n if (expiresAt < new Date()) {\n // Tier expired, but license still valid (falls back to free)\n return true;\n }\n }\n\n return true;\n }\n\n /**\n * Get current user profile from stored license\n */\n async getCurrentUser(): Promise<UserProfile | null> {\n const license = await this.licenseStorage.retrieve();\n if (!license) {\n return null;\n }\n\n // Determine effective tier (check expiration)\n let effectiveTier: TierLevel = license.tier as TierLevel;\n if (license.tierExpiresAt) {\n const expiresAt = new Date(license.tierExpiresAt);\n if (expiresAt < new Date()) {\n effectiveTier = 'free';\n }\n }\n\n return {\n email: license.email,\n tier: effectiveTier,\n tierExpiresAt: license.tierExpiresAt,\n };\n }\n\n /**\n * Get user's tier level\n * Returns 'free' if no license or expired\n */\n async getUserTier(): Promise<TierLevel> {\n const user = await this.getCurrentUser();\n return user?.tier ?? 'free';\n }\n\n /**\n * Get stored license key for API requests\n */\n async getLicenseKey(): Promise<string | null> {\n const license = await this.licenseStorage.retrieve();\n return license?.licenseKey ?? null;\n }\n\n /**\n * Redeem an invitation code\n * Calls API to exchange invite code for license key, then activates it\n */\n async redeem(inviteCode: string, email: string): Promise<ActivationResult> {\n // Basic format validation\n if (!inviteCode.startsWith('JAWKIT_INV_')) {\n return {\n success: false,\n user: null,\n error: 'Invalid invitation code format. Invitation codes start with JAWKIT_INV_',\n };\n }\n\n try {\n // Call redeem API\n const response = await ofetch<{\n success: boolean;\n licenseKey: string;\n email: string;\n tier: string;\n tierExpiresAt: string | null;\n }>(`${API_URL}/invitation/redeem`, {\n method: 'POST',\n body: { inviteCode, email },\n });\n\n if (!response.success || !response.licenseKey) {\n return {\n success: false,\n user: null,\n error: 'Failed to redeem invitation',\n };\n }\n\n // Store the new license locally\n const storedLicense: StoredLicense = {\n licenseKey: response.licenseKey,\n email: response.email,\n tier: response.tier,\n tierExpiresAt: response.tierExpiresAt,\n validatedAt: Date.now(),\n };\n\n await this.licenseStorage.store(storedLicense);\n\n return {\n success: true,\n user: {\n email: response.email,\n tier: response.tier as TierLevel,\n tierExpiresAt: response.tierExpiresAt,\n },\n };\n } catch (error) {\n // Handle specific HTTP errors\n if (error instanceof Error && 'data' in error) {\n const data = (error as { data?: { error?: string } }).data;\n if (data?.error) {\n return {\n success: false,\n user: null,\n error: data.error,\n };\n }\n }\n\n return {\n success: false,\n user: null,\n error: error instanceof Error ? error.message : 'Failed to redeem invitation',\n };\n }\n }\n\n /**\n * Re-validate stored license against server\n * Useful for refreshing tier status\n */\n async revalidate(): Promise<ActivationResult> {\n const license = await this.licenseStorage.retrieve();\n if (!license) {\n return {\n success: false,\n user: null,\n error: 'No license key stored',\n };\n }\n\n return this.activate(license.licenseKey);\n }\n\n}\n\n// Singleton instance\nlet authServiceInstance: AuthService | null = null;\n\n/**\n * Get the AuthService singleton instance\n */\nexport function getAuthService(): AuthService {\n if (!authServiceInstance) {\n authServiceInstance = new AuthService();\n }\n return authServiceInstance;\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\n\nconst STORAGE_DIR = path.join(os.homedir(), '.jawkit');\nconst LICENSE_FILE = 'license.json';\n\n/**\n * Stored license data\n */\nexport interface StoredLicense {\n licenseKey: string;\n email: string;\n tier: string;\n tierExpiresAt: string | null;\n validatedAt: number; // Unix timestamp in milliseconds\n}\n\n/**\n * File-based license storage with restricted permissions\n */\nexport class LicenseStorage {\n private getFilePath(): string {\n return path.join(STORAGE_DIR, LICENSE_FILE);\n }\n\n /**\n * Store license data\n */\n async store(license: StoredLicense): Promise<void> {\n await fs.mkdir(STORAGE_DIR, { recursive: true });\n const filePath = this.getFilePath();\n\n // Store with restricted permissions (owner read/write only)\n await fs.writeFile(filePath, JSON.stringify(license, null, 2), {\n mode: 0o600,\n });\n }\n\n /**\n * Retrieve stored license\n */\n async retrieve(): Promise<StoredLicense | null> {\n try {\n const filePath = this.getFilePath();\n const data = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(data) as StoredLicense;\n } catch {\n return null;\n }\n }\n\n /**\n * Clear stored license\n */\n async clear(): Promise<void> {\n try {\n const filePath = this.getFilePath();\n await fs.unlink(filePath);\n } catch {\n // File doesn't exist, ignore\n }\n }\n\n /**\n * Check if license is stored\n */\n async hasLicense(): Promise<boolean> {\n const license = await this.retrieve();\n return license !== null;\n }\n}\n","import fs from 'fs/promises';\nimport type {\n ContentManifest,\n BundleManifest,\n ExtractResult,\n UpdateInfo,\n ProgressCallback,\n} from './types.js';\nimport type { TierLevel } from '../auth/types.js';\nimport { RemoteProvider, getRemoteProvider } from './remote-provider.js';\nimport { CacheManager, getCacheManager } from './cache-manager.js';\nimport { BundledContent, getBundledContent } from './bundled-content.js';\nimport { extractBundle, verifyChecksum } from './extractor.js';\nimport { getAuthService } from '../auth/index.js';\nimport { ContentError } from '../lib/errors.js';\n\n/**\n * Main content service for downloading and managing JawKit content\n */\nexport class ContentService {\n private remote: RemoteProvider;\n private cache: CacheManager;\n private bundled: BundledContent;\n\n constructor(\n remote?: RemoteProvider,\n cache?: CacheManager,\n bundled?: BundledContent\n ) {\n this.remote = remote || getRemoteProvider();\n this.cache = cache || getCacheManager();\n this.bundled = bundled || getBundledContent();\n }\n\n /**\n * Get the content manifest\n * Falls back: remote → cache → bundled\n */\n async getManifest(version: string = 'latest'): Promise<ContentManifest> {\n // Try remote first\n try {\n const manifest = await this.remote.fetchManifest(version);\n await this.cache.saveManifest(manifest);\n return manifest;\n } catch {\n // Fall back to cached manifest\n const cached = await this.cache.getManifest();\n if (cached) {\n return cached;\n }\n\n // Fall back to bundled manifest\n const bundledManifest = this.bundled.getManifestOrNull();\n if (bundledManifest) {\n return bundledManifest;\n }\n\n throw ContentError.manifestNotFound();\n }\n }\n\n /**\n * Get bundle info for a user's tier\n */\n async getBundleInfo(agentId: string, tier: TierLevel): Promise<BundleManifest> {\n const manifest = await this.getManifest();\n const agentManifest = manifest.agents[agentId];\n\n if (!agentManifest) {\n throw new ContentError(`Agent not found in manifest: ${agentId}`);\n }\n\n // Try the requested tier, fall back to free\n const bundleInfo = agentManifest.bundles[tier] || agentManifest.bundles['free'];\n\n if (!bundleInfo) {\n throw new ContentError(`No bundle available for agent: ${agentId}`);\n }\n\n return bundleInfo;\n }\n\n /**\n * Download and extract a content bundle\n */\n async downloadAndExtractBundle(\n agentId: string,\n tier: TierLevel,\n targetDir: string,\n onProgress?: ProgressCallback\n ): Promise<ExtractResult> {\n const manifest = await this.getManifest();\n const agentManifest = manifest.agents[agentId];\n\n if (!agentManifest) {\n throw new ContentError(`Agent not found: ${agentId}`);\n }\n\n // Get best available bundle for tier\n const effectiveTier = agentManifest.bundles[tier] ? tier : 'free';\n const bundleInfo = agentManifest.bundles[effectiveTier];\n\n if (!bundleInfo) {\n throw new ContentError(`No bundle available for agent: ${agentId}`);\n }\n\n const version = agentManifest.version;\n\n // Check cache first\n const cachedBundle = await this.cache.getBundle(agentId, version, effectiveTier);\n let bundlePath: string;\n\n if (cachedBundle && (await verifyChecksum(cachedBundle, bundleInfo.checksum))) {\n bundlePath = cachedBundle;\n } else {\n // Download bundle\n bundlePath = await this.downloadBundle(\n agentId,\n version,\n effectiveTier,\n bundleInfo,\n onProgress\n );\n }\n\n // Extract bundle\n const result = await extractBundle(bundlePath, targetDir, onProgress);\n\n // Clean up old versions\n await this.cache.clearOldVersions(agentId, version);\n\n return {\n ...result,\n version,\n };\n }\n\n /**\n * Download a bundle to cache\n */\n private async downloadBundle(\n agentId: string,\n version: string,\n tier: TierLevel | 'free',\n bundleInfo: BundleManifest,\n onProgress?: ProgressCallback\n ): Promise<string> {\n // Get license key for premium tiers\n let licenseKey: string | null = null;\n if (tier !== 'free') {\n const authService = getAuthService();\n licenseKey = await authService.getLicenseKey();\n }\n\n // Get download URL\n const downloadUrl = await this.remote.getBundleUrl(\n agentId,\n version,\n tier as TierLevel,\n licenseKey\n );\n\n // Create temp file path\n const tempPath = await this.cache.getTempPath(`${agentId}-${version}-${tier}.tar.gz`);\n\n // Download with progress\n await this.remote.downloadToFile(downloadUrl, tempPath, bundleInfo.size, (downloaded) => {\n onProgress?.({\n phase: 'downloading',\n totalBytes: bundleInfo.size,\n processedBytes: downloaded,\n percentage: Math.round((downloaded / bundleInfo.size) * 100),\n });\n });\n\n // Verify checksum\n if (!(await verifyChecksum(tempPath, bundleInfo.checksum))) {\n await fs.unlink(tempPath);\n throw ContentError.checksumMismatch(bundleInfo.filename);\n }\n\n // Move to cache\n const cachePath = await this.cache.saveBundle(agentId, version, tier, tempPath);\n\n return cachePath;\n }\n\n /**\n * Check for content updates\n * Returns null if no update available or if check fails\n * Use verbose logging to see failure details\n */\n async checkForUpdates(\n agentId: string,\n currentVersion: string,\n verbose: boolean = false\n ): Promise<UpdateInfo | null> {\n try {\n const manifest = await this.remote.fetchManifest('latest');\n const agentManifest = manifest.agents[agentId];\n\n if (!agentManifest) {\n if (verbose) {\n console.error(`Update check: agent \"${agentId}\" not found in manifest`);\n }\n return null;\n }\n\n if (this.isNewerVersion(agentManifest.version, currentVersion)) {\n // Get bundle info for display (use largest available tier)\n const professional = agentManifest.bundles['professional'];\n const free = agentManifest.bundles['free'];\n const displayBundle = professional || free;\n\n if (!displayBundle) {\n return null;\n }\n\n return {\n currentVersion,\n latestVersion: agentManifest.version,\n changelog: manifest.changelog,\n publishedAt: new Date(manifest.publishedAt),\n bundleSize: displayBundle.size,\n fileCount: displayBundle.fileCount,\n };\n }\n\n return null;\n } catch (error) {\n // Log failure in verbose mode so users can diagnose issues\n if (verbose) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`Update check failed: ${message}`);\n }\n return null;\n }\n }\n\n /**\n * Extract bundled fallback content (free tier only)\n */\n async extractFallbackContent(\n agentId: string,\n targetDir: string,\n onProgress?: ProgressCallback\n ): Promise<ExtractResult> {\n const bundlePath = this.bundled.getBundlePath(agentId);\n\n if (!bundlePath) {\n throw new ContentError('No bundled fallback content available');\n }\n\n const result = await extractBundle(bundlePath, targetDir, onProgress);\n const manifest = this.bundled.getManifestOrNull();\n\n return {\n ...result,\n version: manifest?.version || 'bundled',\n };\n }\n\n /**\n * Check if bundled fallback is available for an agent\n */\n hasFallbackContent(agentId: string): boolean {\n return this.bundled.hasBundle(agentId);\n }\n\n /**\n * Compare semantic versions\n */\n private isNewerVersion(latest: string, current: string): boolean {\n const latestParts = latest.split('.').map(Number);\n const currentParts = current.split('.').map(Number);\n\n for (let i = 0; i < 3; i++) {\n const l = latestParts[i] || 0;\n const c = currentParts[i] || 0;\n if (l > c) return true;\n if (l < c) return false;\n }\n\n return false;\n }\n}\n\n// Singleton instance\nlet contentServiceInstance: ContentService | null = null;\n\n/**\n * Get the ContentService singleton instance\n */\nexport function getContentService(): ContentService {\n if (!contentServiceInstance) {\n contentServiceInstance = new ContentService();\n }\n return contentServiceInstance;\n}\n","import { ofetch, FetchError } from 'ofetch';\nimport { createWriteStream } from 'fs';\nimport { pipeline } from 'stream/promises';\nimport { Readable } from 'stream';\nimport type { ContentManifest, SignedUrlResponse } from './types.js';\nimport type { TierLevel } from '../auth/types.js';\nimport { ContentError } from '../lib/errors.js';\n\n// Cloudflare Worker URL (handles manifest + signed URLs)\n// Set JAWKIT_WORKER_URL environment variable to override\nconst WORKER_URL = process.env.JAWKIT_WORKER_URL || 'https://api.jawkit.cc';\n\n// R2 public URL for content downloads\n// Set R2_PUBLIC_URL environment variable to override\nconst R2_PUBLIC_URL = process.env.R2_PUBLIC_URL || 'https://content.jawkit.cc';\n\n/**\n * Remote content provider using R2 Cloudflare and Cloudflare Worker\n */\nexport class RemoteProvider {\n private r2BaseUrl: string;\n private workerUrl: string;\n\n constructor(r2BaseUrl?: string, workerUrl?: string) {\n this.r2BaseUrl = r2BaseUrl || R2_PUBLIC_URL;\n this.workerUrl = workerUrl || WORKER_URL;\n }\n\n /**\n * Fetch content manifest from R2\n * @param version - 'latest' or specific version (e.g., '1.0.0')\n */\n async fetchManifest(version: string = 'latest'): Promise<ContentManifest> {\n const url =\n version === 'latest'\n ? `${this.r2BaseUrl}/manifests/latest.json`\n : `${this.r2BaseUrl}/manifests/${version}.json`;\n\n try {\n const response = await ofetch<ContentManifest>(url, {\n timeout: 10000,\n retry: 2,\n });\n\n return response;\n } catch (error) {\n if (error instanceof FetchError) {\n if (error.status === 404) {\n throw ContentError.manifestNotFound();\n }\n throw ContentError.downloadFailed('manifest', error.status);\n }\n throw error;\n }\n }\n\n /**\n * Get bundle download URL\n * - Free tier: Direct public R2 URL\n * - Premium tiers: Signed URL via Cloudflare Worker\n */\n async getBundleUrl(\n agentId: string,\n version: string,\n tier: TierLevel,\n licenseKey?: string | null\n ): Promise<string> {\n // Free tier - direct public URL\n if (tier === 'free') {\n return `${this.r2BaseUrl}/bundles/${agentId}/${version}/free.tar.gz`;\n }\n\n // Premium tiers - get signed URL from Cloudflare Worker\n if (!licenseKey) {\n throw ContentError.tierAccessDenied(tier);\n }\n\n try {\n const response = await ofetch<SignedUrlResponse>(\n `${this.workerUrl}/get-download-url`,\n {\n method: 'POST',\n headers: {\n Authorization: `License ${licenseKey}`,\n 'Content-Type': 'application/json',\n },\n body: {\n agent: agentId,\n version,\n tier,\n },\n timeout: 10000,\n }\n );\n\n return response.url;\n } catch (error) {\n if (error instanceof FetchError) {\n if (error.status === 401) {\n throw ContentError.tierAccessDenied(tier);\n }\n if (error.status === 403) {\n throw ContentError.tierAccessDenied(tier);\n }\n throw ContentError.signedUrlFailed();\n }\n throw error;\n }\n }\n\n /**\n * Download file to disk with progress callback and retry logic\n */\n async downloadToFile(\n url: string,\n destPath: string,\n _expectedSize: number,\n onProgress?: (downloaded: number) => void,\n maxRetries: number = 3\n ): Promise<void> {\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw ContentError.downloadFailed(destPath, response.status);\n }\n\n if (!response.body) {\n throw ContentError.downloadFailed(destPath);\n }\n\n const reader = response.body.getReader();\n const writer = createWriteStream(destPath);\n let downloaded = 0;\n\n // Create a readable stream from the web stream reader\n const readable = new Readable({\n async read() {\n try {\n const { done, value } = await reader.read();\n if (done) {\n this.push(null);\n } else {\n downloaded += value.length;\n onProgress?.(downloaded);\n this.push(value);\n }\n } catch (error) {\n this.destroy(error instanceof Error ? error : new Error(String(error)));\n }\n },\n });\n\n await pipeline(readable, writer);\n return; // Success - exit retry loop\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Don't retry on 4xx errors (client errors)\n if (error instanceof ContentError) {\n throw error;\n }\n\n if (attempt < maxRetries) {\n // Exponential backoff: 1s, 2s, 4s\n const delay = Math.pow(2, attempt - 1) * 1000;\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n }\n\n throw lastError || ContentError.downloadFailed(destPath);\n }\n\n /**\n * Check if a bundle exists on the remote server\n */\n async checkBundleExists(\n agentId: string,\n version: string,\n tier: TierLevel\n ): Promise<boolean> {\n const url = `${this.r2BaseUrl}/bundles/${agentId}/${version}/${tier}.tar.gz`;\n\n try {\n const response = await fetch(url, { method: 'HEAD' });\n return response.ok;\n } catch {\n return false;\n }\n }\n\n /**\n * Get the R2 base URL\n */\n getR2BaseUrl(): string {\n return this.r2BaseUrl;\n }\n\n /**\n * Get the Worker URL\n */\n getWorkerUrl(): string {\n return this.workerUrl;\n }\n}\n\n// Singleton instance\nlet remoteProviderInstance: RemoteProvider | null = null;\n\n/**\n * Get the RemoteProvider singleton instance\n */\nexport function getRemoteProvider(): RemoteProvider {\n if (!remoteProviderInstance) {\n remoteProviderInstance = new RemoteProvider();\n }\n return remoteProviderInstance;\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\nimport type { ContentManifest, CacheInfo } from './types.js';\n\nconst DEFAULT_CACHE_DIR = path.join(os.homedir(), '.jawkit', 'cache');\nconst MANIFEST_FILE = 'manifest.json';\nconst BUNDLES_DIR = 'bundles';\nconst TEMP_DIR = 'temp';\n\n/**\n * Manages local caching of content bundles and manifests\n */\nexport class CacheManager {\n private cacheDir: string;\n private initialized: boolean = false;\n\n constructor(cacheDir: string = DEFAULT_CACHE_DIR) {\n this.cacheDir = cacheDir;\n }\n\n /**\n * Initialize cache directories\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n await fs.mkdir(this.cacheDir, { recursive: true });\n await fs.mkdir(path.join(this.cacheDir, BUNDLES_DIR), { recursive: true });\n await fs.mkdir(path.join(this.cacheDir, TEMP_DIR), { recursive: true });\n this.initialized = true;\n }\n\n // Manifest caching\n\n /**\n * Save manifest to cache\n */\n async saveManifest(manifest: ContentManifest): Promise<void> {\n await this.initialize();\n const filePath = path.join(this.cacheDir, MANIFEST_FILE);\n await fs.writeFile(filePath, JSON.stringify(manifest, null, 2), 'utf-8');\n }\n\n /**\n * Get cached manifest\n */\n async getManifest(): Promise<ContentManifest | null> {\n try {\n const filePath = path.join(this.cacheDir, MANIFEST_FILE);\n const content = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(content) as ContentManifest;\n } catch {\n return null;\n }\n }\n\n // Bundle caching\n\n /**\n * Save downloaded bundle to cache\n * @param agentId - Agent identifier\n * @param version - Content version\n * @param tier - Tier level\n * @param sourcePath - Path to the downloaded file (will be moved)\n * @returns Path to cached bundle\n */\n async saveBundle(\n agentId: string,\n version: string,\n tier: string,\n sourcePath: string\n ): Promise<string> {\n await this.initialize();\n\n const bundleDir = path.join(this.cacheDir, BUNDLES_DIR, agentId, version);\n await fs.mkdir(bundleDir, { recursive: true });\n\n const destPath = path.join(bundleDir, `${tier}.tar.gz`);\n\n // Move from temp to cache\n await fs.rename(sourcePath, destPath);\n\n return destPath;\n }\n\n /**\n * Get cached bundle path if exists\n */\n async getBundle(\n agentId: string,\n version: string,\n tier: string\n ): Promise<string | null> {\n const bundlePath = path.join(\n this.cacheDir,\n BUNDLES_DIR,\n agentId,\n version,\n `${tier}.tar.gz`\n );\n\n try {\n await fs.access(bundlePath);\n return bundlePath;\n } catch {\n return null;\n }\n }\n\n /**\n * Check if a bundle exists in cache\n */\n async hasBundle(agentId: string, version: string, tier: string): Promise<boolean> {\n const bundlePath = await this.getBundle(agentId, version, tier);\n return bundlePath !== null;\n }\n\n // Temp file management\n\n /**\n * Get a path in the temp directory for downloads\n */\n async getTempPath(filename: string): Promise<string> {\n await this.initialize();\n return path.join(this.cacheDir, TEMP_DIR, filename);\n }\n\n /**\n * Clean temporary files\n */\n async cleanTemp(): Promise<void> {\n const tempDir = path.join(this.cacheDir, TEMP_DIR);\n try {\n await fs.rm(tempDir, { recursive: true, force: true });\n await fs.mkdir(tempDir, { recursive: true });\n } catch {\n // Ignore errors\n }\n }\n\n // Cache management\n\n /**\n * Clear all cached data\n */\n async clearCache(): Promise<void> {\n await fs.rm(this.cacheDir, { recursive: true, force: true });\n this.initialized = false;\n await this.initialize();\n }\n\n /**\n * Clear cache for a specific agent\n */\n async clearAgentCache(agentId: string): Promise<void> {\n const agentDir = path.join(this.cacheDir, BUNDLES_DIR, agentId);\n try {\n await fs.rm(agentDir, { recursive: true, force: true });\n } catch {\n // Directory doesn't exist\n }\n }\n\n /**\n * Clear old versions, keeping only the specified version\n */\n async clearOldVersions(agentId: string, keepVersion: string): Promise<number> {\n const agentDir = path.join(this.cacheDir, BUNDLES_DIR, agentId);\n let removedCount = 0;\n\n try {\n const versions = await fs.readdir(agentDir);\n\n for (const version of versions) {\n if (version !== keepVersion) {\n await fs.rm(path.join(agentDir, version), { recursive: true, force: true });\n removedCount++;\n }\n }\n } catch {\n // Directory doesn't exist, nothing to clean\n }\n\n return removedCount;\n }\n\n /**\n * Get total cache size in bytes\n */\n async getCacheSize(): Promise<number> {\n let totalSize = 0;\n\n async function calculateSize(dirPath: string): Promise<void> {\n try {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const entryPath = path.join(dirPath, entry.name);\n if (entry.isDirectory()) {\n await calculateSize(entryPath);\n } else {\n const stats = await fs.stat(entryPath);\n totalSize += stats.size;\n }\n }\n } catch {\n // Ignore errors\n }\n }\n\n await calculateSize(this.cacheDir);\n return totalSize;\n }\n\n /**\n * Get detailed cache information\n */\n async getCacheInfo(): Promise<CacheInfo> {\n const size = await this.getCacheSize();\n const bundlesDir = path.join(this.cacheDir, BUNDLES_DIR);\n const agents: Record<string, string[]> = {};\n\n try {\n const agentDirs = await fs.readdir(bundlesDir);\n\n for (const agent of agentDirs) {\n const agentPath = path.join(bundlesDir, agent);\n try {\n const stat = await fs.stat(agentPath);\n if (stat.isDirectory()) {\n const versions = await fs.readdir(agentPath);\n // Filter to only directories (await each stat check)\n const versionDirs: string[] = [];\n for (const v of versions) {\n const vPath = path.join(agentPath, v);\n try {\n const vStat = await fs.stat(vPath);\n if (vStat.isDirectory()) {\n versionDirs.push(v);\n }\n } catch {\n // Skip invalid entries\n }\n }\n agents[agent] = versionDirs;\n }\n } catch {\n // Skip invalid entries\n }\n }\n } catch {\n // No cache\n }\n\n return { size, agents };\n }\n\n /**\n * Get the cache directory path\n */\n getCacheDir(): string {\n return this.cacheDir;\n }\n}\n\n// Singleton instance\nlet cacheManagerInstance: CacheManager | null = null;\n\n/**\n * Get the CacheManager singleton instance\n */\nexport function getCacheManager(): CacheManager {\n if (!cacheManagerInstance) {\n cacheManagerInstance = new CacheManager();\n }\n return cacheManagerInstance;\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport type { ContentManifest } from './types.js';\n\n// Get the directory of the current module\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// Bundled content is included in the npm package at the root level\n// After build: dist/ and content/ are siblings\nconst BUNDLED_DIR = path.join(__dirname, '../../content');\n\n/**\n * Provides access to bundled fallback content included in the npm package\n * This allows the CLI to work offline with free tier content\n */\nexport class BundledContent {\n private bundledDir: string;\n\n constructor(bundledDir: string = BUNDLED_DIR) {\n this.bundledDir = bundledDir;\n }\n\n /**\n * Check if bundled content exists\n */\n isAvailable(): boolean {\n try {\n const manifestPath = path.join(this.bundledDir, 'manifest.json');\n fs.accessSync(manifestPath);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Get bundled manifest (free tier info)\n */\n getManifest(): ContentManifest {\n const manifestPath = path.join(this.bundledDir, 'manifest.json');\n const content = fs.readFileSync(manifestPath, 'utf-8');\n return JSON.parse(content) as ContentManifest;\n }\n\n /**\n * Get bundled manifest or null if not available\n */\n getManifestOrNull(): ContentManifest | null {\n try {\n return this.getManifest();\n } catch {\n return null;\n }\n }\n\n /**\n * Get path to bundled tar.gz file for an agent\n * Only 'free' tier is bundled\n */\n getBundlePath(agentId: string, tier: 'free' = 'free'): string | null {\n const bundlePath = path.join(this.bundledDir, agentId, `${tier}.tar.gz`);\n\n try {\n fs.accessSync(bundlePath);\n return bundlePath;\n } catch {\n return null;\n }\n }\n\n /**\n * Check if bundled content exists for an agent\n */\n hasBundle(agentId: string): boolean {\n return this.getBundlePath(agentId) !== null;\n }\n\n /**\n * List available bundled agents\n */\n listAgents(): string[] {\n try {\n const entries = fs.readdirSync(this.bundledDir, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .filter((e) => {\n // Check if the directory contains a free.tar.gz\n const bundlePath = path.join(this.bundledDir, e.name, 'free.tar.gz');\n try {\n fs.accessSync(bundlePath);\n return true;\n } catch {\n return false;\n }\n })\n .map((e) => e.name);\n } catch {\n return [];\n }\n }\n\n /**\n * Get the version of bundled content\n */\n getVersion(): string | null {\n const manifest = this.getManifestOrNull();\n return manifest?.version ?? null;\n }\n\n /**\n * Get the bundled directory path (for debugging)\n */\n getBundledDir(): string {\n return this.bundledDir;\n }\n}\n\n// Singleton instance\nlet bundledContentInstance: BundledContent | null = null;\n\n/**\n * Get the BundledContent singleton instance\n */\nexport function getBundledContent(): BundledContent {\n if (!bundledContentInstance) {\n bundledContentInstance = new BundledContent();\n }\n return bundledContentInstance;\n}\n","import { createGunzip } from 'zlib';\nimport { extract as tarExtract, type ReadEntry } from 'tar';\nimport { createReadStream } from 'fs';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport crypto from 'crypto';\nimport type { ExtractResult, ProgressCallback } from './types.js';\nimport { ContentError } from '../lib/errors.js';\n\n/**\n * Extract a tar.gz bundle to a target directory\n */\nexport async function extractBundle(\n bundlePath: string,\n targetDir: string,\n onProgress?: ProgressCallback\n): Promise<Omit<ExtractResult, 'version'>> {\n const filesExtracted: string[] = [];\n let totalSize = 0;\n const errors: string[] = [];\n\n try {\n // Ensure target directory exists\n await fs.mkdir(targetDir, { recursive: true });\n\n // Create extraction pipeline\n await new Promise<void>((resolve, reject) => {\n const readStream = createReadStream(bundlePath);\n const gunzip = createGunzip();\n\n const extractor = tarExtract({\n cwd: targetDir,\n strip: 0, // Don't strip leading path components\n filter: (entryPath: string) => {\n // Skip manifest.json - we don't need it in target\n return !entryPath.endsWith('manifest.json');\n },\n onentry: (entry: ReadEntry) => {\n filesExtracted.push(entry.path);\n totalSize += entry.size || 0;\n\n onProgress?.({\n phase: 'extracting',\n totalBytes: totalSize,\n processedBytes: totalSize,\n percentage: 100, // We don't know total until done\n currentFile: entry.path,\n });\n },\n });\n\n readStream\n .on('error', reject)\n .pipe(gunzip)\n .on('error', reject)\n .pipe(extractor)\n .on('error', reject)\n .on('finish', resolve);\n });\n\n return {\n success: true,\n filesExtracted,\n totalSize,\n errors,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown extraction error';\n errors.push(errorMessage);\n return {\n success: false,\n filesExtracted,\n totalSize,\n errors,\n };\n }\n}\n\n/**\n * Verify checksum of a file\n * @param filePath - Path to the file\n * @param expectedChecksum - Expected checksum in format \"sha256:abc123...\"\n */\nexport async function verifyChecksum(\n filePath: string,\n expectedChecksum: string\n): Promise<boolean> {\n const hash = crypto.createHash('sha256');\n const stream = createReadStream(filePath);\n\n for await (const chunk of stream) {\n hash.update(chunk);\n }\n\n const actualChecksum = `sha256:${hash.digest('hex')}`;\n return actualChecksum === expectedChecksum;\n}\n\n/**\n * Calculate SHA256 checksum of a file\n * @param filePath - Path to the file\n * @returns Checksum in format \"sha256:abc123...\"\n */\nexport async function calculateChecksum(filePath: string): Promise<string> {\n const hash = crypto.createHash('sha256');\n const stream = createReadStream(filePath);\n\n for await (const chunk of stream) {\n hash.update(chunk);\n }\n\n return `sha256:${hash.digest('hex')}`;\n}\n\n/**\n * Get file size in bytes\n */\nexport async function getFileSize(filePath: string): Promise<number> {\n const stats = await fs.stat(filePath);\n return stats.size;\n}\n\n/**\n * List files in a tar.gz archive (without extracting)\n */\nexport async function listBundleContents(bundlePath: string): Promise<string[]> {\n const files: string[] = [];\n\n await new Promise<void>((resolve, reject) => {\n const readStream = createReadStream(bundlePath);\n const gunzip = createGunzip();\n\n const extractor = tarExtract({\n onentry: (entry: ReadEntry) => {\n files.push(entry.path);\n entry.resume(); // Skip actual extraction\n },\n });\n\n readStream\n .on('error', reject)\n .pipe(gunzip)\n .on('error', reject)\n .pipe(extractor)\n .on('error', reject)\n .on('finish', resolve);\n });\n\n return files;\n}\n\n/**\n * Extract and verify a bundle\n * Combines extraction with checksum verification\n */\nexport async function extractAndVerifyBundle(\n bundlePath: string,\n targetDir: string,\n expectedChecksum: string,\n onProgress?: ProgressCallback\n): Promise<ExtractResult> {\n // First verify the bundle checksum\n onProgress?.({\n phase: 'verifying',\n totalBytes: 0,\n processedBytes: 0,\n percentage: 0,\n });\n\n const isValid = await verifyChecksum(bundlePath, expectedChecksum);\n if (!isValid) {\n throw ContentError.checksumMismatch(path.basename(bundlePath));\n }\n\n // Then extract\n const result = await extractBundle(bundlePath, targetDir, onProgress);\n\n return {\n ...result,\n version: '', // Will be filled in by ContentService\n };\n}\n","import { ofetch } from 'ofetch';\nimport { version as packageVersion } from '../../package.json';\n\nconst NPM_REGISTRY = 'https://registry.npmjs.org';\nconst PACKAGE_NAME = '@jawkit/cli';\n\n/**\n * Get current CLI version from package.json\n */\nexport function getCliVersion(): string {\n return packageVersion;\n}\n\n/**\n * Check npm registry for latest CLI version\n */\nexport async function checkCliUpdate(): Promise<string | null> {\n try {\n const response = await ofetch<{ 'dist-tags': { latest: string } }>(\n `${NPM_REGISTRY}/${encodeURIComponent(PACKAGE_NAME)}`,\n {\n timeout: 5000,\n headers: {\n Accept: 'application/json',\n },\n }\n );\n\n return response['dist-tags'].latest;\n } catch {\n // Silently fail - update check is non-critical\n return null;\n }\n}\n\n/**\n * Compare versions (semver)\n * Returns true if latest is newer than current\n */\nexport function isNewerVersion(latest: string, current: string): boolean {\n const latestParts = latest.split('.').map(Number);\n const currentParts = current.split('.').map(Number);\n\n for (let i = 0; i < 3; i++) {\n const l = latestParts[i] || 0;\n const c = currentParts[i] || 0;\n\n if (l > c) return true;\n if (l < c) return false;\n }\n\n return false;\n}\n\n/**\n * Check if current CLI version is compatible with content\n */\nexport function isCompatibleVersion(\n cliVersion: string,\n minCliVersion: string\n): boolean {\n return !isNewerVersion(minCliVersion, cliVersion);\n}\n","import { ConfigService } from '../lib/config.js';\nimport { ContentService } from '../content/content.service.js';\nimport { isNewerVersion } from './cli-version.js';\n\n/**\n * Get installed content versions from config\n */\nexport async function getContentVersions(): Promise<Record<string, string>> {\n const config = new ConfigService();\n return (await config.get('contentVersions')) ?? {};\n}\n\n/**\n * Check for content updates\n * Returns a map of agentId -> latest version for agents with updates available\n */\nexport async function checkContentUpdates(\n currentVersions: Record<string, string>\n): Promise<Record<string, string>> {\n const contentService = new ContentService();\n const updates: Record<string, string> = {};\n\n try {\n const manifest = await contentService.getManifest('latest');\n\n for (const [agentId, agentManifest] of Object.entries(manifest.agents)) {\n const current = currentVersions[agentId];\n const latest = agentManifest.version;\n\n // If not installed or newer version available\n if (!current || isNewerVersion(latest, current)) {\n updates[agentId] = latest;\n }\n }\n } catch {\n // Silently fail - update check is non-critical\n }\n\n return updates;\n}\n\n/**\n * Update content version in config\n */\nexport async function updateContentVersion(\n agentId: string,\n version: string\n): Promise<void> {\n const config = new ConfigService();\n const versions = await getContentVersions();\n\n await config.set('contentVersions', {\n ...versions,\n [agentId]: version,\n });\n}\n\n/**\n * Get all installed content versions with update info\n */\nexport async function getContentVersionsWithUpdates(): Promise<\n Array<{\n agentId: string;\n current: string;\n latest: string | null;\n updateAvailable: boolean;\n }>\n> {\n const currentVersions = await getContentVersions();\n const updates = await checkContentUpdates(currentVersions);\n\n const result: Array<{\n agentId: string;\n current: string;\n latest: string | null;\n updateAvailable: boolean;\n }> = [];\n\n for (const [agentId, current] of Object.entries(currentVersions)) {\n const latest = updates[agentId] ?? null;\n result.push({\n agentId,\n current,\n latest: latest ?? current,\n updateAvailable: latest !== null,\n });\n }\n\n return result;\n}\n"],"mappings":"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","names":["chalk","path","logger","fs","path","os","fs","ofetch","version","ofetch","fs","path","os","version","fs","path","__filename","__dirname","fs","fs","version","fs","ofetch","ofetch"]}
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED