teamix-evo 0.8.0 → 0.10.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 +35 -28
- package/dist/core/index.d.ts +234 -11
- package/dist/core/index.js +2424 -861
- package/dist/core/index.js.map +1 -1
- package/dist/index.js +6159 -2153
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -167,34 +167,41 @@ TEAMIX_DEBUG=1 teamix-evo tokens init opentrek
|
|
|
167
167
|
|
|
168
168
|
## 命令参考
|
|
169
169
|
|
|
170
|
-
| 命令
|
|
171
|
-
|
|
|
172
|
-
| `teamix-evo init [-y] [--dry-run] [--variant <n>]`
|
|
173
|
-
| `teamix-evo update [--dry-run] [--cwd <dir>]`
|
|
174
|
-
| `teamix-evo restore [ts] [--list] [-y]`
|
|
175
|
-
| `teamix-evo switch <new-variant> [--apply] [-y]`
|
|
176
|
-
| `teamix-evo tokens init <variant>`
|
|
177
|
-
| `teamix-evo tokens list-variants`
|
|
178
|
-
| `teamix-evo tokens list`
|
|
179
|
-
| `teamix-evo tokens update`
|
|
180
|
-
| `teamix-evo tokens uninstall`
|
|
181
|
-
| `teamix-evo
|
|
182
|
-
| `teamix-evo
|
|
183
|
-
| `teamix-evo
|
|
184
|
-
| `teamix-evo
|
|
185
|
-
| `teamix-evo
|
|
186
|
-
| `teamix-evo
|
|
187
|
-
| `teamix-evo skills
|
|
188
|
-
| `teamix-evo
|
|
189
|
-
| `teamix-evo
|
|
190
|
-
| `teamix-evo
|
|
191
|
-
| `teamix-evo
|
|
192
|
-
| `teamix-evo
|
|
193
|
-
| `teamix-evo
|
|
194
|
-
| `teamix-evo
|
|
195
|
-
| `teamix-evo
|
|
196
|
-
| `teamix-evo
|
|
197
|
-
| `teamix-evo
|
|
170
|
+
| 命令 | 说明 |
|
|
171
|
+
| ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
172
|
+
| `teamix-evo init [-y] [--dry-run] [--variant <n>]` | 普通版接入:检测冲突 → wizard → 静默落地(已有 npm 工程入口) |
|
|
173
|
+
| `teamix-evo update [--dry-run] [--cwd <dir>]` | 一键升级已装资源(tokens + skills,ADR 0003 三态 + ADR 0035 短路) |
|
|
174
|
+
| `teamix-evo restore [ts] [--list] [-y]` | 回滚 `.teamix-evo/` 到指定 snapshot(ADR 0019 §2 — 自身可逆) |
|
|
175
|
+
| `teamix-evo switch <new-variant> [--apply] [-y]` | variant 切换:默认 dry-run 展示 file-level diff,--apply 才真写(ADR 0019 §D3) |
|
|
176
|
+
| `teamix-evo tokens init <variant>` | 初始化 tokens |
|
|
177
|
+
| `teamix-evo tokens list-variants` | 列出可用 variant |
|
|
178
|
+
| `teamix-evo tokens list` | 查看已装机的 variant |
|
|
179
|
+
| `teamix-evo tokens update` | 更新已装资源(stub,v0.7 见 ADR 0019) |
|
|
180
|
+
| `teamix-evo tokens uninstall` | 卸载已装 tokens |
|
|
181
|
+
| `teamix-evo tokens audit` | 审计 tokens 引用(4 类:redundant / kept / migrate / custom,v3↔v4 语义比较) |
|
|
182
|
+
| `teamix-evo tokens diagnose` | 诊断 tokens 使用情况,生成分级报告(L1-L3)+ `.treatment-plan.md` |
|
|
183
|
+
| `teamix-evo tokens treat [--lock-baseline] [--apply]` | 一键 token 治理流水线:lint → codemod → lint → 报告 → 可选锁定 baseline |
|
|
184
|
+
| `teamix-evo tokens codemod [name] [--apply] [--list]` | 执行指定 token codemod(5 个可用:hsl-to-v4 / hex-to-token / tw-scale-to-semantic / space-to-gap / arbitrary-to-token) |
|
|
185
|
+
| `teamix-evo tokens reflect [--min-frequency <n>]` | 扫描重复色值,推荐新增项目级 token(反哺 overrides.css) |
|
|
186
|
+
| `teamix-evo tokens baseline-check` | 对比 baseline 检查 token 违规是否超标(CI 友好,exitCode=1 on fail) |
|
|
187
|
+
| `teamix-evo skills init` | 自举 skills(按 variant + scope 全装 — ADR 0034) |
|
|
188
|
+
| `teamix-evo skills add <name...>` | 增量装指定 skill(`<name...>` 必填) |
|
|
189
|
+
| `teamix-evo skills list` | 列出所有 skill 的安装状态 |
|
|
190
|
+
| `teamix-evo skills update [name...] [--dry-run]` | 升级 skills(双闸 + version 短路 — ADR 0035) |
|
|
191
|
+
| `teamix-evo skills sync [name...]` | 源 → IDE 镜像(漂移恢复用) |
|
|
192
|
+
| `teamix-evo skills doctor` | 检测源/镜像漂移(ADR 0013) |
|
|
193
|
+
| `teamix-evo skills uninstall` | 卸载 skills(源 + 镜像 + lock) |
|
|
194
|
+
| `teamix-evo ui init` | 初始化 ui 配置(aliases / iconLibrary / tsx / rsc) |
|
|
195
|
+
| `teamix-evo ui add <id...>` | 安装指定 ui 组件源码 |
|
|
196
|
+
| `teamix-evo ui list [--installed]` | 列出可用/已安装 ui 组件 |
|
|
197
|
+
| `teamix-evo ui promote-to-biz <id...>` | 把 ui 组件提升为业务组件(8 模式:Coexist/Preset/Wrapper/Compose/Variant/Fork/TokenOnly/ManualReview) |
|
|
198
|
+
| `teamix-evo biz-ui list-variants` | 列出 biz-ui 包内提供的业务变体 |
|
|
199
|
+
| `teamix-evo biz-ui add <id...> --variant <name>` | 安装变体感知业务组件(`--variant` 必填) |
|
|
200
|
+
| `teamix-evo templates list-variants` | 列出 templates 包内提供的页面模板变体 |
|
|
201
|
+
| `teamix-evo templates add <id...> --variant <name>` | 安装变体感知页面模板(`--variant` 必填) |
|
|
202
|
+
| `teamix-evo lint init [-y]` | 一键安装 ESLint + Stylelint token-discipline 规则集 |
|
|
203
|
+
| `teamix-evo logs analyze [...]` | 分析 vibe-logger AI 调用链(`.log/ai/**/*.jsonl`) |
|
|
204
|
+
| `teamix-evo logs trace [...]` | 按会话还原 AI 调用链(prompt → PreToolUse → PostToolUse → Stop) |
|
|
198
205
|
|
|
199
206
|
> 占位组件 → 真组件的升级流程**不是** CLI 子命令,由
|
|
200
207
|
> [`teamix-evo-manage`](../../packages/skills/src/teamix-evo-manage/SKILL.md)
|
package/dist/core/index.d.ts
CHANGED
|
@@ -103,6 +103,13 @@ type RunSkillsInitResult = {
|
|
|
103
103
|
resources: InstalledResource[];
|
|
104
104
|
addedSkillIds: string[];
|
|
105
105
|
skippedSkillIds: string[];
|
|
106
|
+
/**
|
|
107
|
+
* Always `[]` for `runSkillsInit` — bulk bootstrap deliberately does not
|
|
108
|
+
* surface upgrade hints (only `runSkillsAdd` does, ADR 0034). Kept on
|
|
109
|
+
* the type so the result shape stays consistent with `RunSkillsAddResult`
|
|
110
|
+
* and `finalizeSkillsInstall`'s return.
|
|
111
|
+
*/
|
|
112
|
+
outdatedSkills: OutdatedSkillInfo[];
|
|
106
113
|
} | {
|
|
107
114
|
/** Returned when a skills package is already installed and bulk has nothing new to add. */
|
|
108
115
|
status: 'already-initialized';
|
|
@@ -133,6 +140,18 @@ interface RunSkillsAddOptions {
|
|
|
133
140
|
/** Override the skills package name (defaults to "@teamix-evo/skills"). */
|
|
134
141
|
packageName?: string;
|
|
135
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Detail for an already-installed skill whose locked version is older than
|
|
145
|
+
* the manifest's latest version. Use `skills update <id>` to upgrade.
|
|
146
|
+
*/
|
|
147
|
+
interface OutdatedSkillInfo {
|
|
148
|
+
/** Skill id */
|
|
149
|
+
id: string;
|
|
150
|
+
/** Version recorded in `.teamix-evo/skills.lock.json` */
|
|
151
|
+
installed: string;
|
|
152
|
+
/** Version available in the upstream manifest (i.e. `npx` resolved `@latest`) */
|
|
153
|
+
latest: string;
|
|
154
|
+
}
|
|
136
155
|
type RunSkillsAddResult = {
|
|
137
156
|
status: 'installed';
|
|
138
157
|
packageName: string;
|
|
@@ -147,8 +166,18 @@ type RunSkillsAddResult = {
|
|
|
147
166
|
resources: InstalledResource[];
|
|
148
167
|
/** Skill ids that were freshly added in this call. */
|
|
149
168
|
addedSkillIds: string[];
|
|
150
|
-
/**
|
|
169
|
+
/**
|
|
170
|
+
* Skill ids that were requested but already installed at the latest version;
|
|
171
|
+
* nothing to do. Outdated installs are reported separately via
|
|
172
|
+
* {@link outdatedSkills}.
|
|
173
|
+
*/
|
|
151
174
|
skippedSkillIds: string[];
|
|
175
|
+
/**
|
|
176
|
+
* Skill ids that were requested, are already installed, but whose locked
|
|
177
|
+
* version is older than the manifest version. Caller should surface a hint
|
|
178
|
+
* recommending `skills update <id>`.
|
|
179
|
+
*/
|
|
180
|
+
outdatedSkills: OutdatedSkillInfo[];
|
|
152
181
|
};
|
|
153
182
|
/**
|
|
154
183
|
* Programmatic equivalent of `teamix-evo skills add <names...>` (ADR 0034).
|
|
@@ -390,6 +419,15 @@ interface ListVariantUiEntriesResult {
|
|
|
390
419
|
declare function listBizUiEntries(variant: string, packageRoot?: string): Promise<ListVariantUiEntriesResult>;
|
|
391
420
|
declare function listTemplatesEntries(variant: string, packageRoot?: string): Promise<ListVariantUiEntriesResult>;
|
|
392
421
|
|
|
422
|
+
/**
|
|
423
|
+
* Phase 3.E lint conflict strategies (mirrors `init-conflicts.ts`).
|
|
424
|
+
*
|
|
425
|
+
* `merge` and `backup-overwrite` both back up the existing user file before
|
|
426
|
+
* writing the teamix-evo template; `merge` additionally surfaces an AI-assist
|
|
427
|
+
* hint so the manage / code skill can guide the user through merging custom
|
|
428
|
+
* rules. `skip` keeps the user's file as-is and emits no template.
|
|
429
|
+
*/
|
|
430
|
+
type LintConflictStrategy = 'merge' | 'backup-overwrite' | 'skip' | 'overwrite';
|
|
393
431
|
interface RunLintInitOptions {
|
|
394
432
|
/** Absolute project root directory. */
|
|
395
433
|
projectRoot: string;
|
|
@@ -399,11 +437,49 @@ interface RunLintInitOptions {
|
|
|
399
437
|
* installed in a later batch step.
|
|
400
438
|
*/
|
|
401
439
|
skipInstall?: boolean;
|
|
440
|
+
/**
|
|
441
|
+
* Phase 3.E: strategy for handling existing ESLint config files.
|
|
442
|
+
* Defaults to `'overwrite'` (legacy behaviour); the `init` orchestrator
|
|
443
|
+
* passes the wizard-resolved value when consumer files are detected.
|
|
444
|
+
*/
|
|
445
|
+
eslintStrategy?: LintConflictStrategy;
|
|
446
|
+
/**
|
|
447
|
+
* Phase 3.E: strategy for handling existing Stylelint config files.
|
|
448
|
+
*/
|
|
449
|
+
stylelintStrategy?: LintConflictStrategy;
|
|
450
|
+
/**
|
|
451
|
+
* Phase 3.E: paths of existing ESLint configs (relative to projectRoot)
|
|
452
|
+
* to back up. Empty when no consumer config was detected.
|
|
453
|
+
*/
|
|
454
|
+
eslintExistingPaths?: string[];
|
|
455
|
+
/**
|
|
456
|
+
* Phase 3.E: paths of existing Stylelint configs (relative to projectRoot).
|
|
457
|
+
*/
|
|
458
|
+
stylelintExistingPaths?: string[];
|
|
402
459
|
}
|
|
403
460
|
type RunLintInitResult = {
|
|
404
461
|
status: 'installed';
|
|
405
462
|
eslint: boolean;
|
|
406
463
|
stylelint: boolean;
|
|
464
|
+
/** True when the user had a custom config and asked for AI-assisted merge. */
|
|
465
|
+
eslintMergeRequested?: boolean;
|
|
466
|
+
stylelintMergeRequested?: boolean;
|
|
467
|
+
/** True when the strategy asked us to keep the user file untouched. */
|
|
468
|
+
eslintSkipped?: boolean;
|
|
469
|
+
stylelintSkipped?: boolean;
|
|
470
|
+
/**
|
|
471
|
+
* True when `package.json` was actually patched (lint / lint:css
|
|
472
|
+
* scripts inserted). Powers the project-init change ledger so the
|
|
473
|
+
* CLI does not report a phantom write when both scripts already
|
|
474
|
+
* existed.
|
|
475
|
+
*/
|
|
476
|
+
packageJsonPatched?: boolean;
|
|
477
|
+
/**
|
|
478
|
+
* True when the consumer's existing stylelint config was kept (skip /
|
|
479
|
+
* merge) and does not extend a teamix-evo preset — token definition
|
|
480
|
+
* files may trigger false-positive lint errors without `ignoreFiles`.
|
|
481
|
+
*/
|
|
482
|
+
stylelintIgnoreFilesWarning?: boolean;
|
|
407
483
|
} | {
|
|
408
484
|
status: 'already-initialized';
|
|
409
485
|
};
|
|
@@ -445,14 +521,45 @@ interface RunGenerateAgentsMdOptions {
|
|
|
445
521
|
* (e.g. `teamix-evo-manage`).
|
|
446
522
|
*/
|
|
447
523
|
skillIds: string[];
|
|
524
|
+
/**
|
|
525
|
+
* Reconciliation mode (Phase 2.B):
|
|
526
|
+
* - `'overwrite'` (default): always rewrite the full file. Pre-existing
|
|
527
|
+
* content is backed up and discarded.
|
|
528
|
+
* - `'merge-managed'`: rewrite only the `teamix-evo-skills` managed
|
|
529
|
+
* region. When the consumer file lacks the region, prepend a fresh
|
|
530
|
+
* managed block ahead of the user's content (auto-adopt). The user's
|
|
531
|
+
* non-managed sections are preserved.
|
|
532
|
+
*
|
|
533
|
+
* In both modes, an existing file is backed up under
|
|
534
|
+
* `.teamix-evo/.backups/AGENTS.md.<isoTs>.bak` before any mutation.
|
|
535
|
+
*/
|
|
536
|
+
mode?: 'overwrite' | 'merge-managed';
|
|
448
537
|
}
|
|
449
538
|
interface RunGenerateAgentsMdResult {
|
|
450
539
|
/** Absolute path of the written `AGENTS.md`. */
|
|
451
540
|
path: string;
|
|
452
|
-
/** Number of skill sections rendered (
|
|
541
|
+
/** Number of skill sections rendered (missing SKILL.md degradations are still counted). */
|
|
453
542
|
skillCount: number;
|
|
454
543
|
/** Skill ids whose SKILL.md could not be read (rendered as degraded section). */
|
|
455
544
|
missingSkillIds: string[];
|
|
545
|
+
/**
|
|
546
|
+
* True when an existing AGENTS.md was backed up under
|
|
547
|
+
* `.teamix-evo/.backups/AGENTS.md.<isoTs>.bak` before being overwritten
|
|
548
|
+
* (Phase 1.A2 — full backup strategy).
|
|
549
|
+
*/
|
|
550
|
+
backedUp: boolean;
|
|
551
|
+
/**
|
|
552
|
+
* Outcome of the merge step (Phase 2.B):
|
|
553
|
+
* - `'created'`: no AGENTS.md existed; wrote a fresh full template.
|
|
554
|
+
* - `'overwritten'`: existed but mode='overwrite' — full rewrite.
|
|
555
|
+
* - `'managed-replaced'`: mode='merge-managed' and the consumer file
|
|
556
|
+
* already had the `teamix-evo-skills` managed region; only that region
|
|
557
|
+
* was rewritten. User content outside is preserved.
|
|
558
|
+
* - `'managed-prepended'`: mode='merge-managed' but the consumer file
|
|
559
|
+
* did not yet have the managed region; a fresh block was inserted at
|
|
560
|
+
* the top, with the existing user content kept below.
|
|
561
|
+
*/
|
|
562
|
+
merge: 'created' | 'overwritten' | 'managed-replaced' | 'managed-prepended';
|
|
456
563
|
}
|
|
457
564
|
interface SkillDescriptionParts {
|
|
458
565
|
/** First non-empty line(s) of `description` (the capability statement). */
|
|
@@ -462,8 +569,16 @@ interface SkillDescriptionParts {
|
|
|
462
569
|
coordinates: string | null;
|
|
463
570
|
}
|
|
464
571
|
/**
|
|
465
|
-
* Generate and write the `AGENTS.md` file.
|
|
466
|
-
*
|
|
572
|
+
* Generate and write the `AGENTS.md` file.
|
|
573
|
+
*
|
|
574
|
+
* Phase 2.B — reconciliation modes:
|
|
575
|
+
* - `'overwrite'` (default): regenerable behaviour, full rewrite.
|
|
576
|
+
* - `'merge-managed'`: rewrite only the `teamix-evo-skills` managed region
|
|
577
|
+
* so user-authored sections (project-specific guidance, design tokens,
|
|
578
|
+
* prompts) are never clobbered.
|
|
579
|
+
*
|
|
580
|
+
* Existing files are always backed up under `.teamix-evo/.backups/` before
|
|
581
|
+
* mutation (ADR 0019 §2, Phase 1.A2).
|
|
467
582
|
*/
|
|
468
583
|
declare function runGenerateAgentsMd(options: RunGenerateAgentsMdOptions): Promise<RunGenerateAgentsMdResult>;
|
|
469
584
|
/**
|
|
@@ -512,15 +627,15 @@ interface ProjectStateReport {
|
|
|
512
627
|
declare function detectProjectState(cwd: string): Promise<ProjectStateReport>;
|
|
513
628
|
|
|
514
629
|
/**
|
|
515
|
-
* The
|
|
630
|
+
* The 8 categories of consumer-side files that `teamix-evo init` may
|
|
516
631
|
* conflict with when running against a non-teamix-evo project.
|
|
517
632
|
*
|
|
518
633
|
* See ADR 0019 D1 task #5 — these are the only files we mutate at
|
|
519
634
|
* `init` time, so they're the only ones we ask the user about.
|
|
520
635
|
*/
|
|
521
|
-
type ConflictKey = 'agents-md' | 'components-json' | 'tailwind-config' | 'tokens' | 'index-css' | 'shadcn-source';
|
|
636
|
+
type ConflictKey = 'agents-md' | 'components-json' | 'tailwind-config' | 'tokens' | 'index-css' | 'shadcn-source' | 'eslint-config' | 'stylelint-config';
|
|
522
637
|
/** Strategy options per conflict category. */
|
|
523
|
-
type ConflictStrategy = 'overwrite' | 'merge-managed' | 'skip' | 'diff-prompt' | 'backup-overwrite' | 'migrate' | 'coexist' | 'append' | 'skip-existing' | 'per-file-prompt';
|
|
638
|
+
type ConflictStrategy = 'overwrite' | 'merge-managed' | 'skip' | 'diff-prompt' | 'backup-overwrite' | 'migrate' | 'coexist' | 'append' | 'skip-existing' | 'per-file-prompt' | 'merge';
|
|
524
639
|
interface ConflictItem {
|
|
525
640
|
/** Stable id for the category. */
|
|
526
641
|
key: ConflictKey;
|
|
@@ -542,13 +657,13 @@ interface ConflictItem {
|
|
|
542
657
|
}
|
|
543
658
|
interface ConflictReport {
|
|
544
659
|
cwd: string;
|
|
545
|
-
/** Always
|
|
660
|
+
/** Always 8 items, ordered by ConflictKey enumeration above. */
|
|
546
661
|
items: ConflictItem[];
|
|
547
662
|
/** True if any item has `exists === true`. */
|
|
548
663
|
hasAnyConflict: boolean;
|
|
549
664
|
}
|
|
550
665
|
/**
|
|
551
|
-
* Inspect `cwd` for the
|
|
666
|
+
* Inspect `cwd` for the 8 categories of files that `teamix-evo init` may
|
|
552
667
|
* touch. Pure read-only — never mutates the filesystem. Returns one
|
|
553
668
|
* `ConflictItem` per category in stable order so callers can render a
|
|
554
669
|
* deterministic wizard.
|
|
@@ -577,6 +692,33 @@ interface InitWizardAnswers {
|
|
|
577
692
|
conflictDecisions: Record<ConflictKey, ConflictStrategy>;
|
|
578
693
|
}
|
|
579
694
|
|
|
695
|
+
interface UiConflictEntry {
|
|
696
|
+
/** UI entry id from manifest (e.g. "button") */
|
|
697
|
+
id: string;
|
|
698
|
+
/** Absolute path on disk that conflicts */
|
|
699
|
+
targetPath: string;
|
|
700
|
+
/** Project-relative posix path for display */
|
|
701
|
+
relativePath: string;
|
|
702
|
+
/**
|
|
703
|
+
* Heuristic guess: true when the existing file looks like an unmodified
|
|
704
|
+
* shadcn/ui original (no `data-slot` attribute from teamix-evo).
|
|
705
|
+
* v1 uses filename + content heuristics; future versions may hash-compare.
|
|
706
|
+
*/
|
|
707
|
+
isShadcnOriginal: boolean;
|
|
708
|
+
}
|
|
709
|
+
interface UiConflictReport {
|
|
710
|
+
/** Entries whose target file already exists on disk */
|
|
711
|
+
conflictEntries: UiConflictEntry[];
|
|
712
|
+
/** Number of manifest entries with no on-disk conflict */
|
|
713
|
+
unconflictedTargets: number;
|
|
714
|
+
/** Total manifest entries checked */
|
|
715
|
+
totalEntries: number;
|
|
716
|
+
/** True when at least one conflict exists — caller should block */
|
|
717
|
+
shouldBlock: boolean;
|
|
718
|
+
/** Distinct target alias directories that have conflicts */
|
|
719
|
+
conflictDirs: string[];
|
|
720
|
+
}
|
|
721
|
+
|
|
580
722
|
/** Result of `createSnapshot` when a snapshot was actually taken. */
|
|
581
723
|
interface SnapshotResult {
|
|
582
724
|
/** Filesystem-safe UTC timestamp identifier (e.g. `2026-06-11T20-59-03-000Z`). */
|
|
@@ -585,6 +727,17 @@ interface SnapshotResult {
|
|
|
585
727
|
path: string;
|
|
586
728
|
}
|
|
587
729
|
|
|
730
|
+
type FileChangeKind = 'created' | 'modified' | 'backed-up' | 'deleted';
|
|
731
|
+
interface FileChange {
|
|
732
|
+
kind: FileChangeKind;
|
|
733
|
+
/** Project-root-relative path, posix style (forward slashes). */
|
|
734
|
+
path: string;
|
|
735
|
+
/** Originating pipeline step (free-form to avoid coupling on `ProjectInitStepName`). */
|
|
736
|
+
step: string;
|
|
737
|
+
/** Optional human-readable note (e.g. `frozen` / `regenerable` / `managed`). */
|
|
738
|
+
detail?: string;
|
|
739
|
+
}
|
|
740
|
+
|
|
588
741
|
/**
|
|
589
742
|
* Programmatic orchestrator for `teamix-evo init` (existing-project adoption).
|
|
590
743
|
*
|
|
@@ -609,12 +762,31 @@ interface SnapshotResult {
|
|
|
609
762
|
* No interactive prompts, no `process.exit`. Throws on hard failure (P8).
|
|
610
763
|
*/
|
|
611
764
|
|
|
612
|
-
|
|
765
|
+
/**
|
|
766
|
+
* Strategy for handling UI component conflicts when existing shadcn/ui
|
|
767
|
+
* components are found in the target project.
|
|
768
|
+
*
|
|
769
|
+
* - `isolate-progressive` (Path A): move existing → shadcn-ui/, install
|
|
770
|
+
* fresh teamix-evo components into ui/, rewrite imports, let user
|
|
771
|
+
* migrate at their own pace.
|
|
772
|
+
* - `isolate-aggressive` (Path C): same as A + immediately generate
|
|
773
|
+
* upgrade staging so user can batch-replace.
|
|
774
|
+
* - `frozen-skip`: legacy behaviour — skip existing files, no migration.
|
|
775
|
+
*/
|
|
776
|
+
type UiConflictStrategy = 'isolate-progressive' | 'isolate-aggressive' | 'frozen-skip';
|
|
777
|
+
type ProjectInitStepName = 'tokens' | 'skills' | 'agents-md' | 'ui-init' | 'ui-add' | 'lint' | 'gitignore';
|
|
613
778
|
type ProjectInitStepStatus = 'ok' | 'skip' | 'fail' | 'planned';
|
|
614
779
|
interface ProjectInitStep {
|
|
615
780
|
name: ProjectInitStepName;
|
|
616
781
|
status: ProjectInitStepStatus;
|
|
617
782
|
detail?: string;
|
|
783
|
+
/**
|
|
784
|
+
* Files this step touched (Phase 1.A1). Empty when the step skipped or
|
|
785
|
+
* failed before any I/O. The `kind` is `created` by default; the orchestrator
|
|
786
|
+
* upgrades entries to `modified` post-hoc by checking the backup ledger
|
|
787
|
+
* (`.teamix-evo/.backups/`).
|
|
788
|
+
*/
|
|
789
|
+
changes?: FileChange[];
|
|
618
790
|
}
|
|
619
791
|
interface PendingConflictWork {
|
|
620
792
|
key: ConflictKey;
|
|
@@ -668,6 +840,30 @@ interface RunProjectInitOptions {
|
|
|
668
840
|
* responsible for filtering out paths already inside `tokens/`.
|
|
669
841
|
*/
|
|
670
842
|
legacyTokensPaths?: string[];
|
|
843
|
+
/**
|
|
844
|
+
* Phase 3.E: existing ESLint config paths (relative to `projectRoot`)
|
|
845
|
+
* detected by `detectConflicts` for the `eslint-config` key. Used to
|
|
846
|
+
* back up the consumer's file before writing the teamix-evo template,
|
|
847
|
+
* and to gate the `merge` / `backup-overwrite` / `skip` strategies in
|
|
848
|
+
* `runLintInit`.
|
|
849
|
+
*/
|
|
850
|
+
legacyEslintPaths?: string[];
|
|
851
|
+
/**
|
|
852
|
+
* Phase 3.E: existing Stylelint config paths (relative to `projectRoot`).
|
|
853
|
+
*/
|
|
854
|
+
legacyStylelintPaths?: string[];
|
|
855
|
+
/**
|
|
856
|
+
* UI conflict resolution strategy. When omitted AND conflicts are
|
|
857
|
+
* detected, the orchestrator returns `uiDecisionRequired` so the
|
|
858
|
+
* caller can prompt the user. When `-y` (non-interactive), defaults
|
|
859
|
+
* to `'isolate-progressive'`.
|
|
860
|
+
*/
|
|
861
|
+
uiConflictStrategy?: UiConflictStrategy;
|
|
862
|
+
/**
|
|
863
|
+
* When true, treat the invocation as non-interactive (`-y` flag).
|
|
864
|
+
* Affects default conflict strategy selection.
|
|
865
|
+
*/
|
|
866
|
+
nonInteractive?: boolean;
|
|
671
867
|
/** Step-level progress hook (caller controls presentation). */
|
|
672
868
|
onStep?: (step: ProjectInitStep) => void;
|
|
673
869
|
/**
|
|
@@ -676,11 +872,32 @@ interface RunProjectInitOptions {
|
|
|
676
872
|
*/
|
|
677
873
|
dryRun?: boolean;
|
|
678
874
|
}
|
|
875
|
+
/**
|
|
876
|
+
* Returned when UI conflicts are detected and no `uiConflictStrategy` was
|
|
877
|
+
* provided. The caller should present the options to the user and re-invoke
|
|
878
|
+
* `runProjectInit` with the chosen strategy.
|
|
879
|
+
*/
|
|
880
|
+
interface UiDecisionRequired {
|
|
881
|
+
/** The full conflict report for display */
|
|
882
|
+
report: UiConflictReport;
|
|
883
|
+
/** Available strategies with human-readable descriptions */
|
|
884
|
+
options: Array<{
|
|
885
|
+
strategy: UiConflictStrategy;
|
|
886
|
+
label: string;
|
|
887
|
+
description: string;
|
|
888
|
+
}>;
|
|
889
|
+
}
|
|
679
890
|
interface RunProjectInitResult {
|
|
680
891
|
status: 'installed' | 'partial' | 'dry-run';
|
|
681
892
|
steps: ProjectInitStep[];
|
|
682
893
|
/** Conflicts whose strategy needs the post-batch-4 managed-region engine. */
|
|
683
894
|
pendingConflictWork: PendingConflictWork[];
|
|
895
|
+
/**
|
|
896
|
+
* Aggregated, classified file-change ledger covering every step
|
|
897
|
+
* (Phase 1.A1). Backup entries are surfaced as `kind: 'backed-up'` so the
|
|
898
|
+
* CLI can render a four-bucket summary (新建 / 修改 / 备份 / 删除).
|
|
899
|
+
*/
|
|
900
|
+
changes: FileChange[];
|
|
684
901
|
/**
|
|
685
902
|
* Present when at least one step ended in `fail`. Lets the CLI surface a
|
|
686
903
|
* structured recovery message instead of just a stack-trace, and gives
|
|
@@ -700,6 +917,12 @@ interface RunProjectInitResult {
|
|
|
700
917
|
snapshot?: SnapshotResult | null;
|
|
701
918
|
/** Reason a snapshot capture failed (best-effort — never blocks init). */
|
|
702
919
|
snapshotError?: string;
|
|
920
|
+
/**
|
|
921
|
+
* Present when UI conflicts are detected and no `uiConflictStrategy`
|
|
922
|
+
* was provided (interactive mode). Caller should prompt the user with
|
|
923
|
+
* `options`, then re-invoke with the chosen strategy.
|
|
924
|
+
*/
|
|
925
|
+
uiDecisionRequired?: UiDecisionRequired;
|
|
703
926
|
}
|
|
704
927
|
/**
|
|
705
928
|
* Existing-project init pipeline.
|
|
@@ -805,7 +1028,7 @@ declare function installResources(options: InstallOptions): Promise<InstallResul
|
|
|
805
1028
|
*
|
|
806
1029
|
* Two-stage flow:
|
|
807
1030
|
* 1. **writeSkillSources** — render upstream `<packageRoot>/<skill.source>` and
|
|
808
|
-
* write to `<projectRoot>/.teamix-evo/skills/<id>/` (the consumer-side
|
|
1031
|
+
* write to `<projectRoot>/.teamix-evo/skills-source/<id>/` (the consumer-side
|
|
809
1032
|
* source of truth, regenerable, in git).
|
|
810
1033
|
* 2. **syncSkillsToIdes** — pure byte-for-byte copy from source dir to each
|
|
811
1034
|
* requested IDE mirror path (`.qoder/skills/<id>/`, `.claude/skills/<id>/`).
|