fix: replace Bun-specific APIs with Node.js APIs for npm compatibility

- Replace Bun.spawn with exec from child_process in extract.ts
- Replace Bun.file().exists() with access from fs/promises
- Replace Bun.write with writeFile from fs/promises in github.ts
- Add cp and rm from fs/promises for file operations
- Bump version to 1.0.2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Viet Tran 2025-12-02 19:23:28 +07:00
parent 77d47409c4
commit f9b65919cf
4 changed files with 40 additions and 33 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "uipro-cli", "name": "uipro-cli",
"version": "1.0.0", "version": "1.0.2",
"description": "CLI to install UI/UX Pro Max skill for AI coding assistants", "description": "CLI to install UI/UX Pro Max skill for AI coding assistants",
"type": "module", "type": "module",
"bin": { "bin": {

View File

@ -12,7 +12,7 @@ const program = new Command();
program program
.name('uipro') .name('uipro')
.description('CLI to install UI/UX Pro Max skill for AI coding assistants') .description('CLI to install UI/UX Pro Max skill for AI coding assistants')
.version('1.0.0'); .version('1.0.2');
program program
.command('init') .command('init')

View File

@ -1,17 +1,26 @@
import { mkdir } from 'node:fs/promises'; import { mkdir, rm, access, cp } from 'node:fs/promises';
import { join } from 'node:path'; import { join } from 'node:path';
import { exec } from 'node:child_process';
import { promisify } from 'node:util';
import type { AIType } from '../types/index.js'; import type { AIType } from '../types/index.js';
import { AI_FOLDERS } from '../types/index.js'; import { AI_FOLDERS } from '../types/index.js';
export async function extractZip(zipPath: string, destDir: string): Promise<void> { const execAsync = promisify(exec);
const proc = Bun.spawn(['unzip', '-o', zipPath, '-d', destDir], {
stdout: 'pipe',
stderr: 'pipe',
});
const exitCode = await proc.exited; export async function extractZip(zipPath: string, destDir: string): Promise<void> {
if (exitCode !== 0) { try {
throw new Error(`Failed to extract zip: exit code ${exitCode}`); await execAsync(`unzip -o "${zipPath}" -d "${destDir}"`);
} catch (error) {
throw new Error(`Failed to extract zip: ${error}`);
}
}
async function exists(path: string): Promise<boolean> {
try {
await access(path);
return true;
} catch {
return false;
} }
} }
@ -34,29 +43,26 @@ export async function copyFolders(
const targetPath = join(targetDir, folder); const targetPath = join(targetDir, folder);
// Check if source folder exists // Check if source folder exists
const sourceExists = await Bun.file(sourcePath).exists().catch(() => false); const sourceExists = await exists(sourcePath);
if (!sourceExists) { if (!sourceExists) {
// Try checking if it's a directory
try {
const proc = Bun.spawn(['test', '-d', sourcePath]);
await proc.exited;
} catch {
continue; continue;
} }
}
// Create target directory if needed // Create target directory if needed
await mkdir(targetPath, { recursive: true }); await mkdir(targetPath, { recursive: true });
// Copy using cp -r // Copy recursively
const proc = Bun.spawn(['cp', '-r', `${sourcePath}/.`, targetPath], { try {
stdout: 'pipe', await cp(sourcePath, targetPath, { recursive: true });
stderr: 'pipe',
});
const exitCode = await proc.exited;
if (exitCode === 0) {
copiedFolders.push(folder); copiedFolders.push(folder);
} catch {
// Try shell fallback for older Node versions
try {
await execAsync(`cp -r "${sourcePath}/." "${targetPath}"`);
copiedFolders.push(folder);
} catch {
// Skip if copy fails
}
} }
} }
@ -64,9 +70,9 @@ export async function copyFolders(
} }
export async function cleanup(tempDir: string): Promise<void> { export async function cleanup(tempDir: string): Promise<void> {
const proc = Bun.spawn(['rm', '-rf', tempDir], { try {
stdout: 'pipe', await rm(tempDir, { recursive: true, force: true });
stderr: 'pipe', } catch {
}); // Ignore cleanup errors
await proc.exited; }
} }

View File

@ -1,3 +1,4 @@
import { writeFile } from 'node:fs/promises';
import type { Release } from '../types/index.js'; import type { Release } from '../types/index.js';
const REPO_OWNER = 'nextlevelbuilder'; const REPO_OWNER = 'nextlevelbuilder';
@ -50,7 +51,7 @@ export async function downloadRelease(url: string, dest: string): Promise<void>
} }
const buffer = await response.arrayBuffer(); const buffer = await response.arrayBuffer();
await Bun.write(dest, buffer); await writeFile(dest, Buffer.from(buffer));
} }
export function getAssetUrl(release: Release): string | null { export function getAssetUrl(release: Release): string | null {