mirror of
https://github.com/nextlevelbuilder/ui-ux-pro-max-skill.git
synced 2026-08-01 19:06:14 +00:00
fix(copilot): generate .prompt.md file for VS Code Copilot slash commands (#328)
* fix(copilot): generate .prompt.md file for VS Code Copilot slash commands VS Code Copilot requires reusable prompts to be files named `<name>.prompt.md` directly in `.github/prompts/`. The previous config generated `.github/prompts/ui-ux-pro-max/PROMPT.md` (a folder with PROMPT.md inside), which is not recognized as a slash command. Changes: - copilot.json: set skillPath to 'prompts', filename to 'ui-ux-pro-max.prompt.md', add dataPath for data/scripts location - copilot.json: use 'mode: agent' frontmatter (VS Code format) instead of 'name' field - template.ts: add dataPath support so data/scripts go to a separate directory from the prompt file when configured - template.ts: rewrite hardcoded script paths to platform-specific scriptPath for platforms that differ from the default - uninstall.ts: handle copilot-specific file layout during uninstall After this fix, `uipro init --ai copilot` produces: .github/prompts/ui-ux-pro-max.prompt.md (slash command file) .github/prompts/ui-ux-pro-max/data/ (search database) .github/prompts/ui-ux-pro-max/scripts/ (search engine) * fix(copilot): apply prompt-file layout fix to canonical source template Address review feedback on PR #328: - Update src/ui-ux-pro-max/templates/platforms/copilot.json (source of truth) with the same .prompt.md layout fix that was previously applied only to the packaged CLI asset copy - Sync cli/assets/templates/platforms/copilot.json byte-for-byte from the source template (also fixes stale '15 technology stacks' count; there are 16 stack CSVs) Smoke check (uipro init --ai copilot --offline): .github/prompts/ui-ux-pro-max.prompt.md (slash command, mode: agent) .github/prompts/ui-ux-pro-max/data/ (search database) .github/prompts/ui-ux-pro-max/scripts/ (search engine) uninstall --ai copilot removes both the prompt file and data directory. --------- Co-authored-by: vkayata <volkan.kayatas@mercedes-benz.com>
This commit is contained in:
parent
ec1f2a9027
commit
b0ebb1797e
@ -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, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks."
|
||||
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks.",
|
||||
"mode": "agent"
|
||||
},
|
||||
"sections": {
|
||||
"quickReference": false
|
||||
|
||||
@ -30,9 +30,18 @@ async function removeSkillDir(baseDir: string, aiType: ConcreteAIType): Promise<
|
||||
// `.github/prompts/`, kiro under `.kiro/steering/`. Also clean the legacy
|
||||
// `<folder>/skills/` layout (incl. `.shared/`) so older installs are removed.
|
||||
const parents = new Set<string>();
|
||||
// Standalone skill files to remove (platforms with a dataPath keep the
|
||||
// rendered skill file apart from the data directory — e.g. copilot's
|
||||
// `.github/prompts/ui-ux-pro-max.prompt.md`).
|
||||
const skillFiles = new Set<string>();
|
||||
try {
|
||||
const { folderStructure } = await loadPlatformConfig(aiType);
|
||||
parents.add(join(folderStructure.root, dirname(folderStructure.skillPath)));
|
||||
if (folderStructure.dataPath) {
|
||||
skillFiles.add(join(folderStructure.root, folderStructure.skillPath, folderStructure.filename));
|
||||
parents.add(join(folderStructure.root, dirname(folderStructure.dataPath)));
|
||||
} else {
|
||||
parents.add(join(folderStructure.root, dirname(folderStructure.skillPath)));
|
||||
}
|
||||
} catch {
|
||||
// No platform config — fall back to the legacy folders below.
|
||||
}
|
||||
@ -40,6 +49,18 @@ async function removeSkillDir(baseDir: string, aiType: ConcreteAIType): Promise<
|
||||
parents.add(join(folder, 'skills'));
|
||||
}
|
||||
|
||||
for (const skillFile of skillFiles) {
|
||||
const filePath = join(baseDir, skillFile);
|
||||
try {
|
||||
await stat(filePath);
|
||||
await rm(filePath, { force: true });
|
||||
removed.push(skillFile.replaceAll('\\', '/'));
|
||||
} catch (err: unknown) {
|
||||
// Skip non-existent files; re-throw permission or other errors
|
||||
if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;
|
||||
}
|
||||
}
|
||||
|
||||
for (const parent of parents) {
|
||||
for (const name of skillNames) {
|
||||
const skillDir = join(baseDir, parent, name);
|
||||
|
||||
@ -31,6 +31,7 @@ export interface PlatformConfig {
|
||||
root: string;
|
||||
skillPath: string;
|
||||
filename: string;
|
||||
dataPath?: string;
|
||||
};
|
||||
scriptPath: string;
|
||||
frontmatter: Record<string, string> | null;
|
||||
|
||||
@ -21,6 +21,7 @@ export interface PlatformConfig {
|
||||
root: string;
|
||||
skillPath: string;
|
||||
filename: string;
|
||||
dataPath?: string;
|
||||
};
|
||||
scriptPath: string;
|
||||
frontmatter: Record<string, string> | null;
|
||||
@ -151,12 +152,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}`
|
||||
);
|
||||
}
|
||||
|
||||
@ -272,17 +283,24 @@ 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);
|
||||
|
||||
// Install the sibling sub-skills (banner-design, brand, design, ...) next to
|
||||
// the orchestrator so all 7 skills are delivered. The skills parent is the
|
||||
// orchestrator's parent dir (skills/ for most platforms, prompts/ for
|
||||
// copilot, steering/ for kiro) — derived, not hardcoded.
|
||||
// copilot, steering/ for kiro) — derived, not hardcoded. For platforms with
|
||||
// a separate dataPath (copilot), the orchestrator's data dir is the anchor.
|
||||
const skillsParentDir = join(
|
||||
effectiveDir,
|
||||
config.folderStructure.root,
|
||||
dirname(config.folderStructure.skillPath)
|
||||
config.folderStructure.dataPath
|
||||
? dirname(config.folderStructure.dataPath)
|
||||
: dirname(config.folderStructure.skillPath)
|
||||
);
|
||||
await copySubSkills(skillsParentDir, force);
|
||||
|
||||
|
||||
@ -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, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks."
|
||||
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks.",
|
||||
"mode": "agent"
|
||||
},
|
||||
"sections": {
|
||||
"quickReference": false
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user