teamix-evo 0.8.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 CHANGED
@@ -178,6 +178,7 @@ TEAMIX_DEBUG=1 teamix-evo tokens init opentrek
178
178
  | `teamix-evo tokens list` | 查看已装机的 variant |
179
179
  | `teamix-evo tokens update` | 更新已装资源(stub,v0.7 见 ADR 0019) |
180
180
  | `teamix-evo tokens uninstall` | 卸载已装 tokens |
181
+ | `teamix-evo tokens audit` | 审计 tokens 引用(4 类:redundant / kept / migrate / custom,v3↔v4 语义比较) |
181
182
  | `teamix-evo skills init` | 自举 skills(按 variant + scope 全装 — ADR 0034) |
182
183
  | `teamix-evo skills add <name...>` | 增量装指定 skill(`<name...>` 必填) |
183
184
  | `teamix-evo skills list` | 列出所有 skill 的安装状态 |
@@ -188,6 +189,7 @@ TEAMIX_DEBUG=1 teamix-evo tokens init opentrek
188
189
  | `teamix-evo ui init` | 初始化 ui 配置(aliases / iconLibrary / tsx / rsc) |
189
190
  | `teamix-evo ui add <id...>` | 安装指定 ui 组件源码 |
190
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) |
191
193
  | `teamix-evo biz-ui list-variants` | 列出 biz-ui 包内提供的业务变体 |
192
194
  | `teamix-evo biz-ui add <id...> --variant <name>` | 安装变体感知业务组件(`--variant` 必填) |
193
195
  | `teamix-evo templates list-variants` | 列出 templates 包内提供的页面模板变体 |
@@ -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
- /** Skill ids that were requested but already installed; skipped. */
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
  };
@@ -445,14 +515,45 @@ interface RunGenerateAgentsMdOptions {
445
515
  * (e.g. `teamix-evo-manage`).
446
516
  */
447
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';
448
531
  }
449
532
  interface RunGenerateAgentsMdResult {
450
533
  /** Absolute path of the written `AGENTS.md`. */
451
534
  path: string;
452
- /** Number of skill sections rendered (excludes missing SKILL.md degradations are still counted). */
535
+ /** Number of skill sections rendered (missing SKILL.md degradations are still counted). */
453
536
  skillCount: number;
454
537
  /** Skill ids whose SKILL.md could not be read (rendered as degraded section). */
455
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';
456
557
  }
457
558
  interface SkillDescriptionParts {
458
559
  /** First non-empty line(s) of `description` (the capability statement). */
@@ -462,8 +563,16 @@ interface SkillDescriptionParts {
462
563
  coordinates: string | null;
463
564
  }
464
565
  /**
465
- * Generate and write the `AGENTS.md` file. Idempotent — repeated invocations
466
- * fully overwrite the file (regenerable per ADR 0038 §4).
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).
467
576
  */
468
577
  declare function runGenerateAgentsMd(options: RunGenerateAgentsMdOptions): Promise<RunGenerateAgentsMdResult>;
469
578
  /**
@@ -512,15 +621,15 @@ interface ProjectStateReport {
512
621
  declare function detectProjectState(cwd: string): Promise<ProjectStateReport>;
513
622
 
514
623
  /**
515
- * The 6 categories of consumer-side files that `teamix-evo init` may
624
+ * The 8 categories of consumer-side files that `teamix-evo init` may
516
625
  * conflict with when running against a non-teamix-evo project.
517
626
  *
518
627
  * See ADR 0019 D1 task #5 — these are the only files we mutate at
519
628
  * `init` time, so they're the only ones we ask the user about.
520
629
  */
521
- type ConflictKey = 'agents-md' | 'components-json' | 'tailwind-config' | 'tokens' | 'index-css' | 'shadcn-source';
630
+ type ConflictKey = 'agents-md' | 'components-json' | 'tailwind-config' | 'tokens' | 'index-css' | 'shadcn-source' | 'eslint-config' | 'stylelint-config';
522
631
  /** Strategy options per conflict category. */
523
- type ConflictStrategy = 'overwrite' | 'merge-managed' | 'skip' | 'diff-prompt' | 'backup-overwrite' | 'migrate' | 'coexist' | 'append' | 'skip-existing' | 'per-file-prompt';
632
+ type ConflictStrategy = 'overwrite' | 'merge-managed' | 'skip' | 'diff-prompt' | 'backup-overwrite' | 'migrate' | 'coexist' | 'append' | 'skip-existing' | 'per-file-prompt' | 'merge';
524
633
  interface ConflictItem {
525
634
  /** Stable id for the category. */
526
635
  key: ConflictKey;
@@ -542,13 +651,13 @@ interface ConflictItem {
542
651
  }
543
652
  interface ConflictReport {
544
653
  cwd: string;
545
- /** Always 6 items, ordered by ConflictKey enumeration above. */
654
+ /** Always 8 items, ordered by ConflictKey enumeration above. */
546
655
  items: ConflictItem[];
547
656
  /** True if any item has `exists === true`. */
548
657
  hasAnyConflict: boolean;
549
658
  }
550
659
  /**
551
- * Inspect `cwd` for the 6 categories of files that `teamix-evo init` may
660
+ * Inspect `cwd` for the 8 categories of files that `teamix-evo init` may
552
661
  * touch. Pure read-only — never mutates the filesystem. Returns one
553
662
  * `ConflictItem` per category in stable order so callers can render a
554
663
  * deterministic wizard.
@@ -585,6 +694,17 @@ interface SnapshotResult {
585
694
  path: string;
586
695
  }
587
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
+
588
708
  /**
589
709
  * Programmatic orchestrator for `teamix-evo init` (existing-project adoption).
590
710
  *
@@ -615,6 +735,13 @@ interface ProjectInitStep {
615
735
  name: ProjectInitStepName;
616
736
  status: ProjectInitStepStatus;
617
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[];
618
745
  }
619
746
  interface PendingConflictWork {
620
747
  key: ConflictKey;
@@ -668,6 +795,18 @@ interface RunProjectInitOptions {
668
795
  * responsible for filtering out paths already inside `tokens/`.
669
796
  */
670
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[];
671
810
  /** Step-level progress hook (caller controls presentation). */
672
811
  onStep?: (step: ProjectInitStep) => void;
673
812
  /**
@@ -681,6 +820,12 @@ interface RunProjectInitResult {
681
820
  steps: ProjectInitStep[];
682
821
  /** Conflicts whose strategy needs the post-batch-4 managed-region engine. */
683
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[];
684
829
  /**
685
830
  * Present when at least one step ended in `fail`. Lets the CLI surface a
686
831
  * structured recovery message instead of just a stack-trace, and gives
@@ -805,7 +950,7 @@ declare function installResources(options: InstallOptions): Promise<InstallResul
805
950
  *
806
951
  * Two-stage flow:
807
952
  * 1. **writeSkillSources** — render upstream `<packageRoot>/<skill.source>` and
808
- * write to `<projectRoot>/.teamix-evo/skills/<id>/` (the consumer-side
953
+ * write to `<projectRoot>/.teamix-evo/skills-source/<id>/` (the consumer-side
809
954
  * source of truth, regenerable, in git).
810
955
  * 2. **syncSkillsToIdes** — pure byte-for-byte copy from source dir to each
811
956
  * requested IDE mirror path (`.qoder/skills/<id>/`, `.claude/skills/<id>/`).