jaz-cli 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/skills/api/SKILL.md +162 -0
- package/assets/skills/api/references/dependencies.md +139 -0
- package/assets/skills/api/references/endpoints.md +1299 -0
- package/assets/skills/api/references/errors.md +751 -0
- package/assets/skills/api/references/feature-glossary.md +216 -0
- package/assets/skills/api/references/field-map.md +428 -0
- package/assets/skills/api/references/full-api-surface.md +699 -0
- package/assets/skills/api/references/search-reference.md +714 -0
- package/assets/skills/conversion/SKILL.md +130 -0
- package/assets/skills/conversion/references/edge-cases.md +174 -0
- package/assets/skills/conversion/references/file-analysis.md +120 -0
- package/assets/skills/conversion/references/file-types.md +501 -0
- package/assets/skills/conversion/references/mapping-rules.md +166 -0
- package/assets/skills/conversion/references/option1-full.md +145 -0
- package/assets/skills/conversion/references/option2-quick.md +197 -0
- package/assets/skills/conversion/references/verification.md +142 -0
- package/dist/commands/init.js +76 -0
- package/dist/commands/update.js +28 -0
- package/dist/commands/versions.js +33 -0
- package/dist/index.js +52 -0
- package/dist/types/index.js +5 -0
- package/dist/utils/github.js +81 -0
- package/dist/utils/logger.js +21 -0
- package/dist/utils/template.js +49 -0
- package/package.json +44 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
|
2
|
+
const REPO_OWNER = 'teamtinvio';
|
|
3
|
+
const REPO_NAME = 'claude-plugins';
|
|
4
|
+
const API_BASE = 'https://api.github.com';
|
|
5
|
+
export class GitHubRateLimitError extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = 'GitHubRateLimitError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export class GitHubDownloadError extends Error {
|
|
12
|
+
constructor(message) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'GitHubDownloadError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function checkRateLimit(response) {
|
|
18
|
+
const remaining = response.headers.get('x-ratelimit-remaining');
|
|
19
|
+
if (response.status === 403 && remaining === '0') {
|
|
20
|
+
const resetTime = response.headers.get('x-ratelimit-reset');
|
|
21
|
+
const resetDate = resetTime
|
|
22
|
+
? new Date(parseInt(resetTime) * 1000).toLocaleTimeString()
|
|
23
|
+
: 'unknown';
|
|
24
|
+
throw new GitHubRateLimitError(`GitHub API rate limit exceeded. Resets at ${resetDate}`);
|
|
25
|
+
}
|
|
26
|
+
if (response.status === 429) {
|
|
27
|
+
throw new GitHubRateLimitError('GitHub API rate limit exceeded (429 Too Many Requests)');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export async function fetchReleases() {
|
|
31
|
+
const url = `${API_BASE}/repos/${REPO_OWNER}/${REPO_NAME}/releases`;
|
|
32
|
+
const response = await fetch(url, {
|
|
33
|
+
headers: {
|
|
34
|
+
Accept: 'application/vnd.github.v3+json',
|
|
35
|
+
'User-Agent': 'jaz-cli',
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
checkRateLimit(response);
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
throw new GitHubDownloadError(`Failed to fetch releases: ${response.status} ${response.statusText}`);
|
|
41
|
+
}
|
|
42
|
+
return response.json();
|
|
43
|
+
}
|
|
44
|
+
export async function getLatestRelease() {
|
|
45
|
+
const url = `${API_BASE}/repos/${REPO_OWNER}/${REPO_NAME}/releases/latest`;
|
|
46
|
+
const response = await fetch(url, {
|
|
47
|
+
headers: {
|
|
48
|
+
Accept: 'application/vnd.github.v3+json',
|
|
49
|
+
'User-Agent': 'jaz-cli',
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
checkRateLimit(response);
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
throw new GitHubDownloadError(`Failed to fetch latest release: ${response.status} ${response.statusText}`);
|
|
55
|
+
}
|
|
56
|
+
return response.json();
|
|
57
|
+
}
|
|
58
|
+
export async function downloadRelease(url, dest) {
|
|
59
|
+
const response = await fetch(url, {
|
|
60
|
+
headers: {
|
|
61
|
+
'User-Agent': 'jaz-cli',
|
|
62
|
+
Accept: 'application/octet-stream',
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
checkRateLimit(response);
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
throw new GitHubDownloadError(`Failed to download: ${response.status} ${response.statusText}`);
|
|
68
|
+
}
|
|
69
|
+
const buffer = await response.arrayBuffer();
|
|
70
|
+
await writeFile(dest, Buffer.from(buffer));
|
|
71
|
+
}
|
|
72
|
+
export function getAssetUrl(release) {
|
|
73
|
+
const asset = release.assets.find((a) => a.name.endsWith('.zip'));
|
|
74
|
+
if (asset?.browser_download_url) {
|
|
75
|
+
return asset.browser_download_url;
|
|
76
|
+
}
|
|
77
|
+
if (release.tag_name) {
|
|
78
|
+
return `https://github.com/${REPO_OWNER}/${REPO_NAME}/archive/refs/tags/${release.tag_name}.zip`;
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
export const logger = {
|
|
3
|
+
title(text) {
|
|
4
|
+
console.log();
|
|
5
|
+
console.log(chalk.bold.cyan(` ${text}`));
|
|
6
|
+
console.log(chalk.dim(' ' + '─'.repeat(text.length)));
|
|
7
|
+
console.log();
|
|
8
|
+
},
|
|
9
|
+
info(text) {
|
|
10
|
+
console.log(` ${chalk.blue('i')} ${text}`);
|
|
11
|
+
},
|
|
12
|
+
success(text) {
|
|
13
|
+
console.log(` ${chalk.green('✓')} ${text}`);
|
|
14
|
+
},
|
|
15
|
+
warn(text) {
|
|
16
|
+
console.log(` ${chalk.yellow('!')} ${text}`);
|
|
17
|
+
},
|
|
18
|
+
error(text) {
|
|
19
|
+
console.log(` ${chalk.red('✗')} ${text}`);
|
|
20
|
+
},
|
|
21
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { mkdir, cp, rm, access } from 'node:fs/promises';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
// From dist/utils/template.js -> ../../assets (two levels up to cli/, then assets/)
|
|
6
|
+
const ASSETS_DIR = join(__dirname, '..', '..', 'assets');
|
|
7
|
+
const SKILLS = ['api', 'conversion'];
|
|
8
|
+
async function exists(path) {
|
|
9
|
+
try {
|
|
10
|
+
await access(path);
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Install skill files into a target project directory.
|
|
19
|
+
* Creates .claude/skills/<skillName>/ with SKILL.md + references/
|
|
20
|
+
*/
|
|
21
|
+
async function installSkill(targetDir, skillName, force) {
|
|
22
|
+
const sourceDir = join(ASSETS_DIR, 'skills', skillName);
|
|
23
|
+
const targetSkillDir = join(targetDir, '.claude', 'skills', skillName);
|
|
24
|
+
if (!(await exists(sourceDir))) {
|
|
25
|
+
throw new Error(`Skill source not found: ${sourceDir}`);
|
|
26
|
+
}
|
|
27
|
+
if (await exists(targetSkillDir)) {
|
|
28
|
+
if (!force) {
|
|
29
|
+
throw new Error(`${targetSkillDir} already exists. Use --force to overwrite.`);
|
|
30
|
+
}
|
|
31
|
+
// Remove stale files before copying (ensures deleted references don't linger)
|
|
32
|
+
await rm(targetSkillDir, { recursive: true, force: true });
|
|
33
|
+
}
|
|
34
|
+
await mkdir(targetSkillDir, { recursive: true });
|
|
35
|
+
await cp(sourceDir, targetSkillDir, { recursive: true, force: true });
|
|
36
|
+
return `.claude/skills/${skillName}`;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Install selected skills into the target project.
|
|
40
|
+
*/
|
|
41
|
+
export async function installSkills(targetDir, skillType, force = false) {
|
|
42
|
+
const skillsToInstall = skillType === 'all' ? SKILLS : [skillType];
|
|
43
|
+
const installedPaths = [];
|
|
44
|
+
for (const skill of skillsToInstall) {
|
|
45
|
+
const path = await installSkill(targetDir, skill, force);
|
|
46
|
+
installedPaths.push(path);
|
|
47
|
+
}
|
|
48
|
+
return installedPaths;
|
|
49
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jaz-cli",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "CLI to install Jaz AI skills for Claude Code",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"jaz": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"assets"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc && node --input-type=module -e \"import{readFileSync,writeFileSync}from'fs';const c=readFileSync('dist/index.js','utf8');if(!c.startsWith('#!')){writeFileSync('dist/index.js','#!/usr/bin/env node\\n'+c)}\"",
|
|
15
|
+
"dev": "node --loader ts-node/esm src/index.ts",
|
|
16
|
+
"prepublishOnly": "npm run build"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"jaz",
|
|
20
|
+
"juan",
|
|
21
|
+
"accounting",
|
|
22
|
+
"api",
|
|
23
|
+
"claude",
|
|
24
|
+
"ai",
|
|
25
|
+
"skill",
|
|
26
|
+
"conversion",
|
|
27
|
+
"migration",
|
|
28
|
+
"xero",
|
|
29
|
+
"quickbooks"
|
|
30
|
+
],
|
|
31
|
+
"author": "Jaz Engineering <api-support@jaz.ai>",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"commander": "^12.1.0",
|
|
35
|
+
"chalk": "^5.3.0",
|
|
36
|
+
"ora": "^8.1.1",
|
|
37
|
+
"prompts": "^2.4.2"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^22.10.1",
|
|
41
|
+
"@types/prompts": "^2.4.9",
|
|
42
|
+
"typescript": "^5.7.2"
|
|
43
|
+
}
|
|
44
|
+
}
|