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 +15 -11
- package/dist/index.js +6 -47
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
- package/templates/react-ts/README.md.hbs +2 -2
- package/templates/react-ts/_gitignore +6 -0
- package/templates/react-ts/src/App.tsx +1 -1
- package/templates/react-ts/src/index.css +4 -3
- package/templates/react-ts/tsconfig.json +1 -1
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
|
-
##
|
|
18
|
+
## Preset
|
|
19
19
|
|
|
20
|
-
|
|
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
|
-
|
|
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/ #
|
|
51
|
-
├── .
|
|
52
|
-
├── .
|
|
53
|
-
├──
|
|
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\
|
|
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 = [
|
|
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
|
-
|
|
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 &&
|
|
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.
|
|
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.
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
4
|
-
|
|
5
|
-
@import '../.teamix-evo/
|
|
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';
|