teamix-evo 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -24
- package/dist/core/index.d.ts +510 -3
- package/dist/core/index.js +2909 -148
- package/dist/core/index.js.map +1 -1
- package/dist/index.js +6406 -1185
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -167,30 +167,36 @@ TEAMIX_DEBUG=1 teamix-evo tokens init opentrek
|
|
|
167
167
|
|
|
168
168
|
## 命令参考
|
|
169
169
|
|
|
170
|
-
| 命令 | 说明
|
|
171
|
-
| --------------------------------------------------- |
|
|
172
|
-
| `teamix-evo
|
|
173
|
-
| `teamix-evo
|
|
174
|
-
| `teamix-evo
|
|
175
|
-
| `teamix-evo
|
|
176
|
-
| `teamix-evo tokens
|
|
177
|
-
| `teamix-evo
|
|
178
|
-
| `teamix-evo
|
|
179
|
-
| `teamix-evo
|
|
180
|
-
| `teamix-evo
|
|
181
|
-
| `teamix-evo
|
|
182
|
-
| `teamix-evo skills
|
|
183
|
-
| `teamix-evo skills
|
|
184
|
-
| `teamix-evo
|
|
185
|
-
| `teamix-evo
|
|
186
|
-
| `teamix-evo
|
|
187
|
-
| `teamix-evo
|
|
188
|
-
| `teamix-evo
|
|
189
|
-
| `teamix-evo
|
|
190
|
-
| `teamix-evo
|
|
191
|
-
| `teamix-evo
|
|
192
|
-
| `teamix-evo
|
|
193
|
-
| `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 skills init` | 自举 skills(按 variant + scope 全装 — ADR 0034) |
|
|
183
|
+
| `teamix-evo skills add <name...>` | 增量装指定 skill(`<name...>` 必填) |
|
|
184
|
+
| `teamix-evo skills list` | 列出所有 skill 的安装状态 |
|
|
185
|
+
| `teamix-evo skills update [name...] [--dry-run]` | 升级 skills(双闸 + version 短路 — ADR 0035) |
|
|
186
|
+
| `teamix-evo skills sync [name...]` | 源 → IDE 镜像(漂移恢复用) |
|
|
187
|
+
| `teamix-evo skills doctor` | 检测源/镜像漂移(ADR 0013) |
|
|
188
|
+
| `teamix-evo skills uninstall` | 卸载 skills(源 + 镜像 + lock) |
|
|
189
|
+
| `teamix-evo ui init` | 初始化 ui 配置(aliases / iconLibrary / tsx / rsc) |
|
|
190
|
+
| `teamix-evo ui add <id...>` | 安装指定 ui 组件源码 |
|
|
191
|
+
| `teamix-evo ui list [--installed]` | 列出可用/已安装 ui 组件 |
|
|
192
|
+
| `teamix-evo ui promote-to-biz <id...>` | 把 ui 组件提升为业务组件(8 模式:Coexist/Preset/Wrapper/Compose/Variant/Fork/TokenOnly/ManualReview) |
|
|
193
|
+
| `teamix-evo biz-ui list-variants` | 列出 biz-ui 包内提供的业务变体 |
|
|
194
|
+
| `teamix-evo biz-ui add <id...> --variant <name>` | 安装变体感知业务组件(`--variant` 必填) |
|
|
195
|
+
| `teamix-evo templates list-variants` | 列出 templates 包内提供的页面模板变体 |
|
|
196
|
+
| `teamix-evo templates add <id...> --variant <name>` | 安装变体感知页面模板(`--variant` 必填) |
|
|
197
|
+
| `teamix-evo lint init [-y]` | 一键安装 ESLint + Stylelint token-discipline 规则集 |
|
|
198
|
+
| `teamix-evo logs analyze [...]` | 分析 vibe-logger AI 调用链(`.log/ai/**/*.jsonl`) |
|
|
199
|
+
| `teamix-evo logs trace [...]` | 按会话还原 AI 调用链(prompt → PreToolUse → PostToolUse → Stop) |
|
|
194
200
|
|
|
195
201
|
> 占位组件 → 真组件的升级流程**不是** CLI 子命令,由
|
|
196
202
|
> [`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,43 @@ 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;
|
|
407
477
|
} | {
|
|
408
478
|
status: 'already-initialized';
|
|
409
479
|
};
|
|
@@ -415,6 +485,443 @@ type RunLintInitResult = {
|
|
|
415
485
|
*/
|
|
416
486
|
declare function runLintInit(options: RunLintInitOptions): Promise<RunLintInitResult>;
|
|
417
487
|
|
|
488
|
+
/**
|
|
489
|
+
* Generate `<projectRoot>/AGENTS.md` as a skill-trigger fallback (ADR 0038).
|
|
490
|
+
*
|
|
491
|
+
* The file is **regenerable**: it consolidates TRIGGER / SKIP excerpts from
|
|
492
|
+
* each installed SKILL.md frontmatter description into one terse index, so
|
|
493
|
+
* AGENTS.md-aware IDEs (Codex / Cursor / Claude Code / Qoder) preheat the
|
|
494
|
+
* skill activation conditions even when the user prompt does not directly
|
|
495
|
+
* hit the description-based trigger.
|
|
496
|
+
*
|
|
497
|
+
* Out of scope (per ADR 0038):
|
|
498
|
+
* - Does NOT copy skill body / rules / patterns — those stay in the skill.
|
|
499
|
+
* - Does NOT include `teamix-evo-manage` (entry skill, global scope, ADR 0033).
|
|
500
|
+
*
|
|
501
|
+
* Lifted from `create-teamix-evo` (v0.5) into `teamix-evo/core` so both
|
|
502
|
+
* `npm create teamix-evo` (scaffold path) and `teamix-evo init` (existing-
|
|
503
|
+
* project path, ADR 0019 task #5) emit identical AGENTS.md output.
|
|
504
|
+
*
|
|
505
|
+
* @module teamix-evo/core/agents-md
|
|
506
|
+
*/
|
|
507
|
+
interface RunGenerateAgentsMdOptions {
|
|
508
|
+
/** Absolute path to the consumer project root. */
|
|
509
|
+
projectRoot: string;
|
|
510
|
+
/** Tokens / skills variant (e.g. "opentrek"). Used for header context. */
|
|
511
|
+
variant: string;
|
|
512
|
+
/**
|
|
513
|
+
* Skill ids whose `<projectRoot>/.teamix-evo/skills/<id>/SKILL.md` should be
|
|
514
|
+
* indexed. Caller is responsible for filtering out global-only skills
|
|
515
|
+
* (e.g. `teamix-evo-manage`).
|
|
516
|
+
*/
|
|
517
|
+
skillIds: string[];
|
|
518
|
+
/**
|
|
519
|
+
* Reconciliation mode (Phase 2.B):
|
|
520
|
+
* - `'overwrite'` (default): always rewrite the full file. Pre-existing
|
|
521
|
+
* content is backed up and discarded.
|
|
522
|
+
* - `'merge-managed'`: rewrite only the `teamix-evo-skills` managed
|
|
523
|
+
* region. When the consumer file lacks the region, prepend a fresh
|
|
524
|
+
* managed block ahead of the user's content (auto-adopt). The user's
|
|
525
|
+
* non-managed sections are preserved.
|
|
526
|
+
*
|
|
527
|
+
* In both modes, an existing file is backed up under
|
|
528
|
+
* `.teamix-evo/.backups/AGENTS.md.<isoTs>.bak` before any mutation.
|
|
529
|
+
*/
|
|
530
|
+
mode?: 'overwrite' | 'merge-managed';
|
|
531
|
+
}
|
|
532
|
+
interface RunGenerateAgentsMdResult {
|
|
533
|
+
/** Absolute path of the written `AGENTS.md`. */
|
|
534
|
+
path: string;
|
|
535
|
+
/** Number of skill sections rendered (missing SKILL.md degradations are still counted). */
|
|
536
|
+
skillCount: number;
|
|
537
|
+
/** Skill ids whose SKILL.md could not be read (rendered as degraded section). */
|
|
538
|
+
missingSkillIds: string[];
|
|
539
|
+
/**
|
|
540
|
+
* True when an existing AGENTS.md was backed up under
|
|
541
|
+
* `.teamix-evo/.backups/AGENTS.md.<isoTs>.bak` before being overwritten
|
|
542
|
+
* (Phase 1.A2 — full backup strategy).
|
|
543
|
+
*/
|
|
544
|
+
backedUp: boolean;
|
|
545
|
+
/**
|
|
546
|
+
* Outcome of the merge step (Phase 2.B):
|
|
547
|
+
* - `'created'`: no AGENTS.md existed; wrote a fresh full template.
|
|
548
|
+
* - `'overwritten'`: existed but mode='overwrite' — full rewrite.
|
|
549
|
+
* - `'managed-replaced'`: mode='merge-managed' and the consumer file
|
|
550
|
+
* already had the `teamix-evo-skills` managed region; only that region
|
|
551
|
+
* was rewritten. User content outside is preserved.
|
|
552
|
+
* - `'managed-prepended'`: mode='merge-managed' but the consumer file
|
|
553
|
+
* did not yet have the managed region; a fresh block was inserted at
|
|
554
|
+
* the top, with the existing user content kept below.
|
|
555
|
+
*/
|
|
556
|
+
merge: 'created' | 'overwritten' | 'managed-replaced' | 'managed-prepended';
|
|
557
|
+
}
|
|
558
|
+
interface SkillDescriptionParts {
|
|
559
|
+
/** First non-empty line(s) of `description` (the capability statement). */
|
|
560
|
+
capability: string;
|
|
561
|
+
trigger: string | null;
|
|
562
|
+
skip: string | null;
|
|
563
|
+
coordinates: string | null;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Generate and write the `AGENTS.md` file.
|
|
567
|
+
*
|
|
568
|
+
* Phase 2.B — reconciliation modes:
|
|
569
|
+
* - `'overwrite'` (default): regenerable behaviour, full rewrite.
|
|
570
|
+
* - `'merge-managed'`: rewrite only the `teamix-evo-skills` managed region
|
|
571
|
+
* so user-authored sections (project-specific guidance, design tokens,
|
|
572
|
+
* prompts) are never clobbered.
|
|
573
|
+
*
|
|
574
|
+
* Existing files are always backed up under `.teamix-evo/.backups/` before
|
|
575
|
+
* mutation (ADR 0019 §2, Phase 1.A2).
|
|
576
|
+
*/
|
|
577
|
+
declare function runGenerateAgentsMd(options: RunGenerateAgentsMdOptions): Promise<RunGenerateAgentsMdResult>;
|
|
578
|
+
/**
|
|
579
|
+
* Parse a SKILL.md frontmatter description into capability / TRIGGER / SKIP /
|
|
580
|
+
* Coordinates parts.
|
|
581
|
+
*
|
|
582
|
+
* Why hand-rolled (no gray-matter): we only need the `description: |` block.
|
|
583
|
+
* The full YAML grammar is overkill and adds a runtime dep to a CLI / scaffold
|
|
584
|
+
* tool that should stay zero-cost. ADR 0015 keeps frontmatter shape stable.
|
|
585
|
+
*/
|
|
586
|
+
declare function extractDescriptionParts(fileContent: string): SkillDescriptionParts | null;
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* Three branches of `teamix-evo init` decision tree (ADR 0019 D1).
|
|
590
|
+
*
|
|
591
|
+
* - `empty` : 空目录或仅含可忽略文件 → 推荐用户走 `npm create teamix-evo`(完整版)
|
|
592
|
+
* - `teamix-evo-installed`: 已存在 `.teamix-evo/` → 推荐 `teamix-evo update` / 卸载流程
|
|
593
|
+
* - `non-teamix-evo` : 已有非 teamix-evo 工程 → 走 `teamix-evo init` 普通版接入
|
|
594
|
+
*/
|
|
595
|
+
type ProjectState = 'empty' | 'teamix-evo-installed' | 'non-teamix-evo';
|
|
596
|
+
interface ProjectStateReport {
|
|
597
|
+
/** Decision-tree branch the caller should take. */
|
|
598
|
+
state: ProjectState;
|
|
599
|
+
/** Absolute path that was inspected. */
|
|
600
|
+
cwd: string;
|
|
601
|
+
/** Whether `.teamix-evo/` exists at `cwd`. */
|
|
602
|
+
hasTeamixDir: boolean;
|
|
603
|
+
/** Whether `package.json` exists at `cwd`. */
|
|
604
|
+
hasPackageJson: boolean;
|
|
605
|
+
/**
|
|
606
|
+
* Up to 20 entries (relative to `cwd`) that caused us to consider the
|
|
607
|
+
* directory non-empty. Useful for explaining the decision to humans.
|
|
608
|
+
*/
|
|
609
|
+
significantEntries: string[];
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Inspect `cwd` and decide which branch of the `teamix-evo init` decision
|
|
613
|
+
* tree applies. Pure read-only — never mutates the filesystem.
|
|
614
|
+
*
|
|
615
|
+
* Resolution order (first match wins):
|
|
616
|
+
* 1. `.teamix-evo/` exists → `teamix-evo-installed`
|
|
617
|
+
* 2. cwd missing OR all entries are in the IGNORED_TOP_LEVEL set
|
|
618
|
+
* → `empty`
|
|
619
|
+
* 3. otherwise → `non-teamix-evo`
|
|
620
|
+
*/
|
|
621
|
+
declare function detectProjectState(cwd: string): Promise<ProjectStateReport>;
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* The 8 categories of consumer-side files that `teamix-evo init` may
|
|
625
|
+
* conflict with when running against a non-teamix-evo project.
|
|
626
|
+
*
|
|
627
|
+
* See ADR 0019 D1 task #5 — these are the only files we mutate at
|
|
628
|
+
* `init` time, so they're the only ones we ask the user about.
|
|
629
|
+
*/
|
|
630
|
+
type ConflictKey = 'agents-md' | 'components-json' | 'tailwind-config' | 'tokens' | 'index-css' | 'shadcn-source' | 'eslint-config' | 'stylelint-config';
|
|
631
|
+
/** Strategy options per conflict category. */
|
|
632
|
+
type ConflictStrategy = 'overwrite' | 'merge-managed' | 'skip' | 'diff-prompt' | 'backup-overwrite' | 'migrate' | 'coexist' | 'append' | 'skip-existing' | 'per-file-prompt' | 'merge';
|
|
633
|
+
interface ConflictItem {
|
|
634
|
+
/** Stable id for the category. */
|
|
635
|
+
key: ConflictKey;
|
|
636
|
+
/** True if at least one path in `paths` matched on disk. */
|
|
637
|
+
exists: boolean;
|
|
638
|
+
/**
|
|
639
|
+
* Project-relative paths that matched. Empty when `exists === false`.
|
|
640
|
+
* For `shadcn-source`, may contain a directory path (with trailing `/`).
|
|
641
|
+
*/
|
|
642
|
+
paths: string[];
|
|
643
|
+
/** sha256 fingerprint of (sorted) matched contents. Omitted for directories or when nothing matched. */
|
|
644
|
+
fingerprint?: string;
|
|
645
|
+
/** Default strategy presented to the user. */
|
|
646
|
+
recommendedStrategy: ConflictStrategy;
|
|
647
|
+
/** All allowed strategies for this category, in display order. */
|
|
648
|
+
availableStrategies: ConflictStrategy[];
|
|
649
|
+
/** Category-specific metadata (e.g. detected tailwind major version). */
|
|
650
|
+
meta?: Record<string, unknown>;
|
|
651
|
+
}
|
|
652
|
+
interface ConflictReport {
|
|
653
|
+
cwd: string;
|
|
654
|
+
/** Always 8 items, ordered by ConflictKey enumeration above. */
|
|
655
|
+
items: ConflictItem[];
|
|
656
|
+
/** True if any item has `exists === true`. */
|
|
657
|
+
hasAnyConflict: boolean;
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Inspect `cwd` for the 8 categories of files that `teamix-evo init` may
|
|
661
|
+
* touch. Pure read-only — never mutates the filesystem. Returns one
|
|
662
|
+
* `ConflictItem` per category in stable order so callers can render a
|
|
663
|
+
* deterministic wizard.
|
|
664
|
+
*/
|
|
665
|
+
declare function detectConflicts(cwd: string): Promise<ConflictReport>;
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Final answers produced by the init wizard. Every consumer of `teamix-evo
|
|
669
|
+
* init` (orchestrator + later sub-commands) reads from this object exclusively
|
|
670
|
+
* — flags / prompts must not be re-evaluated downstream (silent sub-commands).
|
|
671
|
+
*/
|
|
672
|
+
interface InitWizardAnswers {
|
|
673
|
+
variant: string;
|
|
674
|
+
ides: SkillIde[];
|
|
675
|
+
scope: SkillScope;
|
|
676
|
+
withLint: boolean;
|
|
677
|
+
withUi: boolean;
|
|
678
|
+
/** 'baseline' = preset 推荐组件子集;'all' = 全量装 */
|
|
679
|
+
uiSelection: 'baseline' | 'all';
|
|
680
|
+
withBizUi: boolean;
|
|
681
|
+
/**
|
|
682
|
+
* 每类冲突文件的最终策略。键是 6 类 ConflictKey,值是 user-chosen
|
|
683
|
+
* `ConflictStrategy`。当对应 ConflictItem.exists === false 时,值默认为
|
|
684
|
+
* `'overwrite'`(即首次写入)。
|
|
685
|
+
*/
|
|
686
|
+
conflictDecisions: Record<ConflictKey, ConflictStrategy>;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/** Result of `createSnapshot` when a snapshot was actually taken. */
|
|
690
|
+
interface SnapshotResult {
|
|
691
|
+
/** Filesystem-safe UTC timestamp identifier (e.g. `2026-06-11T20-59-03-000Z`). */
|
|
692
|
+
ts: string;
|
|
693
|
+
/** Absolute path to the snapshot directory. */
|
|
694
|
+
path: string;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
type FileChangeKind = 'created' | 'modified' | 'backed-up' | 'deleted';
|
|
698
|
+
interface FileChange {
|
|
699
|
+
kind: FileChangeKind;
|
|
700
|
+
/** Project-root-relative path, posix style (forward slashes). */
|
|
701
|
+
path: string;
|
|
702
|
+
/** Originating pipeline step (free-form to avoid coupling on `ProjectInitStepName`). */
|
|
703
|
+
step: string;
|
|
704
|
+
/** Optional human-readable note (e.g. `frozen` / `regenerable` / `managed`). */
|
|
705
|
+
detail?: string;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* Programmatic orchestrator for `teamix-evo init` (existing-project adoption).
|
|
710
|
+
*
|
|
711
|
+
* Consumes {@link InitWizardAnswers} produced by `runInitWizard` and drives
|
|
712
|
+
* the existing core sub-commands (`runTokensInit`, `runSkillsAdd`,
|
|
713
|
+
* `runGenerateAgentsMd`, `runUiInit`, `runUiAdd`, `runLintInit`) in a fixed
|
|
714
|
+
* order. Sub-commands are invoked silently — no interactive prompts here.
|
|
715
|
+
*
|
|
716
|
+
* Conflict handling:
|
|
717
|
+
* - `conflictDecisions[key] === 'skip'` skips the corresponding step entirely.
|
|
718
|
+
* - `'overwrite'` is the trivial path (the underlying core APIs already write).
|
|
719
|
+
* - `'merge-managed'` (agents-md) is implemented today via
|
|
720
|
+
* `runGenerateAgentsMd` which writes managed regions natively.
|
|
721
|
+
* - `'skip-existing'` (shadcn-source) maps to `runUiAdd({ overwrite: false })`,
|
|
722
|
+
* the existing default.
|
|
723
|
+
* - All other strategies (`diff-prompt`, `backup-overwrite`, `migrate`,
|
|
724
|
+
* `coexist`, `append`, `per-file-prompt`) require the managed-region engine
|
|
725
|
+
* from batch 4 — they are recorded to `pendingConflictWork` so the CLI
|
|
726
|
+
* surface can guide the user to the followup `teamix-evo conflict resolve`
|
|
727
|
+
* step (post-batch-4).
|
|
728
|
+
*
|
|
729
|
+
* No interactive prompts, no `process.exit`. Throws on hard failure (P8).
|
|
730
|
+
*/
|
|
731
|
+
|
|
732
|
+
type ProjectInitStepName = 'tokens' | 'skills' | 'agents-md' | 'ui-init' | 'ui-add' | 'lint';
|
|
733
|
+
type ProjectInitStepStatus = 'ok' | 'skip' | 'fail' | 'planned';
|
|
734
|
+
interface ProjectInitStep {
|
|
735
|
+
name: ProjectInitStepName;
|
|
736
|
+
status: ProjectInitStepStatus;
|
|
737
|
+
detail?: string;
|
|
738
|
+
/**
|
|
739
|
+
* Files this step touched (Phase 1.A1). Empty when the step skipped or
|
|
740
|
+
* failed before any I/O. The `kind` is `created` by default; the orchestrator
|
|
741
|
+
* upgrades entries to `modified` post-hoc by checking the backup ledger
|
|
742
|
+
* (`.teamix-evo/.backups/`).
|
|
743
|
+
*/
|
|
744
|
+
changes?: FileChange[];
|
|
745
|
+
}
|
|
746
|
+
interface PendingConflictWork {
|
|
747
|
+
key: ConflictKey;
|
|
748
|
+
strategy: ConflictStrategy;
|
|
749
|
+
reason: string;
|
|
750
|
+
}
|
|
751
|
+
interface ResumeHint {
|
|
752
|
+
/** The first step that failed (caller resumes from here). */
|
|
753
|
+
failedAt: ProjectInitStepName;
|
|
754
|
+
/** Steps already finished (status === 'ok'); will short-circuit on resume. */
|
|
755
|
+
completed: ProjectInitStepName[];
|
|
756
|
+
/** All steps that ended in fail status. */
|
|
757
|
+
failed: ProjectInitStepName[];
|
|
758
|
+
/** Human-readable error from the first failed step. */
|
|
759
|
+
error: string;
|
|
760
|
+
/**
|
|
761
|
+
* Suggested CLI command to resume. Today this is just `teamix-evo init`
|
|
762
|
+
* itself — every sub-step is idempotent (returns `already-initialized`
|
|
763
|
+
* when the matching state file already exists), so a re-run continues
|
|
764
|
+
* from the failure point automatically. Future batches may grow a
|
|
765
|
+
* dedicated `--resume` flag with a richer recovery model (batch 3).
|
|
766
|
+
*/
|
|
767
|
+
resumeCommand: string;
|
|
768
|
+
}
|
|
769
|
+
interface RunProjectInitOptions {
|
|
770
|
+
/** Absolute project root (existing repo to adopt teamix-evo into). */
|
|
771
|
+
projectRoot: string;
|
|
772
|
+
/** Wizard outcome (single source of truth for every silent sub-command). */
|
|
773
|
+
answers: InitWizardAnswers;
|
|
774
|
+
/**
|
|
775
|
+
* Override the resolved UI entry list. When provided, replaces the
|
|
776
|
+
* `answers.uiSelection`-driven list (`'baseline'` / `'all'`). Useful for
|
|
777
|
+
* tests and for callers that want to install a custom subset.
|
|
778
|
+
*/
|
|
779
|
+
uiEntries?: string[];
|
|
780
|
+
/**
|
|
781
|
+
* If true, skip `npm install` for lint deps. Defaults to `false` so lint
|
|
782
|
+
* works out of the box; pass `true` from the create scaffold which installs
|
|
783
|
+
* everything in one batch.
|
|
784
|
+
*/
|
|
785
|
+
skipInstall?: boolean;
|
|
786
|
+
/**
|
|
787
|
+
* Legacy token CSS files (paths relative to `projectRoot`) detected by
|
|
788
|
+
* `detectConflicts` for the `tokens` key. When `conflictDecisions.tokens`
|
|
789
|
+
* is `'migrate'` and this list is non-empty, the orchestrator appends
|
|
790
|
+
* each file's content into `tokens/tokens.overrides.css` and backs the
|
|
791
|
+
* legacy files up to `.teamix-evo/.backups/` (W1.4 of the manage-entry
|
|
792
|
+
* plan; see [`legacy-tokens-migrate`](./legacy-tokens-migrate.ts)).
|
|
793
|
+
*
|
|
794
|
+
* Ignored for any other `tokens` decision. The caller (init command) is
|
|
795
|
+
* responsible for filtering out paths already inside `tokens/`.
|
|
796
|
+
*/
|
|
797
|
+
legacyTokensPaths?: string[];
|
|
798
|
+
/**
|
|
799
|
+
* Phase 3.E: existing ESLint config paths (relative to `projectRoot`)
|
|
800
|
+
* detected by `detectConflicts` for the `eslint-config` key. Used to
|
|
801
|
+
* back up the consumer's file before writing the teamix-evo template,
|
|
802
|
+
* and to gate the `merge` / `backup-overwrite` / `skip` strategies in
|
|
803
|
+
* `runLintInit`.
|
|
804
|
+
*/
|
|
805
|
+
legacyEslintPaths?: string[];
|
|
806
|
+
/**
|
|
807
|
+
* Phase 3.E: existing Stylelint config paths (relative to `projectRoot`).
|
|
808
|
+
*/
|
|
809
|
+
legacyStylelintPaths?: string[];
|
|
810
|
+
/** Step-level progress hook (caller controls presentation). */
|
|
811
|
+
onStep?: (step: ProjectInitStep) => void;
|
|
812
|
+
/**
|
|
813
|
+
* If true, plan-only mode: compute the full step list without running any
|
|
814
|
+
* sub-command. Returns each step with `status: 'planned'`.
|
|
815
|
+
*/
|
|
816
|
+
dryRun?: boolean;
|
|
817
|
+
}
|
|
818
|
+
interface RunProjectInitResult {
|
|
819
|
+
status: 'installed' | 'partial' | 'dry-run';
|
|
820
|
+
steps: ProjectInitStep[];
|
|
821
|
+
/** Conflicts whose strategy needs the post-batch-4 managed-region engine. */
|
|
822
|
+
pendingConflictWork: PendingConflictWork[];
|
|
823
|
+
/**
|
|
824
|
+
* Aggregated, classified file-change ledger covering every step
|
|
825
|
+
* (Phase 1.A1). Backup entries are surfaced as `kind: 'backed-up'` so the
|
|
826
|
+
* CLI can render a four-bucket summary (新建 / 修改 / 备份 / 删除).
|
|
827
|
+
*/
|
|
828
|
+
changes: FileChange[];
|
|
829
|
+
/**
|
|
830
|
+
* Present when at least one step ended in `fail`. Lets the CLI surface a
|
|
831
|
+
* structured recovery message instead of just a stack-trace, and gives
|
|
832
|
+
* programmatic consumers a deterministic field to branch on.
|
|
833
|
+
*/
|
|
834
|
+
resumeHint?: ResumeHint;
|
|
835
|
+
/**
|
|
836
|
+
* Pre-init snapshot of `.teamix-evo/`, captured automatically before any
|
|
837
|
+
* file is written ([ADR 0019](../../../../docs/adr/0019-project-upgrade-flow.md) §2).
|
|
838
|
+
*
|
|
839
|
+
* - `null` on first-ever init (`.teamix-evo/` did not yet exist) and on
|
|
840
|
+
* `dryRun`.
|
|
841
|
+
* - Failure to capture a snapshot is **non-fatal** — surfaced via
|
|
842
|
+
* {@link snapshotError} so the CLI can warn the user. The init pipeline
|
|
843
|
+
* itself still runs.
|
|
844
|
+
*/
|
|
845
|
+
snapshot?: SnapshotResult | null;
|
|
846
|
+
/** Reason a snapshot capture failed (best-effort — never blocks init). */
|
|
847
|
+
snapshotError?: string;
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Existing-project init pipeline.
|
|
851
|
+
*
|
|
852
|
+
* Order:
|
|
853
|
+
* 1. tokens init (auto-installs `teamix-evo-design-${variant}` skill)
|
|
854
|
+
* 2. skills add (`teamix-evo-code-${variant}`; entry skill is global, ADR 0033)
|
|
855
|
+
* 3. AGENTS.md (skill trigger fallback, ADR 0038)
|
|
856
|
+
* 4. ui init + ui add (gated by `withUi`)
|
|
857
|
+
* 5. lint init (gated by `withLint`)
|
|
858
|
+
*/
|
|
859
|
+
declare function runProjectInit(options: RunProjectInitOptions): Promise<RunProjectInitResult>;
|
|
860
|
+
|
|
861
|
+
type ProjectUpdateStepName = 'tokens' | 'skills' | 'ui' | 'biz-ui';
|
|
862
|
+
type ProjectUpdateStepStatus = 'ok' | 'skip' | 'fail' | 'planned';
|
|
863
|
+
interface ProjectUpdateStep {
|
|
864
|
+
name: ProjectUpdateStepName;
|
|
865
|
+
status: ProjectUpdateStepStatus;
|
|
866
|
+
detail?: string;
|
|
867
|
+
}
|
|
868
|
+
interface ProjectUpdateResumeHint {
|
|
869
|
+
/** The first step that failed (caller resumes from here). */
|
|
870
|
+
failedAt: ProjectUpdateStepName;
|
|
871
|
+
/** Steps already finished (status === 'ok'); will short-circuit on resume. */
|
|
872
|
+
completed: ProjectUpdateStepName[];
|
|
873
|
+
/** All steps that ended in fail status. */
|
|
874
|
+
failed: ProjectUpdateStepName[];
|
|
875
|
+
/** Human-readable error from the first failed step. */
|
|
876
|
+
error: string;
|
|
877
|
+
/**
|
|
878
|
+
* Suggested CLI command to resume. Today this is just `teamix-evo update`
|
|
879
|
+
* itself — every sub-step is idempotent (version-diff short-circuits when
|
|
880
|
+
* up-to-date), so a re-run continues from the failure point automatically.
|
|
881
|
+
*/
|
|
882
|
+
resumeCommand: string;
|
|
883
|
+
}
|
|
884
|
+
interface RunProjectUpdateOptions {
|
|
885
|
+
/** Absolute project root (must already be teamix-evo-installed). */
|
|
886
|
+
projectRoot: string;
|
|
887
|
+
/**
|
|
888
|
+
* If true, plan-only mode: compute version deltas without writing any
|
|
889
|
+
* file. Returns each step with `status: 'planned'`.
|
|
890
|
+
*/
|
|
891
|
+
dryRun?: boolean;
|
|
892
|
+
/** Step-level progress hook (caller controls presentation). */
|
|
893
|
+
onStep?: (step: ProjectUpdateStep) => void;
|
|
894
|
+
/** Override the tokens package name (defaults to `@teamix-evo/tokens`). */
|
|
895
|
+
tokensPackageName?: string;
|
|
896
|
+
/** Override the skills package name (defaults to `@teamix-evo/skills`). */
|
|
897
|
+
skillsPackageName?: string;
|
|
898
|
+
}
|
|
899
|
+
type RunProjectUpdateResult = {
|
|
900
|
+
status: 'not-initialized';
|
|
901
|
+
} | {
|
|
902
|
+
status: 'up-to-date' | 'updated' | 'partial' | 'dry-run';
|
|
903
|
+
steps: ProjectUpdateStep[];
|
|
904
|
+
resumeHint?: ProjectUpdateResumeHint;
|
|
905
|
+
/**
|
|
906
|
+
* Pre-update snapshot of `.teamix-evo/` ([ADR 0019](../../../../docs/adr/0019-project-upgrade-flow.md) §2).
|
|
907
|
+
* `null` on `dryRun`. Best-effort — capture failures surface via
|
|
908
|
+
* {@link snapshotError} but never abort the pipeline.
|
|
909
|
+
*/
|
|
910
|
+
snapshot?: SnapshotResult | null;
|
|
911
|
+
/** Reason a snapshot capture failed (best-effort — never blocks update). */
|
|
912
|
+
snapshotError?: string;
|
|
913
|
+
};
|
|
914
|
+
/**
|
|
915
|
+
* Post-init refresh pipeline.
|
|
916
|
+
*
|
|
917
|
+
* Order:
|
|
918
|
+
* 1. tokens update (regenerable rewrite + frozen preserved — ADR 0003 三态)
|
|
919
|
+
* 2. skills update (lock ∩ scope ∩ version-diff short-circuit — ADR 0035)
|
|
920
|
+
*
|
|
921
|
+
* Re-runs are safe: each sub-step short-circuits when already at latest.
|
|
922
|
+
*/
|
|
923
|
+
declare function runProjectUpdate(options: RunProjectUpdateOptions): Promise<RunProjectUpdateResult>;
|
|
924
|
+
|
|
418
925
|
interface InstallOptions {
|
|
419
926
|
/** Project root directory */
|
|
420
927
|
projectRoot: string;
|
|
@@ -443,7 +950,7 @@ declare function installResources(options: InstallOptions): Promise<InstallResul
|
|
|
443
950
|
*
|
|
444
951
|
* Two-stage flow:
|
|
445
952
|
* 1. **writeSkillSources** — render upstream `<packageRoot>/<skill.source>` and
|
|
446
|
-
* write to `<projectRoot>/.teamix-evo/skills/<id>/` (the consumer-side
|
|
953
|
+
* write to `<projectRoot>/.teamix-evo/skills-source/<id>/` (the consumer-side
|
|
447
954
|
* source of truth, regenerable, in git).
|
|
448
955
|
* 2. **syncSkillsToIdes** — pure byte-for-byte copy from source dir to each
|
|
449
956
|
* requested IDE mirror path (`.qoder/skills/<id>/`, `.claude/skills/<id>/`).
|
|
@@ -662,4 +1169,4 @@ declare function readInstalledManifest(projectRoot: string): Promise<InstalledMa
|
|
|
662
1169
|
*/
|
|
663
1170
|
declare function writeInstalledManifest(projectRoot: string, manifest: InstalledManifest): Promise<void>;
|
|
664
1171
|
|
|
665
|
-
export { DEFAULT_UI_ALIASES, DEFAULT_UI_ICON_LIBRARY, type InstallOptions, type InstallResult, type ListVariantUiEntriesResult, type ListVariantUiResult, type ListVariantsResult, type RunLintInitOptions, type RunLintInitResult, type RunSkillsAddOptions, type RunSkillsAddResult, type RunSkillsInitOptions, type RunSkillsInitResult, type RunSkillsUpdateOptions, type RunSkillsUpdateResult, type RunTokensInitOptions, type RunTokensInitResult, type RunUiAddOptions, type RunUiAddResult, type RunUiInitOptions, type RunUiInitResult, type RunUiListOptions, type RunUiListResult, type RunVariantUiAddOptions, type RunVariantUiAddResult, type SkillInstallOptions, type SkillInstallResult, type SkillSyncOptions, type SkillSyncResult, type SkillUpdateOptions, type SkillUpdateResult, type UiEntryListItem, type UiInstallOptions, type UiInstallResult, type UpdatePlanItem, ensureTeamixDir, getTeamixDir, installResources, installSkills, installUiEntries, listBizUiEntries, listBizUiVariants, listTemplatesEntries, listTemplatesVariants, listTokenVariants, loadSkillsData, loadUiData, loadVariantData, readInstalledManifest, readProjectConfig, removeSkillFiles, removeUiFiles, runBizUiAdd, runLintInit, runSkillsAdd, runSkillsInit, runSkillsUpdate, runTemplatesAdd, runTokensInit, runUiAdd, runUiInit, runUiList, syncSkillsToIdes, updateSkills, writeInstalledManifest, writeProjectConfig };
|
|
1172
|
+
export { type ConflictItem, type ConflictKey, type ConflictReport, type ConflictStrategy, DEFAULT_UI_ALIASES, DEFAULT_UI_ICON_LIBRARY, type InstallOptions, type InstallResult, type ListVariantUiEntriesResult, type ListVariantUiResult, type ListVariantsResult, type PendingConflictWork, type ProjectInitStep, type ProjectInitStepName, type ProjectInitStepStatus, type ProjectState, type ProjectStateReport, type ProjectUpdateResumeHint, type ProjectUpdateStep, type ProjectUpdateStepName, type ProjectUpdateStepStatus, type ResumeHint, type RunGenerateAgentsMdOptions, type RunGenerateAgentsMdResult, type RunLintInitOptions, type RunLintInitResult, type RunProjectInitOptions, type RunProjectInitResult, type RunProjectUpdateOptions, type RunProjectUpdateResult, type RunSkillsAddOptions, type RunSkillsAddResult, type RunSkillsInitOptions, type RunSkillsInitResult, type RunSkillsUpdateOptions, type RunSkillsUpdateResult, type RunTokensInitOptions, type RunTokensInitResult, type RunUiAddOptions, type RunUiAddResult, type RunUiInitOptions, type RunUiInitResult, type RunUiListOptions, type RunUiListResult, type RunVariantUiAddOptions, type RunVariantUiAddResult, type SkillInstallOptions, type SkillInstallResult, type SkillSyncOptions, type SkillSyncResult, type SkillUpdateOptions, type SkillUpdateResult, type UiEntryListItem, type UiInstallOptions, type UiInstallResult, type UpdatePlanItem, detectConflicts, detectProjectState, ensureTeamixDir, extractDescriptionParts, getTeamixDir, installResources, installSkills, installUiEntries, listBizUiEntries, listBizUiVariants, listTemplatesEntries, listTemplatesVariants, listTokenVariants, loadSkillsData, loadUiData, loadVariantData, readInstalledManifest, readProjectConfig, removeSkillFiles, removeUiFiles, runBizUiAdd, runGenerateAgentsMd, runLintInit, runProjectInit, runProjectUpdate, runSkillsAdd, runSkillsInit, runSkillsUpdate, runTemplatesAdd, runTokensInit, runUiAdd, runUiInit, runUiList, syncSkillsToIdes, updateSkills, writeInstalledManifest, writeProjectConfig };
|