create-teamix-evo 0.1.1 → 0.2.1

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 CHANGED
@@ -15,14 +15,14 @@ npm create teamix-evo my-app
15
15
  yarn create teamix-evo my-app
16
16
  ```
17
17
 
18
- ## Presets
18
+ ## Preset
19
19
 
20
- | Preset | Description |
21
- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
22
- | `minimal` | Vite + React + TS + Tailwind v4 + design tokens (`opentrek` variant) + AI skills (Qoder + Claude) |
23
- | `console` | Everything in `minimal` plus react-router-dom, ConsoleLayout, and Dashboard / List / Detail / Form pages with placeholder Table/Form/Input/Card |
20
+ `create-teamix-evo` 默认产出 **完整中后台工程**(无需 `--preset` 选择):
24
21
 
25
- Pick a preset interactively, or pass `--preset minimal` / `--preset console` directly.
22
+ - Vite + React + TS + Tailwind v4
23
+ - `@teamix-evo/design` tokens(`opentrek` variant)+ AI skills(Qoder + Claude)
24
+ - react-router-dom + ConsoleLayout + Dashboard / List / Detail / Form 页面
25
+ - 真装 Button + Card / Table / Form / Input 占位(后续用 `ui add` 一键替换)
26
26
 
27
27
  ## Options
28
28
 
@@ -33,7 +33,6 @@ Arguments:
33
33
  dir Target directory (will be created if it does not exist)
34
34
 
35
35
  Options:
36
- --preset <id> Preset id: minimal | console
37
36
  --pm <name> Package manager: pnpm | npm | yarn (auto-detected by default)
38
37
  --no-git Skip git init
39
38
  --no-install Skip dependency installation
@@ -47,10 +46,15 @@ After the command finishes:
47
46
 
48
47
  ```
49
48
  my-app/
50
- ├── .teamix-evo/ # design tokens + config (frozen / regenerable)
51
- ├── .qoder/agents/ # AI skills for Qoder
52
- ├── .claude/agents/ # AI skills for Claude Code
53
- ├── AGENTS.md / CLAUDE.md # project-level AI context (managed regions)
49
+ ├── .teamix-evo/ # 装机元数据 + 资源(frozen / regenerable / managed)
50
+ ├── config.json # 工程级 config (frozen)
51
+ ├── manifest.json # 装机产物清单
52
+ ├── tokens/ # design tokens(W1.4 提层)
53
+ │ ├── design/ # philosophy / foundations / patterns / ...
54
+ │ └── skills/ # skills 源(source-mirror 模型,ADR 0013)
55
+ ├── .qoder/skills/ # AI skills mirror for Qoder
56
+ ├── .claude/skills/ # AI skills mirror for Claude Code
57
+ ├── AGENTS.md / CLAUDE.md # 工程级 AI 上下文(managed regions)
54
58
  ├── src/
55
59
  │ ├── components/ui/ # ui add 落地的真实组件(如 button.tsx)
56
60
  │ ├── components/_placeholder/ # console preset 占位组件(待 ui 包补齐)
package/dist/index.js CHANGED
@@ -184,31 +184,11 @@ function buildInfo(name) {
184
184
  }
185
185
  }
186
186
 
187
- // src/presets/minimal.ts
188
- var minimalPreset = {
189
- id: "minimal",
190
- displayName: "Minimal",
191
- description: "Vite + React + TS + Tailwind v4\uFF0C\u88C5 design tokens + AI skills\uFF0C\u65E0\u8DEF\u7531\u3001\u4E0D\u88C5 UI \u7EC4\u4EF6\u3002",
192
- baseTemplate: "react-ts",
193
- design: {
194
- variant: "opentrek",
195
- tailwind: "v4"
196
- },
197
- skills: {
198
- entries: ["teamix-evo-manage"],
199
- ides: ["qoder", "claude"]
200
- },
201
- ui: {
202
- components: []
203
- },
204
- overlay: null
205
- };
206
-
207
187
  // src/presets/console.ts
208
188
  var consolePreset = {
209
189
  id: "console",
210
190
  displayName: "Console",
211
- description: "\u4E2D\u540E\u53F0\u6807\u914D\uFF1Aminimal + react-router-dom + ConsoleLayout + Dashboard / List / Detail / Form \u56DB\u9875\u9762 + \u771F\u88C5 Button\u3002",
191
+ description: "\u4E2D\u540E\u53F0\u6807\u914D\uFF1AVite + React + TS + Tailwind v4 + design tokens + AI skills + react-router-dom + ConsoleLayout + Dashboard / List / Detail / Form \u56DB\u9875\u9762 + \u771F\u88C5 Button\u3002",
212
192
  baseTemplate: "react-ts",
213
193
  design: {
214
194
  variant: "opentrek",
@@ -225,7 +205,7 @@ var consolePreset = {
225
205
  };
226
206
 
227
207
  // src/presets/index.ts
228
- var presets = [minimalPreset, consolePreset];
208
+ var presets = [consolePreset];
229
209
  function findPreset(id) {
230
210
  return presets.find((p2) => p2.id === id);
231
211
  }
@@ -269,10 +249,7 @@ async function orchestrate(options) {
269
249
  const preset = findPreset(options.presetId);
270
250
  if (!preset) {
271
251
  throw new Error(
272
- `Unknown preset "${options.presetId}". Available: ${[
273
- "minimal",
274
- "console"
275
- ].join(", ")}.`
252
+ `Unknown preset "${options.presetId}". Available: console.`
276
253
  );
277
254
  }
278
255
  const dir = path2.resolve(options.dir);
@@ -294,7 +271,6 @@ async function orchestrate(options) {
294
271
  const designResult = await runDesignInit({
295
272
  projectRoot: dir,
296
273
  variant: preset.design.variant,
297
- tailwind: preset.design.tailwind,
298
274
  ide: "qoder"
299
275
  });
300
276
  if (designResult.status === "installed") {
@@ -468,23 +444,7 @@ import * as p from "@clack/prompts";
468
444
  async function promptMissing(seed) {
469
445
  p.intro("create-teamix-evo");
470
446
  p.note(`\u{1F4E6} Target directory: ${seed.dir}`);
471
- let presetId = seed.presetId;
472
- if (!presetId) {
473
- const choice = await p.select({
474
- message: "\u9009\u62E9 preset",
475
- options: presets.map((preset) => ({
476
- value: preset.id,
477
- label: preset.displayName,
478
- hint: preset.description
479
- })),
480
- initialValue: "minimal"
481
- });
482
- if (p.isCancel(choice)) {
483
- p.cancel("\u5DF2\u53D6\u6D88");
484
- process.exit(0);
485
- }
486
- presetId = choice;
487
- }
447
+ const presetId = seed.presetId ?? "console";
488
448
  let pm = seed.pm && isValidPackageManager(seed.pm) ? seed.pm : void 0;
489
449
  if (!pm) {
490
450
  const pmChoice = await p.select({
@@ -544,10 +504,10 @@ async function main() {
544
504
  logger.error(`\u672A\u77E5\u5305\u7BA1\u7406\u5668 "${opts.pm}"\u3002\u53EF\u9009\uFF1Apnpm | npm | yarn`);
545
505
  process.exit(1);
546
506
  }
547
- let presetId = opts.preset;
507
+ let presetId = opts.preset ?? "console";
548
508
  let pm = opts.pm;
549
509
  let git = opts.git;
550
- if (process.stdin.isTTY && (!presetId || git === void 0)) {
510
+ if (process.stdin.isTTY && git === void 0) {
551
511
  const answers = await promptMissing({
552
512
  dir,
553
513
  presetId,
@@ -558,7 +518,6 @@ async function main() {
558
518
  git = answers.git;
559
519
  if (answers.pm) pm = answers.pm;
560
520
  } else {
561
- presetId = presetId ?? "minimal";
562
521
  git = git ?? true;
563
522
  }
564
523
  try {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/orchestrator.ts","../src/copy.ts","../src/git.ts","../src/merge-package-json.ts","../src/pm.ts","../src/presets/minimal.ts","../src/presets/console.ts","../src/presets/index.ts","../src/utils/logger.ts","../src/prompts.ts"],"sourcesContent":["import path from 'node:path';\nimport { Command } from 'commander';\nimport { red } from 'kolorist';\nimport { orchestrate } from './orchestrator.js';\nimport { listPresetIds } from './presets/index.js';\nimport { isValidPackageManager } from './pm.js';\nimport { promptMissing } from './prompts.js';\nimport { logger } from './utils/logger.js';\n\ninterface CliOptions {\n preset?: string;\n pm?: string;\n /** commander treats `--no-git` as `git: false`. */\n git?: boolean;\n /** commander treats `--no-install` as `install: false`. */\n install?: boolean;\n force?: boolean;\n}\n\nasync function main(): Promise<void> {\n const program = new Command();\n\n program\n .name('create-teamix-evo')\n .description(\n 'Scaffold a Vite + React + TypeScript project pre-wired with Teamix Evo design tokens, AI skills, and UI components.',\n )\n .argument(\n '[dir]',\n 'target directory (will be created if it does not exist)',\n )\n .option('--preset <id>', `preset id (${listPresetIds().join(' | ')})`)\n .option('--pm <name>', 'package manager: pnpm | npm | yarn')\n .option('--no-git', 'skip git init')\n .option('--no-install', 'skip dependency installation')\n .option('--force', 'overwrite non-empty target directory')\n .helpOption('-h, --help', 'display help');\n\n program.parse(process.argv);\n const opts = program.opts<CliOptions>();\n const dirArg = program.args[0];\n\n // Resolve target directory (interactive only if no dirArg).\n const dir = dirArg\n ? path.resolve(dirArg)\n : path.resolve(process.cwd(), 'my-app');\n if (!dirArg) {\n logger.warn(`未指定目录,使用默认路径:${dir}`);\n }\n\n // Validate --preset / --pm if provided\n if (opts.preset && !listPresetIds().includes(opts.preset)) {\n logger.error(\n `未知 preset \"${opts.preset}\"。可选:${listPresetIds().join(', ')}`,\n );\n process.exit(1);\n }\n if (opts.pm && !isValidPackageManager(opts.pm)) {\n logger.error(`未知包管理器 \"${opts.pm}\"。可选:pnpm | npm | yarn`);\n process.exit(1);\n }\n\n // Interactive prompts for missing fields (when running in a TTY).\n let presetId = opts.preset;\n let pm = opts.pm;\n let git = opts.git;\n if (process.stdin.isTTY && (!presetId || git === undefined)) {\n const answers = await promptMissing({\n dir,\n presetId,\n pm,\n git,\n });\n presetId = answers.presetId;\n git = answers.git;\n if (answers.pm) pm = answers.pm;\n } else {\n presetId = presetId ?? 'minimal';\n git = git ?? true;\n }\n\n try {\n await orchestrate({\n dir,\n presetId: presetId!,\n pm: pm && isValidPackageManager(pm) ? pm : undefined,\n install: opts.install ?? true,\n git: git ?? true,\n force: opts.force ?? false,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(`\\n${red('✗')} ${message}`);\n process.exit(1);\n }\n}\n\nmain().catch((err) => {\n console.error(`\\n${red('✗')} 未捕获的错误`);\n console.error(err);\n process.exit(1);\n});\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { execa } from 'execa';\nimport {\n runDesignInit,\n runSkillsAdd,\n runUiInit,\n runUiAdd,\n} from 'teamix-evo/core';\nimport { copyDir } from './copy.js';\nimport { gitInit } from './git.js';\nimport {\n mergePackageJson,\n readJson,\n writeJson,\n VersionConflictError,\n} from './merge-package-json.js';\nimport {\n detectPackageManager,\n type PackageManager,\n type PackageManagerInfo,\n} from './pm.js';\nimport { findPreset, type Preset } from './presets/index.js';\nimport { logger } from './utils/logger.js';\n\nexport interface OrchestrateOptions {\n /** Absolute target directory. */\n dir: string;\n /** Preset id. */\n presetId: string;\n /** Preferred package manager (else auto-detect). */\n pm?: PackageManager;\n /** Run package manager install at the end. */\n install: boolean;\n /** Run git init at the end. */\n git: boolean;\n /** Overwrite non-empty target directory. */\n force?: boolean;\n}\n\n/**\n * Locate the create-teamix-evo package root (regardless of whether running\n * from source via tsx, or from `dist/index.js` after bundling).\n */\nfunction getPackageRoot(): string {\n // Resolves to <pkg>/dist/index.js.map's directory in dev/build.\n const here = path.dirname(fileURLToPath(import.meta.url));\n // From dist/ go up to package root.\n return path.resolve(here, '..');\n}\n\n/**\n * Main scaffolding pipeline.\n *\n * Order:\n * 1. validate target dir\n * 2. copy base template (renders all `.hbs`)\n * 3. copy overlay if any\n * 4. teamix-evo design init\n * 5. teamix-evo skills add\n * 6. teamix-evo ui init + ui add\n * 7. rewrite package.json (base + overlay fragment + ui npm deps)\n * 8. write pending-ui.json (if overlay declares placeholders)\n * 9. install deps\n * 10. git init\n */\nexport async function orchestrate(options: OrchestrateOptions): Promise<void> {\n const preset = findPreset(options.presetId);\n if (!preset) {\n throw new Error(\n `Unknown preset \"${options.presetId}\". Available: ${[\n 'minimal',\n 'console',\n ].join(', ')}.`,\n );\n }\n\n const dir = path.resolve(options.dir);\n await prepareTargetDir(dir, options.force ?? false);\n\n const pmInfo = detectPackageManager(options.pm);\n const projectName = path.basename(dir);\n const pkgRoot = getPackageRoot();\n\n // ─── 1. base template ───────────────────────────────────────────────────\n logger.step('拷贝 base 模板');\n const baseTemplateDir = path.join(pkgRoot, 'templates', preset.baseTemplate);\n const hbsCtx = buildHbsContext({ preset, projectName, pmInfo });\n await copyDir(baseTemplateDir, dir, { hbs: hbsCtx });\n logger.detail(`base: ${preset.baseTemplate}`);\n\n // ─── 2. overlay ─────────────────────────────────────────────────────────\n if (preset.overlay) {\n logger.step(`应用 overlay: ${preset.overlay}`);\n const overlayDir = path.join(pkgRoot, 'overlays', preset.overlay);\n await copyDir(overlayDir, dir, { hbs: hbsCtx });\n }\n\n // ─── 3. design tokens ───────────────────────────────────────────────────\n logger.step('装载 design tokens');\n const designResult = await runDesignInit({\n projectRoot: dir,\n variant: preset.design.variant,\n tailwind: preset.design.tailwind,\n ide: 'qoder',\n });\n if (designResult.status === 'installed') {\n logger.detail(\n `${designResult.packageName}@${designResult.version} (${designResult.count} files)`,\n );\n }\n\n // ─── 4. AI skills ───────────────────────────────────────────────────────\n logger.step('装载 AI skills');\n const skillsResult = await runSkillsAdd({\n projectRoot: dir,\n ides: preset.skills.ides,\n scope: 'project',\n });\n if (skillsResult.status === 'installed') {\n logger.detail(\n `${skillsResult.skillCount} skill(s) → ${skillsResult.ides.join(' + ')}`,\n );\n }\n\n // ─── 5. ui init + ui add ────────────────────────────────────────────────\n logger.step('配置 UI');\n await runUiInit({ projectRoot: dir });\n let uiAddDeps: Record<string, string> = {};\n if (preset.ui.components.length > 0) {\n const uiAddResult = await runUiAdd({\n projectRoot: dir,\n ids: preset.ui.components,\n });\n uiAddDeps = uiAddResult.npmDependencies;\n logger.detail(\n `installed: ${uiAddResult.orderedIds.join(', ')} (${\n uiAddResult.written\n } files)`,\n );\n } else {\n logger.detail('ui init only — 无组件落地');\n }\n\n // ─── 6. merge package.json ──────────────────────────────────────────────\n logger.step('合并 package.json');\n await mergeProjectPackageJson({\n dir,\n overlayFragmentPath: preset.overlay\n ? path.join(\n pkgRoot,\n 'overlays',\n preset.overlay,\n 'package.json.fragment.json',\n )\n : null,\n extraDependencies: uiAddDeps,\n });\n\n // ─── 7. pending-ui.json ─────────────────────────────────────────────────\n if (preset.overlay === 'console') {\n await writePendingUi(dir, preset.id);\n logger.detail('.teamix-evo/create/pending-ui.json 已写入');\n }\n\n // ─── 8. install deps ────────────────────────────────────────────────────\n if (options.install) {\n logger.step(`安装依赖(${pmInfo.installCommand})`);\n try {\n await execa(pmInfo.name, pmInfo.install, { cwd: dir, stdio: 'inherit' });\n } catch (err) {\n logger.warn(\n `依赖安装失败 — 可手动执行:cd ${\n path.relative(process.cwd(), dir) || '.'\n } && ${pmInfo.installCommand}`,\n );\n if (err instanceof Error) logger.detail(err.message);\n }\n } else {\n logger.detail(`跳过依赖安装(手动执行:${pmInfo.installCommand})`);\n }\n\n // ─── 9. git init ────────────────────────────────────────────────────────\n if (options.git) {\n logger.step('初始化 git');\n const result = await gitInit(dir);\n if (result.ok) logger.detail('git 仓库已就绪(含首个 commit)');\n else logger.warn(`git init 失败:${result.reason}`);\n }\n\n // ─── done ───────────────────────────────────────────────────────────────\n printNextSteps({ dir, pmInfo, preset });\n}\n\nasync function prepareTargetDir(dir: string, force: boolean): Promise<void> {\n let exists = false;\n try {\n await fs.access(dir);\n exists = true;\n } catch {\n /* not exists */\n }\n\n if (!exists) {\n await fs.mkdir(dir, { recursive: true });\n return;\n }\n\n const entries = await fs.readdir(dir);\n if (entries.length === 0) return;\n\n // Reject existing teamix-evo project regardless of --force\n if (entries.includes('.teamix-evo')) {\n throw new Error(\n `Target directory already contains a .teamix-evo/ — please run \\`teamix-evo design init\\` inside it instead of using create-teamix-evo.`,\n );\n }\n\n if (!force) {\n throw new Error(\n `Target directory \"${dir}\" is not empty. Use --force to overwrite.`,\n );\n }\n logger.warn(`--force:覆盖已有目录 ${dir}`);\n}\n\nfunction buildHbsContext(args: {\n preset: Preset;\n projectName: string;\n pmInfo: PackageManagerInfo;\n}): Record<string, unknown> {\n const { preset, projectName, pmInfo } = args;\n return {\n projectName,\n designVariant: preset.design.variant,\n pmInstall: pmInfo.installCommand,\n pmRun: pmInfo.runPrefix,\n uiInstalled:\n preset.ui.components.length > 0\n ? preset.ui.components.join(', ')\n : '(无)',\n };\n}\n\nasync function mergeProjectPackageJson(args: {\n dir: string;\n overlayFragmentPath: string | null;\n extraDependencies: Record<string, string>;\n}): Promise<void> {\n const pkgPath = path.join(args.dir, 'package.json');\n const base = await readJson<Record<string, unknown>>(pkgPath);\n let overlay: Record<string, unknown> | null = null;\n if (args.overlayFragmentPath) {\n try {\n overlay = await readJson<Record<string, unknown>>(\n args.overlayFragmentPath,\n );\n } catch {\n overlay = null;\n }\n }\n try {\n const merged = mergePackageJson(base, overlay, {\n extraDependencies: args.extraDependencies,\n });\n await writeJson(pkgPath, merged);\n } catch (err) {\n if (err instanceof VersionConflictError) {\n throw new Error(\n `package.json 合并失败:${err.message}\\n` +\n `请检查 base 模板与 overlay/ui 组件依赖的版本声明,确保一致。`,\n );\n }\n throw err;\n }\n}\n\nasync function writePendingUi(dir: string, presetId: string): Promise<void> {\n const pendingDir = path.join(dir, '.teamix-evo', 'create');\n await fs.mkdir(pendingDir, { recursive: true });\n const pendingPath = path.join(pendingDir, 'pending-ui.json');\n const payload = {\n $schema: 'https://teamix-evo.dev/schema/pending-ui/v1.json',\n schemaVersion: 1,\n preset: presetId,\n pendingComponents: [\n { id: 'card', placeholder: 'src/components/_placeholder/Card.tsx' },\n { id: 'input', placeholder: 'src/components/_placeholder/Input.tsx' },\n { id: 'form', placeholder: 'src/components/_placeholder/Form.tsx' },\n { id: 'table', placeholder: 'src/components/_placeholder/Table.tsx' },\n ],\n };\n await writeJson(pendingPath, payload);\n}\n\nfunction printNextSteps(args: {\n dir: string;\n pmInfo: PackageManagerInfo;\n preset: Preset;\n}): void {\n const { dir, pmInfo, preset } = args;\n const rel = path.relative(process.cwd(), dir) || '.';\n logger.blank();\n logger.success(`${preset.displayName} preset 已就绪:${dir}`);\n logger.blank();\n console.log('Next steps:');\n console.log(` cd ${rel}`);\n console.log(\n ` ${pmInfo.runPrefix}${pmInfo.runPrefix === 'yarn' ? ' ' : ' '}dev`,\n );\n if (preset.id === 'console') {\n logger.blank();\n console.log(\n '💡 console preset 内含占位组件,可用 `npx teamix-evo ui add card` 等替换为真组件。',\n );\n }\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport Handlebars from 'handlebars';\n\nexport interface CopyContext {\n /** Handlebars render context for `.hbs` templates. */\n hbs: Record<string, unknown>;\n}\n\n/**\n * Recursively copy `srcDir` into `destDir`, applying:\n * - `.hbs` files: rendered with `ctx.hbs`, written without `.hbs` extension\n * - `_gitignore` / `_editorconfig` etc. → `.gitignore` / `.editorconfig`\n * - Skips `package.json.fragment.json` (handled separately by the merger)\n *\n * Existing files are overwritten — call site is responsible for `--force`\n * / clean-target semantics.\n */\nexport async function copyDir(\n srcDir: string,\n destDir: string,\n ctx: CopyContext,\n): Promise<void> {\n await fs.mkdir(destDir, { recursive: true });\n\n const entries = await fs.readdir(srcDir, { withFileTypes: true });\n for (const entry of entries) {\n const srcPath = path.join(srcDir, entry.name);\n const destName = mapDestName(entry.name);\n if (destName === null) continue; // explicitly skipped\n const destPath = path.join(destDir, destName);\n\n if (entry.isDirectory()) {\n await copyDir(srcPath, destPath, ctx);\n continue;\n }\n\n if (entry.name.endsWith('.hbs')) {\n const tpl = await fs.readFile(srcPath, 'utf8');\n const rendered = Handlebars.compile(tpl, { noEscape: true })(ctx.hbs);\n await fs.writeFile(destPath, rendered, 'utf8');\n continue;\n }\n\n await fs.copyFile(srcPath, destPath);\n }\n}\n\n/**\n * Translate a source filename to its destination filename, or `null` to skip.\n */\nfunction mapDestName(name: string): string | null {\n // Skip the package.json fragment — orchestrator merges it into base.\n if (name === 'package.json.fragment.json') return null;\n\n // _gitignore → .gitignore (npm strips real `.gitignore` from packed tarballs)\n if (name === '_gitignore') return '.gitignore';\n if (name === '_editorconfig') return '.editorconfig';\n if (name === '_npmrc') return '.npmrc';\n\n // Strip .hbs extension\n if (name.endsWith('.hbs')) {\n return name.slice(0, -'.hbs'.length);\n }\n\n return name;\n}\n","import { execa } from 'execa';\n\n/**\n * Initialize a fresh git repo with a single commit. Best-effort:\n * any failure is reported as `{ ok: false }` instead of throwing —\n * scaffolding should not fail just because git is missing.\n */\nexport async function gitInit(\n cwd: string,\n): Promise<{ ok: true } | { ok: false; reason: string }> {\n try {\n await execa('git', ['init', '--quiet'], { cwd });\n await execa('git', ['add', '-A'], { cwd });\n await execa(\n 'git',\n [\n '-c',\n 'user.email=create-teamix-evo@local',\n '-c',\n 'user.name=create-teamix-evo',\n 'commit',\n '--quiet',\n '--no-gpg-sign',\n '-m',\n 'chore: scaffolded by create-teamix-evo',\n ],\n { cwd },\n );\n return { ok: true };\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n return { ok: false, reason };\n }\n}\n","import fs from 'node:fs/promises';\n\ninterface PackageJsonLike {\n [key: string]: unknown;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n scripts?: Record<string, string>;\n}\n\nexport interface MergeOptions {\n /** Extra dependencies (e.g. from `runUiAdd`) merged with conflict checks. */\n extraDependencies?: Record<string, string>;\n /** Extra dev dependencies merged with conflict checks. */\n extraDevDependencies?: Record<string, string>;\n}\n\nexport class VersionConflictError extends Error {\n constructor(\n readonly key: 'dependencies' | 'devDependencies' | 'scripts',\n readonly name: string,\n readonly base: string,\n readonly incoming: string,\n ) {\n super(\n `Version conflict in ${key}: ${name} declared as \"${base}\" in base but \"${incoming}\" in overlay/extras.`,\n );\n this.name = 'VersionConflictError';\n }\n}\n\n/**\n * Merge a base package.json with an overlay fragment + extras.\n *\n * - Merges `dependencies`, `devDependencies`, and `scripts` (shallow).\n * - Throws {@link VersionConflictError} on any version mismatch within the same key.\n * - Other top-level keys (`name`, `version`, etc.) come from `base` only.\n */\nexport function mergePackageJson(\n base: PackageJsonLike,\n overlay: PackageJsonLike | null,\n options: MergeOptions = {},\n): PackageJsonLike {\n const merged: PackageJsonLike = { ...base };\n\n for (const key of ['dependencies', 'devDependencies', 'scripts'] as const) {\n const baseMap = (base[key] ?? {}) as Record<string, string>;\n const overlayMap = (overlay?.[key] ?? {}) as Record<string, string>;\n const extrasMap =\n key === 'dependencies'\n ? options.extraDependencies ?? {}\n : key === 'devDependencies'\n ? options.extraDevDependencies ?? {}\n : {};\n\n const result: Record<string, string> = { ...baseMap };\n for (const [name, version] of Object.entries(overlayMap)) {\n if (result[name] !== undefined && result[name] !== version) {\n throw new VersionConflictError(key, name, result[name], version);\n }\n result[name] = version;\n }\n for (const [name, version] of Object.entries(extrasMap)) {\n if (result[name] !== undefined && result[name] !== version) {\n throw new VersionConflictError(key, name, result[name], version);\n }\n result[name] = version;\n }\n if (Object.keys(result).length > 0) {\n merged[key] = sortObjectByKey(result);\n }\n }\n\n return merged;\n}\n\nfunction sortObjectByKey<T extends Record<string, unknown>>(obj: T): T {\n const sorted: Record<string, unknown> = {};\n for (const k of Object.keys(obj).sort()) sorted[k] = obj[k];\n return sorted as T;\n}\n\nexport async function readJson<T = unknown>(filePath: string): Promise<T> {\n const raw = await fs.readFile(filePath, 'utf8');\n return JSON.parse(raw) as T;\n}\n\nexport async function writeJson(\n filePath: string,\n value: unknown,\n): Promise<void> {\n await fs.writeFile(filePath, JSON.stringify(value, null, 2) + '\\n', 'utf8');\n}\n","/**\n * Detect the user's package manager from `npm_config_user_agent`,\n * with fallback heuristics, and produce install / run commands.\n */\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn';\n\nexport interface PackageManagerInfo {\n name: PackageManager;\n /** Command + args to install dependencies in cwd. */\n install: string[];\n /** Command + args prefix to run a package script. */\n run: string[];\n /** Human-readable command (`pnpm install`, etc.). */\n installCommand: string;\n /** Human-readable run prefix (`pnpm`, `npm run`, `yarn`). */\n runPrefix: string;\n}\n\n/**\n * Detect the package manager invoking `create-teamix-evo`.\n *\n * Priority:\n * 1. explicit `prefer` argument\n * 2. `npm_config_user_agent` env (set by `pnpm create` / `npm create` / `yarn create`)\n * 3. fallback to `npm`\n */\nexport function detectPackageManager(\n prefer?: PackageManager,\n): PackageManagerInfo {\n const detected = prefer ?? detectFromUserAgent() ?? 'npm';\n return buildInfo(detected);\n}\n\nexport function isValidPackageManager(value: string): value is PackageManager {\n return value === 'pnpm' || value === 'npm' || value === 'yarn';\n}\n\nfunction detectFromUserAgent(): PackageManager | null {\n const ua = process.env.npm_config_user_agent;\n if (!ua) return null;\n const head = ua.split(' ')[0] ?? '';\n if (head.startsWith('pnpm')) return 'pnpm';\n if (head.startsWith('yarn')) return 'yarn';\n if (head.startsWith('npm')) return 'npm';\n return null;\n}\n\nfunction buildInfo(name: PackageManager): PackageManagerInfo {\n switch (name) {\n case 'pnpm':\n return {\n name,\n install: ['install'],\n run: ['run'],\n installCommand: 'pnpm install',\n runPrefix: 'pnpm',\n };\n case 'yarn':\n return {\n name,\n install: ['install'],\n run: [],\n installCommand: 'yarn install',\n runPrefix: 'yarn',\n };\n case 'npm':\n default:\n return {\n name,\n install: ['install'],\n run: ['run'],\n installCommand: 'npm install',\n runPrefix: 'npm run',\n };\n }\n}\n","import type { Preset } from './types.js';\n\nexport const minimalPreset: Preset = {\n id: 'minimal',\n displayName: 'Minimal',\n description:\n 'Vite + React + TS + Tailwind v4,装 design tokens + AI skills,无路由、不装 UI 组件。',\n baseTemplate: 'react-ts',\n design: {\n variant: 'opentrek',\n tailwind: 'v4',\n },\n skills: {\n entries: ['teamix-evo-manage'],\n ides: ['qoder', 'claude'],\n },\n ui: {\n components: [],\n },\n overlay: null,\n};\n","import type { Preset } from './types.js';\n\nexport const consolePreset: Preset = {\n id: 'console',\n displayName: 'Console',\n description:\n '中后台标配:minimal + react-router-dom + ConsoleLayout + Dashboard / List / Detail / Form 四页面 + 真装 Button。',\n baseTemplate: 'react-ts',\n design: {\n variant: 'opentrek',\n tailwind: 'v4',\n },\n skills: {\n entries: ['teamix-evo-manage'],\n ides: ['qoder', 'claude'],\n },\n ui: {\n components: ['button'],\n },\n overlay: 'console',\n};\n","import type { Preset } from './types.js';\nimport { minimalPreset } from './minimal.js';\nimport { consolePreset } from './console.js';\n\nexport type { Preset } from './types.js';\n\nexport const presets: Preset[] = [minimalPreset, consolePreset];\n\nexport function findPreset(id: string): Preset | undefined {\n return presets.find((p) => p.id === id);\n}\n\nexport function listPresetIds(): string[] {\n return presets.map((p) => p.id);\n}\n","import { bold, cyan, dim, green, red, yellow } from 'kolorist';\n\nexport const logger = {\n info(message: string): void {\n console.log(`${cyan('ℹ')} ${message}`);\n },\n success(message: string): void {\n console.log(`${green('✓')} ${message}`);\n },\n warn(message: string): void {\n console.warn(`${yellow('⚠')} ${message}`);\n },\n error(message: string): void {\n console.error(`${red('✗')} ${message}`);\n },\n step(message: string): void {\n console.log(`\\n${bold(cyan('▸'))} ${bold(message)}`);\n },\n detail(message: string): void {\n console.log(` ${dim(message)}`);\n },\n blank(): void {\n console.log('');\n },\n};\n","import * as p from '@clack/prompts';\nimport { presets } from './presets/index.js';\nimport { isValidPackageManager, type PackageManager } from './pm.js';\n\nexport interface InteractiveAnswers {\n presetId: string;\n pm: PackageManager | undefined;\n git: boolean;\n}\n\n/**\n * Run interactive prompts for missing options. The `seed` represents whatever\n * the user already passed via flags; only unanswered fields are prompted for.\n */\nexport async function promptMissing(seed: {\n dir: string;\n presetId?: string;\n pm?: string;\n git?: boolean;\n}): Promise<InteractiveAnswers> {\n p.intro('create-teamix-evo');\n p.note(`📦 Target directory: ${seed.dir}`);\n\n let presetId = seed.presetId;\n if (!presetId) {\n const choice = await p.select({\n message: '选择 preset',\n options: presets.map((preset) => ({\n value: preset.id,\n label: preset.displayName,\n hint: preset.description,\n })),\n initialValue: 'minimal',\n });\n if (p.isCancel(choice)) {\n p.cancel('已取消');\n process.exit(0);\n }\n presetId = choice as string;\n }\n\n let pm: PackageManager | undefined =\n seed.pm && isValidPackageManager(seed.pm) ? seed.pm : undefined;\n if (!pm) {\n const pmChoice = await p.select<string>({\n message: '包管理器',\n options: [\n { value: 'auto', label: '自动检测(推荐)' },\n { value: 'pnpm', label: 'pnpm' },\n { value: 'npm', label: 'npm' },\n { value: 'yarn', label: 'yarn' },\n ],\n initialValue: 'auto',\n });\n if (p.isCancel(pmChoice)) {\n p.cancel('已取消');\n process.exit(0);\n }\n pm =\n pmChoice === 'auto'\n ? undefined\n : isValidPackageManager(pmChoice as string)\n ? (pmChoice as PackageManager)\n : undefined;\n }\n\n let git = seed.git;\n if (git === undefined) {\n const confirmed = await p.confirm({\n message: '初始化 git 仓库?',\n initialValue: true,\n });\n if (p.isCancel(confirmed)) {\n p.cancel('已取消');\n process.exit(0);\n }\n git = confirmed as boolean;\n }\n\n return { presetId, pm, git };\n}\n"],"mappings":"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","names":["path","red","fs","path","execa","fs","p","path","execa","fs","path","red"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/orchestrator.ts","../src/copy.ts","../src/git.ts","../src/merge-package-json.ts","../src/pm.ts","../src/presets/console.ts","../src/presets/index.ts","../src/utils/logger.ts","../src/prompts.ts"],"sourcesContent":["import path from 'node:path';\nimport { Command } from 'commander';\nimport { red } from 'kolorist';\nimport { orchestrate } from './orchestrator.js';\nimport { listPresetIds } from './presets/index.js';\nimport { isValidPackageManager } from './pm.js';\nimport { promptMissing } from './prompts.js';\nimport { logger } from './utils/logger.js';\n\ninterface CliOptions {\n preset?: string;\n pm?: string;\n /** commander treats `--no-git` as `git: false`. */\n git?: boolean;\n /** commander treats `--no-install` as `install: false`. */\n install?: boolean;\n force?: boolean;\n}\n\nasync function main(): Promise<void> {\n const program = new Command();\n\n program\n .name('create-teamix-evo')\n .description(\n 'Scaffold a Vite + React + TypeScript project pre-wired with Teamix Evo design tokens, AI skills, and UI components.',\n )\n .argument(\n '[dir]',\n 'target directory (will be created if it does not exist)',\n )\n .option('--preset <id>', `preset id (${listPresetIds().join(' | ')})`)\n .option('--pm <name>', 'package manager: pnpm | npm | yarn')\n .option('--no-git', 'skip git init')\n .option('--no-install', 'skip dependency installation')\n .option('--force', 'overwrite non-empty target directory')\n .helpOption('-h, --help', 'display help');\n\n program.parse(process.argv);\n const opts = program.opts<CliOptions>();\n const dirArg = program.args[0];\n\n // Resolve target directory (interactive only if no dirArg).\n const dir = dirArg\n ? path.resolve(dirArg)\n : path.resolve(process.cwd(), 'my-app');\n if (!dirArg) {\n logger.warn(`未指定目录,使用默认路径:${dir}`);\n }\n\n // Validate --preset / --pm if provided\n if (opts.preset && !listPresetIds().includes(opts.preset)) {\n logger.error(\n `未知 preset \"${opts.preset}\"。可选:${listPresetIds().join(', ')}`,\n );\n process.exit(1);\n }\n if (opts.pm && !isValidPackageManager(opts.pm)) {\n logger.error(`未知包管理器 \"${opts.pm}\"。可选:pnpm | npm | yarn`);\n process.exit(1);\n }\n\n // Interactive prompts for missing fields (when running in a TTY).\n let presetId = opts.preset ?? 'console';\n let pm = opts.pm;\n let git = opts.git;\n if (process.stdin.isTTY && git === undefined) {\n const answers = await promptMissing({\n dir,\n presetId,\n pm,\n git,\n });\n presetId = answers.presetId;\n git = answers.git;\n if (answers.pm) pm = answers.pm;\n } else {\n git = git ?? true;\n }\n\n try {\n await orchestrate({\n dir,\n presetId: presetId!,\n pm: pm && isValidPackageManager(pm) ? pm : undefined,\n install: opts.install ?? true,\n git: git ?? true,\n force: opts.force ?? false,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(`\\n${red('✗')} ${message}`);\n process.exit(1);\n }\n}\n\nmain().catch((err) => {\n console.error(`\\n${red('✗')} 未捕获的错误`);\n console.error(err);\n process.exit(1);\n});\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { execa } from 'execa';\nimport {\n runDesignInit,\n runSkillsAdd,\n runUiInit,\n runUiAdd,\n} from 'teamix-evo/core';\nimport { copyDir } from './copy.js';\nimport { gitInit } from './git.js';\nimport {\n mergePackageJson,\n readJson,\n writeJson,\n VersionConflictError,\n} from './merge-package-json.js';\nimport {\n detectPackageManager,\n type PackageManager,\n type PackageManagerInfo,\n} from './pm.js';\nimport { findPreset, type Preset } from './presets/index.js';\nimport { logger } from './utils/logger.js';\n\nexport interface OrchestrateOptions {\n /** Absolute target directory. */\n dir: string;\n /** Preset id. */\n presetId: string;\n /** Preferred package manager (else auto-detect). */\n pm?: PackageManager;\n /** Run package manager install at the end. */\n install: boolean;\n /** Run git init at the end. */\n git: boolean;\n /** Overwrite non-empty target directory. */\n force?: boolean;\n}\n\n/**\n * Locate the create-teamix-evo package root (regardless of whether running\n * from source via tsx, or from `dist/index.js` after bundling).\n */\nfunction getPackageRoot(): string {\n // Resolves to <pkg>/dist/index.js.map's directory in dev/build.\n const here = path.dirname(fileURLToPath(import.meta.url));\n // From dist/ go up to package root.\n return path.resolve(here, '..');\n}\n\n/**\n * Main scaffolding pipeline.\n *\n * Order:\n * 1. validate target dir\n * 2. copy base template (renders all `.hbs`)\n * 3. copy overlay if any\n * 4. teamix-evo design init\n * 5. teamix-evo skills add\n * 6. teamix-evo ui init + ui add\n * 7. rewrite package.json (base + overlay fragment + ui npm deps)\n * 8. write pending-ui.json (if overlay declares placeholders)\n * 9. install deps\n * 10. git init\n */\nexport async function orchestrate(options: OrchestrateOptions): Promise<void> {\n const preset = findPreset(options.presetId);\n if (!preset) {\n throw new Error(\n `Unknown preset \"${options.presetId}\". Available: console.`,\n );\n }\n\n const dir = path.resolve(options.dir);\n await prepareTargetDir(dir, options.force ?? false);\n\n const pmInfo = detectPackageManager(options.pm);\n const projectName = path.basename(dir);\n const pkgRoot = getPackageRoot();\n\n // ─── 1. base template ───────────────────────────────────────────────────\n logger.step('拷贝 base 模板');\n const baseTemplateDir = path.join(pkgRoot, 'templates', preset.baseTemplate);\n const hbsCtx = buildHbsContext({ preset, projectName, pmInfo });\n await copyDir(baseTemplateDir, dir, { hbs: hbsCtx });\n logger.detail(`base: ${preset.baseTemplate}`);\n\n // ─── 2. overlay ─────────────────────────────────────────────────────────\n if (preset.overlay) {\n logger.step(`应用 overlay: ${preset.overlay}`);\n const overlayDir = path.join(pkgRoot, 'overlays', preset.overlay);\n await copyDir(overlayDir, dir, { hbs: hbsCtx });\n }\n\n // ─── 3. design tokens ───────────────────────────────────────────────────\n logger.step('装载 design tokens');\n const designResult = await runDesignInit({\n projectRoot: dir,\n variant: preset.design.variant,\n ide: 'qoder',\n });\n if (designResult.status === 'installed') {\n logger.detail(\n `${designResult.packageName}@${designResult.version} (${designResult.count} files)`,\n );\n }\n\n // ─── 4. AI skills ───────────────────────────────────────────────────────\n logger.step('装载 AI skills');\n const skillsResult = await runSkillsAdd({\n projectRoot: dir,\n ides: preset.skills.ides,\n scope: 'project',\n });\n if (skillsResult.status === 'installed') {\n logger.detail(\n `${skillsResult.skillCount} skill(s) → ${skillsResult.ides.join(' + ')}`,\n );\n }\n\n // ─── 5. ui init + ui add ────────────────────────────────────────────────\n logger.step('配置 UI');\n await runUiInit({ projectRoot: dir });\n let uiAddDeps: Record<string, string> = {};\n if (preset.ui.components.length > 0) {\n const uiAddResult = await runUiAdd({\n projectRoot: dir,\n ids: preset.ui.components,\n });\n uiAddDeps = uiAddResult.npmDependencies;\n logger.detail(\n `installed: ${uiAddResult.orderedIds.join(', ')} (${\n uiAddResult.written\n } files)`,\n );\n } else {\n logger.detail('ui init only — 无组件落地');\n }\n\n // ─── 6. merge package.json ──────────────────────────────────────────────\n logger.step('合并 package.json');\n await mergeProjectPackageJson({\n dir,\n overlayFragmentPath: preset.overlay\n ? path.join(\n pkgRoot,\n 'overlays',\n preset.overlay,\n 'package.json.fragment.json',\n )\n : null,\n extraDependencies: uiAddDeps,\n });\n\n // ─── 7. pending-ui.json ─────────────────────────────────────────────────\n if (preset.overlay === 'console') {\n await writePendingUi(dir, preset.id);\n logger.detail('.teamix-evo/create/pending-ui.json 已写入');\n }\n\n // ─── 8. install deps ────────────────────────────────────────────────────\n if (options.install) {\n logger.step(`安装依赖(${pmInfo.installCommand})`);\n try {\n await execa(pmInfo.name, pmInfo.install, { cwd: dir, stdio: 'inherit' });\n } catch (err) {\n logger.warn(\n `依赖安装失败 — 可手动执行:cd ${\n path.relative(process.cwd(), dir) || '.'\n } && ${pmInfo.installCommand}`,\n );\n if (err instanceof Error) logger.detail(err.message);\n }\n } else {\n logger.detail(`跳过依赖安装(手动执行:${pmInfo.installCommand})`);\n }\n\n // ─── 9. git init ────────────────────────────────────────────────────────\n if (options.git) {\n logger.step('初始化 git');\n const result = await gitInit(dir);\n if (result.ok) logger.detail('git 仓库已就绪(含首个 commit)');\n else logger.warn(`git init 失败:${result.reason}`);\n }\n\n // ─── done ───────────────────────────────────────────────────────────────\n printNextSteps({ dir, pmInfo, preset });\n}\n\nasync function prepareTargetDir(dir: string, force: boolean): Promise<void> {\n let exists = false;\n try {\n await fs.access(dir);\n exists = true;\n } catch {\n /* not exists */\n }\n\n if (!exists) {\n await fs.mkdir(dir, { recursive: true });\n return;\n }\n\n const entries = await fs.readdir(dir);\n if (entries.length === 0) return;\n\n // Reject existing teamix-evo project regardless of --force\n if (entries.includes('.teamix-evo')) {\n throw new Error(\n `Target directory already contains a .teamix-evo/ — please run \\`teamix-evo design init\\` inside it instead of using create-teamix-evo.`,\n );\n }\n\n if (!force) {\n throw new Error(\n `Target directory \"${dir}\" is not empty. Use --force to overwrite.`,\n );\n }\n logger.warn(`--force:覆盖已有目录 ${dir}`);\n}\n\nfunction buildHbsContext(args: {\n preset: Preset;\n projectName: string;\n pmInfo: PackageManagerInfo;\n}): Record<string, unknown> {\n const { preset, projectName, pmInfo } = args;\n return {\n projectName,\n designVariant: preset.design.variant,\n pmInstall: pmInfo.installCommand,\n pmRun: pmInfo.runPrefix,\n uiInstalled:\n preset.ui.components.length > 0\n ? preset.ui.components.join(', ')\n : '(无)',\n };\n}\n\nasync function mergeProjectPackageJson(args: {\n dir: string;\n overlayFragmentPath: string | null;\n extraDependencies: Record<string, string>;\n}): Promise<void> {\n const pkgPath = path.join(args.dir, 'package.json');\n const base = await readJson<Record<string, unknown>>(pkgPath);\n let overlay: Record<string, unknown> | null = null;\n if (args.overlayFragmentPath) {\n try {\n overlay = await readJson<Record<string, unknown>>(\n args.overlayFragmentPath,\n );\n } catch {\n overlay = null;\n }\n }\n try {\n const merged = mergePackageJson(base, overlay, {\n extraDependencies: args.extraDependencies,\n });\n await writeJson(pkgPath, merged);\n } catch (err) {\n if (err instanceof VersionConflictError) {\n throw new Error(\n `package.json 合并失败:${err.message}\\n` +\n `请检查 base 模板与 overlay/ui 组件依赖的版本声明,确保一致。`,\n );\n }\n throw err;\n }\n}\n\nasync function writePendingUi(dir: string, presetId: string): Promise<void> {\n const pendingDir = path.join(dir, '.teamix-evo', 'create');\n await fs.mkdir(pendingDir, { recursive: true });\n const pendingPath = path.join(pendingDir, 'pending-ui.json');\n const payload = {\n $schema: 'https://teamix-evo.dev/schema/pending-ui/v1.json',\n schemaVersion: 1,\n preset: presetId,\n pendingComponents: [\n { id: 'card', placeholder: 'src/components/_placeholder/Card.tsx' },\n { id: 'input', placeholder: 'src/components/_placeholder/Input.tsx' },\n { id: 'form', placeholder: 'src/components/_placeholder/Form.tsx' },\n { id: 'table', placeholder: 'src/components/_placeholder/Table.tsx' },\n ],\n };\n await writeJson(pendingPath, payload);\n}\n\nfunction printNextSteps(args: {\n dir: string;\n pmInfo: PackageManagerInfo;\n preset: Preset;\n}): void {\n const { dir, pmInfo, preset } = args;\n const rel = path.relative(process.cwd(), dir) || '.';\n logger.blank();\n logger.success(`${preset.displayName} preset 已就绪:${dir}`);\n logger.blank();\n console.log('Next steps:');\n console.log(` cd ${rel}`);\n console.log(\n ` ${pmInfo.runPrefix}${pmInfo.runPrefix === 'yarn' ? ' ' : ' '}dev`,\n );\n if (preset.id === 'console') {\n logger.blank();\n console.log(\n '💡 console preset 内含占位组件,可用 `npx teamix-evo ui add card` 等替换为真组件。',\n );\n }\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport Handlebars from 'handlebars';\n\nexport interface CopyContext {\n /** Handlebars render context for `.hbs` templates. */\n hbs: Record<string, unknown>;\n}\n\n/**\n * Recursively copy `srcDir` into `destDir`, applying:\n * - `.hbs` files: rendered with `ctx.hbs`, written without `.hbs` extension\n * - `_gitignore` / `_editorconfig` etc. → `.gitignore` / `.editorconfig`\n * - Skips `package.json.fragment.json` (handled separately by the merger)\n *\n * Existing files are overwritten — call site is responsible for `--force`\n * / clean-target semantics.\n */\nexport async function copyDir(\n srcDir: string,\n destDir: string,\n ctx: CopyContext,\n): Promise<void> {\n await fs.mkdir(destDir, { recursive: true });\n\n const entries = await fs.readdir(srcDir, { withFileTypes: true });\n for (const entry of entries) {\n const srcPath = path.join(srcDir, entry.name);\n const destName = mapDestName(entry.name);\n if (destName === null) continue; // explicitly skipped\n const destPath = path.join(destDir, destName);\n\n if (entry.isDirectory()) {\n await copyDir(srcPath, destPath, ctx);\n continue;\n }\n\n if (entry.name.endsWith('.hbs')) {\n const tpl = await fs.readFile(srcPath, 'utf8');\n const rendered = Handlebars.compile(tpl, { noEscape: true })(ctx.hbs);\n await fs.writeFile(destPath, rendered, 'utf8');\n continue;\n }\n\n await fs.copyFile(srcPath, destPath);\n }\n}\n\n/**\n * Translate a source filename to its destination filename, or `null` to skip.\n */\nfunction mapDestName(name: string): string | null {\n // Skip the package.json fragment — orchestrator merges it into base.\n if (name === 'package.json.fragment.json') return null;\n\n // _gitignore → .gitignore (npm strips real `.gitignore` from packed tarballs)\n if (name === '_gitignore') return '.gitignore';\n if (name === '_editorconfig') return '.editorconfig';\n if (name === '_npmrc') return '.npmrc';\n\n // Strip .hbs extension\n if (name.endsWith('.hbs')) {\n return name.slice(0, -'.hbs'.length);\n }\n\n return name;\n}\n","import { execa } from 'execa';\n\n/**\n * Initialize a fresh git repo with a single commit. Best-effort:\n * any failure is reported as `{ ok: false }` instead of throwing —\n * scaffolding should not fail just because git is missing.\n */\nexport async function gitInit(\n cwd: string,\n): Promise<{ ok: true } | { ok: false; reason: string }> {\n try {\n await execa('git', ['init', '--quiet'], { cwd });\n await execa('git', ['add', '-A'], { cwd });\n await execa(\n 'git',\n [\n '-c',\n 'user.email=create-teamix-evo@local',\n '-c',\n 'user.name=create-teamix-evo',\n 'commit',\n '--quiet',\n '--no-gpg-sign',\n '-m',\n 'chore: scaffolded by create-teamix-evo',\n ],\n { cwd },\n );\n return { ok: true };\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n return { ok: false, reason };\n }\n}\n","import fs from 'node:fs/promises';\n\ninterface PackageJsonLike {\n [key: string]: unknown;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n scripts?: Record<string, string>;\n}\n\nexport interface MergeOptions {\n /** Extra dependencies (e.g. from `runUiAdd`) merged with conflict checks. */\n extraDependencies?: Record<string, string>;\n /** Extra dev dependencies merged with conflict checks. */\n extraDevDependencies?: Record<string, string>;\n}\n\nexport class VersionConflictError extends Error {\n constructor(\n readonly key: 'dependencies' | 'devDependencies' | 'scripts',\n override readonly name: string,\n readonly base: string,\n readonly incoming: string,\n ) {\n super(\n `Version conflict in ${key}: ${name} declared as \"${base}\" in base but \"${incoming}\" in overlay/extras.`,\n );\n this.name = 'VersionConflictError';\n }\n}\n\n/**\n * Merge a base package.json with an overlay fragment + extras.\n *\n * - Merges `dependencies`, `devDependencies`, and `scripts` (shallow).\n * - Throws {@link VersionConflictError} on any version mismatch within the same key.\n * - Other top-level keys (`name`, `version`, etc.) come from `base` only.\n */\nexport function mergePackageJson(\n base: PackageJsonLike,\n overlay: PackageJsonLike | null,\n options: MergeOptions = {},\n): PackageJsonLike {\n const merged: PackageJsonLike = { ...base };\n\n for (const key of ['dependencies', 'devDependencies', 'scripts'] as const) {\n const baseMap = (base[key] ?? {}) as Record<string, string>;\n const overlayMap = (overlay?.[key] ?? {}) as Record<string, string>;\n const extrasMap =\n key === 'dependencies'\n ? options.extraDependencies ?? {}\n : key === 'devDependencies'\n ? options.extraDevDependencies ?? {}\n : {};\n\n const result: Record<string, string> = { ...baseMap };\n for (const [name, version] of Object.entries(overlayMap)) {\n if (result[name] !== undefined && result[name] !== version) {\n throw new VersionConflictError(key, name, result[name], version);\n }\n result[name] = version;\n }\n for (const [name, version] of Object.entries(extrasMap)) {\n if (result[name] !== undefined && result[name] !== version) {\n throw new VersionConflictError(key, name, result[name], version);\n }\n result[name] = version;\n }\n if (Object.keys(result).length > 0) {\n merged[key] = sortObjectByKey(result);\n }\n }\n\n return merged;\n}\n\nfunction sortObjectByKey<T extends Record<string, unknown>>(obj: T): T {\n const sorted: Record<string, unknown> = {};\n for (const k of Object.keys(obj).sort()) sorted[k] = obj[k];\n return sorted as T;\n}\n\nexport async function readJson<T = unknown>(filePath: string): Promise<T> {\n const raw = await fs.readFile(filePath, 'utf8');\n return JSON.parse(raw) as T;\n}\n\nexport async function writeJson(\n filePath: string,\n value: unknown,\n): Promise<void> {\n await fs.writeFile(filePath, JSON.stringify(value, null, 2) + '\\n', 'utf8');\n}\n","/**\n * Detect the user's package manager from `npm_config_user_agent`,\n * with fallback heuristics, and produce install / run commands.\n */\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn';\n\nexport interface PackageManagerInfo {\n name: PackageManager;\n /** Command + args to install dependencies in cwd. */\n install: string[];\n /** Command + args prefix to run a package script. */\n run: string[];\n /** Human-readable command (`pnpm install`, etc.). */\n installCommand: string;\n /** Human-readable run prefix (`pnpm`, `npm run`, `yarn`). */\n runPrefix: string;\n}\n\n/**\n * Detect the package manager invoking `create-teamix-evo`.\n *\n * Priority:\n * 1. explicit `prefer` argument\n * 2. `npm_config_user_agent` env (set by `pnpm create` / `npm create` / `yarn create`)\n * 3. fallback to `npm`\n */\nexport function detectPackageManager(\n prefer?: PackageManager,\n): PackageManagerInfo {\n const detected = prefer ?? detectFromUserAgent() ?? 'npm';\n return buildInfo(detected);\n}\n\nexport function isValidPackageManager(value: string): value is PackageManager {\n return value === 'pnpm' || value === 'npm' || value === 'yarn';\n}\n\nfunction detectFromUserAgent(): PackageManager | null {\n const ua = process.env.npm_config_user_agent;\n if (!ua) return null;\n const head = ua.split(' ')[0] ?? '';\n if (head.startsWith('pnpm')) return 'pnpm';\n if (head.startsWith('yarn')) return 'yarn';\n if (head.startsWith('npm')) return 'npm';\n return null;\n}\n\nfunction buildInfo(name: PackageManager): PackageManagerInfo {\n switch (name) {\n case 'pnpm':\n return {\n name,\n install: ['install'],\n run: ['run'],\n installCommand: 'pnpm install',\n runPrefix: 'pnpm',\n };\n case 'yarn':\n return {\n name,\n install: ['install'],\n run: [],\n installCommand: 'yarn install',\n runPrefix: 'yarn',\n };\n case 'npm':\n default:\n return {\n name,\n install: ['install'],\n run: ['run'],\n installCommand: 'npm install',\n runPrefix: 'npm run',\n };\n }\n}\n","import type { Preset } from './types.js';\n\nexport const consolePreset: Preset = {\n id: 'console',\n displayName: 'Console',\n description:\n '中后台标配:Vite + React + TS + Tailwind v4 + design tokens + AI skills + react-router-dom + ConsoleLayout + Dashboard / List / Detail / Form 四页面 + 真装 Button。',\n baseTemplate: 'react-ts',\n design: {\n variant: 'opentrek',\n tailwind: 'v4',\n },\n skills: {\n entries: ['teamix-evo-manage'],\n ides: ['qoder', 'claude'],\n },\n ui: {\n components: ['button'],\n },\n overlay: 'console',\n};\n","import type { Preset } from './types.js';\nimport { consolePreset } from './console.js';\n\nexport type { Preset } from './types.js';\n\nexport const presets: Preset[] = [consolePreset];\n\nexport function findPreset(id: string): Preset | undefined {\n return presets.find((p) => p.id === id);\n}\n\nexport function listPresetIds(): string[] {\n return presets.map((p) => p.id);\n}\n","import { bold, cyan, dim, green, red, yellow } from 'kolorist';\n\nexport const logger = {\n info(message: string): void {\n console.log(`${cyan('ℹ')} ${message}`);\n },\n success(message: string): void {\n console.log(`${green('✓')} ${message}`);\n },\n warn(message: string): void {\n console.warn(`${yellow('⚠')} ${message}`);\n },\n error(message: string): void {\n console.error(`${red('✗')} ${message}`);\n },\n step(message: string): void {\n console.log(`\\n${bold(cyan('▸'))} ${bold(message)}`);\n },\n detail(message: string): void {\n console.log(` ${dim(message)}`);\n },\n blank(): void {\n console.log('');\n },\n};\n","import * as p from '@clack/prompts';\nimport { isValidPackageManager, type PackageManager } from './pm.js';\n\nexport interface InteractiveAnswers {\n presetId: string;\n pm: PackageManager | undefined;\n git: boolean;\n}\n\n/**\n * Run interactive prompts for missing options. The `seed` represents whatever\n * the user already passed via flags; only unanswered fields are prompted for.\n */\nexport async function promptMissing(seed: {\n dir: string;\n presetId?: string;\n pm?: string;\n git?: boolean;\n}): Promise<InteractiveAnswers> {\n p.intro('create-teamix-evo');\n p.note(`📦 Target directory: ${seed.dir}`);\n\n const presetId = seed.presetId ?? 'console';\n\n let pm: PackageManager | undefined =\n seed.pm && isValidPackageManager(seed.pm) ? seed.pm : undefined;\n if (!pm) {\n const pmChoice = await p.select<string>({\n message: '包管理器',\n options: [\n { value: 'auto', label: '自动检测(推荐)' },\n { value: 'pnpm', label: 'pnpm' },\n { value: 'npm', label: 'npm' },\n { value: 'yarn', label: 'yarn' },\n ],\n initialValue: 'auto',\n });\n if (p.isCancel(pmChoice)) {\n p.cancel('已取消');\n process.exit(0);\n }\n pm =\n pmChoice === 'auto'\n ? undefined\n : isValidPackageManager(pmChoice as string)\n ? (pmChoice as PackageManager)\n : undefined;\n }\n\n let git = seed.git;\n if (git === undefined) {\n const confirmed = await p.confirm({\n message: '初始化 git 仓库?',\n initialValue: true,\n });\n if (p.isCancel(confirmed)) {\n p.cancel('已取消');\n process.exit(0);\n }\n git = confirmed as boolean;\n }\n\n return { presetId, pm, git };\n}\n"],"mappings":"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","names":["path","red","fs","path","execa","fs","p","path","execa","fs","path","red"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-teamix-evo",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "Scaffold a Vite + React + TypeScript project pre-wired with Teamix Evo design tokens, AI skills, and UI components.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,7 +18,7 @@
18
18
  "execa": "^9.0.0",
19
19
  "handlebars": "^4.7.0",
20
20
  "kolorist": "^1.8.0",
21
- "teamix-evo": "0.2.0"
21
+ "teamix-evo": "0.3.1"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/cross-spawn": "^6.0.6",
@@ -27,6 +27,10 @@
27
27
  "typescript": "^5.5.0",
28
28
  "vitest": "^2.0.0"
29
29
  },
30
+ "publishConfig": {
31
+ "access": "public",
32
+ "registry": "https://registry.npmjs.org/"
33
+ },
30
34
  "scripts": {
31
35
  "build": "tsup",
32
36
  "dev": "tsup --watch",
@@ -12,7 +12,7 @@
12
12
 
13
13
  ## 已安装资产
14
14
 
15
- - **设计 tokens**:`.teamix-evo/design/tokens/`(variant: `{{designVariant}}`)
15
+ - **设计 tokens**:`.teamix-evo/tokens/`(variant: `{{designVariant}}`)
16
16
  - **AI 入口**:`AGENTS.md`(项目级)/ `.qoder/agents/` / `.claude/agents/`
17
17
  - **UI 组件**:`src/components/ui/`(已落地:`{{uiInstalled}}`)
18
18
 
@@ -32,7 +32,7 @@ npx teamix-evo ui list
32
32
 
33
33
  ## 自定义 token
34
34
 
35
- `.teamix-evo/design/tokens/tokens.overrides.css` 是 **frozen** 资源 — 在这里覆盖任何 `--color-primary` 等 CSS 变量后,刷新即可生效,CLI 升级不会覆盖你的改动。
35
+ `.teamix-evo/tokens/tokens.overrides.css` 是 **frozen** 资源 — 在这里覆盖任何 `--color-primary` 等 CSS 变量后,刷新即可生效,CLI 升级不会覆盖你的改动。
36
36
 
37
37
  ## AI 协作
38
38
 
@@ -22,3 +22,9 @@ dist-ssr
22
22
  *.njsproj
23
23
  *.sln
24
24
  *.sw?
25
+
26
+ # teamix-evo skills IDE mirrors (per ADR 0013 source-mirror model).
27
+ # The source lives at .teamix-evo/skills/ (in git); IDE paths below are
28
+ # regenerable mirrors produced by `teamix-evo skills sync`.
29
+ .qoder/skills/
30
+ .claude/skills/
@@ -5,7 +5,7 @@ export default function App() {
5
5
  <p className="text-muted-foreground max-w-md text-center">
6
6
  设计 tokens 已就位 — 修改{' '}
7
7
  <code className="px-1 py-0.5 rounded bg-muted">
8
- .teamix-evo/design/tokens/tokens.overrides.css
8
+ .teamix-evo/tokens/tokens.overrides.css
9
9
  </code>{' '}
10
10
  试试热更新。
11
11
  </p>
@@ -1,5 +1,6 @@
1
1
  @import 'tailwindcss';
2
2
 
3
- /* Teamix Evo design tokens — 由 `teamix-evo design init` 装载到 .teamix-evo/design/tokens/ */
4
- @import '../.teamix-evo/design/tokens/tokens.theme.css';
5
- @import '../.teamix-evo/design/tokens/tokens.overrides.css';
3
+ /* Teamix Evo design tokens — 由 `teamix-evo design init` 装载到 .teamix-evo/tokens/
4
+ * (tokens 被 lift 出 design/ 目录以缩短嵌套,见 design-pack-classify.ts) */
5
+ @import '../.teamix-evo/tokens/tokens.theme.css';
6
+ @import '../.teamix-evo/tokens/tokens.overrides.css';
@@ -23,7 +23,7 @@
23
23
  "paths": {
24
24
  "@/*": ["./src/*"]
25
25
  },
26
- "types": ["node", "vite/client"]
26
+ "types": ["node"]
27
27
  },
28
28
  "include": ["src", "vite.config.ts"]
29
29
  }