@jawkit.cc/cli 0.1.1 → 0.1.3
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 +77 -77
- 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/github-copilot/professional.tar.gz +0 -0
- package/content/manifest.json +21 -13
- package/dist/{chunk-3QQ6HWDH.js → chunk-VREGQDBU.js} +2 -2
- package/dist/chunk-VREGQDBU.js.map +1 -0
- package/dist/cli.js +40 -19
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +71 -68
- package/dist/chunk-3QQ6HWDH.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,77 +1,77 @@
|
|
|
1
|
-
# JawKit CLI
|
|
2
|
-
|
|
3
|
-
CLI toolkit for installing AI coding assistant configurations (Claude Code, GitHub Copilot).
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Multi-agent support**: Claude Code, GitHub Copilot
|
|
8
|
-
- **Tiered content**: Free and Professional tiers
|
|
9
|
-
- **Easy setup**: One command to install prompts, skills, and configurations
|
|
10
|
-
|
|
11
|
-
## Installation
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm install -g @jawkit.cc/cli
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Quick Start
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
# Initialize in your project (free tier - no license needed)
|
|
21
|
-
jawkit init
|
|
22
|
-
|
|
23
|
-
# Check available content
|
|
24
|
-
jawkit version
|
|
25
|
-
|
|
26
|
-
# Upgrade to latest content
|
|
27
|
-
jawkit upgrade
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Professional Tier
|
|
31
|
-
|
|
32
|
-
Get access to premium prompts, skills, and configurations:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
# Purchase at jawkit.cc
|
|
36
|
-
# Then activate your license:
|
|
37
|
-
jawkit auth activate YOUR_LICENSE_KEY
|
|
38
|
-
|
|
39
|
-
# Check license status
|
|
40
|
-
jawkit auth status
|
|
41
|
-
|
|
42
|
-
# Re-run init to get professional content
|
|
43
|
-
jawkit init
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Commands
|
|
47
|
-
|
|
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 |
|
|
57
|
-
|
|
58
|
-
## Supported Agents
|
|
59
|
-
|
|
60
|
-
- **Claude Code** - Anthropic's AI coding assistant
|
|
61
|
-
- **GitHub Copilot** - GitHub's AI pair programmer
|
|
62
|
-
|
|
63
|
-
## Requirements
|
|
64
|
-
|
|
65
|
-
- Node.js 18 or higher
|
|
66
|
-
|
|
67
|
-
## Links
|
|
68
|
-
|
|
69
|
-
- Website: https://jawkit.cc
|
|
70
|
-
- Purchase: https://jawkit.cc/pro
|
|
71
|
-
- Documentation: https://jawkit.cc/docs
|
|
72
|
-
|
|
73
|
-
## License
|
|
74
|
-
|
|
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.
|
|
1
|
+
# JawKit CLI
|
|
2
|
+
|
|
3
|
+
CLI toolkit for installing AI coding assistant configurations (Claude Code, GitHub Copilot).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Multi-agent support**: Claude Code, GitHub Copilot
|
|
8
|
+
- **Tiered content**: Free and Professional tiers
|
|
9
|
+
- **Easy setup**: One command to install prompts, skills, and configurations
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g "@jawkit.cc/cli"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Initialize in your project (free tier - no license needed)
|
|
21
|
+
jawkit init
|
|
22
|
+
|
|
23
|
+
# Check available content
|
|
24
|
+
jawkit version
|
|
25
|
+
|
|
26
|
+
# Upgrade to latest content
|
|
27
|
+
jawkit upgrade
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Professional Tier
|
|
31
|
+
|
|
32
|
+
Get access to premium prompts, skills, and configurations:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Purchase at jawkit.cc
|
|
36
|
+
# Then activate your license:
|
|
37
|
+
jawkit auth activate YOUR_LICENSE_KEY
|
|
38
|
+
|
|
39
|
+
# Check license status
|
|
40
|
+
jawkit auth status
|
|
41
|
+
|
|
42
|
+
# Re-run init to get professional content
|
|
43
|
+
jawkit init
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Commands
|
|
47
|
+
|
|
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 |
|
|
57
|
+
|
|
58
|
+
## Supported Agents
|
|
59
|
+
|
|
60
|
+
- **Claude Code** - Anthropic's AI coding assistant
|
|
61
|
+
- **GitHub Copilot** - GitHub's AI pair programmer
|
|
62
|
+
|
|
63
|
+
## Requirements
|
|
64
|
+
|
|
65
|
+
- Node.js 18 or higher
|
|
66
|
+
|
|
67
|
+
## Links
|
|
68
|
+
|
|
69
|
+
- Website: https://jawkit.cc
|
|
70
|
+
- Purchase: https://jawkit.cc/pro
|
|
71
|
+
- Documentation: https://jawkit.cc/docs
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
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
|
|
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-
|
|
4
|
+
"publishedAt": "2026-03-02T04:50:59.796Z",
|
|
5
5
|
"minCliVersion": "1.0.0",
|
|
6
6
|
"agents": {
|
|
7
7
|
"claude-code": {
|
|
@@ -9,23 +9,23 @@
|
|
|
9
9
|
"bundles": {
|
|
10
10
|
"free": {
|
|
11
11
|
"filename": "free.tar.gz",
|
|
12
|
-
"checksum": "sha256:
|
|
13
|
-
"size":
|
|
14
|
-
"fileCount":
|
|
12
|
+
"checksum": "sha256:2ed74809a21ac89a5b8d759d4d006c25cd86df706f0b5141e049789b6008f1b5",
|
|
13
|
+
"size": 101097,
|
|
14
|
+
"fileCount": 28,
|
|
15
15
|
"contentTypes": [
|
|
16
|
+
"agents",
|
|
16
17
|
"commands",
|
|
17
18
|
"skills"
|
|
18
19
|
]
|
|
19
20
|
},
|
|
20
21
|
"professional": {
|
|
21
22
|
"filename": "professional.tar.gz",
|
|
22
|
-
"checksum": "sha256:
|
|
23
|
-
"size":
|
|
24
|
-
"fileCount":
|
|
23
|
+
"checksum": "sha256:3923d8143ff480438934e8d4df23b00ce5603e1bbca75c604d7ac201658221b2",
|
|
24
|
+
"size": 1109527,
|
|
25
|
+
"fileCount": 415,
|
|
25
26
|
"contentTypes": [
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"skills"
|
|
27
|
+
".claude",
|
|
28
|
+
".jawkit"
|
|
29
29
|
]
|
|
30
30
|
}
|
|
31
31
|
}
|
|
@@ -35,13 +35,21 @@
|
|
|
35
35
|
"bundles": {
|
|
36
36
|
"free": {
|
|
37
37
|
"filename": "free.tar.gz",
|
|
38
|
-
"checksum": "sha256:
|
|
39
|
-
"size":
|
|
40
|
-
"fileCount":
|
|
38
|
+
"checksum": "sha256:a84bad72604c787dfbbe201aa9c0c50f269bc55eb30b43e28a5e399f699d86b9",
|
|
39
|
+
"size": 101090,
|
|
40
|
+
"fileCount": 28,
|
|
41
41
|
"contentTypes": [
|
|
42
|
+
"agents",
|
|
42
43
|
"commands",
|
|
43
44
|
"skills"
|
|
44
45
|
]
|
|
46
|
+
},
|
|
47
|
+
"professional": {
|
|
48
|
+
"filename": "professional.tar.gz",
|
|
49
|
+
"checksum": "sha256:4f27a9a6db15b7d0ff4be07d86f54393762ed346d1a0fde13532792debb3884a",
|
|
50
|
+
"size": 145,
|
|
51
|
+
"fileCount": 1,
|
|
52
|
+
"contentTypes": []
|
|
45
53
|
}
|
|
46
54
|
}
|
|
47
55
|
}
|
|
@@ -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.3";
|
|
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-VREGQDBU.js.map
|
|
@@ -0,0 +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":["{\r\n \"name\": \"@jawkit.cc/cli\",\r\n \"version\": \"0.1.3\",\r\n \"description\": \"CLI toolkit for installing AI coding assistant configurations\",\r\n \"type\": \"module\",\r\n \"bin\": {\r\n \"jawkit\": \"./dist/cli.js\"\r\n },\r\n \"main\": \"./dist/index.js\",\r\n \"types\": \"./dist/index.d.ts\",\r\n \"exports\": {\r\n \".\": {\r\n \"import\": \"./dist/index.js\",\r\n \"types\": \"./dist/index.d.ts\"\r\n }\r\n },\r\n \"files\": [\r\n \"dist\",\r\n \"content\"\r\n ],\r\n \"scripts\": {\r\n \"dev\": \"tsup --watch\",\r\n \"build\": \"tsup\",\r\n \"start\": \"node dist/cli.js\",\r\n \"lint\": \"eslint src --ext .ts\",\r\n \"lint:fix\": \"eslint src --ext .ts --fix\",\r\n \"test\": \"vitest\",\r\n \"test:run\": \"vitest run\",\r\n \"typecheck\": \"tsc --noEmit\",\r\n \"bundle-content\": \"tsx scripts/bundle-content.ts\",\r\n \"upload-content\": \"node scripts/upload-content.js\",\r\n \"deploy\": \"node scripts/deploy.js api\",\r\n \"deploy:site\": \"node scripts/deploy.js site\",\r\n \"deploy:api\": \"node scripts/deploy.js api\",\r\n \"publish-content\": \"npm run bundle-content && npm run upload-content\",\r\n \"create-invite\": \"node scripts/create-invitation.js\",\r\n \"serve:local\": \"tsx scripts/local-r2-server.ts\",\r\n \"prebuild\": \"npm run bundle-content || true\",\r\n \"prepublishOnly\": \"npm run build\"\r\n },\r\n \"keywords\": [\r\n \"cli\",\r\n \"ai\",\r\n \"claude\",\r\n \"copilot\",\r\n \"coding-assistant\",\r\n \"developer-tools\"\r\n ],\r\n \"author\": \"JawKit\",\r\n \"license\": \"SEE LICENSE IN LICENSE\",\r\n \"private\": false,\r\n \"engines\": {\r\n \"node\": \">=18.0.0\"\r\n },\r\n \"dependencies\": {\r\n \"@inquirer/prompts\": \"^7.2.1\",\r\n \"chalk\": \"^5.4.1\",\r\n \"commander\": \"^13.0.0\",\r\n \"ofetch\": \"^1.4.1\",\r\n \"ora\": \"^8.1.1\",\r\n \"tar\": \"^7.4.3\"\r\n },\r\n \"devDependencies\": {\r\n \"@types/node\": \"^22.10.7\",\r\n \"eslint\": \"^9.18.0\",\r\n \"tsup\": \"^8.3.5\",\r\n \"tsx\": \"^4.7.0\",\r\n \"typescript\": \"^5.7.3\",\r\n \"vitest\": \"^2.1.8\"\r\n }\r\n}\r\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
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
handleError,
|
|
14
14
|
isNewerVersion,
|
|
15
15
|
version
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-VREGQDBU.js";
|
|
17
17
|
|
|
18
18
|
// src/cli.ts
|
|
19
19
|
import { Command as Command5 } from "commander";
|
|
@@ -535,7 +535,7 @@ function initCommand() {
|
|
|
535
535
|
}
|
|
536
536
|
}
|
|
537
537
|
logger.info(`Agent: ${chalk2.cyan(agent.config.name)}`);
|
|
538
|
-
logger.info(`Target: ${chalk2.dim(
|
|
538
|
+
logger.info(`Target: ${chalk2.dim(projectPath)}`);
|
|
539
539
|
logger.divider();
|
|
540
540
|
const bundleInfo = await contentService.getBundleInfo(agent.config.id, userTier);
|
|
541
541
|
logger.info(`Bundle size: ${chalk2.dim(formatBytes(bundleInfo.size))}`);
|
|
@@ -550,35 +550,56 @@ function initCommand() {
|
|
|
550
550
|
return;
|
|
551
551
|
}
|
|
552
552
|
}
|
|
553
|
-
const
|
|
554
|
-
|
|
553
|
+
const claudeDir = path4.join(projectPath, ".claude");
|
|
554
|
+
const jawkitDir = path4.join(projectPath, ".jawkit");
|
|
555
|
+
let claudeBackupPath = null;
|
|
556
|
+
let jawkitBackupPath = null;
|
|
555
557
|
try {
|
|
556
|
-
const stats = await fs4.stat(
|
|
558
|
+
const stats = await fs4.stat(claudeDir);
|
|
557
559
|
if (stats.isDirectory()) {
|
|
558
|
-
|
|
559
|
-
logger.info(chalk2.yellow(
|
|
560
|
+
claudeBackupPath = `${claudeDir}.backup`;
|
|
561
|
+
logger.info(chalk2.yellow("Existing .claude/ found - will backup to .claude.backup/"));
|
|
562
|
+
}
|
|
563
|
+
} catch {
|
|
564
|
+
}
|
|
565
|
+
try {
|
|
566
|
+
const stats = await fs4.stat(jawkitDir);
|
|
567
|
+
if (stats.isDirectory()) {
|
|
568
|
+
jawkitBackupPath = `${jawkitDir}.backup`;
|
|
569
|
+
logger.info(chalk2.yellow("Existing .jawkit/ found - will backup to .jawkit.backup/"));
|
|
560
570
|
}
|
|
561
571
|
} catch {
|
|
562
572
|
}
|
|
563
573
|
if (options.dryRun) {
|
|
564
574
|
logger.info(chalk2.yellow("\n[DRY RUN] Would perform the following:"));
|
|
565
|
-
if (
|
|
566
|
-
logger.info(
|
|
575
|
+
if (claudeBackupPath) {
|
|
576
|
+
logger.info(" - Backup existing: .claude/ \u2192 .claude.backup/");
|
|
577
|
+
}
|
|
578
|
+
if (jawkitBackupPath) {
|
|
579
|
+
logger.info(" - Backup existing: .jawkit/ \u2192 .jawkit.backup/");
|
|
567
580
|
}
|
|
568
|
-
logger.info(` - Prepare directory: ${agent.config.targetDirectory}/`);
|
|
569
581
|
logger.info(` - Download bundle: ${bundleInfo.filename}`);
|
|
570
|
-
logger.info(` - Extract ${bundleInfo.fileCount} files`);
|
|
582
|
+
logger.info(` - Extract ${bundleInfo.fileCount} files to current directory`);
|
|
571
583
|
return;
|
|
572
584
|
}
|
|
573
585
|
logger.divider();
|
|
574
|
-
if (
|
|
575
|
-
const backupSpinner = logger.spinner("Backing up existing
|
|
586
|
+
if (claudeBackupPath) {
|
|
587
|
+
const backupSpinner = logger.spinner("Backing up existing .claude/ ...");
|
|
588
|
+
try {
|
|
589
|
+
await fs4.rm(claudeBackupPath, { recursive: true, force: true });
|
|
590
|
+
} catch {
|
|
591
|
+
}
|
|
592
|
+
await fs4.rename(claudeDir, claudeBackupPath);
|
|
593
|
+
backupSpinner.succeed("Backed up to .claude.backup/");
|
|
594
|
+
}
|
|
595
|
+
if (jawkitBackupPath) {
|
|
596
|
+
const backupSpinner = logger.spinner("Backing up existing .jawkit/ ...");
|
|
576
597
|
try {
|
|
577
|
-
await fs4.rm(
|
|
598
|
+
await fs4.rm(jawkitBackupPath, { recursive: true, force: true });
|
|
578
599
|
} catch {
|
|
579
600
|
}
|
|
580
|
-
await fs4.rename(
|
|
581
|
-
backupSpinner.succeed(
|
|
601
|
+
await fs4.rename(jawkitDir, jawkitBackupPath);
|
|
602
|
+
backupSpinner.succeed("Backed up to .jawkit.backup/");
|
|
582
603
|
}
|
|
583
604
|
const prepareSpinner = logger.spinner("Preparing target directory...");
|
|
584
605
|
await agent.prepare(projectPath);
|
|
@@ -587,7 +608,7 @@ function initCommand() {
|
|
|
587
608
|
const result = await contentService.downloadAndExtractBundle(
|
|
588
609
|
agent.config.id,
|
|
589
610
|
userTier,
|
|
590
|
-
|
|
611
|
+
projectPath,
|
|
591
612
|
(progress) => {
|
|
592
613
|
if (progress.phase === "downloading") {
|
|
593
614
|
downloadSpinner.text = `Downloading... ${progress.percentage}%`;
|
|
@@ -623,7 +644,7 @@ function initCommand() {
|
|
|
623
644
|
logger.divider();
|
|
624
645
|
logger.success("JawKit content installed successfully!");
|
|
625
646
|
logger.info(`
|
|
626
|
-
Installed to: ${chalk2.cyan(
|
|
647
|
+
Installed to: ${chalk2.cyan(projectPath)}`);
|
|
627
648
|
if (result.filesExtracted.length > 0) {
|
|
628
649
|
logger.info("\nFiles installed:");
|
|
629
650
|
for (const file of result.filesExtracted.slice(0, 5)) {
|
|
@@ -1120,7 +1141,7 @@ function upgradeCommand() {
|
|
|
1120
1141
|
let totalUpdated = 0;
|
|
1121
1142
|
for (const update of updates) {
|
|
1122
1143
|
try {
|
|
1123
|
-
const targetDir =
|
|
1144
|
+
const targetDir = update.install.path;
|
|
1124
1145
|
const result = await contentService.downloadAndExtractBundle(
|
|
1125
1146
|
agentId,
|
|
1126
1147
|
tier,
|