feng3d-cli 0.0.12 → 0.1.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.
@@ -0,0 +1,182 @@
1
+ # feng3d Skill
2
+
3
+ You are helping users create and manage feng3d projects using the feng3d-cli tool.
4
+
5
+ ## Overview
6
+
7
+ feng3d-cli is a command-line tool that provides:
8
+ - Unified code standards (ESLint configuration)
9
+ - Unified dependency version management
10
+ - Project templates (LICENSE, .gitignore, tsconfig.json, vite.config.js, etc.)
11
+ - GitHub Actions workflows (CI/CD, GitHub Pages deployment, OSS upload)
12
+ - Git pre-commit hooks (code linting + unit tests)
13
+
14
+ ## Commands
15
+
16
+ ### 1. Create New Project
17
+
18
+ **Command**: `npx feng3d-cli create <project-name> [options]`
19
+
20
+ **Description**: Creates a new project following feng3d standards.
21
+
22
+ **Options**:
23
+ - `-d, --directory <dir>` - Project directory (default: current directory)
24
+ - `--no-examples` - Do not create examples directory
25
+ - `--no-vitest` - Do not include vitest test configuration
26
+
27
+ **Examples**:
28
+ ```bash
29
+ # Create a new project in current directory
30
+ npx feng3d-cli create my-project
31
+
32
+ # Create project in specific directory
33
+ npx feng3d-cli create my-project -d ./packages
34
+
35
+ # Create without examples
36
+ npx feng3d-cli create my-project --no-examples
37
+
38
+ # Create without vitest
39
+ npx feng3d-cli create my-project --no-vitest
40
+ ```
41
+
42
+ **What it creates**:
43
+ - `package.json` with unified dependencies
44
+ - `LICENSE` (MIT in Chinese)
45
+ - `.gitignore`
46
+ - `.cursorrules`
47
+ - `tsconfig.json`
48
+ - `vite.config.js`
49
+ - `vitest.config.ts` (unless --no-vitest)
50
+ - `eslint.config.js`
51
+ - `typedoc.json`
52
+ - `.vscode/settings.json`
53
+ - `.husky/pre-commit` hook
54
+ - `scripts/prepublish.js`, `scripts/postpublish.js`, `scripts/postdocs.js`
55
+ - `.github/workflows/` (pull-request.yml, publish.yml, pages.yml, upload-oss.yml)
56
+ - `src/index.ts`
57
+ - `test/_.test.ts`
58
+ - `examples/` directory (unless --no-examples)
59
+
60
+ ### 2. Update Existing Project
61
+
62
+ **Command**: `npx feng3d-cli update [options]`
63
+
64
+ **Description**: Updates all standard configuration files in an existing project.
65
+
66
+ **Options**:
67
+ - `-d, --directory <dir>` - Project directory (default: current directory)
68
+
69
+ **Examples**:
70
+ ```bash
71
+ # Update current project
72
+ npx feng3d-cli update
73
+
74
+ # Update specific project
75
+ npx feng3d-cli update -d ./my-project
76
+ ```
77
+
78
+ **What it updates**:
79
+ - All configuration files (ESLint, TypeScript, Vite, etc.)
80
+ - GitHub Actions workflows
81
+ - Scripts
82
+ - Dependencies versions in package.json
83
+ - If `examples` directory exists, automatically adds `examples:dev` and `postdocs` scripts
84
+
85
+ ## Usage Guidelines
86
+
87
+ ### When to use CREATE command:
88
+ - User wants to start a new feng3d project
89
+ - User needs a project with feng3d standards
90
+ - Setting up a new package in a monorepo
91
+
92
+ ### When to use UPDATE command:
93
+ - User wants to sync with latest feng3d standards
94
+ - Project configuration is outdated
95
+ - User wants to adopt new feng3d conventions
96
+ - After feng3d-cli version update
97
+
98
+ ### Important Notes:
99
+ 1. **Always use npx**: Run commands with `npx feng3d-cli` to ensure the latest version
100
+ 2. **Check directory**: Verify the target directory before creating/updating
101
+ 3. **Backup warning**: Warn users that UPDATE will overwrite configuration files
102
+ 4. **Git status**: Recommend checking git status before UPDATE
103
+ 5. **Examples directory**: If project has `examples/`, UPDATE will automatically configure related scripts
104
+
105
+ ## Code Standards
106
+
107
+ When working with feng3d projects, follow these standards:
108
+
109
+ ### Indentation
110
+ - Use 4 spaces
111
+
112
+ ### Quotes
113
+ - Use single quotes
114
+
115
+ ### Naming Conventions
116
+ - Variables and functions: camelCase
117
+ - Classes and interfaces: PascalCase
118
+ - Constants: UPPER_SNAKE_CASE
119
+
120
+ ### Git Commit Conventions
121
+ - Use Simplified Chinese
122
+ - Follow Conventional Commits format
123
+ - Types: feat, fix, refactor, perf, style, docs, test, chore, build, ci
124
+
125
+ ### Pre-commit Checks
126
+ Before committing, the project automatically runs:
127
+ 1. ESLint code style check
128
+ 2. Unit tests via vitest
129
+
130
+ ## Unified Versions
131
+
132
+ The tool maintains unified versions for:
133
+ - TypeScript: 5.8.3
134
+ - ESLint: 9.26.0
135
+ - Vitest: ^3.1.3
136
+ - Vite: ^6.3.5
137
+ - TypeDoc: ^0.28.4
138
+
139
+ ## Implementation
140
+
141
+ When the user invokes this skill:
142
+
143
+ 1. **Understand the request**: Determine if they want to create or update
144
+ 2. **Confirm details**: Ask for project name (for create) or confirm directory
145
+ 3. **Execute command**: Use the Bash tool to run `npx feng3d-cli <command>`
146
+ 4. **Handle output**: Show the command output to the user
147
+ 5. **Next steps**: Suggest running `npm install` after creation, or checking git diff after update
148
+
149
+ ## Example Interactions
150
+
151
+ ### Example 1: Creating a new project
152
+ ```
153
+ User: Create a new feng3d project called "my-lib"
154
+ Assistant: I'll create a new feng3d project for you.
155
+ [Uses Bash tool to run: npx feng3d-cli create my-lib]
156
+ [Shows output]
157
+ Assistant: Project created successfully! Next steps:
158
+ 1. cd my-lib
159
+ 2. npm install
160
+ 3. npm run dev
161
+ ```
162
+
163
+ ### Example 2: Updating existing project
164
+ ```
165
+ User: Update my project to latest feng3d standards
166
+ Assistant: I'll update your project configuration. This will overwrite your configuration files. Make sure you've committed any important changes.
167
+ [Uses Bash tool to run: npx feng3d-cli update]
168
+ [Shows output]
169
+ Assistant: Configuration updated! Review the changes with `git diff` and test your project.
170
+ ```
171
+
172
+ ## Error Handling
173
+
174
+ - If the command fails, show the error message and suggest solutions
175
+ - If directory doesn't exist, suggest creating it or checking the path
176
+ - If package.json is missing for update, suggest running create instead
177
+ - If npm/node is not installed, guide user to install them first
178
+
179
+ ## Additional Resources
180
+
181
+ - Repository: https://github.com/feng3d-labs/feng3d-cli
182
+ - Documentation: https://feng3d.com/feng3d-cli/
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "feng3d",
3
+ "version": "0.1.0",
4
+ "description": "创建或更新符合 feng3d 规范的项目",
5
+ "author": "feng",
6
+ "commands": {
7
+ "create": {
8
+ "description": "创建新的 feng3d 项目",
9
+ "usage": "/feng3d create <project-name> [options]"
10
+ },
11
+ "update": {
12
+ "description": "更新当前项目的 feng3d 规范配置",
13
+ "usage": "/feng3d update [options]"
14
+ }
15
+ },
16
+ "repository": "https://github.com/feng3d-labs/feng3d-cli",
17
+ "cli": {
18
+ "command": "npx feng3d-cli",
19
+ "package": "feng3d-cli"
20
+ }
21
+ }
package/README.md CHANGED
@@ -11,12 +11,46 @@ feng3d 命令行工具,包含项目规范、配置模板等功能。
11
11
 
12
12
  ## 使用方式
13
13
 
14
+ ### CLI 命令行使用
15
+
14
16
  推荐使用 `npx` 直接运行,无需安装:
15
17
 
16
18
  ```bash
17
19
  npx feng3d-cli <command>
18
20
  ```
19
21
 
22
+ 或全局安装:
23
+
24
+ ```bash
25
+ npm install -g feng3d-cli
26
+ feng3d-cli <command>
27
+ ```
28
+
29
+ ### Claude Code Skill 使用
30
+
31
+ 如果你使用 [Claude Code](https://github.com/anthropics/claude-code),只需一条命令即可安装:
32
+
33
+ ```bash
34
+ npx feng3d-cli skill
35
+ ```
36
+
37
+ 手动安装:
38
+ ```bash
39
+ mkdir -p ~/.claude/skills
40
+ cp -r .claude-skill ~/.claude/skills/feng3d
41
+ ```
42
+
43
+ 安装后,在 Claude Code 中可以直接使用:
44
+
45
+ ```bash
46
+ /feng3d create my-project
47
+ /feng3d update
48
+ ```
49
+
50
+ 或者直接对话:"用 feng3d 创建一个新项目"
51
+
52
+ 详细说明见 [.claude-skill/README.md](./.claude-skill/README.md)
53
+
20
54
  ## CLI 命令
21
55
 
22
56
  ### 创建新项目
@@ -37,6 +71,14 @@ npx feng3d-cli update
37
71
  npx feng3d-cli update -d ./my-project # 指定项目目录
38
72
  ```
39
73
 
74
+ ### 安装 Claude Code Skill
75
+
76
+ ```bash
77
+ npx feng3d-cli skill
78
+ ```
79
+
80
+ > 💡 提示:也可以使用完整命令 `npx feng3d-cli install-skill`
81
+
40
82
  更新项目的所有规范配置文件,包括 ESLint、TypeScript、Vite、GitHub Actions 等。
41
83
 
42
84
  > 注意:如果项目中存在 `examples` 目录,会自动添加 `examples:dev` 和 `postdocs` 脚本。
package/bin/cli.js CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  import { Command } from 'commander';
8
8
  import chalk from 'chalk';
9
- import { createProject, updateProject } from '../dist/index.js';
9
+ import { createProject, updateProject, installSkill } from '../dist/index.js';
10
10
 
11
11
  const program = new Command();
12
12
 
@@ -55,4 +55,21 @@ program
55
55
  }
56
56
  });
57
57
 
58
+ program
59
+ .command('install-skill')
60
+ .alias('skill')
61
+ .description('安装 feng3d Claude Code Skill')
62
+ .action(async () =>
63
+ {
64
+ try
65
+ {
66
+ await installSkill();
67
+ }
68
+ catch (error)
69
+ {
70
+ console.error(chalk.red(`\n❌ 安装失败: ${error}\n`));
71
+ process.exit(1);
72
+ }
73
+ });
74
+
58
75
  program.parse();
package/dist/index.js CHANGED
@@ -2,8 +2,9 @@ import fs from "fs-extra";
2
2
  import path from "path";
3
3
  import { fileURLToPath } from "url";
4
4
  import chalk from "chalk";
5
- const __dirname$2 = path.dirname(fileURLToPath(import.meta.url));
6
- const TEMPLATES_DIR$1 = path.resolve(__dirname$2, "../templates");
5
+ import os from "os";
6
+ const __dirname$3 = path.dirname(fileURLToPath(import.meta.url));
7
+ const TEMPLATES_DIR$1 = path.resolve(__dirname$3, "../templates");
7
8
  function loadVersionsFromTemplate() {
8
9
  const packageJsonPath = path.join(TEMPLATES_DIR$1, "package.json");
9
10
  const packageJson = fs.readJsonSync(packageJsonPath);
@@ -23,8 +24,8 @@ function getDevDependencies(options = {}) {
23
24
  }
24
25
  return deps;
25
26
  }
26
- const __dirname$1 = path.dirname(fileURLToPath(import.meta.url));
27
- const TEMPLATES_DIR = path.resolve(__dirname$1, "../templates");
27
+ const __dirname$2 = path.dirname(fileURLToPath(import.meta.url));
28
+ const TEMPLATES_DIR = path.resolve(__dirname$2, "../templates");
28
29
  function getGitignoreTemplate() {
29
30
  return fs.readFileSync(path.join(TEMPLATES_DIR, "gitignore"), "utf-8");
30
31
  }
@@ -489,6 +490,71 @@ function createPackageJson(name, options) {
489
490
  })
490
491
  };
491
492
  }
493
+ const __filename$1 = fileURLToPath(import.meta.url);
494
+ const __dirname$1 = path.dirname(__filename$1);
495
+ async function installSkill() {
496
+ try {
497
+ const homeDir = os.homedir();
498
+ const claudeSkillsDir = path.join(homeDir, ".claude", "skills", "feng3d");
499
+ const possiblePaths = [
500
+ // 从当前文件位置向上查找(开发环境)
501
+ path.resolve(__dirname$1, "../../.claude-skill"),
502
+ path.resolve(__dirname$1, "../../../.claude-skill"),
503
+ path.resolve(__dirname$1, "../.claude-skill"),
504
+ // 从 package.json 所在目录查找
505
+ path.resolve(process.cwd(), ".claude-skill"),
506
+ // 从 node_modules 查找(全局安装)
507
+ path.resolve(__dirname$1, "../../../../feng3d-cli/.claude-skill")
508
+ ];
509
+ let sourceDir = "";
510
+ for (const tryPath of possiblePaths) {
511
+ if (fs.existsSync(path.join(tryPath, "skill.json"))) {
512
+ sourceDir = tryPath;
513
+ break;
514
+ }
515
+ }
516
+ if (!sourceDir) {
517
+ console.error(chalk.red("❌ 错误:找不到 .claude-skill 目录"));
518
+ console.log(chalk.yellow("尝试的路径:"));
519
+ possiblePaths.forEach((p) => console.log(` - ${p}`));
520
+ console.log(chalk.yellow("\n请确保 feng3d-cli 已正确安装"));
521
+ process.exit(1);
522
+ }
523
+ if (!fs.existsSync(path.join(sourceDir, "skill.json"))) {
524
+ console.error(chalk.red("❌ 错误:.claude-skill/skill.json 不存在"));
525
+ process.exit(1);
526
+ }
527
+ console.log(chalk.blue("\n📦 开始安装 feng3d Claude Code Skill...\n"));
528
+ if (fs.existsSync(claudeSkillsDir)) {
529
+ console.log(chalk.yellow("⚠️ 检测到已安装的 skill,将进行覆盖更新..."));
530
+ await fs.remove(claudeSkillsDir);
531
+ }
532
+ await fs.ensureDir(path.dirname(claudeSkillsDir));
533
+ console.log(chalk.blue("📂 复制 skill 文件..."));
534
+ await fs.copy(sourceDir, claudeSkillsDir, {
535
+ overwrite: true,
536
+ errorOnExist: false
537
+ });
538
+ if (fs.existsSync(path.join(claudeSkillsDir, "skill.json"))) {
539
+ console.log(chalk.green("\n✅ feng3d Skill 安装成功!\n"));
540
+ console.log(chalk.cyan(`安装位置: ${claudeSkillsDir}
541
+ `));
542
+ console.log(chalk.yellow("使用方法:"));
543
+ console.log(" /feng3d create my-project");
544
+ console.log(" /feng3d update\n");
545
+ console.log(chalk.yellow('或直接对话: "用 feng3d 创建一个新项目"\n'));
546
+ console.log(chalk.cyan("💡 提示: 可能需要重启 Claude Code 使 skill 生效\n"));
547
+ } else {
548
+ console.error(chalk.red("\n❌ 安装失败:无法验证安装结果\n"));
549
+ process.exit(1);
550
+ }
551
+ } catch (error) {
552
+ console.error(chalk.red(`
553
+ ❌ 安装失败: ${error}
554
+ `));
555
+ process.exit(1);
556
+ }
557
+ }
492
558
  export {
493
559
  VERSIONS,
494
560
  createProject,
@@ -514,6 +580,7 @@ export {
514
580
  getViteConfigTemplate,
515
581
  getVitestConfigTemplate,
516
582
  getVscodeSettingsTemplate,
583
+ installSkill,
517
584
  updateProject
518
585
  };
519
586
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/versions.ts","../src/templates.ts","../src/commands/update.ts","../src/commands/create.ts"],"sourcesContent":["/**\n * feng3d 项目统一依赖版本\n * 从 templates/package.json 中读取\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\n/**\n * 模板目录路径\n */\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst TEMPLATES_DIR = path.resolve(__dirname, '../templates');\n\n/**\n * 从模板 package.json 中读取 devDependencies\n */\nfunction loadVersionsFromTemplate(): Record<string, string>\n{\n const packageJsonPath = path.join(TEMPLATES_DIR, 'package.json');\n const packageJson = fs.readJsonSync(packageJsonPath);\n\n return packageJson.devDependencies || {};\n}\n\n/**\n * 统一依赖版本(从 templates/package.json 读取)\n */\nexport const VERSIONS = loadVersionsFromTemplate();\n\n/**\n * 获取 devDependencies 配置\n */\nexport function getDevDependencies(options: {\n includeVitest?: boolean;\n includeTypedoc?: boolean;\n includeCoverage?: boolean;\n} = {}): Record<string, string>\n{\n // 从 VERSIONS 中复制所有依赖\n const deps: Record<string, string> = { ...VERSIONS };\n\n // 根据选项移除可选依赖\n if (options.includeVitest === false)\n {\n delete deps.vitest;\n }\n\n if (options.includeTypedoc === false)\n {\n delete deps.typedoc;\n }\n\n // 可选添加覆盖率依赖(默认不包含)\n if (options.includeCoverage && !deps['@vitest/coverage-v8'])\n {\n deps['@vitest/coverage-v8'] = '^3.2.4';\n }\n\n return deps;\n}\n","/**\n * 项目模板文件内容\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\n/**\n * 模板目录路径\n */\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst TEMPLATES_DIR = path.resolve(__dirname, '../templates');\n\n/**\n * 获取 .gitignore 模板内容\n */\nexport function getGitignoreTemplate(): string\n{\n // 模板文件命名为 gitignore(不带点),避免对 templates 目录生效\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'gitignore'), 'utf-8');\n}\n\n/**\n * 获取 .cursorrules 模板内容\n */\nexport function getCursorrrulesTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.cursorrules'), 'utf-8');\n}\n\n/**\n * 获取 tsconfig.json 模板内容(对象形式)\n */\nexport function getTsconfigTemplate(): object\n{\n return fs.readJsonSync(path.join(TEMPLATES_DIR, 'tsconfig.json'));\n}\n\n/**\n * 获取 tsconfig.json 模板内容(字符串形式)\n */\nexport function getTsconfigTemplateString(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'tsconfig.json'), 'utf-8');\n}\n\n/**\n * 获取 vite.config.js 模板内容\n */\nexport function getViteConfigTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'vite.config.js'), 'utf-8');\n}\n\n/**\n * 获取 eslint.config.js 模板内容\n */\nexport function getEslintConfigTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'eslint.config.js'), 'utf-8');\n}\n\n/**\n * 获取 typedoc.json 模板内容(返回对象)\n */\nexport function getTypedocConfig(options: {\n repoName: string;\n}): object\n{\n return JSON.parse(getTypedocConfigTemplate(options));\n}\n\n/**\n * 获取 typedoc.json 模板内容(返回字符串)\n */\nexport function getTypedocConfigTemplate(options: {\n repoName: string;\n}): string\n{\n const templateContent = fs.readFileSync(path.join(TEMPLATES_DIR, 'typedoc.json'), 'utf-8');\n\n return templateContent.replace(/\\{\\{repoName\\}\\}/g, options.repoName);\n}\n\n/**\n * 获取 test/_.test.ts 模板内容(空文件占位)\n */\nexport function getTestIndexTemplate(_options: { name: string }): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'test/_.test.ts'), 'utf-8');\n}\n\n/**\n * 获取 GitHub Actions publish workflow 模板内容\n */\nexport function getPublishWorkflowTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.github/workflows/publish.yml'), 'utf-8');\n}\n\n/**\n * 获取 GitHub Actions pages workflow 模板内容\n */\nexport function getPagesWorkflowTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.github/workflows/pages.yml'), 'utf-8');\n}\n\n/**\n * 获取 GitHub Actions pull-request workflow 模板内容\n */\nexport function getPullRequestWorkflowTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.github/workflows/pull-request.yml'), 'utf-8');\n}\n\n/**\n * 获取 GitHub Actions upload-oss workflow 模板内容\n */\nexport function getUploadOssWorkflowTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.github/workflows/upload-oss.yml'), 'utf-8');\n}\n\n/**\n * 获取 .husky/pre-commit 模板内容\n */\nexport function getHuskyPreCommitTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.husky/pre-commit'), 'utf-8');\n}\n\n/**\n * 获取 LICENSE 模板内容\n */\nexport function getLicenseTemplate(ctx: { year?: number } = {}): string\n{\n const year = ctx.year || new Date().getFullYear();\n const template = fs.readFileSync(path.join(TEMPLATES_DIR, 'LICENSE'), 'utf-8');\n\n return template.replace('{{year}}', String(year));\n}\n\n/**\n * 获取 .vscode/settings.json 模板内容\n */\nexport function getVscodeSettingsTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.vscode/settings.json'), 'utf-8');\n}\n\n/**\n * 获取 scripts/prepublish.js 模板内容\n */\nexport function getPrepublishScriptTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'scripts/prepublish.js'), 'utf-8');\n}\n\n/**\n * 获取 scripts/postpublish.js 模板内容\n */\nexport function getPostpublishScriptTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'scripts/postpublish.js'), 'utf-8');\n}\n\n/**\n * 获取 scripts/postdocs.js 模板内容\n */\nexport function getPostdocsScriptTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'scripts/postdocs.js'), 'utf-8');\n}\n\n/**\n * 获取 src/index.ts 模板内容\n */\nexport function getSrcIndexTemplate(options: { name: string }): string\n{\n const template = fs.readFileSync(path.join(TEMPLATES_DIR, 'src/index.ts'), 'utf-8');\n\n return template.replace(/\\{\\{name\\}\\}/g, options.name);\n}\n\n/**\n * 获取 vitest.config.ts 模板内容\n */\nexport function getVitestConfigTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'vitest.config.ts'), 'utf-8');\n}\n\n","/**\n * 更新项目规范命令\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport chalk from 'chalk';\nimport { getDevDependencies, VERSIONS } from '../versions.js';\nimport {\n getGitignoreTemplate,\n getCursorrrulesTemplate,\n getEslintConfigTemplate,\n getPublishWorkflowTemplate,\n getPagesWorkflowTemplate,\n getPullRequestWorkflowTemplate,\n getUploadOssWorkflowTemplate,\n getTypedocConfigTemplate,\n getTestIndexTemplate,\n getHuskyPreCommitTemplate,\n getLicenseTemplate,\n getVscodeSettingsTemplate,\n getTsconfigTemplateString,\n getViteConfigTemplate,\n getVitestConfigTemplate,\n getPrepublishScriptTemplate,\n getPostpublishScriptTemplate,\n getPostdocsScriptTemplate,\n getSrcIndexTemplate,\n} from '../templates.js';\n\n/**\n * 模板上下文\n */\ninterface TemplateContext {\n name: string;\n repoName: string;\n}\n\n/**\n * 更新项目的规范配置\n * @param directory 项目目录路径\n */\nexport async function updateProject(directory: string = '.'): Promise<void>\n{\n const projectDir = path.resolve(directory);\n const packageJsonPath = path.join(projectDir, 'package.json');\n\n // 如果 package.json 不存在,创建基础 package.json\n if (!await fs.pathExists(packageJsonPath))\n {\n await fs.ensureDir(projectDir);\n const dirName = path.basename(projectDir);\n const initialPackageJson = {\n name: `@feng3d/${dirName}`,\n version: '0.0.1',\n description: '',\n };\n\n await fs.writeJson(packageJsonPath, initialPackageJson, { spaces: 4 });\n console.log(chalk.gray(' 创建: package.json'));\n\n // 创建 src/index.ts\n const srcDir = path.join(projectDir, 'src');\n\n await fs.ensureDir(srcDir);\n await fs.writeFile(path.join(srcDir, 'index.ts'), getSrcIndexTemplate({ name: `@feng3d/${dirName}` }));\n console.log(chalk.gray(' 创建: src/index.ts'));\n }\n\n // 获取项目信息用于模板\n const packageJson = await fs.readJson(packageJsonPath);\n const name = packageJson.name || path.basename(projectDir);\n const repoName = name.replace(/^@[^/]+\\//, ''); // 移除 scope 前缀\n const templateContext: TemplateContext = { name, repoName };\n\n // feng3d-cli 项目:不更新 tsconfig.json 和 vite.config.js(有自定义配置)\n const isFeng3dCli = name === 'feng3d-cli';\n\n // 更新 .gitignore(强制覆盖)\n await fs.writeFile(path.join(projectDir, '.gitignore'), getGitignoreTemplate());\n console.log(chalk.gray(' 更新: .gitignore'));\n\n // 更新 .cursorrules\n await fs.writeFile(path.join(projectDir, '.cursorrules'), getCursorrrulesTemplate());\n console.log(chalk.gray(' 更新: .cursorrules'));\n\n // 更新 eslint.config.js\n await createEslintConfigFile(projectDir);\n console.log(chalk.gray(' 更新: eslint.config.js'));\n\n // 更新 .github/workflows/publish.yml\n await fs.ensureDir(path.join(projectDir, '.github/workflows'));\n await fs.writeFile(path.join(projectDir, '.github/workflows/publish.yml'), getPublishWorkflowTemplate());\n console.log(chalk.gray(' 更新: .github/workflows/publish.yml'));\n\n // 更新 .github/workflows/pages.yml\n await fs.writeFile(path.join(projectDir, '.github/workflows/pages.yml'), getPagesWorkflowTemplate());\n console.log(chalk.gray(' 更新: .github/workflows/pages.yml'));\n\n // 更新 .github/workflows/pull-request.yml\n await fs.writeFile(path.join(projectDir, '.github/workflows/pull-request.yml'), getPullRequestWorkflowTemplate());\n console.log(chalk.gray(' 更新: .github/workflows/pull-request.yml'));\n\n // 更新 .github/workflows/upload-oss.yml\n await fs.writeFile(path.join(projectDir, '.github/workflows/upload-oss.yml'), getUploadOssWorkflowTemplate());\n console.log(chalk.gray(' 更新: .github/workflows/upload-oss.yml'));\n\n // 更新 typedoc.json\n const typedocContent = getTypedocConfigTemplate({ repoName });\n\n await fs.writeFile(path.join(projectDir, 'typedoc.json'), typedocContent);\n console.log(chalk.gray(' 更新: typedoc.json'));\n\n // 创建 test/_.test.ts(仅当 test 目录为空时)\n const testDir = path.join(projectDir, 'test');\n\n await fs.ensureDir(testDir);\n const testFiles = await fs.readdir(testDir);\n\n if (testFiles.length === 0)\n {\n const testContent = getTestIndexTemplate({ name });\n\n await fs.writeFile(path.join(testDir, '_.test.ts'), testContent);\n console.log(chalk.gray(' 创建: test/_.test.ts'));\n }\n\n // 更新依赖版本\n await updateDependencies(projectDir);\n console.log(chalk.gray(' 更新: package.json devDependencies'));\n\n // 更新 husky pre-commit hook\n await fs.ensureDir(path.join(projectDir, '.husky'));\n await fs.writeFile(path.join(projectDir, '.husky/pre-commit'), getHuskyPreCommitTemplate());\n console.log(chalk.gray(' 更新: .husky/pre-commit'));\n await updateHuskyConfig(projectDir);\n\n // 更新 LICENSE 文件(强制覆盖)\n await fs.writeFile(path.join(projectDir, 'LICENSE'), getLicenseTemplate());\n console.log(chalk.gray(' 更新: LICENSE'));\n\n // 更新 .vscode/settings.json\n await fs.ensureDir(path.join(projectDir, '.vscode'));\n await fs.writeFile(path.join(projectDir, '.vscode/settings.json'), getVscodeSettingsTemplate());\n console.log(chalk.gray(' 更新: .vscode/settings.json'));\n\n // 更新 tsconfig.json(强制覆盖,feng3d-cli 跳过)\n if (!isFeng3dCli)\n {\n await fs.writeFile(path.join(projectDir, 'tsconfig.json'), getTsconfigTemplateString());\n console.log(chalk.gray(' 更新: tsconfig.json'));\n }\n\n // 更新 vite.config.js(强制覆盖,feng3d-cli 跳过)\n if (!isFeng3dCli)\n {\n await fs.writeFile(path.join(projectDir, 'vite.config.js'), getViteConfigTemplate());\n console.log(chalk.gray(' 更新: vite.config.js'));\n }\n\n // 更新 vitest.config.ts(强制覆盖,feng3d-cli 跳过)\n if (!isFeng3dCli)\n {\n await fs.writeFile(path.join(projectDir, 'vitest.config.ts'), getVitestConfigTemplate());\n console.log(chalk.gray(' 更新: vitest.config.ts'));\n }\n\n // 更新发布脚本(强制覆盖)\n const scriptsDir = path.join(projectDir, 'scripts');\n\n await fs.ensureDir(scriptsDir);\n await fs.writeFile(path.join(scriptsDir, 'prepublish.js'), getPrepublishScriptTemplate());\n console.log(chalk.gray(' 更新: scripts/prepublish.js'));\n\n await fs.writeFile(path.join(scriptsDir, 'postpublish.js'), getPostpublishScriptTemplate());\n console.log(chalk.gray(' 更新: scripts/postpublish.js'));\n\n // 如果存在 examples 目录,更新 postdocs.js 脚本(强制覆盖)\n const examplesDir = path.join(projectDir, 'examples');\n\n if (await fs.pathExists(examplesDir))\n {\n await fs.writeFile(path.join(scriptsDir, 'postdocs.js'), getPostdocsScriptTemplate());\n console.log(chalk.gray(' 更新: scripts/postdocs.js'));\n }\n}\n\n/**\n * 创建 ESLint 配置文件\n */\nexport async function createEslintConfigFile(projectDir: string): Promise<void>\n{\n await fs.writeFile(path.join(projectDir, 'eslint.config.js'), getEslintConfigTemplate());\n}\n\n/**\n * 检测 JSON 文件的缩进风格\n */\nfunction detectIndent(content: string): string\n{\n const match = content.match(/^[ \\t]+/m);\n\n return match ? match[0] : ' ';\n}\n\n/**\n * package.json 字段的标准顺序\n */\nconst PACKAGE_JSON_FIELD_ORDER = [\n 'name',\n 'version',\n 'description',\n 'homepage',\n 'author',\n 'license',\n 'type',\n 'main',\n 'types',\n 'module',\n 'exports',\n 'bin',\n 'scripts',\n 'repository',\n 'publishConfig',\n 'files',\n 'devDependencies',\n 'dependencies',\n 'peerDependencies',\n 'lint-staged',\n 'workspaces',\n];\n\n/**\n * scripts 字段的标准顺序\n */\nconst SCRIPTS_ORDER = [\n 'examples:dev',\n 'test_web',\n 'postdocs',\n 'clean',\n 'build',\n 'watch',\n 'test',\n 'lint',\n 'lintfix',\n 'docs',\n 'prepublishOnly',\n 'release',\n 'postpublish',\n 'prepare',\n];\n\n/**\n * 按标准顺序重新排列对象字段\n */\nfunction reorderObject(obj: Record<string, unknown>, order: string[]): Record<string, unknown>\n{\n const ordered: Record<string, unknown> = {};\n\n // 先按标准顺序添加已存在的字段\n for (const key of order)\n {\n if (key in obj)\n {\n ordered[key] = obj[key];\n }\n }\n\n // 再添加其他未在标准顺序中的字段\n for (const key of Object.keys(obj))\n {\n if (!(key in ordered))\n {\n ordered[key] = obj[key];\n }\n }\n\n return ordered;\n}\n\n/**\n * 按标准顺序重新排列 package.json 字段\n */\nfunction reorderPackageJson(packageJson: Record<string, unknown>): Record<string, unknown>\n{\n const ordered = reorderObject(packageJson, PACKAGE_JSON_FIELD_ORDER);\n\n // 重新排列 scripts\n if (ordered.scripts && typeof ordered.scripts === 'object')\n {\n ordered.scripts = reorderObject(ordered.scripts as Record<string, unknown>, SCRIPTS_ORDER);\n }\n\n return ordered;\n}\n\n/**\n * 更新 package.json 中的 devDependencies 版本\n */\nasync function updateDependencies(projectDir: string): Promise<void>\n{\n const packageJsonPath = path.join(projectDir, 'package.json');\n\n // 读取原始内容以检测缩进风格\n const originalContent = await fs.readFile(packageJsonPath, 'utf-8');\n const indent = detectIndent(originalContent);\n const hasTrailingNewline = originalContent.endsWith('\\n');\n\n const packageJson = JSON.parse(originalContent);\n\n const standardDeps = getDevDependencies({\n includeVitest: true,\n includeTypedoc: true,\n });\n\n // 添加或更新 devDependencies\n let updated = false;\n\n if (!packageJson.devDependencies)\n {\n packageJson.devDependencies = {};\n }\n\n for (const [key, value] of Object.entries(standardDeps))\n {\n if (!(key in packageJson.devDependencies))\n {\n packageJson.devDependencies[key] = value;\n updated = true;\n console.log(chalk.gray(` 添加: devDependencies.${key} = \"${value}\"`));\n }\n else if (packageJson.devDependencies[key] !== value)\n {\n packageJson.devDependencies[key] = value;\n updated = true;\n console.log(chalk.gray(` 更新: devDependencies.${key} = \"${value}\"`));\n }\n }\n\n // 添加标准 scripts\n if (!packageJson.scripts)\n {\n packageJson.scripts = {};\n }\n\n const standardScripts: Record<string, string> = {\n clean: 'rimraf lib dist public',\n build: 'vite build && tsc',\n watch: 'concurrently \"vite build --watch\" \"tsc -w\" \"vitest\"',\n test: 'vitest run',\n lint: 'eslint . --ext .js,.ts --max-warnings 0',\n lintfix: 'npm run lint -- --fix',\n docs: 'typedoc',\n prepublishOnly: 'node scripts/prepublish.js',\n release: 'npm run clean && npm run lint && npm test && npm run build && npm run docs && npm publish',\n postpublish: 'node scripts/postpublish.js',\n };\n\n // 检查是否存在 examples 目录,添加相关脚本\n const examplesDir = path.join(projectDir, 'examples');\n\n if (await fs.pathExists(examplesDir))\n {\n standardScripts['examples:dev'] = 'cd examples && npm run dev';\n standardScripts.postdocs = 'node scripts/postdocs.js && cd examples && vite build --outDir ../public';\n }\n\n // 如果 scripts 不存在则添加,存在时不覆盖\n for (const [key, value] of Object.entries(standardScripts))\n {\n if (!(key in packageJson.scripts))\n {\n packageJson.scripts[key] = value;\n updated = true;\n console.log(chalk.gray(` 添加: scripts.${key}`));\n }\n }\n\n // 设置标准入口点配置(强制覆盖)\n if (packageJson.type !== 'module')\n {\n packageJson.type = 'module';\n updated = true;\n console.log(chalk.gray(' 更新: type = \"module\"'));\n }\n\n const entryPoints = {\n main: './src/index.ts',\n types: './src/index.ts',\n module: './src/index.ts',\n };\n\n for (const [key, value] of Object.entries(entryPoints))\n {\n if (packageJson[key] !== value)\n {\n packageJson[key] = value;\n updated = true;\n console.log(chalk.gray(` 更新: ${key} = \"${value}\"`));\n }\n }\n\n // 设置 exports 配置(强制覆盖)\n const standardExports = {\n '.': {\n types: './src/index.ts',\n import: './src/index.ts',\n require: './src/index.ts',\n },\n };\n\n if (JSON.stringify(packageJson.exports) !== JSON.stringify(standardExports))\n {\n packageJson.exports = standardExports;\n updated = true;\n console.log(chalk.gray(' 更新: exports'));\n }\n\n // 如果 workspaces 不存在则添加\n if (!packageJson.workspaces)\n {\n packageJson.workspaces = [\n '.',\n './examples',\n './test_web',\n 'packages/*',\n 'packages/*/examples',\n ];\n updated = true;\n console.log(chalk.gray(' 添加: workspaces'));\n }\n\n // 只有在有更新时才写入文件\n if (updated)\n {\n const orderedPackageJson = reorderPackageJson(packageJson);\n let newContent = JSON.stringify(orderedPackageJson, null, indent);\n\n if (hasTrailingNewline)\n {\n newContent += '\\n';\n }\n await fs.writeFile(packageJsonPath, newContent);\n }\n}\n\n/**\n * 更新 package.json 添加 husky 配置\n */\nasync function updateHuskyConfig(projectDir: string): Promise<void>\n{\n const packageJsonPath = path.join(projectDir, 'package.json');\n\n // 读取原始内容以检测缩进风格\n const originalContent = await fs.readFile(packageJsonPath, 'utf-8');\n const indent = detectIndent(originalContent);\n const hasTrailingNewline = originalContent.endsWith('\\n');\n\n const packageJson = JSON.parse(originalContent);\n let updated = false;\n\n // 强制覆盖 husky 和 lint-staged 依赖\n if (!packageJson.devDependencies)\n {\n packageJson.devDependencies = {};\n }\n if (packageJson.devDependencies.husky !== VERSIONS.husky)\n {\n packageJson.devDependencies.husky = VERSIONS.husky;\n updated = true;\n console.log(chalk.gray(` 更新: devDependencies.husky = \"${VERSIONS.husky}\"`));\n }\n if (packageJson.devDependencies['lint-staged'] !== VERSIONS['lint-staged'])\n {\n packageJson.devDependencies['lint-staged'] = VERSIONS['lint-staged'];\n updated = true;\n console.log(chalk.gray(` 更新: devDependencies.lint-staged = \"${VERSIONS['lint-staged']}\"`));\n }\n\n // 强制覆盖 prepare 脚本\n if (!packageJson.scripts)\n {\n packageJson.scripts = {};\n }\n if (packageJson.scripts.prepare !== 'husky')\n {\n packageJson.scripts.prepare = 'husky';\n updated = true;\n console.log(chalk.gray(' 更新: scripts.prepare = \"husky\"'));\n }\n\n // 强制覆盖 lint-staged 配置\n const standardLintStaged = {\n '*.{js,ts}': ['eslint --fix --max-warnings 0'],\n };\n\n if (JSON.stringify(packageJson['lint-staged']) !== JSON.stringify(standardLintStaged))\n {\n packageJson['lint-staged'] = standardLintStaged;\n updated = true;\n console.log(chalk.gray(' 更新: lint-staged 配置'));\n }\n\n // 只有在有更新时才写入文件\n if (updated)\n {\n const orderedPackageJson = reorderPackageJson(packageJson);\n let newContent = JSON.stringify(orderedPackageJson, null, indent);\n\n if (hasTrailingNewline)\n {\n newContent += '\\n';\n }\n await fs.writeFile(packageJsonPath, newContent);\n }\n}\n","/**\n * 创建新项目命令\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport chalk from 'chalk';\nimport { getDevDependencies } from '../versions.js';\nimport {\n getGitignoreTemplate,\n getCursorrrulesTemplate,\n getTsconfigTemplate,\n getTypedocConfig,\n getPublishWorkflowTemplate,\n getPrepublishScriptTemplate,\n getPostpublishScriptTemplate,\n getPostdocsScriptTemplate,\n getSrcIndexTemplate,\n} from '../templates.js';\nimport { createEslintConfigFile } from './update.js';\n\nexport interface CreateOptions {\n directory: string;\n examples?: boolean;\n vitest?: boolean;\n}\n\n/**\n * 创建符合 feng3d 规范的新项目\n */\nexport async function createProject(name: string, options: CreateOptions): Promise<void>\n{\n const projectDir = path.join(options.directory, name);\n\n // 检查目录是否已存在\n if (await fs.pathExists(projectDir))\n {\n throw new Error(`目录 ${projectDir} 已存在`);\n }\n\n // 创建项目目录\n await fs.ensureDir(projectDir);\n await fs.ensureDir(path.join(projectDir, 'src'));\n\n console.log(chalk.gray(` 创建目录: ${projectDir}`));\n\n // 创建 package.json\n const packageJson = createPackageJson(name, options);\n\n await fs.writeJson(path.join(projectDir, 'package.json'), packageJson, { spaces: 4 });\n console.log(chalk.gray(' 创建: package.json'));\n\n // 创建 tsconfig.json\n await fs.writeJson(path.join(projectDir, 'tsconfig.json'), getTsconfigTemplate(), { spaces: 4 });\n console.log(chalk.gray(' 创建: tsconfig.json'));\n\n // 创建 .gitignore\n await fs.writeFile(path.join(projectDir, '.gitignore'), getGitignoreTemplate());\n console.log(chalk.gray(' 创建: .gitignore'));\n\n // 创建 .cursorrules\n await fs.writeFile(path.join(projectDir, '.cursorrules'), getCursorrrulesTemplate());\n console.log(chalk.gray(' 创建: .cursorrules'));\n\n // 创建 eslint.config.js\n await createEslintConfigFile(projectDir);\n console.log(chalk.gray(' 创建: eslint.config.js'));\n\n // 创建 typedoc.json\n const typedocConfig = getTypedocConfig({ repoName: name });\n\n await fs.writeJson(path.join(projectDir, 'typedoc.json'), typedocConfig, { spaces: 4 });\n console.log(chalk.gray(' 创建: typedoc.json'));\n\n // 创建 src/index.ts\n await fs.writeFile(path.join(projectDir, 'src/index.ts'), getSrcIndexTemplate({ name: `@feng3d/${name}` }));\n console.log(chalk.gray(' 创建: src/index.ts'));\n\n // 创建 README.md\n await fs.writeFile(path.join(projectDir, 'README.md'), `# @feng3d/${name}\\n`);\n console.log(chalk.gray(' 创建: README.md'));\n\n // 创建示例目录\n if (options.examples !== false)\n {\n await fs.ensureDir(path.join(projectDir, 'examples'));\n console.log(chalk.gray(' 创建: examples/'));\n }\n\n // 创建测试目录\n if (options.vitest !== false)\n {\n await fs.ensureDir(path.join(projectDir, 'test'));\n console.log(chalk.gray(' 创建: test/'));\n }\n\n // 创建 .github/workflows 目录和 publish.yml\n await fs.ensureDir(path.join(projectDir, '.github/workflows'));\n await fs.writeFile(path.join(projectDir, '.github/workflows/publish.yml'), getPublishWorkflowTemplate());\n console.log(chalk.gray(' 创建: .github/workflows/publish.yml'));\n\n // 创建 scripts 目录和发布脚本\n await fs.ensureDir(path.join(projectDir, 'scripts'));\n await fs.writeFile(path.join(projectDir, 'scripts/prepublish.js'), getPrepublishScriptTemplate());\n await fs.writeFile(path.join(projectDir, 'scripts/postpublish.js'), getPostpublishScriptTemplate());\n console.log(chalk.gray(' 创建: scripts/prepublish.js'));\n console.log(chalk.gray(' 创建: scripts/postpublish.js'));\n\n // 如果创建了 examples 目录,添加 postdocs.js 脚本\n if (options.examples !== false)\n {\n await fs.writeFile(path.join(projectDir, 'scripts/postdocs.js'), getPostdocsScriptTemplate());\n console.log(chalk.gray(' 创建: scripts/postdocs.js'));\n }\n}\n\n/**\n * 创建 package.json 内容\n */\nfunction createPackageJson(name: string, options: CreateOptions): object\n{\n const scripts: Record<string, string> = {\n clean: 'rimraf lib dist public',\n build: 'vite build && tsc',\n types: 'tsc',\n watch: 'tsc -w',\n lint: 'eslint . --ext .js,.ts --max-warnings 0',\n lintfix: 'npm run lint -- --fix',\n docs: 'typedoc',\n release: 'npm run clean && npm run lint && npm test && npm run build && npm run docs && npm publish',\n prepublishOnly: 'node scripts/prepublish.js',\n postpublish: 'node scripts/postpublish.js',\n };\n\n // 如果包含 examples 目录,添加相关脚本\n if (options.examples !== false)\n {\n scripts['examples:dev'] = 'cd examples && npm run dev';\n scripts.postdocs = 'node scripts/postdocs.js && cd examples && vite build --outDir ../public';\n }\n\n if (options.vitest !== false)\n {\n scripts.test = 'vitest run';\n scripts['test:watch'] = 'vitest';\n }\n\n return {\n name: `@feng3d/${name}`,\n version: '0.0.1',\n description: '',\n homepage: `https://feng3d.com/${name}/`,\n author: 'feng',\n type: 'module',\n main: './src/index.ts',\n types: './src/index.ts',\n module: './src/index.ts',\n exports: {\n '.': {\n types: './src/index.ts',\n import: './src/index.ts',\n require: './src/index.ts',\n },\n },\n scripts,\n repository: {\n type: 'git',\n url: `https://github.com/feng3d-labs/${name}.git`,\n },\n publishConfig: {\n access: 'public',\n },\n files: ['src', 'dist', 'lib'],\n devDependencies: getDevDependencies({\n includeVitest: options.vitest !== false,\n includeTypedoc: true,\n }),\n };\n}\n\n"],"names":["__dirname","TEMPLATES_DIR"],"mappings":";;;;AAYA,MAAMA,cAAY,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAC7D,MAAMC,kBAAgB,KAAK,QAAQD,aAAW,cAAc;AAK5D,SAAS,2BACT;AACI,QAAM,kBAAkB,KAAK,KAAKC,iBAAe,cAAc;AAC/D,QAAM,cAAc,GAAG,aAAa,eAAe;AAEnD,SAAO,YAAY,mBAAmB,CAAA;AAC1C;AAKO,MAAM,WAAW,yBAAA;AAKjB,SAAS,mBAAmB,UAI/B,IACJ;AAEI,QAAM,OAA+B,EAAE,GAAG,SAAA;AAG1C,MAAI,QAAQ,kBAAkB,OAC9B;AACI,WAAO,KAAK;AAAA,EAChB;AAEA,MAAI,QAAQ,mBAAmB,OAC/B;AACI,WAAO,KAAK;AAAA,EAChB;AAGA,MAAI,QAAQ,mBAAmB,CAAC,KAAK,qBAAqB,GAC1D;AACI,SAAK,qBAAqB,IAAI;AAAA,EAClC;AAEA,SAAO;AACX;AClDA,MAAMD,cAAY,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAC7D,MAAM,gBAAgB,KAAK,QAAQA,aAAW,cAAc;AAKrD,SAAS,uBAChB;AAEI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,WAAW,GAAG,OAAO;AACzE;AAKO,SAAS,0BAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,cAAc,GAAG,OAAO;AAC5E;AAKO,SAAS,sBAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,eAAe,CAAC;AACpE;AAKO,SAAS,4BAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,eAAe,GAAG,OAAO;AAC7E;AAKO,SAAS,wBAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,gBAAgB,GAAG,OAAO;AAC9E;AAKO,SAAS,0BAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,kBAAkB,GAAG,OAAO;AAChF;AAKO,SAAS,iBAAiB,SAGjC;AACI,SAAO,KAAK,MAAM,yBAAyB,OAAO,CAAC;AACvD;AAKO,SAAS,yBAAyB,SAGzC;AACI,QAAM,kBAAkB,GAAG,aAAa,KAAK,KAAK,eAAe,cAAc,GAAG,OAAO;AAEzF,SAAO,gBAAgB,QAAQ,qBAAqB,QAAQ,QAAQ;AACxE;AAKO,SAAS,qBAAqB,UACrC;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,gBAAgB,GAAG,OAAO;AAC9E;AAKO,SAAS,6BAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,+BAA+B,GAAG,OAAO;AAC7F;AAKO,SAAS,2BAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,6BAA6B,GAAG,OAAO;AAC3F;AAKO,SAAS,iCAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,oCAAoC,GAAG,OAAO;AAClG;AAKO,SAAS,+BAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,kCAAkC,GAAG,OAAO;AAChG;AAKO,SAAS,4BAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,mBAAmB,GAAG,OAAO;AACjF;AAKO,SAAS,mBAAmB,MAAyB,IAC5D;AACI,QAAM,OAAO,IAAI,SAAQ,oBAAI,KAAA,GAAO,YAAA;AACpC,QAAM,WAAW,GAAG,aAAa,KAAK,KAAK,eAAe,SAAS,GAAG,OAAO;AAE7E,SAAO,SAAS,QAAQ,YAAY,OAAO,IAAI,CAAC;AACpD;AAKO,SAAS,4BAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,uBAAuB,GAAG,OAAO;AACrF;AAKO,SAAS,8BAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,uBAAuB,GAAG,OAAO;AACrF;AAKO,SAAS,+BAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,wBAAwB,GAAG,OAAO;AACtF;AAKO,SAAS,4BAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,qBAAqB,GAAG,OAAO;AACnF;AAKO,SAAS,oBAAoB,SACpC;AACI,QAAM,WAAW,GAAG,aAAa,KAAK,KAAK,eAAe,cAAc,GAAG,OAAO;AAElF,SAAO,SAAS,QAAQ,iBAAiB,QAAQ,IAAI;AACzD;AAKO,SAAS,0BAChB;AACI,SAAO,GAAG,aAAa,KAAK,KAAK,eAAe,kBAAkB,GAAG,OAAO;AAChF;ACtJA,eAAsB,cAAc,YAAoB,KACxD;AACI,QAAM,aAAa,KAAK,QAAQ,SAAS;AACzC,QAAM,kBAAkB,KAAK,KAAK,YAAY,cAAc;AAG5D,MAAI,CAAC,MAAM,GAAG,WAAW,eAAe,GACxC;AACI,UAAM,GAAG,UAAU,UAAU;AAC7B,UAAM,UAAU,KAAK,SAAS,UAAU;AACxC,UAAM,qBAAqB;AAAA,MACvB,MAAM,WAAW,OAAO;AAAA,MACxB,SAAS;AAAA,MACT,aAAa;AAAA,IAAA;AAGjB,UAAM,GAAG,UAAU,iBAAiB,oBAAoB,EAAE,QAAQ,GAAG;AACrE,YAAQ,IAAI,MAAM,KAAK,oBAAoB,CAAC;AAG5C,UAAM,SAAS,KAAK,KAAK,YAAY,KAAK;AAE1C,UAAM,GAAG,UAAU,MAAM;AACzB,UAAM,GAAG,UAAU,KAAK,KAAK,QAAQ,UAAU,GAAG,oBAAoB,EAAE,MAAM,WAAW,OAAO,GAAA,CAAI,CAAC;AACrG,YAAQ,IAAI,MAAM,KAAK,oBAAoB,CAAC;AAAA,EAChD;AAGA,QAAM,cAAc,MAAM,GAAG,SAAS,eAAe;AACrD,QAAM,OAAO,YAAY,QAAQ,KAAK,SAAS,UAAU;AACzD,QAAM,WAAW,KAAK,QAAQ,aAAa,EAAE;AAI7C,QAAM,cAAc,SAAS;AAG7B,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,YAAY,GAAG,sBAAsB;AAC9E,UAAQ,IAAI,MAAM,KAAK,kBAAkB,CAAC;AAG1C,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,cAAc,GAAG,yBAAyB;AACnF,UAAQ,IAAI,MAAM,KAAK,oBAAoB,CAAC;AAG5C,QAAM,uBAAuB,UAAU;AACvC,UAAQ,IAAI,MAAM,KAAK,wBAAwB,CAAC;AAGhD,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,mBAAmB,CAAC;AAC7D,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,+BAA+B,GAAG,4BAA4B;AACvG,UAAQ,IAAI,MAAM,KAAK,qCAAqC,CAAC;AAG7D,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,6BAA6B,GAAG,0BAA0B;AACnG,UAAQ,IAAI,MAAM,KAAK,mCAAmC,CAAC;AAG3D,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,oCAAoC,GAAG,gCAAgC;AAChH,UAAQ,IAAI,MAAM,KAAK,0CAA0C,CAAC;AAGlE,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,kCAAkC,GAAG,8BAA8B;AAC5G,UAAQ,IAAI,MAAM,KAAK,wCAAwC,CAAC;AAGhE,QAAM,iBAAiB,yBAAyB,EAAE,UAAU;AAE5D,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,cAAc,GAAG,cAAc;AACxE,UAAQ,IAAI,MAAM,KAAK,oBAAoB,CAAC;AAG5C,QAAM,UAAU,KAAK,KAAK,YAAY,MAAM;AAE5C,QAAM,GAAG,UAAU,OAAO;AAC1B,QAAM,YAAY,MAAM,GAAG,QAAQ,OAAO;AAE1C,MAAI,UAAU,WAAW,GACzB;AACI,UAAM,cAAc,qBAA6B;AAEjD,UAAM,GAAG,UAAU,KAAK,KAAK,SAAS,WAAW,GAAG,WAAW;AAC/D,YAAQ,IAAI,MAAM,KAAK,sBAAsB,CAAC;AAAA,EAClD;AAGA,QAAM,mBAAmB,UAAU;AACnC,UAAQ,IAAI,MAAM,KAAK,oCAAoC,CAAC;AAG5D,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,QAAQ,CAAC;AAClD,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,mBAAmB,GAAG,2BAA2B;AAC1F,UAAQ,IAAI,MAAM,KAAK,yBAAyB,CAAC;AACjD,QAAM,kBAAkB,UAAU;AAGlC,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,SAAS,GAAG,oBAAoB;AACzE,UAAQ,IAAI,MAAM,KAAK,eAAe,CAAC;AAGvC,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,SAAS,CAAC;AACnD,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,uBAAuB,GAAG,2BAA2B;AAC9F,UAAQ,IAAI,MAAM,KAAK,6BAA6B,CAAC;AAGrD,MAAI,CAAC,aACL;AACI,UAAM,GAAG,UAAU,KAAK,KAAK,YAAY,eAAe,GAAG,2BAA2B;AACtF,YAAQ,IAAI,MAAM,KAAK,qBAAqB,CAAC;AAAA,EACjD;AAGA,MAAI,CAAC,aACL;AACI,UAAM,GAAG,UAAU,KAAK,KAAK,YAAY,gBAAgB,GAAG,uBAAuB;AACnF,YAAQ,IAAI,MAAM,KAAK,sBAAsB,CAAC;AAAA,EAClD;AAGA,MAAI,CAAC,aACL;AACI,UAAM,GAAG,UAAU,KAAK,KAAK,YAAY,kBAAkB,GAAG,yBAAyB;AACvF,YAAQ,IAAI,MAAM,KAAK,wBAAwB,CAAC;AAAA,EACpD;AAGA,QAAM,aAAa,KAAK,KAAK,YAAY,SAAS;AAElD,QAAM,GAAG,UAAU,UAAU;AAC7B,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,eAAe,GAAG,6BAA6B;AACxF,UAAQ,IAAI,MAAM,KAAK,6BAA6B,CAAC;AAErD,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,gBAAgB,GAAG,8BAA8B;AAC1F,UAAQ,IAAI,MAAM,KAAK,8BAA8B,CAAC;AAGtD,QAAM,cAAc,KAAK,KAAK,YAAY,UAAU;AAEpD,MAAI,MAAM,GAAG,WAAW,WAAW,GACnC;AACI,UAAM,GAAG,UAAU,KAAK,KAAK,YAAY,aAAa,GAAG,2BAA2B;AACpF,YAAQ,IAAI,MAAM,KAAK,2BAA2B,CAAC;AAAA,EACvD;AACJ;AAKA,eAAsB,uBAAuB,YAC7C;AACI,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,kBAAkB,GAAG,yBAAyB;AAC3F;AAKA,SAAS,aAAa,SACtB;AACI,QAAM,QAAQ,QAAQ,MAAM,UAAU;AAEtC,SAAO,QAAQ,MAAM,CAAC,IAAI;AAC9B;AAKA,MAAM,2BAA2B;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAKA,MAAM,gBAAgB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAKA,SAAS,cAAc,KAA8B,OACrD;AACI,QAAM,UAAmC,CAAA;AAGzC,aAAW,OAAO,OAClB;AACI,QAAI,OAAO,KACX;AACI,cAAQ,GAAG,IAAI,IAAI,GAAG;AAAA,IAC1B;AAAA,EACJ;AAGA,aAAW,OAAO,OAAO,KAAK,GAAG,GACjC;AACI,QAAI,EAAE,OAAO,UACb;AACI,cAAQ,GAAG,IAAI,IAAI,GAAG;AAAA,IAC1B;AAAA,EACJ;AAEA,SAAO;AACX;AAKA,SAAS,mBAAmB,aAC5B;AACI,QAAM,UAAU,cAAc,aAAa,wBAAwB;AAGnE,MAAI,QAAQ,WAAW,OAAO,QAAQ,YAAY,UAClD;AACI,YAAQ,UAAU,cAAc,QAAQ,SAAoC,aAAa;AAAA,EAC7F;AAEA,SAAO;AACX;AAKA,eAAe,mBAAmB,YAClC;AACI,QAAM,kBAAkB,KAAK,KAAK,YAAY,cAAc;AAG5D,QAAM,kBAAkB,MAAM,GAAG,SAAS,iBAAiB,OAAO;AAClE,QAAM,SAAS,aAAa,eAAe;AAC3C,QAAM,qBAAqB,gBAAgB,SAAS,IAAI;AAExD,QAAM,cAAc,KAAK,MAAM,eAAe;AAE9C,QAAM,eAAe,mBAAmB;AAAA,IACpC,eAAe;AAAA,IACf,gBAAgB;AAAA,EAAA,CACnB;AAGD,MAAI,UAAU;AAEd,MAAI,CAAC,YAAY,iBACjB;AACI,gBAAY,kBAAkB,CAAA;AAAA,EAClC;AAEA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,YAAY,GACtD;AACI,QAAI,EAAE,OAAO,YAAY,kBACzB;AACI,kBAAY,gBAAgB,GAAG,IAAI;AACnC,gBAAU;AACV,cAAQ,IAAI,MAAM,KAAK,yBAAyB,GAAG,OAAO,KAAK,GAAG,CAAC;AAAA,IACvE,WACS,YAAY,gBAAgB,GAAG,MAAM,OAC9C;AACI,kBAAY,gBAAgB,GAAG,IAAI;AACnC,gBAAU;AACV,cAAQ,IAAI,MAAM,KAAK,yBAAyB,GAAG,OAAO,KAAK,GAAG,CAAC;AAAA,IACvE;AAAA,EACJ;AAGA,MAAI,CAAC,YAAY,SACjB;AACI,gBAAY,UAAU,CAAA;AAAA,EAC1B;AAEA,QAAM,kBAA0C;AAAA,IAC5C,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,SAAS;AAAA,IACT,aAAa;AAAA,EAAA;AAIjB,QAAM,cAAc,KAAK,KAAK,YAAY,UAAU;AAEpD,MAAI,MAAM,GAAG,WAAW,WAAW,GACnC;AACI,oBAAgB,cAAc,IAAI;AAClC,oBAAgB,WAAW;AAAA,EAC/B;AAGA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,eAAe,GACzD;AACI,QAAI,EAAE,OAAO,YAAY,UACzB;AACI,kBAAY,QAAQ,GAAG,IAAI;AAC3B,gBAAU;AACV,cAAQ,IAAI,MAAM,KAAK,iBAAiB,GAAG,EAAE,CAAC;AAAA,IAClD;AAAA,EACJ;AAGA,MAAI,YAAY,SAAS,UACzB;AACI,gBAAY,OAAO;AACnB,cAAU;AACV,YAAQ,IAAI,MAAM,KAAK,uBAAuB,CAAC;AAAA,EACnD;AAEA,QAAM,cAAc;AAAA,IAChB,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,EAAA;AAGZ,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,WAAW,GACrD;AACI,QAAI,YAAY,GAAG,MAAM,OACzB;AACI,kBAAY,GAAG,IAAI;AACnB,gBAAU;AACV,cAAQ,IAAI,MAAM,KAAK,SAAS,GAAG,OAAO,KAAK,GAAG,CAAC;AAAA,IACvD;AAAA,EACJ;AAGA,QAAM,kBAAkB;AAAA,IACpB,KAAK;AAAA,MACD,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,IAAA;AAAA,EACb;AAGJ,MAAI,KAAK,UAAU,YAAY,OAAO,MAAM,KAAK,UAAU,eAAe,GAC1E;AACI,gBAAY,UAAU;AACtB,cAAU;AACV,YAAQ,IAAI,MAAM,KAAK,eAAe,CAAC;AAAA,EAC3C;AAGA,MAAI,CAAC,YAAY,YACjB;AACI,gBAAY,aAAa;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEJ,cAAU;AACV,YAAQ,IAAI,MAAM,KAAK,kBAAkB,CAAC;AAAA,EAC9C;AAGA,MAAI,SACJ;AACI,UAAM,qBAAqB,mBAAmB,WAAW;AACzD,QAAI,aAAa,KAAK,UAAU,oBAAoB,MAAM,MAAM;AAEhE,QAAI,oBACJ;AACI,oBAAc;AAAA,IAClB;AACA,UAAM,GAAG,UAAU,iBAAiB,UAAU;AAAA,EAClD;AACJ;AAKA,eAAe,kBAAkB,YACjC;AACI,QAAM,kBAAkB,KAAK,KAAK,YAAY,cAAc;AAG5D,QAAM,kBAAkB,MAAM,GAAG,SAAS,iBAAiB,OAAO;AAClE,QAAM,SAAS,aAAa,eAAe;AAC3C,QAAM,qBAAqB,gBAAgB,SAAS,IAAI;AAExD,QAAM,cAAc,KAAK,MAAM,eAAe;AAC9C,MAAI,UAAU;AAGd,MAAI,CAAC,YAAY,iBACjB;AACI,gBAAY,kBAAkB,CAAA;AAAA,EAClC;AACA,MAAI,YAAY,gBAAgB,UAAU,SAAS,OACnD;AACI,gBAAY,gBAAgB,QAAQ,SAAS;AAC7C,cAAU;AACV,YAAQ,IAAI,MAAM,KAAK,kCAAkC,SAAS,KAAK,GAAG,CAAC;AAAA,EAC/E;AACA,MAAI,YAAY,gBAAgB,aAAa,MAAM,SAAS,aAAa,GACzE;AACI,gBAAY,gBAAgB,aAAa,IAAI,SAAS,aAAa;AACnE,cAAU;AACV,YAAQ,IAAI,MAAM,KAAK,wCAAwC,SAAS,aAAa,CAAC,GAAG,CAAC;AAAA,EAC9F;AAGA,MAAI,CAAC,YAAY,SACjB;AACI,gBAAY,UAAU,CAAA;AAAA,EAC1B;AACA,MAAI,YAAY,QAAQ,YAAY,SACpC;AACI,gBAAY,QAAQ,UAAU;AAC9B,cAAU;AACV,YAAQ,IAAI,MAAM,KAAK,iCAAiC,CAAC;AAAA,EAC7D;AAGA,QAAM,qBAAqB;AAAA,IACvB,aAAa,CAAC,+BAA+B;AAAA,EAAA;AAGjD,MAAI,KAAK,UAAU,YAAY,aAAa,CAAC,MAAM,KAAK,UAAU,kBAAkB,GACpF;AACI,gBAAY,aAAa,IAAI;AAC7B,cAAU;AACV,YAAQ,IAAI,MAAM,KAAK,sBAAsB,CAAC;AAAA,EAClD;AAGA,MAAI,SACJ;AACI,UAAM,qBAAqB,mBAAmB,WAAW;AACzD,QAAI,aAAa,KAAK,UAAU,oBAAoB,MAAM,MAAM;AAEhE,QAAI,oBACJ;AACI,oBAAc;AAAA,IAClB;AACA,UAAM,GAAG,UAAU,iBAAiB,UAAU;AAAA,EAClD;AACJ;ACreA,eAAsB,cAAc,MAAc,SAClD;AACI,QAAM,aAAa,KAAK,KAAK,QAAQ,WAAW,IAAI;AAGpD,MAAI,MAAM,GAAG,WAAW,UAAU,GAClC;AACI,UAAM,IAAI,MAAM,MAAM,UAAU,MAAM;AAAA,EAC1C;AAGA,QAAM,GAAG,UAAU,UAAU;AAC7B,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,KAAK,CAAC;AAE/C,UAAQ,IAAI,MAAM,KAAK,WAAW,UAAU,EAAE,CAAC;AAG/C,QAAM,cAAc,kBAAkB,MAAM,OAAO;AAEnD,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,cAAc,GAAG,aAAa,EAAE,QAAQ,EAAA,CAAG;AACpF,UAAQ,IAAI,MAAM,KAAK,oBAAoB,CAAC;AAG5C,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,eAAe,GAAG,oBAAA,GAAuB,EAAE,QAAQ,EAAA,CAAG;AAC/F,UAAQ,IAAI,MAAM,KAAK,qBAAqB,CAAC;AAG7C,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,YAAY,GAAG,sBAAsB;AAC9E,UAAQ,IAAI,MAAM,KAAK,kBAAkB,CAAC;AAG1C,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,cAAc,GAAG,yBAAyB;AACnF,UAAQ,IAAI,MAAM,KAAK,oBAAoB,CAAC;AAG5C,QAAM,uBAAuB,UAAU;AACvC,UAAQ,IAAI,MAAM,KAAK,wBAAwB,CAAC;AAGhD,QAAM,gBAAgB,iBAAiB,EAAE,UAAU,MAAM;AAEzD,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,cAAc,GAAG,eAAe,EAAE,QAAQ,EAAA,CAAG;AACtF,UAAQ,IAAI,MAAM,KAAK,oBAAoB,CAAC;AAG5C,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,cAAc,GAAG,oBAAoB,EAAE,MAAM,WAAW,IAAI,GAAA,CAAI,CAAC;AAC1G,UAAQ,IAAI,MAAM,KAAK,oBAAoB,CAAC;AAG5C,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,WAAW,GAAG,aAAa,IAAI;AAAA,CAAI;AAC5E,UAAQ,IAAI,MAAM,KAAK,iBAAiB,CAAC;AAGzC,MAAI,QAAQ,aAAa,OACzB;AACI,UAAM,GAAG,UAAU,KAAK,KAAK,YAAY,UAAU,CAAC;AACpD,YAAQ,IAAI,MAAM,KAAK,iBAAiB,CAAC;AAAA,EAC7C;AAGA,MAAI,QAAQ,WAAW,OACvB;AACI,UAAM,GAAG,UAAU,KAAK,KAAK,YAAY,MAAM,CAAC;AAChD,YAAQ,IAAI,MAAM,KAAK,aAAa,CAAC;AAAA,EACzC;AAGA,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,mBAAmB,CAAC;AAC7D,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,+BAA+B,GAAG,4BAA4B;AACvG,UAAQ,IAAI,MAAM,KAAK,qCAAqC,CAAC;AAG7D,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,SAAS,CAAC;AACnD,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,uBAAuB,GAAG,6BAA6B;AAChG,QAAM,GAAG,UAAU,KAAK,KAAK,YAAY,wBAAwB,GAAG,8BAA8B;AAClG,UAAQ,IAAI,MAAM,KAAK,6BAA6B,CAAC;AACrD,UAAQ,IAAI,MAAM,KAAK,8BAA8B,CAAC;AAGtD,MAAI,QAAQ,aAAa,OACzB;AACI,UAAM,GAAG,UAAU,KAAK,KAAK,YAAY,qBAAqB,GAAG,2BAA2B;AAC5F,YAAQ,IAAI,MAAM,KAAK,2BAA2B,CAAC;AAAA,EACvD;AACJ;AAKA,SAAS,kBAAkB,MAAc,SACzC;AACI,QAAM,UAAkC;AAAA,IACpC,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,aAAa;AAAA,EAAA;AAIjB,MAAI,QAAQ,aAAa,OACzB;AACI,YAAQ,cAAc,IAAI;AAC1B,YAAQ,WAAW;AAAA,EACvB;AAEA,MAAI,QAAQ,WAAW,OACvB;AACI,YAAQ,OAAO;AACf,YAAQ,YAAY,IAAI;AAAA,EAC5B;AAEA,SAAO;AAAA,IACH,MAAM,WAAW,IAAI;AAAA,IACrB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,UAAU,sBAAsB,IAAI;AAAA,IACpC,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,MACL,KAAK;AAAA,QACD,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,MAAA;AAAA,IACb;AAAA,IAEJ;AAAA,IACA,YAAY;AAAA,MACR,MAAM;AAAA,MACN,KAAK,kCAAkC,IAAI;AAAA,IAAA;AAAA,IAE/C,eAAe;AAAA,MACX,QAAQ;AAAA,IAAA;AAAA,IAEZ,OAAO,CAAC,OAAO,QAAQ,KAAK;AAAA,IAC5B,iBAAiB,mBAAmB;AAAA,MAChC,eAAe,QAAQ,WAAW;AAAA,MAClC,gBAAgB;AAAA,IAAA,CACnB;AAAA,EAAA;AAET;"}
1
+ {"version":3,"file":"index.js","sources":["../src/versions.ts","../src/templates.ts","../src/commands/update.ts","../src/commands/create.ts","../src/commands/install-skill.ts"],"sourcesContent":["/**\n * feng3d 项目统一依赖版本\n * 从 templates/package.json 中读取\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\n/**\n * 模板目录路径\n */\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst TEMPLATES_DIR = path.resolve(__dirname, '../templates');\n\n/**\n * 从模板 package.json 中读取 devDependencies\n */\nfunction loadVersionsFromTemplate(): Record<string, string>\n{\n const packageJsonPath = path.join(TEMPLATES_DIR, 'package.json');\n const packageJson = fs.readJsonSync(packageJsonPath);\n\n return packageJson.devDependencies || {};\n}\n\n/**\n * 统一依赖版本(从 templates/package.json 读取)\n */\nexport const VERSIONS = loadVersionsFromTemplate();\n\n/**\n * 获取 devDependencies 配置\n */\nexport function getDevDependencies(options: {\n includeVitest?: boolean;\n includeTypedoc?: boolean;\n includeCoverage?: boolean;\n} = {}): Record<string, string>\n{\n // 从 VERSIONS 中复制所有依赖\n const deps: Record<string, string> = { ...VERSIONS };\n\n // 根据选项移除可选依赖\n if (options.includeVitest === false)\n {\n delete deps.vitest;\n }\n\n if (options.includeTypedoc === false)\n {\n delete deps.typedoc;\n }\n\n // 可选添加覆盖率依赖(默认不包含)\n if (options.includeCoverage && !deps['@vitest/coverage-v8'])\n {\n deps['@vitest/coverage-v8'] = '^3.2.4';\n }\n\n return deps;\n}\n","/**\n * 项目模板文件内容\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\n/**\n * 模板目录路径\n */\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst TEMPLATES_DIR = path.resolve(__dirname, '../templates');\n\n/**\n * 获取 .gitignore 模板内容\n */\nexport function getGitignoreTemplate(): string\n{\n // 模板文件命名为 gitignore(不带点),避免对 templates 目录生效\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'gitignore'), 'utf-8');\n}\n\n/**\n * 获取 .cursorrules 模板内容\n */\nexport function getCursorrrulesTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.cursorrules'), 'utf-8');\n}\n\n/**\n * 获取 tsconfig.json 模板内容(对象形式)\n */\nexport function getTsconfigTemplate(): object\n{\n return fs.readJsonSync(path.join(TEMPLATES_DIR, 'tsconfig.json'));\n}\n\n/**\n * 获取 tsconfig.json 模板内容(字符串形式)\n */\nexport function getTsconfigTemplateString(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'tsconfig.json'), 'utf-8');\n}\n\n/**\n * 获取 vite.config.js 模板内容\n */\nexport function getViteConfigTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'vite.config.js'), 'utf-8');\n}\n\n/**\n * 获取 eslint.config.js 模板内容\n */\nexport function getEslintConfigTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'eslint.config.js'), 'utf-8');\n}\n\n/**\n * 获取 typedoc.json 模板内容(返回对象)\n */\nexport function getTypedocConfig(options: {\n repoName: string;\n}): object\n{\n return JSON.parse(getTypedocConfigTemplate(options));\n}\n\n/**\n * 获取 typedoc.json 模板内容(返回字符串)\n */\nexport function getTypedocConfigTemplate(options: {\n repoName: string;\n}): string\n{\n const templateContent = fs.readFileSync(path.join(TEMPLATES_DIR, 'typedoc.json'), 'utf-8');\n\n return templateContent.replace(/\\{\\{repoName\\}\\}/g, options.repoName);\n}\n\n/**\n * 获取 test/_.test.ts 模板内容(空文件占位)\n */\nexport function getTestIndexTemplate(_options: { name: string }): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'test/_.test.ts'), 'utf-8');\n}\n\n/**\n * 获取 GitHub Actions publish workflow 模板内容\n */\nexport function getPublishWorkflowTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.github/workflows/publish.yml'), 'utf-8');\n}\n\n/**\n * 获取 GitHub Actions pages workflow 模板内容\n */\nexport function getPagesWorkflowTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.github/workflows/pages.yml'), 'utf-8');\n}\n\n/**\n * 获取 GitHub Actions pull-request workflow 模板内容\n */\nexport function getPullRequestWorkflowTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.github/workflows/pull-request.yml'), 'utf-8');\n}\n\n/**\n * 获取 GitHub Actions upload-oss workflow 模板内容\n */\nexport function getUploadOssWorkflowTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.github/workflows/upload-oss.yml'), 'utf-8');\n}\n\n/**\n * 获取 .husky/pre-commit 模板内容\n */\nexport function getHuskyPreCommitTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.husky/pre-commit'), 'utf-8');\n}\n\n/**\n * 获取 LICENSE 模板内容\n */\nexport function getLicenseTemplate(ctx: { year?: number } = {}): string\n{\n const year = ctx.year || new Date().getFullYear();\n const template = fs.readFileSync(path.join(TEMPLATES_DIR, 'LICENSE'), 'utf-8');\n\n return template.replace('{{year}}', String(year));\n}\n\n/**\n * 获取 .vscode/settings.json 模板内容\n */\nexport function getVscodeSettingsTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.vscode/settings.json'), 'utf-8');\n}\n\n/**\n * 获取 scripts/prepublish.js 模板内容\n */\nexport function getPrepublishScriptTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'scripts/prepublish.js'), 'utf-8');\n}\n\n/**\n * 获取 scripts/postpublish.js 模板内容\n */\nexport function getPostpublishScriptTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'scripts/postpublish.js'), 'utf-8');\n}\n\n/**\n * 获取 scripts/postdocs.js 模板内容\n */\nexport function getPostdocsScriptTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'scripts/postdocs.js'), 'utf-8');\n}\n\n/**\n * 获取 src/index.ts 模板内容\n */\nexport function getSrcIndexTemplate(options: { name: string }): string\n{\n const template = fs.readFileSync(path.join(TEMPLATES_DIR, 'src/index.ts'), 'utf-8');\n\n return template.replace(/\\{\\{name\\}\\}/g, options.name);\n}\n\n/**\n * 获取 vitest.config.ts 模板内容\n */\nexport function getVitestConfigTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'vitest.config.ts'), 'utf-8');\n}\n\n","/**\n * 更新项目规范命令\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport chalk from 'chalk';\nimport { getDevDependencies, VERSIONS } from '../versions.js';\nimport {\n getGitignoreTemplate,\n getCursorrrulesTemplate,\n getEslintConfigTemplate,\n getPublishWorkflowTemplate,\n getPagesWorkflowTemplate,\n getPullRequestWorkflowTemplate,\n getUploadOssWorkflowTemplate,\n getTypedocConfigTemplate,\n getTestIndexTemplate,\n getHuskyPreCommitTemplate,\n getLicenseTemplate,\n getVscodeSettingsTemplate,\n getTsconfigTemplateString,\n getViteConfigTemplate,\n getVitestConfigTemplate,\n getPrepublishScriptTemplate,\n getPostpublishScriptTemplate,\n getPostdocsScriptTemplate,\n getSrcIndexTemplate,\n} from '../templates.js';\n\n/**\n * 模板上下文\n */\ninterface TemplateContext {\n name: string;\n repoName: string;\n}\n\n/**\n * 更新项目的规范配置\n * @param directory 项目目录路径\n */\nexport async function updateProject(directory: string = '.'): Promise<void>\n{\n const projectDir = path.resolve(directory);\n const packageJsonPath = path.join(projectDir, 'package.json');\n\n // 如果 package.json 不存在,创建基础 package.json\n if (!await fs.pathExists(packageJsonPath))\n {\n await fs.ensureDir(projectDir);\n const dirName = path.basename(projectDir);\n const initialPackageJson = {\n name: `@feng3d/${dirName}`,\n version: '0.0.1',\n description: '',\n };\n\n await fs.writeJson(packageJsonPath, initialPackageJson, { spaces: 4 });\n console.log(chalk.gray(' 创建: package.json'));\n\n // 创建 src/index.ts\n const srcDir = path.join(projectDir, 'src');\n\n await fs.ensureDir(srcDir);\n await fs.writeFile(path.join(srcDir, 'index.ts'), getSrcIndexTemplate({ name: `@feng3d/${dirName}` }));\n console.log(chalk.gray(' 创建: src/index.ts'));\n }\n\n // 获取项目信息用于模板\n const packageJson = await fs.readJson(packageJsonPath);\n const name = packageJson.name || path.basename(projectDir);\n const repoName = name.replace(/^@[^/]+\\//, ''); // 移除 scope 前缀\n const templateContext: TemplateContext = { name, repoName };\n\n // feng3d-cli 项目:不更新 tsconfig.json 和 vite.config.js(有自定义配置)\n const isFeng3dCli = name === 'feng3d-cli';\n\n // 更新 .gitignore(强制覆盖)\n await fs.writeFile(path.join(projectDir, '.gitignore'), getGitignoreTemplate());\n console.log(chalk.gray(' 更新: .gitignore'));\n\n // 更新 .cursorrules\n await fs.writeFile(path.join(projectDir, '.cursorrules'), getCursorrrulesTemplate());\n console.log(chalk.gray(' 更新: .cursorrules'));\n\n // 更新 eslint.config.js\n await createEslintConfigFile(projectDir);\n console.log(chalk.gray(' 更新: eslint.config.js'));\n\n // 更新 .github/workflows/publish.yml\n await fs.ensureDir(path.join(projectDir, '.github/workflows'));\n await fs.writeFile(path.join(projectDir, '.github/workflows/publish.yml'), getPublishWorkflowTemplate());\n console.log(chalk.gray(' 更新: .github/workflows/publish.yml'));\n\n // 更新 .github/workflows/pages.yml\n await fs.writeFile(path.join(projectDir, '.github/workflows/pages.yml'), getPagesWorkflowTemplate());\n console.log(chalk.gray(' 更新: .github/workflows/pages.yml'));\n\n // 更新 .github/workflows/pull-request.yml\n await fs.writeFile(path.join(projectDir, '.github/workflows/pull-request.yml'), getPullRequestWorkflowTemplate());\n console.log(chalk.gray(' 更新: .github/workflows/pull-request.yml'));\n\n // 更新 .github/workflows/upload-oss.yml\n await fs.writeFile(path.join(projectDir, '.github/workflows/upload-oss.yml'), getUploadOssWorkflowTemplate());\n console.log(chalk.gray(' 更新: .github/workflows/upload-oss.yml'));\n\n // 更新 typedoc.json\n const typedocContent = getTypedocConfigTemplate({ repoName });\n\n await fs.writeFile(path.join(projectDir, 'typedoc.json'), typedocContent);\n console.log(chalk.gray(' 更新: typedoc.json'));\n\n // 创建 test/_.test.ts(仅当 test 目录为空时)\n const testDir = path.join(projectDir, 'test');\n\n await fs.ensureDir(testDir);\n const testFiles = await fs.readdir(testDir);\n\n if (testFiles.length === 0)\n {\n const testContent = getTestIndexTemplate({ name });\n\n await fs.writeFile(path.join(testDir, '_.test.ts'), testContent);\n console.log(chalk.gray(' 创建: test/_.test.ts'));\n }\n\n // 更新依赖版本\n await updateDependencies(projectDir);\n console.log(chalk.gray(' 更新: package.json devDependencies'));\n\n // 更新 husky pre-commit hook\n await fs.ensureDir(path.join(projectDir, '.husky'));\n await fs.writeFile(path.join(projectDir, '.husky/pre-commit'), getHuskyPreCommitTemplate());\n console.log(chalk.gray(' 更新: .husky/pre-commit'));\n await updateHuskyConfig(projectDir);\n\n // 更新 LICENSE 文件(强制覆盖)\n await fs.writeFile(path.join(projectDir, 'LICENSE'), getLicenseTemplate());\n console.log(chalk.gray(' 更新: LICENSE'));\n\n // 更新 .vscode/settings.json\n await fs.ensureDir(path.join(projectDir, '.vscode'));\n await fs.writeFile(path.join(projectDir, '.vscode/settings.json'), getVscodeSettingsTemplate());\n console.log(chalk.gray(' 更新: .vscode/settings.json'));\n\n // 更新 tsconfig.json(强制覆盖,feng3d-cli 跳过)\n if (!isFeng3dCli)\n {\n await fs.writeFile(path.join(projectDir, 'tsconfig.json'), getTsconfigTemplateString());\n console.log(chalk.gray(' 更新: tsconfig.json'));\n }\n\n // 更新 vite.config.js(强制覆盖,feng3d-cli 跳过)\n if (!isFeng3dCli)\n {\n await fs.writeFile(path.join(projectDir, 'vite.config.js'), getViteConfigTemplate());\n console.log(chalk.gray(' 更新: vite.config.js'));\n }\n\n // 更新 vitest.config.ts(强制覆盖,feng3d-cli 跳过)\n if (!isFeng3dCli)\n {\n await fs.writeFile(path.join(projectDir, 'vitest.config.ts'), getVitestConfigTemplate());\n console.log(chalk.gray(' 更新: vitest.config.ts'));\n }\n\n // 更新发布脚本(强制覆盖)\n const scriptsDir = path.join(projectDir, 'scripts');\n\n await fs.ensureDir(scriptsDir);\n await fs.writeFile(path.join(scriptsDir, 'prepublish.js'), getPrepublishScriptTemplate());\n console.log(chalk.gray(' 更新: scripts/prepublish.js'));\n\n await fs.writeFile(path.join(scriptsDir, 'postpublish.js'), getPostpublishScriptTemplate());\n console.log(chalk.gray(' 更新: scripts/postpublish.js'));\n\n // 如果存在 examples 目录,更新 postdocs.js 脚本(强制覆盖)\n const examplesDir = path.join(projectDir, 'examples');\n\n if (await fs.pathExists(examplesDir))\n {\n await fs.writeFile(path.join(scriptsDir, 'postdocs.js'), getPostdocsScriptTemplate());\n console.log(chalk.gray(' 更新: scripts/postdocs.js'));\n }\n}\n\n/**\n * 创建 ESLint 配置文件\n */\nexport async function createEslintConfigFile(projectDir: string): Promise<void>\n{\n await fs.writeFile(path.join(projectDir, 'eslint.config.js'), getEslintConfigTemplate());\n}\n\n/**\n * 检测 JSON 文件的缩进风格\n */\nfunction detectIndent(content: string): string\n{\n const match = content.match(/^[ \\t]+/m);\n\n return match ? match[0] : ' ';\n}\n\n/**\n * package.json 字段的标准顺序\n */\nconst PACKAGE_JSON_FIELD_ORDER = [\n 'name',\n 'version',\n 'description',\n 'homepage',\n 'author',\n 'license',\n 'type',\n 'main',\n 'types',\n 'module',\n 'exports',\n 'bin',\n 'scripts',\n 'repository',\n 'publishConfig',\n 'files',\n 'devDependencies',\n 'dependencies',\n 'peerDependencies',\n 'lint-staged',\n 'workspaces',\n];\n\n/**\n * scripts 字段的标准顺序\n */\nconst SCRIPTS_ORDER = [\n 'examples:dev',\n 'test_web',\n 'postdocs',\n 'clean',\n 'build',\n 'watch',\n 'test',\n 'lint',\n 'lintfix',\n 'docs',\n 'prepublishOnly',\n 'release',\n 'postpublish',\n 'prepare',\n];\n\n/**\n * 按标准顺序重新排列对象字段\n */\nfunction reorderObject(obj: Record<string, unknown>, order: string[]): Record<string, unknown>\n{\n const ordered: Record<string, unknown> = {};\n\n // 先按标准顺序添加已存在的字段\n for (const key of order)\n {\n if (key in obj)\n {\n ordered[key] = obj[key];\n }\n }\n\n // 再添加其他未在标准顺序中的字段\n for (const key of Object.keys(obj))\n {\n if (!(key in ordered))\n {\n ordered[key] = obj[key];\n }\n }\n\n return ordered;\n}\n\n/**\n * 按标准顺序重新排列 package.json 字段\n */\nfunction reorderPackageJson(packageJson: Record<string, unknown>): Record<string, unknown>\n{\n const ordered = reorderObject(packageJson, PACKAGE_JSON_FIELD_ORDER);\n\n // 重新排列 scripts\n if (ordered.scripts && typeof ordered.scripts === 'object')\n {\n ordered.scripts = reorderObject(ordered.scripts as Record<string, unknown>, SCRIPTS_ORDER);\n }\n\n return ordered;\n}\n\n/**\n * 更新 package.json 中的 devDependencies 版本\n */\nasync function updateDependencies(projectDir: string): Promise<void>\n{\n const packageJsonPath = path.join(projectDir, 'package.json');\n\n // 读取原始内容以检测缩进风格\n const originalContent = await fs.readFile(packageJsonPath, 'utf-8');\n const indent = detectIndent(originalContent);\n const hasTrailingNewline = originalContent.endsWith('\\n');\n\n const packageJson = JSON.parse(originalContent);\n\n const standardDeps = getDevDependencies({\n includeVitest: true,\n includeTypedoc: true,\n });\n\n // 添加或更新 devDependencies\n let updated = false;\n\n if (!packageJson.devDependencies)\n {\n packageJson.devDependencies = {};\n }\n\n for (const [key, value] of Object.entries(standardDeps))\n {\n if (!(key in packageJson.devDependencies))\n {\n packageJson.devDependencies[key] = value;\n updated = true;\n console.log(chalk.gray(` 添加: devDependencies.${key} = \"${value}\"`));\n }\n else if (packageJson.devDependencies[key] !== value)\n {\n packageJson.devDependencies[key] = value;\n updated = true;\n console.log(chalk.gray(` 更新: devDependencies.${key} = \"${value}\"`));\n }\n }\n\n // 添加标准 scripts\n if (!packageJson.scripts)\n {\n packageJson.scripts = {};\n }\n\n const standardScripts: Record<string, string> = {\n clean: 'rimraf lib dist public',\n build: 'vite build && tsc',\n watch: 'concurrently \"vite build --watch\" \"tsc -w\" \"vitest\"',\n test: 'vitest run',\n lint: 'eslint . --ext .js,.ts --max-warnings 0',\n lintfix: 'npm run lint -- --fix',\n docs: 'typedoc',\n prepublishOnly: 'node scripts/prepublish.js',\n release: 'npm run clean && npm run lint && npm test && npm run build && npm run docs && npm publish',\n postpublish: 'node scripts/postpublish.js',\n };\n\n // 检查是否存在 examples 目录,添加相关脚本\n const examplesDir = path.join(projectDir, 'examples');\n\n if (await fs.pathExists(examplesDir))\n {\n standardScripts['examples:dev'] = 'cd examples && npm run dev';\n standardScripts.postdocs = 'node scripts/postdocs.js && cd examples && vite build --outDir ../public';\n }\n\n // 如果 scripts 不存在则添加,存在时不覆盖\n for (const [key, value] of Object.entries(standardScripts))\n {\n if (!(key in packageJson.scripts))\n {\n packageJson.scripts[key] = value;\n updated = true;\n console.log(chalk.gray(` 添加: scripts.${key}`));\n }\n }\n\n // 设置标准入口点配置(强制覆盖)\n if (packageJson.type !== 'module')\n {\n packageJson.type = 'module';\n updated = true;\n console.log(chalk.gray(' 更新: type = \"module\"'));\n }\n\n const entryPoints = {\n main: './src/index.ts',\n types: './src/index.ts',\n module: './src/index.ts',\n };\n\n for (const [key, value] of Object.entries(entryPoints))\n {\n if (packageJson[key] !== value)\n {\n packageJson[key] = value;\n updated = true;\n console.log(chalk.gray(` 更新: ${key} = \"${value}\"`));\n }\n }\n\n // 设置 exports 配置(强制覆盖)\n const standardExports = {\n '.': {\n types: './src/index.ts',\n import: './src/index.ts',\n require: './src/index.ts',\n },\n };\n\n if (JSON.stringify(packageJson.exports) !== JSON.stringify(standardExports))\n {\n packageJson.exports = standardExports;\n updated = true;\n console.log(chalk.gray(' 更新: exports'));\n }\n\n // 如果 workspaces 不存在则添加\n if (!packageJson.workspaces)\n {\n packageJson.workspaces = [\n '.',\n './examples',\n './test_web',\n 'packages/*',\n 'packages/*/examples',\n ];\n updated = true;\n console.log(chalk.gray(' 添加: workspaces'));\n }\n\n // 只有在有更新时才写入文件\n if (updated)\n {\n const orderedPackageJson = reorderPackageJson(packageJson);\n let newContent = JSON.stringify(orderedPackageJson, null, indent);\n\n if (hasTrailingNewline)\n {\n newContent += '\\n';\n }\n await fs.writeFile(packageJsonPath, newContent);\n }\n}\n\n/**\n * 更新 package.json 添加 husky 配置\n */\nasync function updateHuskyConfig(projectDir: string): Promise<void>\n{\n const packageJsonPath = path.join(projectDir, 'package.json');\n\n // 读取原始内容以检测缩进风格\n const originalContent = await fs.readFile(packageJsonPath, 'utf-8');\n const indent = detectIndent(originalContent);\n const hasTrailingNewline = originalContent.endsWith('\\n');\n\n const packageJson = JSON.parse(originalContent);\n let updated = false;\n\n // 强制覆盖 husky 和 lint-staged 依赖\n if (!packageJson.devDependencies)\n {\n packageJson.devDependencies = {};\n }\n if (packageJson.devDependencies.husky !== VERSIONS.husky)\n {\n packageJson.devDependencies.husky = VERSIONS.husky;\n updated = true;\n console.log(chalk.gray(` 更新: devDependencies.husky = \"${VERSIONS.husky}\"`));\n }\n if (packageJson.devDependencies['lint-staged'] !== VERSIONS['lint-staged'])\n {\n packageJson.devDependencies['lint-staged'] = VERSIONS['lint-staged'];\n updated = true;\n console.log(chalk.gray(` 更新: devDependencies.lint-staged = \"${VERSIONS['lint-staged']}\"`));\n }\n\n // 强制覆盖 prepare 脚本\n if (!packageJson.scripts)\n {\n packageJson.scripts = {};\n }\n if (packageJson.scripts.prepare !== 'husky')\n {\n packageJson.scripts.prepare = 'husky';\n updated = true;\n console.log(chalk.gray(' 更新: scripts.prepare = \"husky\"'));\n }\n\n // 强制覆盖 lint-staged 配置\n const standardLintStaged = {\n '*.{js,ts}': ['eslint --fix --max-warnings 0'],\n };\n\n if (JSON.stringify(packageJson['lint-staged']) !== JSON.stringify(standardLintStaged))\n {\n packageJson['lint-staged'] = standardLintStaged;\n updated = true;\n console.log(chalk.gray(' 更新: lint-staged 配置'));\n }\n\n // 只有在有更新时才写入文件\n if (updated)\n {\n const orderedPackageJson = reorderPackageJson(packageJson);\n let newContent = JSON.stringify(orderedPackageJson, null, indent);\n\n if (hasTrailingNewline)\n {\n newContent += '\\n';\n }\n await fs.writeFile(packageJsonPath, newContent);\n }\n}\n","/**\n * 创建新项目命令\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport chalk from 'chalk';\nimport { getDevDependencies } from '../versions.js';\nimport {\n getGitignoreTemplate,\n getCursorrrulesTemplate,\n getTsconfigTemplate,\n getTypedocConfig,\n getPublishWorkflowTemplate,\n getPrepublishScriptTemplate,\n getPostpublishScriptTemplate,\n getPostdocsScriptTemplate,\n getSrcIndexTemplate,\n} from '../templates.js';\nimport { createEslintConfigFile } from './update.js';\n\nexport interface CreateOptions {\n directory: string;\n examples?: boolean;\n vitest?: boolean;\n}\n\n/**\n * 创建符合 feng3d 规范的新项目\n */\nexport async function createProject(name: string, options: CreateOptions): Promise<void>\n{\n const projectDir = path.join(options.directory, name);\n\n // 检查目录是否已存在\n if (await fs.pathExists(projectDir))\n {\n throw new Error(`目录 ${projectDir} 已存在`);\n }\n\n // 创建项目目录\n await fs.ensureDir(projectDir);\n await fs.ensureDir(path.join(projectDir, 'src'));\n\n console.log(chalk.gray(` 创建目录: ${projectDir}`));\n\n // 创建 package.json\n const packageJson = createPackageJson(name, options);\n\n await fs.writeJson(path.join(projectDir, 'package.json'), packageJson, { spaces: 4 });\n console.log(chalk.gray(' 创建: package.json'));\n\n // 创建 tsconfig.json\n await fs.writeJson(path.join(projectDir, 'tsconfig.json'), getTsconfigTemplate(), { spaces: 4 });\n console.log(chalk.gray(' 创建: tsconfig.json'));\n\n // 创建 .gitignore\n await fs.writeFile(path.join(projectDir, '.gitignore'), getGitignoreTemplate());\n console.log(chalk.gray(' 创建: .gitignore'));\n\n // 创建 .cursorrules\n await fs.writeFile(path.join(projectDir, '.cursorrules'), getCursorrrulesTemplate());\n console.log(chalk.gray(' 创建: .cursorrules'));\n\n // 创建 eslint.config.js\n await createEslintConfigFile(projectDir);\n console.log(chalk.gray(' 创建: eslint.config.js'));\n\n // 创建 typedoc.json\n const typedocConfig = getTypedocConfig({ repoName: name });\n\n await fs.writeJson(path.join(projectDir, 'typedoc.json'), typedocConfig, { spaces: 4 });\n console.log(chalk.gray(' 创建: typedoc.json'));\n\n // 创建 src/index.ts\n await fs.writeFile(path.join(projectDir, 'src/index.ts'), getSrcIndexTemplate({ name: `@feng3d/${name}` }));\n console.log(chalk.gray(' 创建: src/index.ts'));\n\n // 创建 README.md\n await fs.writeFile(path.join(projectDir, 'README.md'), `# @feng3d/${name}\\n`);\n console.log(chalk.gray(' 创建: README.md'));\n\n // 创建示例目录\n if (options.examples !== false)\n {\n await fs.ensureDir(path.join(projectDir, 'examples'));\n console.log(chalk.gray(' 创建: examples/'));\n }\n\n // 创建测试目录\n if (options.vitest !== false)\n {\n await fs.ensureDir(path.join(projectDir, 'test'));\n console.log(chalk.gray(' 创建: test/'));\n }\n\n // 创建 .github/workflows 目录和 publish.yml\n await fs.ensureDir(path.join(projectDir, '.github/workflows'));\n await fs.writeFile(path.join(projectDir, '.github/workflows/publish.yml'), getPublishWorkflowTemplate());\n console.log(chalk.gray(' 创建: .github/workflows/publish.yml'));\n\n // 创建 scripts 目录和发布脚本\n await fs.ensureDir(path.join(projectDir, 'scripts'));\n await fs.writeFile(path.join(projectDir, 'scripts/prepublish.js'), getPrepublishScriptTemplate());\n await fs.writeFile(path.join(projectDir, 'scripts/postpublish.js'), getPostpublishScriptTemplate());\n console.log(chalk.gray(' 创建: scripts/prepublish.js'));\n console.log(chalk.gray(' 创建: scripts/postpublish.js'));\n\n // 如果创建了 examples 目录,添加 postdocs.js 脚本\n if (options.examples !== false)\n {\n await fs.writeFile(path.join(projectDir, 'scripts/postdocs.js'), getPostdocsScriptTemplate());\n console.log(chalk.gray(' 创建: scripts/postdocs.js'));\n }\n}\n\n/**\n * 创建 package.json 内容\n */\nfunction createPackageJson(name: string, options: CreateOptions): object\n{\n const scripts: Record<string, string> = {\n clean: 'rimraf lib dist public',\n build: 'vite build && tsc',\n types: 'tsc',\n watch: 'tsc -w',\n lint: 'eslint . --ext .js,.ts --max-warnings 0',\n lintfix: 'npm run lint -- --fix',\n docs: 'typedoc',\n release: 'npm run clean && npm run lint && npm test && npm run build && npm run docs && npm publish',\n prepublishOnly: 'node scripts/prepublish.js',\n postpublish: 'node scripts/postpublish.js',\n };\n\n // 如果包含 examples 目录,添加相关脚本\n if (options.examples !== false)\n {\n scripts['examples:dev'] = 'cd examples && npm run dev';\n scripts.postdocs = 'node scripts/postdocs.js && cd examples && vite build --outDir ../public';\n }\n\n if (options.vitest !== false)\n {\n scripts.test = 'vitest run';\n scripts['test:watch'] = 'vitest';\n }\n\n return {\n name: `@feng3d/${name}`,\n version: '0.0.1',\n description: '',\n homepage: `https://feng3d.com/${name}/`,\n author: 'feng',\n type: 'module',\n main: './src/index.ts',\n types: './src/index.ts',\n module: './src/index.ts',\n exports: {\n '.': {\n types: './src/index.ts',\n import: './src/index.ts',\n require: './src/index.ts',\n },\n },\n scripts,\n repository: {\n type: 'git',\n url: `https://github.com/feng3d-labs/${name}.git`,\n },\n publishConfig: {\n access: 'public',\n },\n files: ['src', 'dist', 'lib'],\n devDependencies: getDevDependencies({\n includeVitest: options.vitest !== false,\n includeTypedoc: true,\n }),\n };\n}\n\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport os from 'os';\nimport chalk from 'chalk';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/**\n * 安装 Claude Code Skill\n */\nexport async function installSkill()\n{\n try\n {\n // 获取用户主目录\n const homeDir = os.homedir();\n const claudeSkillsDir = path.join(homeDir, '.claude', 'skills', 'feng3d');\n\n // 获取 .claude-skill 源目录\n // 尝试多个可能的路径\n const possiblePaths = [\n // 从当前文件位置向上查找(开发环境)\n path.resolve(__dirname, '../../.claude-skill'),\n path.resolve(__dirname, '../../../.claude-skill'),\n path.resolve(__dirname, '../.claude-skill'),\n // 从 package.json 所在目录查找\n path.resolve(process.cwd(), '.claude-skill'),\n // 从 node_modules 查找(全局安装)\n path.resolve(__dirname, '../../../../feng3d-cli/.claude-skill'),\n ];\n\n let sourceDir = '';\n\n for (const tryPath of possiblePaths)\n {\n if (fs.existsSync(path.join(tryPath, 'skill.json')))\n {\n sourceDir = tryPath;\n break;\n }\n }\n\n if (!sourceDir)\n {\n console.error(chalk.red('❌ 错误:找不到 .claude-skill 目录'));\n console.log(chalk.yellow('尝试的路径:'));\n possiblePaths.forEach((p) => console.log(` - ${p}`));\n console.log(chalk.yellow('\\n请确保 feng3d-cli 已正确安装'));\n process.exit(1);\n }\n\n // 检查 skill.json 是否存在\n if (!fs.existsSync(path.join(sourceDir, 'skill.json')))\n {\n console.error(chalk.red('❌ 错误:.claude-skill/skill.json 不存在'));\n process.exit(1);\n }\n\n // 创建目标目录\n console.log(chalk.blue('\\n📦 开始安装 feng3d Claude Code Skill...\\n'));\n\n // 检查是否已安装\n if (fs.existsSync(claudeSkillsDir))\n {\n console.log(chalk.yellow('⚠️ 检测到已安装的 skill,将进行覆盖更新...'));\n await fs.remove(claudeSkillsDir);\n }\n\n // 确保父目录存在\n await fs.ensureDir(path.dirname(claudeSkillsDir));\n\n // 复制 skill 文件\n console.log(chalk.blue('📂 复制 skill 文件...'));\n await fs.copy(sourceDir, claudeSkillsDir, {\n overwrite: true,\n errorOnExist: false,\n });\n\n // 验证安装\n if (fs.existsSync(path.join(claudeSkillsDir, 'skill.json')))\n {\n console.log(chalk.green('\\n✅ feng3d Skill 安装成功!\\n'));\n console.log(chalk.cyan(`安装位置: ${claudeSkillsDir}\\n`));\n console.log(chalk.yellow('使用方法:'));\n console.log(' /feng3d create my-project');\n console.log(' /feng3d update\\n');\n console.log(chalk.yellow('或直接对话: \"用 feng3d 创建一个新项目\"\\n'));\n console.log(chalk.cyan('💡 提示: 可能需要重启 Claude Code 使 skill 生效\\n'));\n }\n else\n {\n console.error(chalk.red('\\n❌ 安装失败:无法验证安装结果\\n'));\n process.exit(1);\n }\n }\n catch (error)\n {\n console.error(chalk.red(`\\n❌ 安装失败: ${error}\\n`));\n process.exit(1);\n }\n}\n"],"names":["__dirname","TEMPLATES_DIR","__filename"],"mappings":"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"}