ui-pro-forge-cli 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -0
- package/assets/data/app-interface.csv +31 -0
- package/assets/data/charts.csv +26 -0
- package/assets/data/colors.csv +194 -0
- package/assets/data/google-fonts.csv +1924 -0
- package/assets/data/icons.csv +106 -0
- package/assets/data/landing.csv +35 -0
- package/assets/data/motion.csv +17 -0
- package/assets/data/products.csv +193 -0
- package/assets/data/react-performance.csv +45 -0
- package/assets/data/stacks/angular.csv +51 -0
- package/assets/data/stacks/astro.csv +54 -0
- package/assets/data/stacks/avalonia.csv +57 -0
- package/assets/data/stacks/flutter.csv +53 -0
- package/assets/data/stacks/html-tailwind.csv +56 -0
- package/assets/data/stacks/javafx.csv +76 -0
- package/assets/data/stacks/jetpack-compose.csv +53 -0
- package/assets/data/stacks/laravel.csv +51 -0
- package/assets/data/stacks/nextjs.csv +53 -0
- package/assets/data/stacks/nuxt-ui.csv +71 -0
- package/assets/data/stacks/nuxtjs.csv +59 -0
- package/assets/data/stacks/react-native.csv +52 -0
- package/assets/data/stacks/react.csv +54 -0
- package/assets/data/stacks/shadcn.csv +61 -0
- package/assets/data/stacks/solidjs.csv +21 -0
- package/assets/data/stacks/svelte.csv +54 -0
- package/assets/data/stacks/swiftui.csv +51 -0
- package/assets/data/stacks/threejs.csv +54 -0
- package/assets/data/stacks/uno.csv +60 -0
- package/assets/data/stacks/vue.csv +50 -0
- package/assets/data/stacks/winui.csv +60 -0
- package/assets/data/styles.csv +86 -0
- package/assets/data/typography.csv +75 -0
- package/assets/data/ui-reasoning.csv +162 -0
- package/assets/data/ux-guidelines.csv +100 -0
- package/assets/scripts/core.py +463 -0
- package/assets/scripts/design_system.py +1371 -0
- package/assets/scripts/search.py +162 -0
- package/assets/scripts/tests/test_core.py +134 -0
- package/assets/scripts/validate_data.py +114 -0
- package/assets/skills/banner-design/SKILL.md +196 -0
- package/assets/skills/banner-design/references/banner-sizes-and-styles.md +118 -0
- package/assets/skills/brand/SKILL.md +97 -0
- package/assets/skills/brand/references/approval-checklist.md +169 -0
- package/assets/skills/brand/references/asset-organization.md +157 -0
- package/assets/skills/brand/references/brand-guideline-template.md +140 -0
- package/assets/skills/brand/references/color-palette-management.md +186 -0
- package/assets/skills/brand/references/consistency-checklist.md +94 -0
- package/assets/skills/brand/references/logo-usage-rules.md +185 -0
- package/assets/skills/brand/references/messaging-framework.md +85 -0
- package/assets/skills/brand/references/typography-specifications.md +214 -0
- package/assets/skills/brand/references/update.md +118 -0
- package/assets/skills/brand/references/visual-identity.md +96 -0
- package/assets/skills/brand/references/voice-framework.md +88 -0
- package/assets/skills/brand/scripts/extract-colors.cjs +341 -0
- package/assets/skills/brand/scripts/inject-brand-context.cjs +349 -0
- package/assets/skills/brand/scripts/sync-brand-to-tokens.cjs +248 -0
- package/assets/skills/brand/scripts/tests/test_sync_brand_to_tokens.py +52 -0
- package/assets/skills/brand/scripts/validate-asset.cjs +387 -0
- package/assets/skills/brand/templates/brand-guidelines-starter.md +275 -0
- package/assets/skills/design/SKILL.md +313 -0
- package/assets/skills/design/data/cip/deliverables.csv +51 -0
- package/assets/skills/design/data/cip/industries.csv +21 -0
- package/assets/skills/design/data/cip/mockup-contexts.csv +21 -0
- package/assets/skills/design/data/cip/styles.csv +21 -0
- package/assets/skills/design/data/icon/styles.csv +16 -0
- package/assets/skills/design/data/logo/colors.csv +56 -0
- package/assets/skills/design/data/logo/industries.csv +56 -0
- package/assets/skills/design/data/logo/styles.csv +56 -0
- package/assets/skills/design/references/banner-sizes-and-styles.md +118 -0
- package/assets/skills/design/references/cip-deliverable-guide.md +95 -0
- package/assets/skills/design/references/cip-design.md +121 -0
- package/assets/skills/design/references/cip-prompt-engineering.md +84 -0
- package/assets/skills/design/references/cip-style-guide.md +68 -0
- package/assets/skills/design/references/design-routing.md +207 -0
- package/assets/skills/design/references/icon-design.md +122 -0
- package/assets/skills/design/references/logo-color-psychology.md +101 -0
- package/assets/skills/design/references/logo-design.md +92 -0
- package/assets/skills/design/references/logo-prompt-engineering.md +158 -0
- package/assets/skills/design/references/logo-style-guide.md +109 -0
- package/assets/skills/design/references/slides-copywriting-formulas.md +84 -0
- package/assets/skills/design/references/slides-create.md +4 -0
- package/assets/skills/design/references/slides-html-template.md +295 -0
- package/assets/skills/design/references/slides-layout-patterns.md +137 -0
- package/assets/skills/design/references/slides-strategies.md +94 -0
- package/assets/skills/design/references/slides.md +42 -0
- package/assets/skills/design/references/social-photos-design.md +329 -0
- package/assets/skills/design/scripts/cip/core.py +215 -0
- package/assets/skills/design/scripts/cip/generate.py +484 -0
- package/assets/skills/design/scripts/cip/render-html.py +424 -0
- package/assets/skills/design/scripts/cip/search.py +127 -0
- package/assets/skills/design/scripts/icon/generate.py +487 -0
- package/assets/skills/design/scripts/logo/core.py +175 -0
- package/assets/skills/design/scripts/logo/generate.py +362 -0
- package/assets/skills/design/scripts/logo/search.py +114 -0
- package/assets/skills/design-system/SKILL.md +244 -0
- package/assets/skills/design-system/data/slide-backgrounds.csv +11 -0
- package/assets/skills/design-system/data/slide-charts.csv +26 -0
- package/assets/skills/design-system/data/slide-color-logic.csv +14 -0
- package/assets/skills/design-system/data/slide-copy.csv +26 -0
- package/assets/skills/design-system/data/slide-layout-logic.csv +16 -0
- package/assets/skills/design-system/data/slide-layouts.csv +26 -0
- package/assets/skills/design-system/data/slide-strategies.csv +16 -0
- package/assets/skills/design-system/data/slide-typography.csv +15 -0
- package/assets/skills/design-system/references/component-specs.md +236 -0
- package/assets/skills/design-system/references/component-tokens.md +214 -0
- package/assets/skills/design-system/references/primitive-tokens.md +203 -0
- package/assets/skills/design-system/references/semantic-tokens.md +215 -0
- package/assets/skills/design-system/references/states-and-variants.md +241 -0
- package/assets/skills/design-system/references/tailwind-integration.md +251 -0
- package/assets/skills/design-system/references/token-architecture.md +224 -0
- package/assets/skills/design-system/scripts/embed-tokens.cjs +99 -0
- package/assets/skills/design-system/scripts/fetch-background.py +317 -0
- package/assets/skills/design-system/scripts/generate-slide.py +770 -0
- package/assets/skills/design-system/scripts/generate-tokens.cjs +205 -0
- package/assets/skills/design-system/scripts/html-token-validator.py +327 -0
- package/assets/skills/design-system/scripts/search-slides.py +218 -0
- package/assets/skills/design-system/scripts/slide-token-validator.py +35 -0
- package/assets/skills/design-system/scripts/slide_search_core.py +453 -0
- package/assets/skills/design-system/scripts/tests/test_validate_tokens.py +48 -0
- package/assets/skills/design-system/scripts/validate-tokens.cjs +246 -0
- package/assets/skills/design-system/templates/design-tokens-starter.json +143 -0
- package/assets/skills/slides/SKILL.md +40 -0
- package/assets/skills/slides/references/copywriting-formulas.md +84 -0
- package/assets/skills/slides/references/create.md +4 -0
- package/assets/skills/slides/references/html-template.md +295 -0
- package/assets/skills/slides/references/layout-patterns.md +137 -0
- package/assets/skills/slides/references/slide-strategies.md +94 -0
- package/assets/skills/ui-styling/LICENSE.txt +202 -0
- package/assets/skills/ui-styling/SKILL.md +324 -0
- package/assets/skills/ui-styling/references/canvas-design-system.md +320 -0
- package/assets/skills/ui-styling/references/shadcn-accessibility.md +471 -0
- package/assets/skills/ui-styling/references/shadcn-components.md +424 -0
- package/assets/skills/ui-styling/references/shadcn-theming.md +373 -0
- package/assets/skills/ui-styling/references/tailwind-customization.md +483 -0
- package/assets/skills/ui-styling/references/tailwind-responsive.md +382 -0
- package/assets/skills/ui-styling/references/tailwind-utilities.md +455 -0
- package/assets/skills/ui-styling/scripts/requirements.txt +17 -0
- package/assets/skills/ui-styling/scripts/shadcn_add.py +308 -0
- package/assets/skills/ui-styling/scripts/tailwind_config_gen.py +473 -0
- package/assets/skills/ui-styling/scripts/tests/coverage-ui.json +1 -0
- package/assets/skills/ui-styling/scripts/tests/requirements.txt +3 -0
- package/assets/skills/ui-styling/scripts/tests/test_shadcn_add.py +266 -0
- package/assets/skills/ui-styling/scripts/tests/test_tailwind_config_gen.py +394 -0
- package/assets/templates/base/quick-reference.md +297 -0
- package/assets/templates/base/skill-content.md +384 -0
- package/assets/templates/platforms/agent.json +21 -0
- package/assets/templates/platforms/augment.json +18 -0
- package/assets/templates/platforms/claude.json +21 -0
- package/assets/templates/platforms/codebuddy.json +21 -0
- package/assets/templates/platforms/codewhale.json +21 -0
- package/assets/templates/platforms/codex.json +21 -0
- package/assets/templates/platforms/continue.json +21 -0
- package/assets/templates/platforms/copilot.json +21 -0
- package/assets/templates/platforms/cursor.json +21 -0
- package/assets/templates/platforms/droid.json +21 -0
- package/assets/templates/platforms/gemini.json +21 -0
- package/assets/templates/platforms/kilocode.json +21 -0
- package/assets/templates/platforms/kiro.json +21 -0
- package/assets/templates/platforms/opencode.json +21 -0
- package/assets/templates/platforms/qoder.json +21 -0
- package/assets/templates/platforms/roocode.json +21 -0
- package/assets/templates/platforms/trae.json +21 -0
- package/assets/templates/platforms/warp.json +18 -0
- package/assets/templates/platforms/windsurf.json +21 -0
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.js +165 -0
- package/dist/commands/uninstall.d.ts +7 -0
- package/dist/commands/uninstall.js +131 -0
- package/dist/commands/update.d.ts +7 -0
- package/dist/commands/update.js +73 -0
- package/dist/commands/versions.d.ts +5 -0
- package/dist/commands/versions.js +36 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +78 -0
- package/dist/types/index.d.ts +40 -0
- package/dist/types/index.js +25 -0
- package/dist/utils/detect.d.ts +8 -0
- package/dist/utils/detect.js +115 -0
- package/dist/utils/extract.d.ts +15 -0
- package/dist/utils/extract.js +125 -0
- package/dist/utils/github.d.ts +12 -0
- package/dist/utils/github.js +97 -0
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.js +9 -0
- package/dist/utils/template.d.ts +50 -0
- package/dist/utils/template.js +249 -0
- package/package.json +65 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "kiro",
|
|
3
|
+
"displayName": "Kiro",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".kiro",
|
|
7
|
+
"skillPath": "steering/ui-pro-forge",
|
|
8
|
+
"filename": "SKILL.md"
|
|
9
|
+
},
|
|
10
|
+
"scriptPath": "steering/ui-pro-forge/scripts/search.py",
|
|
11
|
+
"frontmatter": {
|
|
12
|
+
"name": "ui-pro-forge",
|
|
13
|
+
"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."
|
|
14
|
+
},
|
|
15
|
+
"sections": {
|
|
16
|
+
"quickReference": false
|
|
17
|
+
},
|
|
18
|
+
"title": "ui-pro-forge",
|
|
19
|
+
"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. Searchable database with priority-based recommendations.",
|
|
20
|
+
"skillOrWorkflow": "Workflow"
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "opencode",
|
|
3
|
+
"displayName": "OpenCode",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".opencode",
|
|
7
|
+
"skillPath": "skills/ui-pro-forge",
|
|
8
|
+
"filename": "SKILL.md"
|
|
9
|
+
},
|
|
10
|
+
"scriptPath": "skills/ui-pro-forge/scripts/search.py",
|
|
11
|
+
"frontmatter": {
|
|
12
|
+
"name": "ui-pro-forge",
|
|
13
|
+
"description": "UI/UX design intelligence with searchable database"
|
|
14
|
+
},
|
|
15
|
+
"sections": {
|
|
16
|
+
"quickReference": false
|
|
17
|
+
},
|
|
18
|
+
"title": "ui-pro-forge",
|
|
19
|
+
"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. Searchable database with priority-based recommendations.",
|
|
20
|
+
"skillOrWorkflow": "Skill"
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "qoder",
|
|
3
|
+
"displayName": "Qoder",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".qoder",
|
|
7
|
+
"skillPath": "skills/ui-pro-forge",
|
|
8
|
+
"filename": "SKILL.md"
|
|
9
|
+
},
|
|
10
|
+
"scriptPath": "skills/ui-pro-forge/scripts/search.py",
|
|
11
|
+
"frontmatter": {
|
|
12
|
+
"name": "ui-pro-forge",
|
|
13
|
+
"description": "UI/UX design intelligence with searchable database"
|
|
14
|
+
},
|
|
15
|
+
"sections": {
|
|
16
|
+
"quickReference": false
|
|
17
|
+
},
|
|
18
|
+
"title": "ui-pro-forge",
|
|
19
|
+
"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. Searchable database with priority-based recommendations.",
|
|
20
|
+
"skillOrWorkflow": "Skill"
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "roocode",
|
|
3
|
+
"displayName": "Roo Code",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".roo",
|
|
7
|
+
"skillPath": "skills/ui-pro-forge",
|
|
8
|
+
"filename": "SKILL.md"
|
|
9
|
+
},
|
|
10
|
+
"scriptPath": "skills/ui-pro-forge/scripts/search.py",
|
|
11
|
+
"frontmatter": {
|
|
12
|
+
"name": "ui-pro-forge",
|
|
13
|
+
"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."
|
|
14
|
+
},
|
|
15
|
+
"sections": {
|
|
16
|
+
"quickReference": false
|
|
17
|
+
},
|
|
18
|
+
"title": "ui-pro-forge",
|
|
19
|
+
"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. Searchable database with priority-based recommendations.",
|
|
20
|
+
"skillOrWorkflow": "Workflow"
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "trae",
|
|
3
|
+
"displayName": "Trae",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".trae",
|
|
7
|
+
"skillPath": "skills/ui-pro-forge",
|
|
8
|
+
"filename": "SKILL.md"
|
|
9
|
+
},
|
|
10
|
+
"scriptPath": "skills/ui-pro-forge/scripts/search.py",
|
|
11
|
+
"frontmatter": {
|
|
12
|
+
"name": "ui-pro-forge",
|
|
13
|
+
"description": "UI/UX design intelligence with searchable database"
|
|
14
|
+
},
|
|
15
|
+
"sections": {
|
|
16
|
+
"quickReference": false
|
|
17
|
+
},
|
|
18
|
+
"title": "ui-pro-forge",
|
|
19
|
+
"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. Searchable database with priority-based recommendations.",
|
|
20
|
+
"skillOrWorkflow": "Skill"
|
|
21
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "warp",
|
|
3
|
+
"displayName": "Warp",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".warp",
|
|
7
|
+
"skillPath": "skills/ui-pro-forge",
|
|
8
|
+
"filename": "SKILL.md"
|
|
9
|
+
},
|
|
10
|
+
"scriptPath": "skills/ui-pro-forge/scripts/search.py",
|
|
11
|
+
"frontmatter": null,
|
|
12
|
+
"sections": {
|
|
13
|
+
"quickReference": false
|
|
14
|
+
},
|
|
15
|
+
"title": "ui-pro-forge",
|
|
16
|
+
"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. Searchable database with priority-based recommendations.",
|
|
17
|
+
"skillOrWorkflow": "Skill"
|
|
18
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "windsurf",
|
|
3
|
+
"displayName": "Windsurf",
|
|
4
|
+
"installType": "full",
|
|
5
|
+
"folderStructure": {
|
|
6
|
+
"root": ".windsurf",
|
|
7
|
+
"skillPath": "skills/ui-pro-forge",
|
|
8
|
+
"filename": "SKILL.md"
|
|
9
|
+
},
|
|
10
|
+
"scriptPath": "skills/ui-pro-forge/scripts/search.py",
|
|
11
|
+
"frontmatter": {
|
|
12
|
+
"name": "ui-pro-forge",
|
|
13
|
+
"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."
|
|
14
|
+
},
|
|
15
|
+
"sections": {
|
|
16
|
+
"quickReference": false
|
|
17
|
+
},
|
|
18
|
+
"title": "ui-pro-forge",
|
|
19
|
+
"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. Searchable database with priority-based recommendations.",
|
|
20
|
+
"skillOrWorkflow": "Skill"
|
|
21
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AIType } from '../types/index.js';
|
|
2
|
+
interface InitOptions {
|
|
3
|
+
ai?: AIType;
|
|
4
|
+
force?: boolean;
|
|
5
|
+
offline?: boolean;
|
|
6
|
+
legacy?: boolean;
|
|
7
|
+
global?: boolean;
|
|
8
|
+
token?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function initCommand(options: InitOptions): Promise<void>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import prompts from 'prompts';
|
|
7
|
+
import { AI_TYPES } from '../types/index.js';
|
|
8
|
+
import { copyFolders, installFromZip, createTempDir, cleanup } from '../utils/extract.js';
|
|
9
|
+
import { generatePlatformFiles, generateAllPlatformFiles } from '../utils/template.js';
|
|
10
|
+
import { detectAIType, getAITypeDescription } from '../utils/detect.js';
|
|
11
|
+
import { logger } from '../utils/logger.js';
|
|
12
|
+
import { getLatestRelease, getAssetUrl, downloadRelease, getGitHubTokenGuidance, GitHubRateLimitError, GitHubDownloadError, } from '../utils/github.js';
|
|
13
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const ASSETS_CANDIDATES = [
|
|
15
|
+
// Bun bundle: dist/index.js
|
|
16
|
+
join(__dirname, '..', 'assets'),
|
|
17
|
+
// TypeScript fallback: dist/commands/init.js
|
|
18
|
+
join(__dirname, '..', '..', 'assets'),
|
|
19
|
+
];
|
|
20
|
+
const ASSETS_DIR = ASSETS_CANDIDATES.find(path => existsSync(path)) ?? ASSETS_CANDIDATES[0];
|
|
21
|
+
/**
|
|
22
|
+
* Try to install from GitHub release (legacy method)
|
|
23
|
+
* Returns the copied folders if successful, null if failed
|
|
24
|
+
*/
|
|
25
|
+
async function tryGitHubInstall(targetDir, aiType, spinner, token) {
|
|
26
|
+
let tempDir = null;
|
|
27
|
+
try {
|
|
28
|
+
spinner.text = 'Fetching latest release from GitHub...';
|
|
29
|
+
const release = await getLatestRelease(token);
|
|
30
|
+
const assetUrl = getAssetUrl(release);
|
|
31
|
+
if (!assetUrl) {
|
|
32
|
+
throw new GitHubDownloadError('No ZIP asset found in latest release');
|
|
33
|
+
}
|
|
34
|
+
spinner.text = `Downloading ${release.tag_name}...`;
|
|
35
|
+
tempDir = await createTempDir();
|
|
36
|
+
const zipPath = join(tempDir, 'release.zip');
|
|
37
|
+
await downloadRelease(assetUrl, zipPath, token);
|
|
38
|
+
spinner.text = 'Extracting and installing files...';
|
|
39
|
+
const { copiedFolders, tempDir: extractedTempDir } = await installFromZip(zipPath, targetDir, aiType);
|
|
40
|
+
// Cleanup temp directory
|
|
41
|
+
await cleanup(extractedTempDir);
|
|
42
|
+
return copiedFolders;
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
// Cleanup temp directory on error
|
|
46
|
+
if (tempDir) {
|
|
47
|
+
await cleanup(tempDir);
|
|
48
|
+
}
|
|
49
|
+
if (error instanceof GitHubRateLimitError) {
|
|
50
|
+
spinner.warn(`GitHub rate limit reached, falling back to bundled assets.\n${getGitHubTokenGuidance()}`);
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
if (error instanceof GitHubDownloadError) {
|
|
54
|
+
spinner.warn('GitHub download failed, using template generation...');
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
// Network errors or other fetch failures
|
|
58
|
+
if (error instanceof TypeError && error.message.includes('fetch')) {
|
|
59
|
+
spinner.warn('Network error, using template generation...');
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
// Unknown errors - still fall back
|
|
63
|
+
spinner.warn('Download failed, using template generation...');
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Install using template generation (new method)
|
|
69
|
+
*/
|
|
70
|
+
async function templateInstall(targetDir, aiType, spinner, isGlobal = false, force = false) {
|
|
71
|
+
spinner.text = isGlobal
|
|
72
|
+
? 'Generating skill files globally...'
|
|
73
|
+
: 'Generating skill files from templates...';
|
|
74
|
+
if (aiType === 'all') {
|
|
75
|
+
return generateAllPlatformFiles(targetDir, isGlobal, force);
|
|
76
|
+
}
|
|
77
|
+
return generatePlatformFiles(targetDir, aiType, isGlobal, force);
|
|
78
|
+
}
|
|
79
|
+
export async function initCommand(options) {
|
|
80
|
+
logger.title('UI Pro Forge Installer');
|
|
81
|
+
let aiType = options.ai;
|
|
82
|
+
// Auto-detect or prompt for AI type
|
|
83
|
+
if (!aiType) {
|
|
84
|
+
const { detected, suggested } = detectAIType();
|
|
85
|
+
if (detected.length > 0) {
|
|
86
|
+
logger.info(`Detected: ${detected.map(t => chalk.cyan(t)).join(', ')}`);
|
|
87
|
+
}
|
|
88
|
+
const response = await prompts({
|
|
89
|
+
type: 'select',
|
|
90
|
+
name: 'aiType',
|
|
91
|
+
message: 'Select AI assistant to install for:',
|
|
92
|
+
choices: AI_TYPES.map(type => ({
|
|
93
|
+
title: getAITypeDescription(type),
|
|
94
|
+
value: type,
|
|
95
|
+
})),
|
|
96
|
+
initial: suggested ? AI_TYPES.indexOf(suggested) : 0,
|
|
97
|
+
});
|
|
98
|
+
if (!response.aiType) {
|
|
99
|
+
logger.warn('Installation cancelled');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
aiType = response.aiType;
|
|
103
|
+
}
|
|
104
|
+
const isGlobal = !!options.global;
|
|
105
|
+
const modeLabel = isGlobal ? ' (global)' : '';
|
|
106
|
+
logger.info(`Installing for: ${chalk.cyan(getAITypeDescription(aiType))}${modeLabel}`);
|
|
107
|
+
const spinner = ora('Installing files...').start();
|
|
108
|
+
const cwd = process.cwd();
|
|
109
|
+
let copiedFolders = [];
|
|
110
|
+
let installMethod = 'template';
|
|
111
|
+
try {
|
|
112
|
+
// Use legacy ZIP-based install if --legacy flag is set
|
|
113
|
+
if (options.legacy) {
|
|
114
|
+
if (isGlobal) {
|
|
115
|
+
spinner.warn('--global is not supported with --legacy mode, installing locally instead');
|
|
116
|
+
}
|
|
117
|
+
// Try GitHub download first (unless offline mode)
|
|
118
|
+
if (!options.offline) {
|
|
119
|
+
const githubResult = await tryGitHubInstall(cwd, aiType, spinner, options.token);
|
|
120
|
+
if (githubResult) {
|
|
121
|
+
copiedFolders = githubResult;
|
|
122
|
+
installMethod = 'github';
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Fall back to bundled assets if GitHub failed or offline mode
|
|
126
|
+
if (installMethod !== 'github') {
|
|
127
|
+
spinner.text = 'Installing from bundled assets...';
|
|
128
|
+
copiedFolders = await copyFolders(ASSETS_DIR, cwd, aiType);
|
|
129
|
+
installMethod = 'bundled';
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
// Use new template-based generation (default)
|
|
134
|
+
copiedFolders = await templateInstall(cwd, aiType, spinner, isGlobal, options.force);
|
|
135
|
+
installMethod = 'template';
|
|
136
|
+
}
|
|
137
|
+
const methodMessage = {
|
|
138
|
+
github: 'Installed from GitHub release!',
|
|
139
|
+
bundled: 'Installed from bundled assets!',
|
|
140
|
+
template: 'Generated from templates!',
|
|
141
|
+
}[installMethod];
|
|
142
|
+
spinner.succeed(methodMessage);
|
|
143
|
+
// Summary
|
|
144
|
+
console.log();
|
|
145
|
+
logger.info('Installed folders:');
|
|
146
|
+
copiedFolders.forEach(folder => {
|
|
147
|
+
console.log(` ${chalk.green('+')} ${folder}`);
|
|
148
|
+
});
|
|
149
|
+
console.log();
|
|
150
|
+
logger.success('UI Pro Forge installed successfully!');
|
|
151
|
+
// Next steps
|
|
152
|
+
console.log();
|
|
153
|
+
console.log(chalk.bold('Next steps:'));
|
|
154
|
+
console.log(chalk.dim(' 1. Restart your AI coding assistant'));
|
|
155
|
+
console.log(chalk.dim(' 2. Try: "Build a landing page for a SaaS product"'));
|
|
156
|
+
console.log();
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
spinner.fail('Installation failed');
|
|
160
|
+
if (error instanceof Error) {
|
|
161
|
+
logger.error(error.message);
|
|
162
|
+
}
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { rm, stat } from 'node:fs/promises';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import prompts from 'prompts';
|
|
7
|
+
import { AI_FOLDERS } from '../types/index.js';
|
|
8
|
+
import { detectAIType, getAITypeDescription } from '../utils/detect.js';
|
|
9
|
+
import { listBundledSubSkills, loadPlatformConfig } from '../utils/template.js';
|
|
10
|
+
import { logger } from '../utils/logger.js';
|
|
11
|
+
/**
|
|
12
|
+
* Remove skill directory for a given AI type
|
|
13
|
+
*/
|
|
14
|
+
async function removeSkillDir(baseDir, aiType) {
|
|
15
|
+
const removed = [];
|
|
16
|
+
// The orchestrator plus the bundled sibling sub-skills installed by init.
|
|
17
|
+
const skillNames = ['ui-pro-forge', ...(await listBundledSubSkills())];
|
|
18
|
+
// Parent directories to clean. Derive the real install location from the
|
|
19
|
+
// platform config's skillPath (same source the installer uses), so
|
|
20
|
+
// non-`skills/` platforms are handled — copilot installs under
|
|
21
|
+
// `.github/prompts/`, kiro under `.kiro/steering/`. Also clean the legacy
|
|
22
|
+
// `<folder>/skills/` layout (incl. `.shared/`) so older installs are removed.
|
|
23
|
+
const parents = new Set();
|
|
24
|
+
try {
|
|
25
|
+
const { folderStructure } = await loadPlatformConfig(aiType);
|
|
26
|
+
parents.add(join(folderStructure.root, dirname(folderStructure.skillPath)));
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// No platform config — fall back to the legacy folders below.
|
|
30
|
+
}
|
|
31
|
+
for (const folder of AI_FOLDERS[aiType]) {
|
|
32
|
+
parents.add(join(folder, 'skills'));
|
|
33
|
+
}
|
|
34
|
+
for (const parent of parents) {
|
|
35
|
+
for (const name of skillNames) {
|
|
36
|
+
const skillDir = join(baseDir, parent, name);
|
|
37
|
+
try {
|
|
38
|
+
await stat(skillDir);
|
|
39
|
+
await rm(skillDir, { recursive: true, force: true });
|
|
40
|
+
removed.push(`${parent.replaceAll('\\', '/')}/${name}`);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
// Skip non-existent dirs; re-throw permission or other errors
|
|
44
|
+
if (err.code !== 'ENOENT')
|
|
45
|
+
throw err;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return removed;
|
|
50
|
+
}
|
|
51
|
+
export async function uninstallCommand(options) {
|
|
52
|
+
logger.title('UI Pro Forge Uninstaller');
|
|
53
|
+
const isGlobal = !!options.global;
|
|
54
|
+
const baseDir = isGlobal ? homedir() : process.cwd();
|
|
55
|
+
const locationLabel = isGlobal ? '~/ (global)' : process.cwd();
|
|
56
|
+
let aiType = options.ai;
|
|
57
|
+
const { detected: initialDetected } = detectAIType(baseDir);
|
|
58
|
+
// Auto-detect or prompt for AI type
|
|
59
|
+
if (!aiType) {
|
|
60
|
+
const detected = initialDetected;
|
|
61
|
+
if (detected.length === 0) {
|
|
62
|
+
logger.warn('No installed AI skill directories detected.');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
logger.info(`Detected installations: ${detected.map(t => chalk.cyan(t)).join(', ')}`);
|
|
66
|
+
const choices = [
|
|
67
|
+
...detected.map(type => ({
|
|
68
|
+
title: getAITypeDescription(type),
|
|
69
|
+
value: type,
|
|
70
|
+
})),
|
|
71
|
+
{ title: 'All detected', value: 'all' },
|
|
72
|
+
];
|
|
73
|
+
const response = await prompts({
|
|
74
|
+
type: 'select',
|
|
75
|
+
name: 'aiType',
|
|
76
|
+
message: 'Select which AI skill to uninstall:',
|
|
77
|
+
choices,
|
|
78
|
+
});
|
|
79
|
+
if (!response.aiType) {
|
|
80
|
+
logger.warn('Uninstall cancelled');
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
aiType = response.aiType;
|
|
84
|
+
}
|
|
85
|
+
// Confirm before removing
|
|
86
|
+
const { confirmed } = await prompts({
|
|
87
|
+
type: 'confirm',
|
|
88
|
+
name: 'confirmed',
|
|
89
|
+
message: `Remove UI Pro Forge skill for ${chalk.cyan(getAITypeDescription(aiType))} from ${locationLabel}?`,
|
|
90
|
+
initial: false,
|
|
91
|
+
});
|
|
92
|
+
if (!confirmed) {
|
|
93
|
+
logger.warn('Uninstall cancelled');
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const spinner = ora('Removing skill files...').start();
|
|
97
|
+
try {
|
|
98
|
+
const allRemoved = [];
|
|
99
|
+
if (aiType === 'all') {
|
|
100
|
+
// Remove for all detected platforms
|
|
101
|
+
for (const type of initialDetected) {
|
|
102
|
+
const removed = await removeSkillDir(baseDir, type);
|
|
103
|
+
allRemoved.push(...removed);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
const removed = await removeSkillDir(baseDir, aiType);
|
|
108
|
+
allRemoved.push(...removed);
|
|
109
|
+
}
|
|
110
|
+
if (allRemoved.length === 0) {
|
|
111
|
+
spinner.warn('No skill files found to remove');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
spinner.succeed('Skill files removed!');
|
|
115
|
+
console.log();
|
|
116
|
+
logger.info('Removed:');
|
|
117
|
+
allRemoved.forEach(folder => {
|
|
118
|
+
console.log(` ${chalk.red('-')} ${folder}`);
|
|
119
|
+
});
|
|
120
|
+
console.log();
|
|
121
|
+
logger.success('UI Pro Forge uninstalled successfully!');
|
|
122
|
+
console.log();
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
spinner.fail('Uninstall failed');
|
|
126
|
+
if (error instanceof Error) {
|
|
127
|
+
logger.error(error.message);
|
|
128
|
+
}
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import ora from 'ora';
|
|
7
|
+
import { getLatestRelease } from '../utils/github.js';
|
|
8
|
+
import { logger } from '../utils/logger.js';
|
|
9
|
+
import { initCommand } from './init.js';
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const CLI_PACKAGE_NAME = 'ui-pro-forge-cli';
|
|
12
|
+
async function getPackageVersion() {
|
|
13
|
+
const packagePath = join(__dirname, '..', 'package.json');
|
|
14
|
+
const pkg = JSON.parse(await readFile(packagePath, 'utf-8'));
|
|
15
|
+
return pkg.version;
|
|
16
|
+
}
|
|
17
|
+
function normalizeTagVersion(tagName) {
|
|
18
|
+
return tagName.replace(/^v/i, '');
|
|
19
|
+
}
|
|
20
|
+
export async function updateCommand(options) {
|
|
21
|
+
logger.title('UI Pro Forge Updater');
|
|
22
|
+
const spinner = ora('Checking for updates...').start();
|
|
23
|
+
try {
|
|
24
|
+
const release = await getLatestRelease(options.token);
|
|
25
|
+
const currentVersion = await getPackageVersion();
|
|
26
|
+
const latestVersion = normalizeTagVersion(release.tag_name);
|
|
27
|
+
spinner.succeed(`Latest version: ${chalk.cyan(release.tag_name)}`);
|
|
28
|
+
if (currentVersion !== latestVersion) {
|
|
29
|
+
console.log();
|
|
30
|
+
// Only auto-run with a well-formed semver, so nothing unexpected can
|
|
31
|
+
// reach the shell that npm.cmd requires on Windows.
|
|
32
|
+
if (!/^\d+\.\d+\.\d+([.-][0-9A-Za-z.-]+)?$/.test(latestVersion)) {
|
|
33
|
+
logger.warn(`Installed CLI is ${chalk.cyan(currentVersion)}; latest release is ${chalk.cyan(release.tag_name)}.`);
|
|
34
|
+
logger.info(`Update the CLI package: ${chalk.cyan(`npm install -g ${CLI_PACKAGE_NAME}@${latestVersion}`)}`);
|
|
35
|
+
logger.info('Then rerun: uipro init --ai <platform> --force');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
logger.info(`Updating CLI from ${chalk.cyan(currentVersion)} to ${chalk.cyan(latestVersion)}...`);
|
|
39
|
+
console.log();
|
|
40
|
+
const isWindows = process.platform === 'win32';
|
|
41
|
+
try {
|
|
42
|
+
// execFileSync with an explicit args array — no shell string to expand.
|
|
43
|
+
// On Windows npm is npm.cmd, which Node only spawns via a shell.
|
|
44
|
+
execFileSync(isWindows ? 'npm.cmd' : 'npm', ['install', '-g', `${CLI_PACKAGE_NAME}@${latestVersion}`], { stdio: 'inherit', shell: isWindows });
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
console.log();
|
|
48
|
+
logger.error('Automatic update failed (you may need elevated/admin permissions).');
|
|
49
|
+
logger.info(`Update manually: ${chalk.cyan(`npm install -g ${CLI_PACKAGE_NAME}@${latestVersion}`)}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
console.log();
|
|
53
|
+
logger.success(`Updated to ${chalk.cyan(latestVersion)}.`);
|
|
54
|
+
logger.info(`Now rerun ${chalk.cyan('uipro init --ai <platform> --force')} to refresh your skill files.`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
console.log();
|
|
58
|
+
logger.info('Refreshing installed skill files from this CLI package...');
|
|
59
|
+
console.log();
|
|
60
|
+
await initCommand({
|
|
61
|
+
ai: options.ai,
|
|
62
|
+
force: true,
|
|
63
|
+
token: options.token,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
spinner.fail('Update check failed');
|
|
68
|
+
if (error instanceof Error) {
|
|
69
|
+
logger.error(error.message);
|
|
70
|
+
}
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { fetchReleases } from '../utils/github.js';
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
export async function versionsCommand(options = {}) {
|
|
6
|
+
const spinner = ora('Fetching available versions...').start();
|
|
7
|
+
try {
|
|
8
|
+
const releases = await fetchReleases(options.token);
|
|
9
|
+
if (releases.length === 0) {
|
|
10
|
+
spinner.warn('No releases found');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
spinner.succeed(`Found ${releases.length} version(s)\n`);
|
|
14
|
+
console.log(chalk.bold('Available versions:\n'));
|
|
15
|
+
releases.forEach((release, index) => {
|
|
16
|
+
const isLatest = index === 0;
|
|
17
|
+
const tag = release.tag_name;
|
|
18
|
+
const date = new Date(release.published_at).toLocaleDateString();
|
|
19
|
+
if (isLatest) {
|
|
20
|
+
console.log(` ${chalk.green('*')} ${chalk.bold(tag)} ${chalk.dim(`(${date})`)} ${chalk.green('[latest]')}`);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
console.log(` ${tag} ${chalk.dim(`(${date})`)}`);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
console.log();
|
|
27
|
+
logger.dim('Update the CLI package first, then run: uipro init --ai <platform>');
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
spinner.fail('Failed to fetch versions');
|
|
31
|
+
if (error instanceof Error) {
|
|
32
|
+
logger.error(error.message);
|
|
33
|
+
}
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
package/dist/index.d.ts
ADDED