Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions cli/assets/templates/platforms/copilot.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
"installType": "full",
"folderStructure": {
"root": ".github",
"skillPath": "prompts/ui-ux-pro-max",
"filename": "PROMPT.md"
"skillPath": "prompts",
"filename": "ui-ux-pro-max.prompt.md",
"dataPath": "prompts/ui-ux-pro-max"
},
"scriptPath": "prompts/ui-ux-pro-max/scripts/search.py",
"frontmatter": {
"name": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 15 technology stacks."
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 15 technology stacks.",
"mode": "agent"
},
"sections": {
"quickReference": false
Expand Down
31 changes: 29 additions & 2 deletions cli/src/commands/uninstall.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { rm, stat } from 'node:fs/promises';
import { rm, stat, unlink } from 'node:fs/promises';
import { join } from 'node:path';
import { homedir } from 'node:os';
import chalk from 'chalk';
Expand All @@ -22,15 +22,41 @@ async function removeSkillDir(baseDir: string, aiType: Exclude<AIType, 'all'>):
const removed: string[] = [];

for (const folder of folders) {
// Standard path: {folder}/skills/ui-ux-pro-max
const skillDir = join(baseDir, folder, 'skills', 'ui-ux-pro-max');
try {
await stat(skillDir);
await rm(skillDir, { recursive: true, force: true });
removed.push(`${folder}/skills/ui-ux-pro-max`);
} catch (err: unknown) {
// Skip non-existent dirs; re-throw permission or other errors
if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;
}

// Copilot-specific paths
if (aiType === 'copilot') {
// Remove .github/prompts/ui-ux-pro-max.prompt.md
const promptFile = join(baseDir, folder, 'prompts', 'ui-ux-pro-max.prompt.md');
try {
await stat(promptFile);
await unlink(promptFile);
removed.push(`${folder}/prompts/ui-ux-pro-max.prompt.md`);
} catch (err: unknown) {
if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;
}

// Remove .github/prompts/ui-ux-pro-max/ (data directory)
const dataDir = join(baseDir, folder, 'prompts', 'ui-ux-pro-max');
try {
await stat(dataDir);
await rm(dataDir, { recursive: true, force: true });
removed.push(`${folder}/prompts/ui-ux-pro-max`);
} catch (err: unknown) {
if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;
}

// Legacy: remove .github/prompts/ui-ux-pro-max/PROMPT.md (old install format)
// Already covered by the dataDir removal above
}
}

return removed;
Expand Down Expand Up @@ -101,6 +127,7 @@ export async function uninstallCommand(options: UninstallOptions): Promise<void>
if (aiType === 'all') {
// Remove for all detected platforms
for (const type of initialDetected) {
if (type === 'all') continue;
const removed = await removeSkillDir(baseDir, type);
allRemoved.push(...removed);
}
Expand Down
1 change: 1 addition & 0 deletions cli/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface PlatformConfig {
root: string;
skillPath: string;
filename: string;
dataPath?: string;
};
scriptPath: string;
frontmatter: Record<string, string> | null;
Expand Down
23 changes: 19 additions & 4 deletions cli/src/utils/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface PlatformConfig {
root: string;
skillPath: string;
filename: string;
dataPath?: string;
};
scriptPath: string;
frontmatter: Record<string, string> | null;
Expand Down Expand Up @@ -144,12 +145,22 @@ export async function renderSkillFile(config: PlatformConfig, isGlobal = false):
.replace(/\{\{SKILL_OR_WORKFLOW\}\}/g, config.skillOrWorkflow)
.replace(/\{\{QUICK_REFERENCE\}\}/g, quickRefWithNewline);

// Rewrite the hardcoded default script path to the platform-specific path
const defaultScriptPath = 'skills/ui-ux-pro-max/scripts/search.py';
if (config.scriptPath !== defaultScriptPath) {
content = content.replace(
new RegExp(defaultScriptPath.replace(/\//g, '\\/'), 'g'),
config.scriptPath
);
}

// For global install, rewrite relative script paths to absolute ~/root/ paths
if (isGlobal) {
const globalPrefix = `~/${config.folderStructure.root}/`;
// Match any platform's script path pattern (skills/, prompts/, steering/, etc.)
content = content.replace(
/python3 skills\//g,
`python3 ${globalPrefix}skills/`
new RegExp(`python3 ${config.scriptPath.replace(/\//g, '\\/')}`, 'g'),
`python3 ${globalPrefix}${config.scriptPath}`
);
}

Expand Down Expand Up @@ -211,8 +222,12 @@ export async function generatePlatformFiles(
await writeFile(skillFilePath, skillContent, 'utf-8');
createdFolders.push(config.folderStructure.root);

// Copy data and scripts into the skill directory (self-contained)
await copyDataAndScripts(skillDir);
// Copy data and scripts into the data directory (may differ from skill file location)
const dataDir = config.folderStructure.dataPath
? join(effectiveDir, config.folderStructure.root, config.folderStructure.dataPath)
: skillDir;
await mkdir(dataDir, { recursive: true });
await copyDataAndScripts(dataDir);

return createdFolders;
}
Expand Down