feat: bundle skill assets in npm package (#12)
- Add assets folder with all skill files (.claude, .cursor, .windsurf, .agent, .shared) - Simplify init command to copy from bundled assets instead of GitHub download - Remove --version option (version tied to npm package) - No more GitHub API rate limits - Works offline - Bump to v1.1.0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,19 +1,20 @@
|
||||
import { join } from 'node:path';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { mkdir } from 'node:fs/promises';
|
||||
import { join, dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import chalk from 'chalk';
|
||||
import ora from 'ora';
|
||||
import prompts from 'prompts';
|
||||
import type { AIType } from '../types/index.js';
|
||||
import { AI_TYPES } from '../types/index.js';
|
||||
import { fetchReleases, getLatestRelease, downloadRelease, getAssetUrl } from '../utils/github.js';
|
||||
import { extractZip, copyFolders, cleanup } from '../utils/extract.js';
|
||||
import { copyFolders } from '../utils/extract.js';
|
||||
import { detectAIType, getAITypeDescription } from '../utils/detect.js';
|
||||
import { logger } from '../utils/logger.js';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
// From dist/index.js -> ../assets (one level up to cli/, then assets/)
|
||||
const ASSETS_DIR = join(__dirname, '..', 'assets');
|
||||
|
||||
interface InitOptions {
|
||||
ai?: AIType;
|
||||
version?: string;
|
||||
force?: boolean;
|
||||
}
|
||||
|
||||
@@ -51,51 +52,11 @@ export async function initCommand(options: InitOptions): Promise<void> {
|
||||
|
||||
logger.info(`Installing for: ${chalk.cyan(getAITypeDescription(aiType))}`);
|
||||
|
||||
// Fetch release
|
||||
const spinner = ora('Fetching release info...').start();
|
||||
const spinner = ora('Installing files...').start();
|
||||
|
||||
try {
|
||||
let release;
|
||||
if (options.version) {
|
||||
const releases = await fetchReleases();
|
||||
release = releases.find(r => r.tag_name === options.version);
|
||||
if (!release) {
|
||||
spinner.fail(`Version ${options.version} not found`);
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
release = await getLatestRelease();
|
||||
}
|
||||
|
||||
spinner.text = `Found version: ${release.tag_name}`;
|
||||
|
||||
const assetUrl = getAssetUrl(release);
|
||||
if (!assetUrl) {
|
||||
spinner.fail('No downloadable asset found in release');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Download
|
||||
spinner.text = 'Downloading...';
|
||||
const tempDir = join(tmpdir(), `uipro-${Date.now()}`);
|
||||
await mkdir(tempDir, { recursive: true });
|
||||
|
||||
const zipPath = join(tempDir, 'release.zip');
|
||||
await downloadRelease(assetUrl, zipPath);
|
||||
|
||||
// Extract
|
||||
spinner.text = 'Extracting...';
|
||||
const extractDir = join(tempDir, 'extracted');
|
||||
await mkdir(extractDir, { recursive: true });
|
||||
await extractZip(zipPath, extractDir);
|
||||
|
||||
// Copy folders
|
||||
spinner.text = 'Installing files...';
|
||||
const cwd = process.cwd();
|
||||
const copiedFolders = await copyFolders(extractDir, cwd, aiType);
|
||||
|
||||
// Cleanup
|
||||
await cleanup(tempDir);
|
||||
const copiedFolders = await copyFolders(ASSETS_DIR, cwd, aiType);
|
||||
|
||||
spinner.succeed('Installation complete!');
|
||||
|
||||
@@ -107,7 +68,7 @@ export async function initCommand(options: InitOptions): Promise<void> {
|
||||
});
|
||||
|
||||
console.log();
|
||||
logger.success(`UI/UX Pro Max ${release.tag_name} installed successfully!`);
|
||||
logger.success('UI/UX Pro Max installed successfully!');
|
||||
|
||||
// Next steps
|
||||
console.log();
|
||||
|
||||
@@ -12,13 +12,12 @@ const program = new Command();
|
||||
program
|
||||
.name('uipro')
|
||||
.description('CLI to install UI/UX Pro Max skill for AI coding assistants')
|
||||
.version('1.0.3');
|
||||
.version('1.1.0');
|
||||
|
||||
program
|
||||
.command('init')
|
||||
.description('Install UI/UX Pro Max skill to current project')
|
||||
.option('-a, --ai <type>', `AI assistant type (${AI_TYPES.join(', ')})`)
|
||||
.option('-v, --version <tag>', 'Specific version to install')
|
||||
.option('-f, --force', 'Overwrite existing files')
|
||||
.action(async (options) => {
|
||||
if (options.ai && !AI_TYPES.includes(options.ai)) {
|
||||
@@ -28,7 +27,6 @@ program
|
||||
}
|
||||
await initCommand({
|
||||
ai: options.ai as AIType | undefined,
|
||||
version: options.version,
|
||||
force: options.force,
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user