diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a6bdd0f..69e0ed1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,6 +5,10 @@ on: paths: - '.claude/skills/**' - 'cli/assets/skills/**' + - 'cli/assets/templates/**' + - 'cli/src/**' + - 'cli/tests/**' + - 'src/ui-ux-pro-max/templates/**' - '.github/workflows/tests.yml' push: branches: [main] diff --git a/cli/assets/templates/base/skill-content.md b/cli/assets/templates/base/skill-content.md index 55812a1..5c5735f 100644 --- a/cli/assets/templates/base/skill-content.md +++ b/cli/assets/templates/base/skill-content.md @@ -54,7 +54,7 @@ Extract key information from user request: **Always start with `--design-system`** to get comprehensive recommendations with reasoning: ```bash -python3 skills/ui-ux-pro-max/scripts/search.py " " --design-system [-p "Project Name"] +python3 {{SCRIPT_PATH}} " " --design-system [-p "Project Name"] ``` This command: @@ -65,7 +65,7 @@ This command: **Example:** ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "beauty spa wellness service" --design-system -p "Serenity Spa" +python3 {{SCRIPT_PATH}} "beauty spa wellness service" --design-system -p "Serenity Spa" ``` ### Step 2b: Persist Design System (Master + Overrides Pattern) @@ -73,7 +73,7 @@ python3 skills/ui-ux-pro-max/scripts/search.py "beauty spa wellness service" --d To save the design system for **hierarchical retrieval across sessions**, add `--persist`: ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "" --design-system --persist -p "Project Name" +python3 {{SCRIPT_PATH}} "" --design-system --persist -p "Project Name" ``` This creates: @@ -82,7 +82,7 @@ This creates: **With page-specific override:** ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "" --design-system --persist -p "Project Name" --page "dashboard" +python3 {{SCRIPT_PATH}} "" --design-system --persist -p "Project Name" --page "dashboard" ``` This also creates: @@ -107,7 +107,7 @@ Now, generate the code... Three optional 1-10 sliders that tune `--design-system` output without changing your query. Add any combination of them to the same command: ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "" --design-system --variance <1-10> --motion <1-10> --density <1-10> +python3 {{SCRIPT_PATH}} "" --design-system --variance <1-10> --motion <1-10> --density <1-10> ``` | Dial | Low (1-3) | Mid (4-7) | High (8-10) | @@ -122,7 +122,7 @@ python3 skills/ui-ux-pro-max/scripts/search.py "" --design-system --varia **Example:** ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "internal analytics dashboard" --design-system --variance 8 --motion 7 --density 8 -p "Ops Console" +python3 {{SCRIPT_PATH}} "internal analytics dashboard" --design-system --variance 8 --motion 7 --density 8 -p "Ops Console" ``` ### Step 3: Supplement with Detailed Searches (as needed) @@ -130,7 +130,7 @@ python3 skills/ui-ux-pro-max/scripts/search.py "internal analytics dashboard" -- After getting the design system, use domain searches to get additional details: ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "" --domain [-n ] +python3 {{SCRIPT_PATH}} "" --domain [-n ] ``` **When to use detailed searches:** @@ -155,7 +155,7 @@ python3 skills/ui-ux-pro-max/scripts/search.py "" --domain [-n Get implementation-specific best practices for the user's stack: ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "" --stack +python3 {{SCRIPT_PATH}} "" --stack ``` --- @@ -186,8 +186,8 @@ python3 skills/ui-ux-pro-max/scripts/search.py "" --stack **JavaFX enterprise examples:** ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "atlantafx primer enterprise theme" --stack javafx -python3 skills/ui-ux-pro-max/scripts/search.py "enterprise tableview density permission" --stack javafx +python3 {{SCRIPT_PATH}} "atlantafx primer enterprise theme" --stack javafx +python3 {{SCRIPT_PATH}} "enterprise tableview density permission" --stack javafx ``` --- @@ -205,7 +205,7 @@ python3 skills/ui-ux-pro-max/scripts/search.py "enterprise tableview density per ### Step 2: Generate Design System (REQUIRED) ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "AI search tool modern minimal" --design-system -p "AI Search" +python3 {{SCRIPT_PATH}} "AI search tool modern minimal" --design-system -p "AI Search" ``` **Output:** Complete design system with pattern, style, colors, typography, effects, and anti-patterns. @@ -214,16 +214,16 @@ python3 skills/ui-ux-pro-max/scripts/search.py "AI search tool modern minimal" - ```bash # Get style options for a modern tool product -python3 skills/ui-ux-pro-max/scripts/search.py "minimalism dark mode" --domain style +python3 {{SCRIPT_PATH}} "minimalism dark mode" --domain style # Get UX best practices for search interaction and loading -python3 skills/ui-ux-pro-max/scripts/search.py "search loading animation" --domain ux +python3 {{SCRIPT_PATH}} "search loading animation" --domain ux ``` ### Step 4: Stack Guidelines ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "list performance navigation" --stack react-native +python3 {{SCRIPT_PATH}} "list performance navigation" --stack react-native ``` **Then:** Synthesize design system + detailed searches and implement the design. @@ -236,10 +236,10 @@ The `--design-system` flag supports two output formats: ```bash # ASCII box (default) - best for terminal display -python3 skills/ui-ux-pro-max/scripts/search.py "fintech crypto" --design-system +python3 {{SCRIPT_PATH}} "fintech crypto" --design-system # Markdown - best for documentation -python3 skills/ui-ux-pro-max/scripts/search.py "fintech crypto" --design-system -f markdown +python3 {{SCRIPT_PATH}} "fintech crypto" --design-system -f markdown ``` --- diff --git a/cli/src/utils/template.ts b/cli/src/utils/template.ts index 67c29a2..c6de4b3 100755 --- a/cli/src/utils/template.ts +++ b/cli/src/utils/template.ts @@ -139,6 +139,13 @@ export async function renderSkillFile(config: PlatformConfig, isGlobal = false): quickReferenceContent = await loadTemplate('base/quick-reference.md'); } + // scriptPath is relative to the platform root. Generated commands run from + // the user's project root, so local installs need the platform root prefix; + // global installs need the same path anchored at the user's home directory. + const rootedScriptPath = `${config.folderStructure.root}/${config.scriptPath}` + .replace(/\/{2,}/g, '/'); + const commandScriptPath = isGlobal ? `~/${rootedScriptPath}` : rootedScriptPath; + // Build the final content const frontmatter = renderFrontmatter(config.frontmatter); @@ -149,29 +156,10 @@ export async function renderSkillFile(config: PlatformConfig, isGlobal = false): content = content .replace(/\{\{TITLE\}\}/g, config.title) .replace(/\{\{DESCRIPTION\}\}/g, config.description) - .replace(/\{\{SCRIPT_PATH\}\}/g, config.scriptPath) + .replace(/\{\{SCRIPT_PATH\}\}/g, commandScriptPath) .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( - new RegExp(`python3 ${config.scriptPath.replace(/\//g, '\\/')}`, 'g'), - `python3 ${globalPrefix}${config.scriptPath}` - ); - } - return frontmatter + content; } diff --git a/cli/tests/e2e/template-script-paths.spec.ts b/cli/tests/e2e/template-script-paths.spec.ts new file mode 100644 index 0000000..c3a5cef --- /dev/null +++ b/cli/tests/e2e/template-script-paths.spec.ts @@ -0,0 +1,32 @@ +import { expect, test } from '@playwright/test'; +import { loadPlatformConfig, renderSkillFile } from '../../src/utils/template.js'; + +const cases = [ + ['claude', '.claude/skills/ui-ux-pro-max/scripts/search.py'], + ['codex', '.agents/skills/ui-ux-pro-max/scripts/search.py'], + ['copilot', '.github/prompts/ui-ux-pro-max/scripts/search.py'], + ['kiro', '.kiro/steering/ui-ux-pro-max/scripts/search.py'], +] as const; +const SEARCH_COMMAND_COUNT = 16; + +function extractSearchScriptPaths(content: string): string[] { + return [...content.matchAll(/^python3\s+(\S*search\.py)\b/gm)].map(match => match[1]); +} + +for (const [platform, localPath] of cases) { + test(`${platform} renders project-root and global script paths`, async () => { + const config = await loadPlatformConfig(platform); + + const localContent = await renderSkillFile(config); + const localPaths = extractSearchScriptPaths(localContent); + expect(localPaths).toHaveLength(SEARCH_COMMAND_COUNT); + expect(new Set(localPaths)).toEqual(new Set([localPath])); + expect(localContent).not.toContain('{{SCRIPT_PATH}}'); + + const globalContent = await renderSkillFile(config, true); + const globalPaths = extractSearchScriptPaths(globalContent); + expect(globalPaths).toHaveLength(SEARCH_COMMAND_COUNT); + expect(new Set(globalPaths)).toEqual(new Set([`~/${localPath}`])); + expect(globalContent).not.toContain('{{SCRIPT_PATH}}'); + }); +} diff --git a/src/ui-ux-pro-max/templates/base/skill-content.md b/src/ui-ux-pro-max/templates/base/skill-content.md index 55812a1..5c5735f 100644 --- a/src/ui-ux-pro-max/templates/base/skill-content.md +++ b/src/ui-ux-pro-max/templates/base/skill-content.md @@ -54,7 +54,7 @@ Extract key information from user request: **Always start with `--design-system`** to get comprehensive recommendations with reasoning: ```bash -python3 skills/ui-ux-pro-max/scripts/search.py " " --design-system [-p "Project Name"] +python3 {{SCRIPT_PATH}} " " --design-system [-p "Project Name"] ``` This command: @@ -65,7 +65,7 @@ This command: **Example:** ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "beauty spa wellness service" --design-system -p "Serenity Spa" +python3 {{SCRIPT_PATH}} "beauty spa wellness service" --design-system -p "Serenity Spa" ``` ### Step 2b: Persist Design System (Master + Overrides Pattern) @@ -73,7 +73,7 @@ python3 skills/ui-ux-pro-max/scripts/search.py "beauty spa wellness service" --d To save the design system for **hierarchical retrieval across sessions**, add `--persist`: ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "" --design-system --persist -p "Project Name" +python3 {{SCRIPT_PATH}} "" --design-system --persist -p "Project Name" ``` This creates: @@ -82,7 +82,7 @@ This creates: **With page-specific override:** ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "" --design-system --persist -p "Project Name" --page "dashboard" +python3 {{SCRIPT_PATH}} "" --design-system --persist -p "Project Name" --page "dashboard" ``` This also creates: @@ -107,7 +107,7 @@ Now, generate the code... Three optional 1-10 sliders that tune `--design-system` output without changing your query. Add any combination of them to the same command: ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "" --design-system --variance <1-10> --motion <1-10> --density <1-10> +python3 {{SCRIPT_PATH}} "" --design-system --variance <1-10> --motion <1-10> --density <1-10> ``` | Dial | Low (1-3) | Mid (4-7) | High (8-10) | @@ -122,7 +122,7 @@ python3 skills/ui-ux-pro-max/scripts/search.py "" --design-system --varia **Example:** ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "internal analytics dashboard" --design-system --variance 8 --motion 7 --density 8 -p "Ops Console" +python3 {{SCRIPT_PATH}} "internal analytics dashboard" --design-system --variance 8 --motion 7 --density 8 -p "Ops Console" ``` ### Step 3: Supplement with Detailed Searches (as needed) @@ -130,7 +130,7 @@ python3 skills/ui-ux-pro-max/scripts/search.py "internal analytics dashboard" -- After getting the design system, use domain searches to get additional details: ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "" --domain [-n ] +python3 {{SCRIPT_PATH}} "" --domain [-n ] ``` **When to use detailed searches:** @@ -155,7 +155,7 @@ python3 skills/ui-ux-pro-max/scripts/search.py "" --domain [-n Get implementation-specific best practices for the user's stack: ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "" --stack +python3 {{SCRIPT_PATH}} "" --stack ``` --- @@ -186,8 +186,8 @@ python3 skills/ui-ux-pro-max/scripts/search.py "" --stack **JavaFX enterprise examples:** ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "atlantafx primer enterprise theme" --stack javafx -python3 skills/ui-ux-pro-max/scripts/search.py "enterprise tableview density permission" --stack javafx +python3 {{SCRIPT_PATH}} "atlantafx primer enterprise theme" --stack javafx +python3 {{SCRIPT_PATH}} "enterprise tableview density permission" --stack javafx ``` --- @@ -205,7 +205,7 @@ python3 skills/ui-ux-pro-max/scripts/search.py "enterprise tableview density per ### Step 2: Generate Design System (REQUIRED) ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "AI search tool modern minimal" --design-system -p "AI Search" +python3 {{SCRIPT_PATH}} "AI search tool modern minimal" --design-system -p "AI Search" ``` **Output:** Complete design system with pattern, style, colors, typography, effects, and anti-patterns. @@ -214,16 +214,16 @@ python3 skills/ui-ux-pro-max/scripts/search.py "AI search tool modern minimal" - ```bash # Get style options for a modern tool product -python3 skills/ui-ux-pro-max/scripts/search.py "minimalism dark mode" --domain style +python3 {{SCRIPT_PATH}} "minimalism dark mode" --domain style # Get UX best practices for search interaction and loading -python3 skills/ui-ux-pro-max/scripts/search.py "search loading animation" --domain ux +python3 {{SCRIPT_PATH}} "search loading animation" --domain ux ``` ### Step 4: Stack Guidelines ```bash -python3 skills/ui-ux-pro-max/scripts/search.py "list performance navigation" --stack react-native +python3 {{SCRIPT_PATH}} "list performance navigation" --stack react-native ``` **Then:** Synthesize design system + detailed searches and implement the design. @@ -236,10 +236,10 @@ The `--design-system` flag supports two output formats: ```bash # ASCII box (default) - best for terminal display -python3 skills/ui-ux-pro-max/scripts/search.py "fintech crypto" --design-system +python3 {{SCRIPT_PATH}} "fintech crypto" --design-system # Markdown - best for documentation -python3 skills/ui-ux-pro-max/scripts/search.py "fintech crypto" --design-system -f markdown +python3 {{SCRIPT_PATH}} "fintech crypto" --design-system -f markdown ``` ---