teamix-evo 0.19.2 → 0.20.2

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/dist/index.js CHANGED
@@ -40,12 +40,12 @@ var init_logger = __esm({
40
40
 
41
41
  // src/utils/fs.ts
42
42
  import * as fs from "fs/promises";
43
- import * as path3 from "path";
43
+ import * as path4 from "path";
44
44
  async function ensureDir(dir) {
45
45
  await fs.mkdir(dir, { recursive: true });
46
46
  }
47
47
  async function writeFileSafe(filePath, content) {
48
- const dir = path3.dirname(filePath);
48
+ const dir = path4.dirname(filePath);
49
49
  await ensureDir(dir);
50
50
  const tmp = filePath + ".tmp";
51
51
  await fs.writeFile(tmp, content, "utf-8");
@@ -67,17 +67,17 @@ async function backupFile(filePath, projectRoot) {
67
67
  logger.debug(`Skip backup: ${filePath} does not exist`);
68
68
  return;
69
69
  }
70
- const rel2 = path3.relative(projectRoot, filePath);
70
+ const rel2 = path4.relative(projectRoot, filePath);
71
71
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
72
- const backupPath = path3.join(
72
+ const backupPath = path4.join(
73
73
  projectRoot,
74
74
  ".teamix-evo",
75
75
  ".backups",
76
76
  `${rel2}.${timestamp}.bak`
77
77
  );
78
- await ensureDir(path3.dirname(backupPath));
78
+ await ensureDir(path4.dirname(backupPath));
79
79
  await fs.writeFile(backupPath, content, "utf-8");
80
- logger.debug(`Backed up ${rel2} \u2192 ${path3.relative(projectRoot, backupPath)}`);
80
+ logger.debug(`Backed up ${rel2} \u2192 ${path4.relative(projectRoot, backupPath)}`);
81
81
  }
82
82
  async function fileExists(filePath) {
83
83
  try {
@@ -126,7 +126,7 @@ __export(state_exports, {
126
126
  writeProjectConfig: () => writeProjectConfig,
127
127
  writeSkillsLock: () => writeSkillsLock
128
128
  });
129
- import * as path4 from "path";
129
+ import * as path5 from "path";
130
130
  import {
131
131
  validateConfig,
132
132
  validateInstalled,
@@ -135,7 +135,7 @@ import {
135
135
  } from "@teamix-evo/registry";
136
136
  import * as fs2 from "fs/promises";
137
137
  function getTeamixDir(projectRoot) {
138
- return path4.join(projectRoot, TEAMIX_DIR);
138
+ return path5.join(projectRoot, TEAMIX_DIR);
139
139
  }
140
140
  async function ensureTeamixDir(projectRoot) {
141
141
  const dir = getTeamixDir(projectRoot);
@@ -143,7 +143,7 @@ async function ensureTeamixDir(projectRoot) {
143
143
  return dir;
144
144
  }
145
145
  async function readProjectConfig(projectRoot) {
146
- const configPath = path4.join(projectRoot, TEAMIX_DIR, CONFIG_FILE);
146
+ const configPath = path5.join(projectRoot, TEAMIX_DIR, CONFIG_FILE);
147
147
  const raw = await readFileOrNull(configPath);
148
148
  if (raw === null) return null;
149
149
  let data;
@@ -163,12 +163,12 @@ async function readProjectConfig(projectRoot) {
163
163
  return result.data;
164
164
  }
165
165
  async function writeProjectConfig(projectRoot, config) {
166
- const configPath = path4.join(projectRoot, TEAMIX_DIR, CONFIG_FILE);
166
+ const configPath = path5.join(projectRoot, TEAMIX_DIR, CONFIG_FILE);
167
167
  await writeFileSafe(configPath, JSON.stringify(config, null, 2) + "\n");
168
168
  logger.debug(`Wrote config \u2192 ${configPath}`);
169
169
  }
170
170
  async function readInstalledManifest(projectRoot) {
171
- const manifestPath = path4.join(projectRoot, TEAMIX_DIR, MANIFEST_FILE);
171
+ const manifestPath = path5.join(projectRoot, TEAMIX_DIR, MANIFEST_FILE);
172
172
  const raw = await readFileOrNull(manifestPath);
173
173
  if (raw === null) return null;
174
174
  let data;
@@ -216,12 +216,12 @@ function migrateManifest(data) {
216
216
  return obj;
217
217
  }
218
218
  async function writeInstalledManifest(projectRoot, manifest) {
219
- const manifestPath = path4.join(projectRoot, TEAMIX_DIR, MANIFEST_FILE);
219
+ const manifestPath = path5.join(projectRoot, TEAMIX_DIR, MANIFEST_FILE);
220
220
  await writeFileSafe(manifestPath, JSON.stringify(manifest, null, 2) + "\n");
221
221
  logger.debug(`Wrote manifest \u2192 ${manifestPath}`);
222
222
  }
223
223
  async function readTokensLock(projectRoot) {
224
- const lockPath = path4.join(projectRoot, TEAMIX_DIR, TOKENS_LOCK_FILE);
224
+ const lockPath = path5.join(projectRoot, TEAMIX_DIR, TOKENS_LOCK_FILE);
225
225
  const raw = await readFileOrNull(lockPath);
226
226
  if (raw === null) return null;
227
227
  try {
@@ -241,7 +241,7 @@ async function readTokensVariant(projectRoot) {
241
241
  return lock?.variant.name ?? null;
242
242
  }
243
243
  async function readSkillsLock(projectRoot) {
244
- const lockPath = path4.join(projectRoot, TEAMIX_DIR, SKILLS_LOCK_FILE);
244
+ const lockPath = path5.join(projectRoot, TEAMIX_DIR, SKILLS_LOCK_FILE);
245
245
  const raw = await readFileOrNull(lockPath);
246
246
  if (raw === null) return null;
247
247
  try {
@@ -260,20 +260,20 @@ async function readSkillsLock(projectRoot) {
260
260
  }
261
261
  }
262
262
  async function writeSkillsLock(projectRoot, lock) {
263
- const lockPath = path4.join(projectRoot, TEAMIX_DIR, SKILLS_LOCK_FILE);
263
+ const lockPath = path5.join(projectRoot, TEAMIX_DIR, SKILLS_LOCK_FILE);
264
264
  await writeFileSafe(lockPath, JSON.stringify(lock, null, 2) + "\n");
265
265
  logger.debug(`Wrote skills lock \u2192 ${lockPath}`);
266
266
  }
267
267
  async function migrateSkillsLockLocation(projectRoot) {
268
- const newPath = path4.join(projectRoot, TEAMIX_DIR, SKILLS_LOCK_FILE);
268
+ const newPath = path5.join(projectRoot, TEAMIX_DIR, SKILLS_LOCK_FILE);
269
269
  try {
270
270
  await fs2.access(newPath);
271
271
  } catch {
272
272
  for (const legacyRel of LEGACY_SKILLS_LOCK_PATHS) {
273
- const legacyPath = path4.join(projectRoot, TEAMIX_DIR, legacyRel);
273
+ const legacyPath = path5.join(projectRoot, TEAMIX_DIR, legacyRel);
274
274
  try {
275
275
  await fs2.access(legacyPath);
276
- await ensureDir(path4.dirname(newPath));
276
+ await ensureDir(path5.dirname(newPath));
277
277
  await fs2.rename(legacyPath, newPath);
278
278
  logger.debug(`Migrated skills lock: ${legacyRel} \u2192 ${SKILLS_LOCK_FILE}`);
279
279
  break;
@@ -283,7 +283,7 @@ async function migrateSkillsLockLocation(projectRoot) {
283
283
  }
284
284
  }
285
285
  for (const staleDir of ["skills-source", "skills"]) {
286
- const abs = path4.join(projectRoot, TEAMIX_DIR, staleDir);
286
+ const abs = path5.join(projectRoot, TEAMIX_DIR, staleDir);
287
287
  try {
288
288
  await fs2.rm(abs, { recursive: true, force: true });
289
289
  logger.debug(`Cleaned up stale dir: .teamix-evo/${staleDir}/`);
@@ -310,8 +310,8 @@ var init_state = __esm({
310
310
  TOKENS_LOCK_FILE = "tokens-lock.json";
311
311
  SKILLS_LOCK_FILE = "skills-lock.json";
312
312
  LEGACY_SKILLS_LOCK_PATHS = [
313
- path4.join("skills-source", "manifest.lock.json"),
314
- path4.join("skills", "manifest.lock.json")
313
+ path5.join("skills-source", "manifest.lock.json"),
314
+ path5.join("skills", "manifest.lock.json")
315
315
  ];
316
316
  }
317
317
  });
@@ -583,7 +583,7 @@ var init_registry = __esm({
583
583
 
584
584
  // src/index.ts
585
585
  import { Command as Command42 } from "commander";
586
- import { createRequire as createRequire9 } from "module";
586
+ import { createRequire as createRequire8 } from "module";
587
587
 
588
588
  // src/commands/tokens/index.ts
589
589
  import { Command as Command12 } from "commander";
@@ -627,14 +627,50 @@ var ClaudeAdapter = class {
627
627
  }
628
628
  };
629
629
 
630
+ // src/ide/CodexAdapter.ts
631
+ import * as os3 from "os";
632
+ import * as path3 from "path";
633
+ var CodexAdapter = class {
634
+ kind = "codex";
635
+ name = "codex";
636
+ getProjectRoot() {
637
+ return process.cwd();
638
+ }
639
+ detectIde() {
640
+ return Boolean(
641
+ process.env.CODEX_HOME || process.env.CODEX_SANDBOX || process.env.CODEX_THREAD_ID || process.env.CODEX_CI
642
+ );
643
+ }
644
+ getSkillTargetDir(skillName, scope, projectRoot) {
645
+ const base = scope === "global" ? path3.join(os3.homedir(), ".agents") : path3.join(projectRoot ?? this.getProjectRoot(), ".agents");
646
+ return path3.join(base, "skills", skillName);
647
+ }
648
+ };
649
+
630
650
  // src/ide/index.ts
631
- var ALL_IDE_KINDS = ["qoder", "claude"];
651
+ var ALL_IDE_KINDS = [
652
+ "qoder",
653
+ "claude",
654
+ "codex"
655
+ ];
656
+ function getIdeDisplayName(kind) {
657
+ switch (kind) {
658
+ case "qoder":
659
+ return "Qoder";
660
+ case "claude":
661
+ return "Claude Code";
662
+ case "codex":
663
+ return "Codex / ChatGPT";
664
+ }
665
+ }
632
666
  function getAdapter(kind) {
633
667
  switch (kind) {
634
668
  case "qoder":
635
669
  return new QoderAdapter();
636
670
  case "claude":
637
671
  return new ClaudeAdapter();
672
+ case "codex":
673
+ return new CodexAdapter();
638
674
  default: {
639
675
  const _exhaustive = kind;
640
676
  throw new Error(`Unsupported IDE kind: ${_exhaustive}`);
@@ -644,12 +680,14 @@ function getAdapter(kind) {
644
680
  function detectIde() {
645
681
  const claude = new ClaudeAdapter();
646
682
  if (claude.detectIde()) return claude;
683
+ const codex = new CodexAdapter();
684
+ if (codex.detectIde()) return codex;
647
685
  return new QoderAdapter();
648
686
  }
649
687
 
650
688
  // src/core/tokens-init.ts
651
689
  init_fs();
652
- import * as path8 from "path";
690
+ import * as path9 from "path";
653
691
  import * as fs7 from "fs/promises";
654
692
  import {
655
693
  loadTokensPackageManifest,
@@ -668,21 +706,21 @@ init_state();
668
706
 
669
707
  // src/core/skills-client.ts
670
708
  init_logger();
671
- import * as path5 from "path";
709
+ import * as path6 from "path";
672
710
  import * as fs3 from "fs/promises";
673
711
  import { createRequire } from "module";
674
712
  import { loadSkillsPackageManifest } from "@teamix-evo/registry";
675
713
  var require2 = createRequire(import.meta.url);
676
714
  function resolvePackageRoot(packageName) {
677
715
  const pkgJsonPath = require2.resolve(`${packageName}/package.json`);
678
- return path5.dirname(pkgJsonPath);
716
+ return path6.dirname(pkgJsonPath);
679
717
  }
680
718
  async function loadSkillsData(packageName) {
681
719
  const packageRoot = resolvePackageRoot(packageName);
682
720
  logger.debug(`Resolved skills package root: ${packageRoot}`);
683
721
  const manifest = await loadSkillsPackageManifest(packageRoot);
684
722
  let data = {};
685
- const dataPath = path5.join(packageRoot, "_data.json");
723
+ const dataPath = path6.join(packageRoot, "_data.json");
686
724
  try {
687
725
  const raw = await fs3.readFile(dataPath, "utf-8");
688
726
  data = JSON.parse(raw);
@@ -696,7 +734,7 @@ async function loadSkillsData(packageName) {
696
734
  }
697
735
 
698
736
  // src/core/skills-installer.ts
699
- import * as path7 from "path";
737
+ import * as path8 from "path";
700
738
  import * as fs6 from "fs/promises";
701
739
  import {
702
740
  replaceManagedRegion,
@@ -739,7 +777,7 @@ init_logger();
739
777
  init_error();
740
778
 
741
779
  // src/utils/path.ts
742
- import * as path6 from "path";
780
+ import * as path7 from "path";
743
781
  import * as fs5 from "fs/promises";
744
782
  import { createRequire as createRequire2 } from "module";
745
783
  var require3 = createRequire2(import.meta.url);
@@ -753,7 +791,7 @@ async function walkDir(dir, skipDirs) {
753
791
  const files = [];
754
792
  const entries = await fs5.readdir(dir, { withFileTypes: true });
755
793
  for (const entry of entries) {
756
- const fullPath = path6.join(dir, entry.name);
794
+ const fullPath = path7.join(dir, entry.name);
757
795
  if (entry.isDirectory()) {
758
796
  if (skipDirs && skipDirs.has(entry.name)) continue;
759
797
  files.push(...await walkDir(fullPath, skipDirs));
@@ -765,10 +803,10 @@ async function walkDir(dir, skipDirs) {
765
803
  }
766
804
  function resolveTokensPackageRoot(packageName) {
767
805
  const pkgJson = require3.resolve(`${packageName}/package.json`);
768
- return path6.dirname(pkgJson);
806
+ return path7.dirname(pkgJson);
769
807
  }
770
808
  function resolveResourceTarget(projectRoot, target) {
771
- return path6.isAbsolute(target) ? target : path6.resolve(projectRoot, target);
809
+ return path7.isAbsolute(target) ? target : path7.resolve(projectRoot, target);
772
810
  }
773
811
 
774
812
  // src/core/skills-installer.ts
@@ -806,7 +844,7 @@ async function installSkills(options) {
806
844
  }
807
845
  async function renderSkillFiles(skill, options) {
808
846
  const { data, packageRoot } = options;
809
- const sourceAbs = path7.resolve(packageRoot, skill.source);
847
+ const sourceAbs = path8.resolve(packageRoot, skill.source);
810
848
  const stat6 = await fs6.stat(sourceAbs);
811
849
  const rendered = /* @__PURE__ */ new Map();
812
850
  if (stat6.isFile()) {
@@ -816,7 +854,7 @@ async function renderSkillFiles(skill, options) {
816
854
  }
817
855
  const entries = await walkDir(sourceAbs);
818
856
  for (const entry of entries) {
819
- let rel2 = path7.relative(sourceAbs, entry);
857
+ let rel2 = path8.relative(sourceAbs, entry);
820
858
  if (skill.template && rel2.endsWith(".hbs")) {
821
859
  rel2 = rel2.slice(0, -4);
822
860
  }
@@ -831,7 +869,7 @@ async function writeRenderedToIde(skill, rendered, ide, scope, projectRoot) {
831
869
  const records = [];
832
870
  await ensureDir(targetDir);
833
871
  for (const [rel2, sourceContent] of rendered) {
834
- const targetFile = path7.join(targetDir, rel2);
872
+ const targetFile = path8.join(targetDir, rel2);
835
873
  const writtenContent = await writeMirrorContent(
836
874
  targetFile,
837
875
  sourceContent,
@@ -903,7 +941,7 @@ function makeMirrorRecord(skill, projectRoot, targetAbs, content, ide, scope, re
903
941
  const id = rel2 && rel2 !== "SKILL.md" ? `${skill.id}:${rel2}` : skill.id;
904
942
  return {
905
943
  id,
906
- target: path7.relative(projectRoot, targetAbs),
944
+ target: path8.relative(projectRoot, targetAbs),
907
945
  hash: computeHash(content),
908
946
  strategy: skill.updateStrategy,
909
947
  ide,
@@ -940,7 +978,7 @@ async function updateRenderedInIde(skill, rendered, ide, scope, projectRoot, sum
940
978
  const records = [];
941
979
  await ensureDir(targetDir);
942
980
  for (const [rel2, newContent] of rendered) {
943
- const targetFile = path7.join(targetDir, rel2);
981
+ const targetFile = path8.join(targetDir, rel2);
944
982
  const exists = await fileExists(targetFile);
945
983
  const written = await rewriteSingleFile({
946
984
  targetFile,
@@ -1030,12 +1068,13 @@ async function reinstallSkillsToIdes(options) {
1030
1068
  continue;
1031
1069
  }
1032
1070
  const rendered = await renderSkillFiles(entry, { data, packageRoot });
1033
- for (const ide of ides) {
1071
+ const supportedIdes = entry.ides.filter((ide) => ides.includes(ide));
1072
+ for (const ide of supportedIdes) {
1034
1073
  const adapter = getAdapter(ide);
1035
1074
  const targetDir = adapter.getSkillTargetDir(skill.name, scope, projectRoot);
1036
1075
  await ensureDir(targetDir);
1037
1076
  for (const [rel2, sourceContent] of rendered) {
1038
- const targetFile = path7.join(targetDir, rel2);
1077
+ const targetFile = path8.join(targetDir, rel2);
1039
1078
  const writtenContent = await writeMirrorContent(
1040
1079
  targetFile,
1041
1080
  sourceContent,
@@ -1043,7 +1082,7 @@ async function reinstallSkillsToIdes(options) {
1043
1082
  );
1044
1083
  out.push({
1045
1084
  id: rel2 === "SKILL.md" ? skill.id : `${skill.id}:${rel2}`,
1046
- target: path7.relative(projectRoot, targetFile),
1085
+ target: path8.relative(projectRoot, targetFile),
1047
1086
  hash: computeHash(writtenContent),
1048
1087
  strategy: skill.updateStrategy,
1049
1088
  ide,
@@ -1063,7 +1102,7 @@ async function pruneEmptyIdeSkillDirs(args) {
1063
1102
  args.scope,
1064
1103
  args.projectRoot
1065
1104
  );
1066
- const skillsRoot = path7.dirname(placeholderDir);
1105
+ const skillsRoot = path8.dirname(placeholderDir);
1067
1106
  let entries;
1068
1107
  try {
1069
1108
  entries = await fs6.readdir(skillsRoot);
@@ -1071,7 +1110,7 @@ async function pruneEmptyIdeSkillDirs(args) {
1071
1110
  continue;
1072
1111
  }
1073
1112
  for (const name of entries) {
1074
- const dir = path7.join(skillsRoot, name);
1113
+ const dir = path8.join(skillsRoot, name);
1075
1114
  let stat6;
1076
1115
  try {
1077
1116
  stat6 = await fs6.stat(dir);
@@ -1111,7 +1150,7 @@ async function removeSkillFiles(records, projectRoot) {
1111
1150
  }
1112
1151
  }
1113
1152
  const startDirs = new Set(
1114
- records.map((r) => path7.dirname(resolveResourceTarget(projectRoot, r.target)))
1153
+ records.map((r) => path8.dirname(resolveResourceTarget(projectRoot, r.target)))
1115
1154
  );
1116
1155
  for (const startDir of startDirs) {
1117
1156
  let dir = startDir;
@@ -1123,7 +1162,7 @@ async function removeSkillFiles(records, projectRoot) {
1123
1162
  } catch {
1124
1163
  break;
1125
1164
  }
1126
- dir = path7.dirname(dir);
1165
+ dir = path8.dirname(dir);
1127
1166
  }
1128
1167
  }
1129
1168
  return removed;
@@ -1556,7 +1595,7 @@ async function autoUpgradeOutdatedSkills(args) {
1556
1595
  init_logger();
1557
1596
  init_error();
1558
1597
  var DEFAULT_SKILLS_PACKAGE2 = "@teamix-evo/skills";
1559
- var DEFAULT_AUTO_SKILL_IDES = ["qoder", "claude"];
1598
+ var DEFAULT_AUTO_SKILL_IDES = [...ALL_IDE_KINDS];
1560
1599
  var DEFAULT_AUTO_SKILL_SCOPE = "project";
1561
1600
  var DEFAULT_TOKENS_PACKAGE = "@teamix-evo/tokens";
1562
1601
  var CONSUMER_TOKENS_DIR = "tokens";
@@ -1596,7 +1635,7 @@ Run \`npx teamix-evo@latest tokens list-variants\` to see all options.`
1596
1635
  const result = await installVariantFile(fileRel, packageRoot, projectRoot);
1597
1636
  if (result) installed.push(result);
1598
1637
  }
1599
- const overridesAbs = path8.join(
1638
+ const overridesAbs = path9.join(
1600
1639
  projectRoot,
1601
1640
  CONSUMER_TOKENS_DIR,
1602
1641
  CONSUMER_OVERRIDES_FILE
@@ -1609,7 +1648,7 @@ Run \`npx teamix-evo@latest tokens list-variants\` to see all options.`
1609
1648
  const overridesContent = await fs7.readFile(overridesAbs, "utf-8");
1610
1649
  installed.push({
1611
1650
  id: overridesId,
1612
- target: path8.posix.join(CONSUMER_TOKENS_DIR, CONSUMER_OVERRIDES_FILE),
1651
+ target: path9.posix.join(CONSUMER_TOKENS_DIR, CONSUMER_OVERRIDES_FILE),
1613
1652
  hash: computeHash(overridesContent),
1614
1653
  strategy: "frozen"
1615
1654
  });
@@ -1627,7 +1666,7 @@ Run \`npx teamix-evo@latest tokens list-variants\` to see all options.`
1627
1666
  installedAt: (/* @__PURE__ */ new Date()).toISOString()
1628
1667
  };
1629
1668
  await writeFileSafe(
1630
- path8.join(projectRoot, ".teamix-evo", "tokens-lock.json"),
1669
+ path9.join(projectRoot, ".teamix-evo", "tokens-lock.json"),
1631
1670
  JSON.stringify(lock, null, 2) + "\n"
1632
1671
  );
1633
1672
  const config = {
@@ -1747,11 +1786,11 @@ async function tryAutoInstallVariantSkills(args) {
1747
1786
  }
1748
1787
  }
1749
1788
  async function installVariantFile(fileRelToPackage, packageRoot, projectRoot) {
1750
- const sourceAbs = path8.join(packageRoot, fileRelToPackage);
1751
- const base = path8.basename(fileRelToPackage);
1789
+ const sourceAbs = path9.join(packageRoot, fileRelToPackage);
1790
+ const base = path9.basename(fileRelToPackage);
1752
1791
  if (base === "theme.css") {
1753
- const targetRel = path8.posix.join(CONSUMER_TOKENS_DIR, CONSUMER_THEME_FILE);
1754
- const targetAbs = path8.join(projectRoot, targetRel);
1792
+ const targetRel = path9.posix.join(CONSUMER_TOKENS_DIR, CONSUMER_THEME_FILE);
1793
+ const targetAbs = path9.join(projectRoot, targetRel);
1755
1794
  const content = await fs7.readFile(sourceAbs, "utf-8");
1756
1795
  if (await fileExists(targetAbs)) {
1757
1796
  await backupFile(targetAbs, projectRoot);
@@ -1765,11 +1804,11 @@ async function installVariantFile(fileRelToPackage, packageRoot, projectRoot) {
1765
1804
  };
1766
1805
  }
1767
1806
  if (base === "overrides.css" || base === "tokens.overrides.css") {
1768
- const targetRel = path8.posix.join(
1807
+ const targetRel = path9.posix.join(
1769
1808
  CONSUMER_TOKENS_DIR,
1770
1809
  CONSUMER_OVERRIDES_FILE
1771
1810
  );
1772
- const targetAbs = path8.join(projectRoot, targetRel);
1811
+ const targetAbs = path9.join(projectRoot, targetRel);
1773
1812
  if (await fileExists(targetAbs)) {
1774
1813
  const existing = await fs7.readFile(targetAbs, "utf-8");
1775
1814
  return {
@@ -1808,9 +1847,9 @@ async function listTokenVariants(packageName = DEFAULT_TOKENS_PACKAGE, packageRo
1808
1847
 
1809
1848
  // src/core/html-theme-patch.ts
1810
1849
  init_fs();
1811
- import * as path9 from "path";
1850
+ import * as path10 from "path";
1812
1851
  async function patchHtmlDataTheme(projectRoot, variant) {
1813
- const htmlPath = path9.join(projectRoot, "index.html");
1852
+ const htmlPath = path10.join(projectRoot, "index.html");
1814
1853
  const content = await readFileOrNull(htmlPath);
1815
1854
  if (content === null) {
1816
1855
  return { status: "not-found", htmlPath };
@@ -1832,16 +1871,16 @@ async function patchHtmlDataTheme(projectRoot, variant) {
1832
1871
  // src/utils/global-root.ts
1833
1872
  import { existsSync } from "fs";
1834
1873
  import * as fs8 from "fs/promises";
1835
- import * as os3 from "os";
1836
- import * as path10 from "path";
1874
+ import * as os4 from "os";
1875
+ import * as path11 from "path";
1837
1876
  var GLOBAL_META_DIR = ".teamix-evo-global";
1838
1877
  var TEAMIX_DIR2 = ".teamix-evo";
1839
1878
  var CONFIG_FILE2 = "config.json";
1840
1879
  function getGlobalMetaRoot() {
1841
- return path10.join(os3.homedir(), GLOBAL_META_DIR);
1880
+ return path11.join(os4.homedir(), GLOBAL_META_DIR);
1842
1881
  }
1843
1882
  function isTeamixEvoProject(dir) {
1844
- return existsSync(path10.join(dir, TEAMIX_DIR2, CONFIG_FILE2));
1883
+ return existsSync(path11.join(dir, TEAMIX_DIR2, CONFIG_FILE2));
1845
1884
  }
1846
1885
  async function ensureGlobalMetaRoot() {
1847
1886
  const root = getGlobalMetaRoot();
@@ -1849,7 +1888,7 @@ async function ensureGlobalMetaRoot() {
1849
1888
  return root;
1850
1889
  }
1851
1890
  function hasPackageJson(projectRoot) {
1852
- return existsSync(path10.join(projectRoot, "package.json"));
1891
+ return existsSync(path11.join(projectRoot, "package.json"));
1853
1892
  }
1854
1893
  function resolveSkillsMaintenanceRoot(cwd) {
1855
1894
  if (isTeamixEvoProject(cwd)) return cwd;
@@ -1954,7 +1993,7 @@ import { Command as Command2 } from "commander";
1954
1993
 
1955
1994
  // src/core/tokens-update.ts
1956
1995
  init_fs();
1957
- import * as path12 from "path";
1996
+ import * as path13 from "path";
1958
1997
  import * as fs9 from "fs/promises";
1959
1998
  import {
1960
1999
  loadTokensPackageManifest as loadTokensPackageManifest2,
@@ -1964,7 +2003,7 @@ init_state();
1964
2003
 
1965
2004
  // src/core/upgrade-hints.ts
1966
2005
  init_fs();
1967
- import * as path11 from "path";
2006
+ import * as path12 from "path";
1968
2007
  var TEAMIX_DIR3 = ".teamix-evo";
1969
2008
  var HINTS_DIR = ".upgrade-hints";
1970
2009
  function isoToFsSafe(iso) {
@@ -1975,7 +2014,7 @@ async function writeTokensUpgradeHint(options) {
1975
2014
  const isoTs = options.isoTs ?? (/* @__PURE__ */ new Date()).toISOString();
1976
2015
  const fsTs = isoToFsSafe(isoTs);
1977
2016
  const filename = `tokens-${fsTs}.json`;
1978
- const target = path11.join(
2017
+ const target = path12.join(
1979
2018
  options.projectRoot,
1980
2019
  TEAMIX_DIR3,
1981
2020
  HINTS_DIR,
@@ -2064,8 +2103,8 @@ async function runTokensUpdate(options) {
2064
2103
  const upstreamByBasename = /* @__PURE__ */ new Map();
2065
2104
  for (const fileRel of variantEntry.files) {
2066
2105
  upstreamByBasename.set(
2067
- path12.basename(fileRel),
2068
- path12.join(packageRoot, fileRel)
2106
+ path13.basename(fileRel),
2107
+ path13.join(packageRoot, fileRel)
2069
2108
  );
2070
2109
  }
2071
2110
  const prior = await readInstalledManifest(projectRoot) ?? {
@@ -2082,8 +2121,8 @@ async function runTokensUpdate(options) {
2082
2121
  const frozenDrift = [];
2083
2122
  const refreshedResources = [];
2084
2123
  for (const resource of priorResources) {
2085
- const consumerAbs = path12.isAbsolute(resource.target) ? resource.target : path12.join(projectRoot, resource.target);
2086
- const consumerBasename = path12.basename(resource.target);
2124
+ const consumerAbs = path13.isAbsolute(resource.target) ? resource.target : path13.join(projectRoot, resource.target);
2125
+ const consumerBasename = path13.basename(resource.target);
2087
2126
  const upstreamBasename = lookupUpstreamBasename(consumerBasename);
2088
2127
  const upstreamAbs = upstreamBasename ? upstreamByBasename.get(upstreamBasename) : void 0;
2089
2128
  if (resource.strategy === "regenerable") {
@@ -2160,7 +2199,7 @@ async function runTokensUpdate(options) {
2160
2199
  installedAt: (/* @__PURE__ */ new Date()).toISOString()
2161
2200
  };
2162
2201
  await writeFileSafe(
2163
- path12.join(projectRoot, ".teamix-evo", "tokens-lock.json"),
2202
+ path13.join(projectRoot, ".teamix-evo", "tokens-lock.json"),
2164
2203
  JSON.stringify(lock, null, 2) + "\n"
2165
2204
  );
2166
2205
  config.packages.tokens.version = variantEntry.version;
@@ -2361,7 +2400,7 @@ var listVariantsCommand = new Command4("list-variants").description("\u5217\u51F
2361
2400
  // src/commands/tokens/uninstall.ts
2362
2401
  import { Command as Command5 } from "commander";
2363
2402
  import * as fs10 from "fs/promises";
2364
- import * as path13 from "path";
2403
+ import * as path14 from "path";
2365
2404
  import * as prompts from "@clack/prompts";
2366
2405
  init_state();
2367
2406
  init_logger();
@@ -2406,7 +2445,7 @@ var uninstallCommand = new Command5("uninstall").description(
2406
2445
  }
2407
2446
  let removed = 0;
2408
2447
  for (const r of removable) {
2409
- const target = path13.isAbsolute(r.target) ? r.target : path13.join(projectRoot, r.target);
2448
+ const target = path14.isAbsolute(r.target) ? r.target : path14.join(projectRoot, r.target);
2410
2449
  try {
2411
2450
  await fs10.unlink(target);
2412
2451
  removed++;
@@ -2424,7 +2463,7 @@ var uninstallCommand = new Command5("uninstall").description(
2424
2463
  }
2425
2464
  delete config.packages.tokens;
2426
2465
  await writeProjectConfig(projectRoot, config);
2427
- const lockPath = path13.join(
2466
+ const lockPath = path14.join(
2428
2467
  projectRoot,
2429
2468
  ".teamix-evo",
2430
2469
  "tokens-lock.json"
@@ -2458,12 +2497,12 @@ init_error();
2458
2497
 
2459
2498
  // src/core/tokens-audit.ts
2460
2499
  import * as fs11 from "fs/promises";
2461
- import * as path14 from "path";
2500
+ import * as path15 from "path";
2462
2501
  var THEME_REL = "tokens/tokens.theme.css";
2463
2502
  var OVERRIDES_REL = "tokens/tokens.overrides.css";
2464
2503
  async function runTokensAudit(options) {
2465
- const themePath = path14.join(options.projectRoot, THEME_REL);
2466
- const overridesPath = path14.join(options.projectRoot, OVERRIDES_REL);
2504
+ const themePath = path15.join(options.projectRoot, THEME_REL);
2505
+ const overridesPath = path15.join(options.projectRoot, OVERRIDES_REL);
2467
2506
  const themeSrc = await safeRead(themePath);
2468
2507
  if (themeSrc === null) {
2469
2508
  return { status: "no-theme", themePath, overridesPath };
@@ -2682,7 +2721,7 @@ init_registry();
2682
2721
 
2683
2722
  // src/codemods/runner.ts
2684
2723
  import * as fs12 from "fs/promises";
2685
- import * as path15 from "path";
2724
+ import * as path16 from "path";
2686
2725
  init_registry();
2687
2726
  async function runCodemod(options) {
2688
2727
  const { projectRoot, codemodId, dryRun = true } = options;
@@ -2692,7 +2731,7 @@ async function runCodemod(options) {
2692
2731
  `Unknown codemod "${codemodId}". Available: ${(await Promise.resolve().then(() => (init_registry(), registry_exports))).listCodemodIds().join(", ")}`
2693
2732
  );
2694
2733
  }
2695
- const scanRoot = path15.join(projectRoot, "src");
2734
+ const scanRoot = path16.join(projectRoot, "src");
2696
2735
  let allFiles;
2697
2736
  try {
2698
2737
  allFiles = await walkDir(scanRoot, DEFAULT_SKIP_DIRS);
@@ -2700,14 +2739,14 @@ async function runCodemod(options) {
2700
2739
  allFiles = [];
2701
2740
  }
2702
2741
  const files = allFiles.filter((abs) => {
2703
- const ext = path15.extname(abs).slice(1);
2742
+ const ext = path16.extname(abs).slice(1);
2704
2743
  return codemod.extensions.includes(ext);
2705
2744
  });
2706
2745
  const results = [];
2707
2746
  let scanned = 0;
2708
2747
  for (const absPath of files) {
2709
2748
  scanned++;
2710
- const relFile = path15.relative(projectRoot, absPath);
2749
+ const relFile = path16.relative(projectRoot, absPath);
2711
2750
  const content = await fs12.readFile(absPath, "utf-8");
2712
2751
  const result = codemod.transform(content, relFile, options.tokenMap);
2713
2752
  if (result) {
@@ -2731,7 +2770,7 @@ async function runCodemod(options) {
2731
2770
  // src/core/tokens-treat.ts
2732
2771
  init_fs();
2733
2772
  import * as fs13 from "fs/promises";
2734
- import * as path16 from "path";
2773
+ import * as path17 from "path";
2735
2774
 
2736
2775
  // src/utils/lint.ts
2737
2776
  import { exec } from "child_process";
@@ -2864,14 +2903,14 @@ async function captureBaseline(projectRoot) {
2864
2903
  };
2865
2904
  }
2866
2905
  async function generateTreatmentReport(projectRoot, pre, post, deltas, codemodResults) {
2867
- const reportsDir = path16.join(
2906
+ const reportsDir = path17.join(
2868
2907
  projectRoot,
2869
2908
  ".teamix-evo",
2870
2909
  ".treatment-reports"
2871
2910
  );
2872
2911
  await ensureDir(reportsDir);
2873
2912
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
2874
- const reportPath = path16.join(reportsDir, `${ts}.md`);
2913
+ const reportPath = path17.join(reportsDir, `${ts}.md`);
2875
2914
  let content = `# Token \u6CBB\u7406\u62A5\u544A
2876
2915
 
2877
2916
  > \u6267\u884C\u65F6\u95F4: ${post.timestamp}
@@ -2906,7 +2945,7 @@ async function generateTreatmentReport(projectRoot, pre, post, deltas, codemodRe
2906
2945
  return reportPath;
2907
2946
  }
2908
2947
  async function lockBaselineFile(projectRoot, baseline) {
2909
- const baselinePath = path16.join(
2948
+ const baselinePath = path17.join(
2910
2949
  projectRoot,
2911
2950
  ".teamix-evo",
2912
2951
  "tokens-baseline.json"
@@ -2920,8 +2959,8 @@ async function lockBaselineFile(projectRoot, baseline) {
2920
2959
  async function buildTokenMapFromProject(projectRoot) {
2921
2960
  const map = /* @__PURE__ */ new Map();
2922
2961
  const tokenFiles = [
2923
- path16.join(projectRoot, "tokens", "tokens.theme.css"),
2924
- path16.join(projectRoot, "tokens", "tokens.overrides.css")
2962
+ path17.join(projectRoot, "tokens", "tokens.theme.css"),
2963
+ path17.join(projectRoot, "tokens", "tokens.overrides.css")
2925
2964
  ];
2926
2965
  for (const file of tokenFiles) {
2927
2966
  const content = await readFileOrNull(file);
@@ -3007,7 +3046,7 @@ import { Command as Command8 } from "commander";
3007
3046
  init_fs();
3008
3047
  init_logger();
3009
3048
  import * as fs14 from "fs/promises";
3010
- import * as path17 from "path";
3049
+ import * as path18 from "path";
3011
3050
  import { exec as exec2 } from "child_process";
3012
3051
  import { promisify as promisify2 } from "util";
3013
3052
  var execAsync2 = promisify2(exec2);
@@ -3118,7 +3157,7 @@ async function collectLintViolations(projectRoot) {
3118
3157
  for (const msg of result.messages) {
3119
3158
  violations.push({
3120
3159
  ruleId: msg.ruleId,
3121
- file: path17.relative(projectRoot, result.filePath),
3160
+ file: path18.relative(projectRoot, result.filePath),
3122
3161
  line: msg.line
3123
3162
  });
3124
3163
  }
@@ -3133,9 +3172,9 @@ async function collectLintViolations(projectRoot) {
3133
3172
  return violations;
3134
3173
  }
3135
3174
  async function generateTreatmentPlan(projectRoot, entries, totalViolations, phaseSummary) {
3136
- const teamixDir = path17.join(projectRoot, ".teamix-evo");
3175
+ const teamixDir = path18.join(projectRoot, ".teamix-evo");
3137
3176
  await ensureDir(teamixDir);
3138
- const planPath = path17.join(teamixDir, ".treatment-plan.md");
3177
+ const planPath = path18.join(teamixDir, ".treatment-plan.md");
3139
3178
  const now = (/* @__PURE__ */ new Date()).toISOString().slice(0, 19).replace("T", " ");
3140
3179
  const phases = [
3141
3180
  {
@@ -3293,7 +3332,7 @@ var treatCommand = new Command9("treat").description("\u4E00\u952E token \u6CBB\
3293
3332
  import { Command as Command10 } from "commander";
3294
3333
 
3295
3334
  // src/core/tokens-reflect.ts
3296
- import * as path18 from "path";
3335
+ import * as path19 from "path";
3297
3336
  import { exec as exec3 } from "child_process";
3298
3337
  import { promisify as promisify3 } from "util";
3299
3338
  var execAsync3 = promisify3(exec3);
@@ -3314,7 +3353,7 @@ async function runTokensReflect(options) {
3314
3353
  const colorMatch = msg.message.match(/#[0-9a-fA-F]{3,8}/);
3315
3354
  if (!colorMatch) continue;
3316
3355
  const color = normaliseHex2(colorMatch[0]);
3317
- const relFile = path18.relative(projectRoot, result.filePath);
3356
+ const relFile = path19.relative(projectRoot, result.filePath);
3318
3357
  const entry = colorMap.get(color) ?? {
3319
3358
  frequency: 0,
3320
3359
  files: /* @__PURE__ */ new Set()
@@ -3422,10 +3461,10 @@ import { Command as Command11 } from "commander";
3422
3461
 
3423
3462
  // src/core/baseline-check.ts
3424
3463
  init_fs();
3425
- import * as path19 from "path";
3464
+ import * as path20 from "path";
3426
3465
  init_logger();
3427
3466
  async function checkBaseline(projectRoot) {
3428
- const baselinePath = path19.join(
3467
+ const baselinePath = path20.join(
3429
3468
  projectRoot,
3430
3469
  ".teamix-evo",
3431
3470
  "tokens-baseline.json"
@@ -3561,8 +3600,9 @@ function parseIdeList(input) {
3561
3600
  const parts = input.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
3562
3601
  const result = [];
3563
3602
  for (const p2 of parts) {
3564
- if (p2 === "qoder" || p2 === "claude") {
3565
- if (!result.includes(p2)) result.push(p2);
3603
+ if (ALL_IDE_KINDS.includes(p2)) {
3604
+ const ide = p2;
3605
+ if (!result.includes(ide)) result.push(ide);
3566
3606
  } else {
3567
3607
  throw new Error(
3568
3608
  `Unknown IDE: "${p2}". Expected one of: ${ALL_IDE_KINDS.join(", ")}.`
@@ -3580,7 +3620,7 @@ function parseScope(input) {
3580
3620
  // src/commands/skills/init.ts
3581
3621
  var initCommand2 = new Command13("init").description(
3582
3622
  "\u81EA\u4E3E teamix-evo skills\uFF08\u6309 tokens variant + scope \u5168\u88C5\u7B26\u5408\u6761\u4EF6\u7684 skill\uFF1Bscope \u4E3A global-only \u7684 entry skill \u81EA\u52A8\u8DF3\u8FC7 \u2014 ADR 0033\uFF09"
3583
- ).option("--ide <list>", '\u9017\u53F7\u5206\u9694\u7684 IDE \u5217\u8868\uFF0C\u5982 "qoder,claude"').option("--scope <scope>", "project | global\uFF08\u9ED8\u8BA4 project\uFF09").option("-y, --yes", "\u4F7F\u7528\u9ED8\u8BA4\u503C\uFF0C\u8DF3\u8FC7\u4EA4\u4E92").action(async (opts) => {
3623
+ ).option("--ide <list>", '\u9017\u53F7\u5206\u9694\u7684 IDE \u5217\u8868\uFF0C\u5982 "qoder,claude,codex"').option("--scope <scope>", "project | global\uFF08\u9ED8\u8BA4 project\uFF09").option("-y, --yes", "\u4F7F\u7528\u9ED8\u8BA4\u503C\uFF0C\u8DF3\u8FC7\u4EA4\u4E92").action(async (opts) => {
3584
3624
  try {
3585
3625
  const ide = detectIde();
3586
3626
  const cwd = ide.getProjectRoot();
@@ -3660,7 +3700,7 @@ async function resolveIdesAndScope(args) {
3660
3700
  message: "\u9009\u62E9\u8981\u6CE8\u5165\u6280\u80FD\u7684 AI IDE\uFF08\u81F3\u5C11\u4E00\u4E2A\uFF09",
3661
3701
  options: ALL_IDE_KINDS.map((k) => ({
3662
3702
  value: k,
3663
- label: k === "qoder" ? "Qoder" : "Claude Code"
3703
+ label: getIdeDisplayName(k)
3664
3704
  })),
3665
3705
  initialValues: [...ALL_IDE_KINDS],
3666
3706
  required: true
@@ -3671,8 +3711,8 @@ async function resolveIdesAndScope(args) {
3671
3711
  const scopeAns = await prompts2.select({
3672
3712
  message: "\u5B89\u88C5\u8303\u56F4\uFF1F",
3673
3713
  options: [
3674
- { value: "project", label: "\u9879\u76EE\u7EA7\uFF08.qoder/.claude \u5728\u5F53\u524D\u9879\u76EE\uFF09" },
3675
- { value: "global", label: "\u5168\u5C40\uFF08~/.qoder/~/.claude\uFF09" }
3714
+ { value: "project", label: "\u9879\u76EE\u7EA7\uFF08\u5199\u5165\u6240\u9009 IDE \u7684\u9879\u76EE skill \u76EE\u5F55\uFF09" },
3715
+ { value: "global", label: "\u5168\u5C40\uFF08\u5199\u5165\u6240\u9009 IDE \u7684\u7528\u6237 skill \u76EE\u5F55\uFF09" }
3676
3716
  ],
3677
3717
  initialValue: "project"
3678
3718
  });
@@ -3690,7 +3730,7 @@ init_logger();
3690
3730
  init_error();
3691
3731
  var addCommand = new Command14("add").description(
3692
3732
  "\u589E\u91CF\u6DFB\u52A0 teamix-evo skills\uFF08\u5FC5\u987B\u6307\u5B9A\u81F3\u5C11\u4E00\u4E2A skill id\uFF1B\u81EA\u4E3E\u8BF7\u7528 `skills init`\uFF09"
3693
- ).argument("<names...>", "\u81F3\u5C11\u4E00\u4E2A skill id\uFF08\u589E\u91CF\u88C5\uFF09").option("--ide <list>", '\u9017\u53F7\u5206\u9694\u7684 IDE \u5217\u8868\uFF0C\u5982 "qoder,claude"').option(
3733
+ ).argument("<names...>", "\u81F3\u5C11\u4E00\u4E2A skill id\uFF08\u589E\u91CF\u88C5\uFF09").option("--ide <list>", '\u9017\u53F7\u5206\u9694\u7684 IDE \u5217\u8868\uFF0C\u5982 "qoder,claude,codex"').option(
3694
3734
  "--scope <scope>",
3695
3735
  "project | global\uFF08\u9ED8\u8BA4\u6CBF\u7528\u65E2\u6709 skills \u914D\u7F6E\uFF1B\u9996\u6B21\u5B89\u88C5\u9ED8\u8BA4 project\uFF09"
3696
3736
  ).option("-y, --yes", "\u4F7F\u7528\u9ED8\u8BA4\u503C\uFF0C\u8DF3\u8FC7\u4EA4\u4E92").action(async (names, opts) => {
@@ -3803,7 +3843,7 @@ async function resolveIdesAndScope2(args) {
3803
3843
  message: "\u9009\u62E9\u8981\u6CE8\u5165\u6280\u80FD\u7684 AI IDE\uFF08\u81F3\u5C11\u4E00\u4E2A\uFF09",
3804
3844
  options: ALL_IDE_KINDS.map((k) => ({
3805
3845
  value: k,
3806
- label: k === "qoder" ? "Qoder" : "Claude Code"
3846
+ label: getIdeDisplayName(k)
3807
3847
  })),
3808
3848
  initialValues: [...ALL_IDE_KINDS],
3809
3849
  required: true
@@ -3814,8 +3854,8 @@ async function resolveIdesAndScope2(args) {
3814
3854
  const scopeAns = await prompts3.select({
3815
3855
  message: "\u5B89\u88C5\u8303\u56F4\uFF1F",
3816
3856
  options: [
3817
- { value: "project", label: "\u9879\u76EE\u7EA7\uFF08.qoder/.claude \u5728\u5F53\u524D\u9879\u76EE\uFF09" },
3818
- { value: "global", label: "\u5168\u5C40\uFF08~/.qoder/~/.claude\uFF09" }
3857
+ { value: "project", label: "\u9879\u76EE\u7EA7\uFF08\u5199\u5165\u6240\u9009 IDE \u7684\u9879\u76EE skill \u76EE\u5F55\uFF09" },
3858
+ { value: "global", label: "\u5168\u5C40\uFF08\u5199\u5165\u6240\u9009 IDE \u7684\u7528\u6237 skill \u76EE\u5F55\uFF09" }
3819
3859
  ],
3820
3860
  initialValue: "project"
3821
3861
  });
@@ -3935,7 +3975,7 @@ init_state();
3935
3975
 
3936
3976
  // src/core/agents-md.ts
3937
3977
  import * as fs15 from "fs/promises";
3938
- import * as path20 from "path";
3978
+ import * as path21 from "path";
3939
3979
  import { hasManagedRegion as hasManagedRegion3, replaceManagedRegion as replaceManagedRegion3 } from "@teamix-evo/registry";
3940
3980
  init_fs();
3941
3981
  init_state();
@@ -3946,7 +3986,7 @@ async function runGenerateAgentsMd(options) {
3946
3986
  const mode = options.mode ?? "overwrite";
3947
3987
  const config = await readProjectConfig(projectRoot);
3948
3988
  const lock = await readSkillsLock(projectRoot);
3949
- const ides = config?.packages?.skills?.ides ?? ["qoder", "claude"];
3989
+ const ides = config?.packages?.skills?.ides ?? [...ALL_IDE_KINDS];
3950
3990
  const scope = config?.packages?.skills?.scope ?? lock?.skills[skillIds[0] ?? ""]?.scope ?? "project";
3951
3991
  const skillScopeMap = /* @__PURE__ */ new Map();
3952
3992
  for (const id of skillIds) skillScopeMap.set(id, scope);
@@ -3963,7 +4003,7 @@ async function runGenerateAgentsMd(options) {
3963
4003
  sections.push(section);
3964
4004
  if (missing) missingSkillIds.push(id);
3965
4005
  }
3966
- const target = path20.join(projectRoot, "AGENTS.md");
4006
+ const target = path21.join(projectRoot, "AGENTS.md");
3967
4007
  const targetExists = await fileExists(target);
3968
4008
  const fullTemplate = renderAgentsMd({ variant, sections });
3969
4009
  const managedBody = renderManagedBlockBody({ variant, sections });
@@ -4018,7 +4058,7 @@ async function renderSkillSection(projectRoot, skillId, ides, scope) {
4018
4058
  let missing = false;
4019
4059
  for (const ide of ides) {
4020
4060
  const adapter = getAdapter(ide);
4021
- const skillPath = path20.join(
4061
+ const skillPath = path21.join(
4022
4062
  adapter.getSkillTargetDir(skillId, scope, projectRoot),
4023
4063
  "SKILL.md"
4024
4064
  );
@@ -4193,7 +4233,7 @@ async function runSkillsUpdate(options) {
4193
4233
  if (!skillsCfg) {
4194
4234
  return { status: "no-skills" };
4195
4235
  }
4196
- const ides = skillsCfg.ides ?? ["qoder", "claude"];
4236
+ const ides = skillsCfg.ides ?? [...ALL_IDE_KINDS];
4197
4237
  const scope = skillsCfg.scope ?? "project";
4198
4238
  let existingLock = await readSkillsLock(projectRoot);
4199
4239
  if (!existingLock || Object.keys(existingLock.skills).length === 0) {
@@ -4523,7 +4563,7 @@ async function printVersionBanner() {
4523
4563
  // src/commands/skills/uninstall.ts
4524
4564
  import { Command as Command17 } from "commander";
4525
4565
  import * as prompts4 from "@clack/prompts";
4526
- import * as path21 from "path";
4566
+ import * as path22 from "path";
4527
4567
  import * as fs16 from "fs/promises";
4528
4568
  init_error();
4529
4569
  init_state();
@@ -4616,7 +4656,7 @@ async function runFullUninstall(args) {
4616
4656
  logger.info(` Removed: ${removed.length} files`);
4617
4657
  if (cleanedMirrorDirs.length > 0) {
4618
4658
  logger.info(
4619
- ` Mirrors: ${cleanedMirrorDirs.map((d) => path21.relative(projectRoot, d)).join(", ")} (cleaned)`
4659
+ ` Mirrors: ${cleanedMirrorDirs.map((d) => path22.relative(projectRoot, d)).join(", ")} (cleaned)`
4620
4660
  );
4621
4661
  }
4622
4662
  }
@@ -4671,7 +4711,7 @@ async function runPartialUninstall(args) {
4671
4711
  logger.info(` Files: ${removed.length}`);
4672
4712
  if (cleanedMirrorDirs.length > 0) {
4673
4713
  logger.info(
4674
- ` Mirrors: ${cleanedMirrorDirs.map((d) => path21.relative(projectRoot, d)).join(", ")} (cleaned)`
4714
+ ` Mirrors: ${cleanedMirrorDirs.map((d) => path22.relative(projectRoot, d)).join(", ")} (cleaned)`
4675
4715
  );
4676
4716
  }
4677
4717
  if (missing.length > 0) {
@@ -4687,7 +4727,9 @@ function collectSkillNames(args) {
4687
4727
  }
4688
4728
  async function removeMirrorDirs(projectRoot, scope, ides, skillNames) {
4689
4729
  if (skillNames.length === 0) return [];
4690
- const targetIdes = ides && ides.length > 0 ? ides.filter((i) => i === "qoder" || i === "claude") : [...ALL_IDE_KINDS];
4730
+ const targetIdes = ides && ides.length > 0 ? ides.filter(
4731
+ (i) => ALL_IDE_KINDS.includes(i)
4732
+ ) : [...ALL_IDE_KINDS];
4691
4733
  const targetScope = scope === "global" ? "global" : "project";
4692
4734
  const removed = [];
4693
4735
  for (const ide of targetIdes) {
@@ -4710,7 +4752,7 @@ async function removeMirrorDirs(projectRoot, scope, ides, skillNames) {
4710
4752
  }
4711
4753
  }
4712
4754
  if (removed.length > 0) {
4713
- const skillsParent = path21.dirname(
4755
+ const skillsParent = path22.dirname(
4714
4756
  adapter.getSkillTargetDir("placeholder", targetScope, projectRoot)
4715
4757
  );
4716
4758
  try {
@@ -4761,30 +4803,18 @@ function resolveUninstallRoot(cwd, scopeFlag) {
4761
4803
  import { Command as Command18 } from "commander";
4762
4804
 
4763
4805
  // src/core/skills-sync.ts
4764
- import * as path22 from "path";
4765
- import { createRequire as createRequire4 } from "module";
4766
- import { loadSkillsPackageManifest as loadSkillsPackageManifest2 } from "@teamix-evo/registry";
4806
+ import * as fs17 from "fs/promises";
4767
4807
  init_state();
4768
4808
  init_logger();
4769
- var require5 = createRequire4(import.meta.url);
4770
- async function readSkillMetaFromUpstream(skillId) {
4771
- try {
4772
- const pkgJson = require5.resolve("@teamix-evo/skills/package.json");
4773
- const packageRoot = path22.dirname(pkgJson);
4774
- const manifest = await loadSkillsPackageManifest2(packageRoot);
4775
- const entry = manifest.skills.find((s) => s.id === skillId);
4776
- if (!entry) return null;
4777
- return {
4778
- updateStrategy: entry.updateStrategy,
4779
- managedRegions: entry.managedRegions
4780
- };
4781
- } catch {
4782
- return null;
4783
- }
4784
- }
4785
4809
  var SKILLS_PACKAGE_DEFAULT = "@teamix-evo/skills";
4786
4810
  async function runSkillsSync(options) {
4787
4811
  const { projectRoot, names } = options;
4812
+ const reconfiguring = options.ides !== void 0 || options.scope !== void 0;
4813
+ if (reconfiguring && names && names.length > 0) {
4814
+ throw new Error(
4815
+ "IDE/scope overrides reconfigure the whole skills installation. Omit skill names and retry."
4816
+ );
4817
+ }
4788
4818
  const lock = await readSkillsLock(projectRoot);
4789
4819
  if (!lock || Object.keys(lock.skills).length === 0) {
4790
4820
  return {
@@ -4807,26 +4837,78 @@ async function runSkillsSync(options) {
4807
4837
  }
4808
4838
  const skillIds = Object.keys(lock.skills);
4809
4839
  const targets = names ? skillIds.filter((id) => names.includes(id)) : skillIds;
4840
+ if (reconfiguring) {
4841
+ const missing = targets.filter(
4842
+ (skillId) => !pkgData.manifest.skills.some((entry) => entry.id === skillId)
4843
+ );
4844
+ if (missing.length > 0) {
4845
+ throw new Error(
4846
+ `Cannot reconfigure skills missing from the upstream package: ${missing.join(", ")}. Run \`skills update\` and retry.`
4847
+ );
4848
+ }
4849
+ }
4850
+ const config = reconfiguring ? await readProjectConfig(projectRoot) : null;
4851
+ const skillsConfig = config?.packages.skills;
4852
+ if (reconfiguring && (!config || !skillsConfig)) {
4853
+ throw new Error(
4854
+ "Cannot persist IDE reconfiguration: .teamix-evo/config.json has no skills entry. Run `skills init` first."
4855
+ );
4856
+ }
4857
+ const configuredIdes = reconfiguring ? [
4858
+ ...options.ides ?? skillsConfig?.ides ?? [...new Set(skillIds.flatMap((id) => lock.skills[id]?.mirroredTo ?? []))]
4859
+ ] : null;
4860
+ const configuredScope = reconfiguring ? options.scope ?? skillsConfig?.scope ?? lock.skills[skillIds[0] ?? ""]?.scope ?? "project" : null;
4861
+ if (configuredIdes && configuredIdes.length === 0) {
4862
+ throw new Error("At least one IDE must be selected.");
4863
+ }
4864
+ const priorTargets = reconfiguring ? skillIds.flatMap((skillId) => {
4865
+ const entry = lock.skills[skillId];
4866
+ if (!entry) return [];
4867
+ return entry.mirroredTo.map((ide) => ({
4868
+ skillId,
4869
+ ide,
4870
+ scope: entry.scope
4871
+ }));
4872
+ }) : [];
4810
4873
  const allResources = [];
4811
4874
  const synced = [];
4812
4875
  for (const skillId of targets) {
4813
4876
  const lockEntry = lock.skills[skillId];
4814
4877
  if (!lockEntry) continue;
4815
- const ides = options.ides ?? lockEntry.mirroredTo;
4816
- const scope = options.scope ?? lockEntry.scope;
4878
+ const requestedIdes = configuredIdes ?? lockEntry.mirroredTo;
4879
+ const scope = configuredScope ?? lockEntry.scope;
4880
+ const upstreamEntry = pkgData.manifest.skills.find(
4881
+ (entry) => entry.id === skillId
4882
+ );
4883
+ if (!upstreamEntry) {
4884
+ logger.warn(`Skill "${skillId}" not found in npm package manifest; skipped.`);
4885
+ continue;
4886
+ }
4887
+ const ides = upstreamEntry.ides.filter(
4888
+ (ide) => requestedIdes.includes(ide)
4889
+ );
4817
4890
  if (ides.length === 0) {
4818
- logger.warn(`Skill "${skillId}" has no IDE mirror targets; skipped.`);
4891
+ logger.warn(
4892
+ `Skill "${skillId}" supports none of [${requestedIdes.join(", ")}]; no mirror written.`
4893
+ );
4894
+ if (reconfiguring) {
4895
+ lock.skills[skillId] = {
4896
+ ...lockEntry,
4897
+ mirroredTo: [],
4898
+ scope,
4899
+ installedAt: (/* @__PURE__ */ new Date()).toISOString()
4900
+ };
4901
+ }
4819
4902
  continue;
4820
4903
  }
4821
- const upstreamMeta = await readSkillMetaFromUpstream(skillId);
4822
4904
  const result = await reinstallSkillsToIdes({
4823
4905
  projectRoot,
4824
4906
  skills: [
4825
4907
  {
4826
4908
  id: skillId,
4827
- name: skillId,
4828
- updateStrategy: upstreamMeta?.updateStrategy ?? "regenerable",
4829
- managedRegions: upstreamMeta?.managedRegions
4909
+ name: upstreamEntry.name,
4910
+ updateStrategy: upstreamEntry.updateStrategy,
4911
+ managedRegions: upstreamEntry.managedRegions
4830
4912
  }
4831
4913
  ],
4832
4914
  manifest: pkgData.manifest,
@@ -4836,7 +4918,7 @@ async function runSkillsSync(options) {
4836
4918
  scope
4837
4919
  });
4838
4920
  allResources.push(...result.resources);
4839
- synced.push(skillId);
4921
+ if (result.count > 0) synced.push(skillId);
4840
4922
  lock.skills[skillId] = {
4841
4923
  ...lockEntry,
4842
4924
  mirroredTo: ides,
@@ -4845,7 +4927,24 @@ async function runSkillsSync(options) {
4845
4927
  };
4846
4928
  }
4847
4929
  await writeSkillsLock(projectRoot, lock);
4848
- await refreshMirrorRecords(projectRoot, allResources);
4930
+ await refreshMirrorRecords(
4931
+ projectRoot,
4932
+ allResources,
4933
+ reconfiguring ? targets : void 0
4934
+ );
4935
+ if (reconfiguring && config && skillsConfig && configuredIdes && configuredScope) {
4936
+ config.packages.skills = {
4937
+ ...skillsConfig,
4938
+ ides: configuredIdes,
4939
+ scope: configuredScope
4940
+ };
4941
+ await writeProjectConfig(projectRoot, config);
4942
+ await removeDeselectedMirrors({
4943
+ projectRoot,
4944
+ priorTargets,
4945
+ retainedTargets: lock.skills
4946
+ });
4947
+ }
4849
4948
  return {
4850
4949
  status: "synced",
4851
4950
  syncedSkillIds: synced,
@@ -4853,13 +4952,28 @@ async function runSkillsSync(options) {
4853
4952
  resources: allResources
4854
4953
  };
4855
4954
  }
4856
- async function refreshMirrorRecords(projectRoot, newRecords) {
4955
+ async function removeDeselectedMirrors(args) {
4956
+ for (const target of args.priorTargets) {
4957
+ const retained = args.retainedTargets[target.skillId];
4958
+ if (retained && target.scope === retained.scope && retained.mirroredTo.includes(target.ide)) {
4959
+ continue;
4960
+ }
4961
+ const dir = getAdapter(target.ide).getSkillTargetDir(
4962
+ target.skillId,
4963
+ target.scope,
4964
+ args.projectRoot
4965
+ );
4966
+ await fs17.rm(dir, { recursive: true, force: true });
4967
+ logger.debug(`Removed deselected IDE mirror: ${dir}`);
4968
+ }
4969
+ }
4970
+ async function refreshMirrorRecords(projectRoot, newRecords, touchedIds) {
4857
4971
  const installed = await readInstalledManifest(projectRoot);
4858
4972
  if (!installed) return;
4859
4973
  const pkg = installed.installed.find((p2) => p2.package === SKILLS_PACKAGE_DEFAULT);
4860
4974
  if (!pkg) return;
4861
4975
  const touchedSkillIds = new Set(
4862
- newRecords.map((r) => r.id.split(":")[0] ?? r.id)
4976
+ touchedIds ?? newRecords.map((r) => r.id.split(":")[0] ?? r.id)
4863
4977
  );
4864
4978
  const preserved = (pkg.resources ?? []).filter((r) => {
4865
4979
  const skillId = r.id.split(":")[0] ?? r.id;
@@ -4874,14 +4988,17 @@ async function refreshMirrorRecords(projectRoot, newRecords) {
4874
4988
  init_logger();
4875
4989
  init_error();
4876
4990
  var syncCommand = new Command18("sync").description(
4877
- "\u4ECE npm \u5305\u91CD\u65B0\u5B89\u88C5 skills \u5230 IDE \u8DEF\u5F84\uFF08.qoder / .claude\uFF09"
4991
+ "\u4ECE npm \u5305\u91CD\u65B0\u5B89\u88C5 skills \u5230 IDE \u8DEF\u5F84\uFF08.qoder / .claude / .agents\uFF09"
4878
4992
  ).argument(
4879
4993
  "[names...]",
4880
4994
  "\u53EF\u9009\uFF1A\u4EC5\u540C\u6B65\u6307\u5B9A skill id\uFF1B\u7701\u7565\u5219\u540C\u6B65\u5168\u90E8\u5DF2\u8BB0\u5F55\u5728 lock \u5185\u7684 skill"
4881
4995
  ).option(
4882
4996
  "--ide <list>",
4883
- "\u9017\u53F7\u5206\u9694\u7684 IDE \u5217\u8868\uFF08\u8986\u76D6 lock \u4E2D\u8BB0\u5F55\u7684 mirroredTo\uFF09"
4884
- ).option("--scope <scope>", "project | global\uFF08\u8986\u76D6 lock \u4E2D\u8BB0\u5F55\u7684 scope\uFF09").action(async (names, opts) => {
4997
+ "\u9017\u53F7\u5206\u9694\u7684 IDE \u5217\u8868\uFF08\u6301\u4E45\u91CD\u914D\u5168\u90E8 skills \u7684 config + lock\uFF09"
4998
+ ).option(
4999
+ "--scope <scope>",
5000
+ "project | global\uFF08\u6301\u4E45\u91CD\u914D\u5168\u90E8 skills \u7684 config + lock\uFF09"
5001
+ ).action(async (names, opts) => {
4885
5002
  try {
4886
5003
  const ide = detectIde();
4887
5004
  const cwd = ide.getProjectRoot();
@@ -4928,7 +5045,7 @@ import { Command as Command19 } from "commander";
4928
5045
 
4929
5046
  // src/core/skills-doctor.ts
4930
5047
  import * as path23 from "path";
4931
- import * as fs17 from "fs/promises";
5048
+ import * as fs18 from "fs/promises";
4932
5049
  init_fs();
4933
5050
  init_state();
4934
5051
  init_logger();
@@ -4995,7 +5112,7 @@ async function runSkillsDoctor(options) {
4995
5112
  });
4996
5113
  continue;
4997
5114
  }
4998
- const mirrorContent = await fs17.readFile(mirrorFile, "utf-8");
5115
+ const mirrorContent = await fs18.readFile(mirrorFile, "utf-8");
4999
5116
  if (computeHash(mirrorContent) !== computeHash(expectedContent)) {
5000
5117
  findings.push({
5001
5118
  kind: "mirror-drift",
@@ -5016,7 +5133,7 @@ async function runSkillsDoctor(options) {
5016
5133
  }
5017
5134
  async function dirExists(p2) {
5018
5135
  try {
5019
- const stat6 = await fs17.stat(p2);
5136
+ const stat6 = await fs18.stat(p2);
5020
5137
  return stat6.isDirectory();
5021
5138
  } catch {
5022
5139
  return false;
@@ -5066,7 +5183,7 @@ var doctorCommand = new Command19("doctor").description(
5066
5183
 
5067
5184
  // src/commands/skills/index.ts
5068
5185
  var skillsCommand = new Command20("skills").description(
5069
- "\u7BA1\u7406 teamix-evo skills\uFF08\u5411 AI IDE \u6CE8\u5165\u6280\u80FD\uFF1Bsource-mirror \u6A21\u578B\u89C1 ADR 0013\uFF09"
5186
+ "\u7BA1\u7406 teamix-evo skills\uFF08\u4ECE npm \u5305\u5411 AI IDE \u6CE8\u5165\u6280\u80FD\uFF1Bdirect-mirror \u6A21\u578B\u89C1 ADR 0048\uFF09"
5070
5187
  );
5071
5188
  skillsCommand.addCommand(initCommand2);
5072
5189
  skillsCommand.addCommand(addCommand);
@@ -5260,12 +5377,12 @@ import { Command as Command22 } from "commander";
5260
5377
  // src/core/ui-client.ts
5261
5378
  init_logger();
5262
5379
  import * as path24 from "path";
5263
- import * as fs18 from "fs/promises";
5264
- import { createRequire as createRequire5 } from "module";
5380
+ import * as fs19 from "fs/promises";
5381
+ import { createRequire as createRequire4 } from "module";
5265
5382
  import { loadUiPackageManifest } from "@teamix-evo/registry";
5266
- var require6 = createRequire5(import.meta.url);
5383
+ var require5 = createRequire4(import.meta.url);
5267
5384
  function resolvePackageRoot2(packageName) {
5268
- const pkgJsonPath = require6.resolve(`${packageName}/package.json`);
5385
+ const pkgJsonPath = require5.resolve(`${packageName}/package.json`);
5269
5386
  return path24.dirname(pkgJsonPath);
5270
5387
  }
5271
5388
  async function loadUiData(packageName) {
@@ -5273,13 +5390,13 @@ async function loadUiData(packageName) {
5273
5390
  logger.debug(`Resolved ui package root: ${packageRoot}`);
5274
5391
  const manifest = await loadUiPackageManifest(packageRoot);
5275
5392
  const pkgJson = JSON.parse(
5276
- await fs18.readFile(path24.join(packageRoot, "package.json"), "utf-8")
5393
+ await fs19.readFile(path24.join(packageRoot, "package.json"), "utf-8")
5277
5394
  );
5278
5395
  manifest.version = pkgJson.version;
5279
5396
  let data = {};
5280
5397
  const dataPath = path24.join(packageRoot, "_data.json");
5281
5398
  try {
5282
- const raw = await fs18.readFile(dataPath, "utf-8");
5399
+ const raw = await fs19.readFile(dataPath, "utf-8");
5283
5400
  data = JSON.parse(raw);
5284
5401
  } catch (err) {
5285
5402
  if (err.code !== "ENOENT") {
@@ -5293,7 +5410,7 @@ async function loadUiData(packageName) {
5293
5410
  // src/core/ui-installer.ts
5294
5411
  init_fs();
5295
5412
  import * as path25 from "path";
5296
- import * as fs19 from "fs/promises";
5413
+ import * as fs20 from "fs/promises";
5297
5414
  import { resolveUiEntryOrder } from "@teamix-evo/registry";
5298
5415
 
5299
5416
  // src/utils/transform-imports.ts
@@ -5377,10 +5494,10 @@ async function installUiEntries(options) {
5377
5494
  }
5378
5495
  const rootForEntry = entryPackageRoot?.get(entry.id) ?? packageRoot;
5379
5496
  const sourceAbs = path25.resolve(rootForEntry, file.source);
5380
- const raw = await fs19.readFile(sourceAbs, "utf-8");
5497
+ const raw = await fs20.readFile(sourceAbs, "utf-8");
5381
5498
  const transformed = rewriteImports(raw, aliases, { flatten });
5382
5499
  if (exists) {
5383
- const current = await fs19.readFile(targetAbs, "utf-8");
5500
+ const current = await fs20.readFile(targetAbs, "utf-8");
5384
5501
  if (current === transformed) {
5385
5502
  logger.info(` skip (identical): ${rel(projectRoot, targetAbs)}`);
5386
5503
  skipped++;
@@ -5538,7 +5655,7 @@ function mergeResources(prior, next) {
5538
5655
 
5539
5656
  // src/core/ui-adopt.ts
5540
5657
  import * as path26 from "path";
5541
- import * as fs20 from "fs/promises";
5658
+ import * as fs21 from "fs/promises";
5542
5659
  init_state();
5543
5660
  init_logger();
5544
5661
  var DEFAULT_UI_PACKAGE2 = "@teamix-evo/ui";
@@ -5578,7 +5695,7 @@ async function runUiAdopt(options) {
5578
5695
  const files = await listSourceFiles(root.abs);
5579
5696
  for (const abs of files) {
5580
5697
  const rel2 = toPosixRel(projectRoot, abs);
5581
- const content = await fs20.readFile(abs, "utf-8");
5698
+ const content = await fs21.readFile(abs, "utf-8");
5582
5699
  const fileType = classifyFile(abs, content);
5583
5700
  const id = inferEntryId(abs);
5584
5701
  if (fileType === "type") {
@@ -5659,7 +5776,7 @@ async function listSourceFiles(dir) {
5659
5776
  const current = stack.pop();
5660
5777
  let entries;
5661
5778
  try {
5662
- entries = await fs20.readdir(current, { withFileTypes: true });
5779
+ entries = await fs21.readdir(current, { withFileTypes: true });
5663
5780
  } catch (err) {
5664
5781
  if (err.code === "ENOENT") continue;
5665
5782
  throw err;
@@ -5714,7 +5831,7 @@ async function readUpstreamContent(packageRoot, entry, aliases) {
5714
5831
  const sourceAbs = path26.resolve(packageRoot, file.source);
5715
5832
  let raw;
5716
5833
  try {
5717
- raw = await fs20.readFile(sourceAbs, "utf-8");
5834
+ raw = await fs21.readFile(sourceAbs, "utf-8");
5718
5835
  } catch {
5719
5836
  return null;
5720
5837
  }
@@ -5767,16 +5884,16 @@ init_state();
5767
5884
  init_fs();
5768
5885
  init_logger();
5769
5886
  import * as path27 from "path";
5770
- import * as fs21 from "fs/promises";
5771
- import { createRequire as createRequire6 } from "module";
5887
+ import * as fs22 from "fs/promises";
5888
+ import { createRequire as createRequire5 } from "module";
5772
5889
  import {
5773
5890
  loadUiPackageManifest as loadUiPackageManifest2,
5774
5891
  loadVariantUiPackageManifest
5775
5892
  } from "@teamix-evo/registry";
5776
- var require7 = createRequire6(import.meta.url);
5893
+ var require6 = createRequire5(import.meta.url);
5777
5894
  var META_DIR = "meta";
5778
5895
  function resolvePackageRoot3(packageName) {
5779
- const pkgJsonPath = require7.resolve(`${packageName}/package.json`);
5896
+ const pkgJsonPath = require6.resolve(`${packageName}/package.json`);
5780
5897
  return path27.dirname(pkgJsonPath);
5781
5898
  }
5782
5899
  function getMetaDir(projectRoot, category) {
@@ -5811,7 +5928,7 @@ async function landManifestMeta(opts) {
5811
5928
  await ensureDir(metaDir);
5812
5929
  const manifestDest = path27.join(metaDir, "manifest.json");
5813
5930
  const manifestSrc = path27.join(packageRoot, "manifest.json");
5814
- await fs21.copyFile(manifestSrc, manifestDest);
5931
+ await fs22.copyFile(manifestSrc, manifestDest);
5815
5932
  logger.debug(`meta: copied manifest.json \u2192 ${manifestDest}`);
5816
5933
  let written = 0;
5817
5934
  let total = 0;
@@ -5821,7 +5938,7 @@ async function landManifestMeta(opts) {
5821
5938
  const srcPath = path27.join(packageRoot, entry.meta);
5822
5939
  const destPath = path27.join(metaDir, `${entry.id}.md`);
5823
5940
  try {
5824
- await fs21.copyFile(srcPath, destPath);
5941
+ await fs22.copyFile(srcPath, destPath);
5825
5942
  written++;
5826
5943
  logger.debug(`meta: ${entry.id} \u2192 ${destPath}`);
5827
5944
  } catch (err) {
@@ -6054,8 +6171,8 @@ import { Command as Command24 } from "commander";
6054
6171
  // src/core/ui-upgrade.ts
6055
6172
  init_state();
6056
6173
  import * as path30 from "path";
6057
- import * as fs23 from "fs/promises";
6058
- import { createRequire as createRequire7 } from "module";
6174
+ import * as fs24 from "fs/promises";
6175
+ import { createRequire as createRequire6 } from "module";
6059
6176
  import {
6060
6177
  loadUiPackageManifest as loadUiPackageManifest3,
6061
6178
  loadVariantUiPackageManifest as loadVariantUiPackageManifest2
@@ -6064,7 +6181,7 @@ import {
6064
6181
  // src/core/ui-upgrade-detector.ts
6065
6182
  init_fs();
6066
6183
  init_state();
6067
- import * as fs22 from "fs/promises";
6184
+ import * as fs23 from "fs/promises";
6068
6185
  import * as path28 from "path";
6069
6186
  var PACKAGE_NAME = {
6070
6187
  ui: "@teamix-evo/ui",
@@ -6125,14 +6242,14 @@ function extractIds(pkg) {
6125
6242
  }
6126
6243
  async function directoryExists(p2) {
6127
6244
  try {
6128
- const stat6 = await fs22.stat(p2);
6245
+ const stat6 = await fs23.stat(p2);
6129
6246
  return stat6.isDirectory();
6130
6247
  } catch {
6131
6248
  return false;
6132
6249
  }
6133
6250
  }
6134
6251
  async function listComponentIds(installDirAbs, layout = "flat") {
6135
- const entries = await fs22.readdir(installDirAbs, { withFileTypes: true });
6252
+ const entries = await fs23.readdir(installDirAbs, { withFileTypes: true });
6136
6253
  const ids = [];
6137
6254
  if (layout === "directory") {
6138
6255
  for (const e of entries) {
@@ -6683,7 +6800,7 @@ function extractDefaultParamList(src) {
6683
6800
  }
6684
6801
 
6685
6802
  // src/core/ui-upgrade.ts
6686
- var nodeRequire = createRequire7(import.meta.url);
6803
+ var nodeRequire = createRequire6(import.meta.url);
6687
6804
  function resolvePackageRoot4(packageName) {
6688
6805
  const pkgJsonPath = nodeRequire.resolve(`${packageName}/package.json`);
6689
6806
  return path30.dirname(pkgJsonPath);
@@ -6808,7 +6925,7 @@ async function buildStaging(args) {
6808
6925
  });
6809
6926
  }
6810
6927
  async function readPkgVersion(packageRoot) {
6811
- const raw = await fs23.readFile(
6928
+ const raw = await fs24.readFile(
6812
6929
  path30.join(packageRoot, "package.json"),
6813
6930
  "utf-8"
6814
6931
  );
@@ -6931,7 +7048,7 @@ import { Command as Command25 } from "commander";
6931
7048
 
6932
7049
  // src/core/ui-promote.ts
6933
7050
  init_fs();
6934
- import * as fs25 from "fs/promises";
7051
+ import * as fs26 from "fs/promises";
6935
7052
  import * as path32 from "path";
6936
7053
  init_logger();
6937
7054
  init_error();
@@ -6939,7 +7056,7 @@ init_state();
6939
7056
 
6940
7057
  // src/core/ui-promote-imports.ts
6941
7058
  init_fs();
6942
- import * as fs24 from "fs/promises";
7059
+ import * as fs25 from "fs/promises";
6943
7060
  import * as path31 from "path";
6944
7061
  var SOURCE_FILE_EXT = /\.(tsx?|jsx?|mts|cts)$/;
6945
7062
  var STATIC_IMPORT_FROM = /^(\s*(?:import|export)\s[\s\S]*?from\s+['"])([^'"\n]+)(['"])/;
@@ -7046,7 +7163,7 @@ async function collectTsFiles(root) {
7046
7163
  async function walk(dir) {
7047
7164
  let entries;
7048
7165
  try {
7049
- entries = await fs24.readdir(dir, { withFileTypes: true });
7166
+ entries = await fs25.readdir(dir, { withFileTypes: true });
7050
7167
  } catch (err) {
7051
7168
  if (err.code === "ENOENT") return;
7052
7169
  throw err;
@@ -7451,7 +7568,7 @@ async function findLatestUiStagingDir(projectRoot) {
7451
7568
  const base = path32.join(projectRoot, TEAMIX_DIR5, STAGING_DIR2);
7452
7569
  let entries;
7453
7570
  try {
7454
- entries = await fs25.readdir(base, { withFileTypes: true });
7571
+ entries = await fs26.readdir(base, { withFileTypes: true });
7455
7572
  } catch (err) {
7456
7573
  if (err.code === "ENOENT") return null;
7457
7574
  throw err;
@@ -7548,7 +7665,7 @@ function posix2(p2) {
7548
7665
  }
7549
7666
 
7550
7667
  // src/core/file-changes.ts
7551
- import * as fs26 from "fs/promises";
7668
+ import * as fs27 from "fs/promises";
7552
7669
  import * as path33 from "path";
7553
7670
  function toRelativePosix(p2, projectRoot) {
7554
7671
  let rel2 = p2;
@@ -7740,17 +7857,17 @@ import { Command as Command27 } from "commander";
7740
7857
 
7741
7858
  // src/core/variant-ui-add.ts
7742
7859
  import * as path34 from "path";
7743
- import * as fs27 from "fs/promises";
7744
- import { createRequire as createRequire8 } from "module";
7860
+ import * as fs28 from "fs/promises";
7861
+ import { createRequire as createRequire7 } from "module";
7745
7862
  import {
7746
7863
  loadUiPackageManifest as loadUiPackageManifest4,
7747
7864
  loadVariantUiPackageCatalog,
7748
7865
  loadVariantUiPackageManifest as loadVariantUiPackageManifest3
7749
7866
  } from "@teamix-evo/registry";
7750
7867
  init_state();
7751
- var require8 = createRequire8(import.meta.url);
7868
+ var require7 = createRequire7(import.meta.url);
7752
7869
  function resolvePackageRoot5(packageName) {
7753
- const pkgJsonPath = require8.resolve(`${packageName}/package.json`);
7870
+ const pkgJsonPath = require7.resolve(`${packageName}/package.json`);
7754
7871
  return path34.dirname(pkgJsonPath);
7755
7872
  }
7756
7873
  async function runVariantUiAdd(packageName, options) {
@@ -7777,7 +7894,7 @@ async function runVariantUiAdd(packageName, options) {
7777
7894
  const variantDir = path34.join(packageRoot, "variants", variant);
7778
7895
  const variantManifest = await loadVariantUiPackageManifest3(variantDir);
7779
7896
  const pkgJson = JSON.parse(
7780
- await fs27.readFile(path34.join(packageRoot, "package.json"), "utf-8")
7897
+ await fs28.readFile(path34.join(packageRoot, "package.json"), "utf-8")
7781
7898
  );
7782
7899
  const packageVersion = pkgJson.version;
7783
7900
  const knownIds = new Set(variantManifest.entries.map((e) => e.id));
@@ -8237,9 +8354,18 @@ import * as prompts6 from "@clack/prompts";
8237
8354
  init_fs();
8238
8355
  init_logger();
8239
8356
  import * as path35 from "path";
8240
- import * as fs28 from "fs";
8357
+ import * as fs29 from "fs";
8241
8358
  import { execa } from "execa";
8242
- var ESLINT_CONFIG_CONTENT = `/**
8359
+ function renderEslintConfig(tailwindCssConfigPath) {
8360
+ const tailwindSettings = tailwindCssConfigPath ? `
8361
+ {
8362
+ settings: {
8363
+ tailwindcss: {
8364
+ cssConfigPath: '${tailwindCssConfigPath}',
8365
+ },
8366
+ },
8367
+ },` : "";
8368
+ return `/**
8243
8369
  * teamix-evo consumer ESLint preset \u2014 9 token-discipline rules.
8244
8370
  * - Repo-wide: no-color-literal / no-arbitrary-tw-value / no-raw-color-scale /
8245
8371
  * no-large-radius / prefer-gap-over-space / no-manual-dark-classnames /
@@ -8250,8 +8376,30 @@ var ESLINT_CONFIG_CONTENT = `/**
8250
8376
  */
8251
8377
  import consumerPreset from '@teamix-evo/eslint-config/presets/consumer';
8252
8378
 
8253
- export default [...consumerPreset];
8379
+ export default [
8380
+ ...consumerPreset,${tailwindSettings}
8381
+ ];
8254
8382
  `;
8383
+ }
8384
+ var TAILWIND_CSS_CANDIDATES = [
8385
+ "src/index.css",
8386
+ "src/globals.css",
8387
+ "src/app/globals.css",
8388
+ "app/globals.css",
8389
+ "styles/globals.css",
8390
+ "src/styles/tailwind.css"
8391
+ ];
8392
+ async function detectTailwindCssConfigPath(projectRoot) {
8393
+ for (const candidate of TAILWIND_CSS_CANDIDATES) {
8394
+ const content = await readFileOrNull(path35.join(projectRoot, candidate));
8395
+ if (content && /@(?:import\s+['"]tailwindcss(?:\/[^'"]*)?['"]|theme\b|tailwind\b)/.test(
8396
+ content
8397
+ )) {
8398
+ return `./${candidate}`;
8399
+ }
8400
+ }
8401
+ return null;
8402
+ }
8255
8403
  var STYLELINT_CONFIG_CONTENT = `/** @type {import('stylelint').Config} */
8256
8404
  module.exports = {
8257
8405
  extends: ['@teamix-evo/stylelint-config/presets/consumer'],
@@ -8316,7 +8464,13 @@ async function runLintInit(options) {
8316
8464
  let wroteEslint = false;
8317
8465
  let wroteStylelint = false;
8318
8466
  if (eslintNeedsWrite) {
8319
- await writeFileSafe(eslintConfigPath, ESLINT_CONFIG_CONTENT);
8467
+ const tailwindCssConfigPath = await detectTailwindCssConfigPath(
8468
+ projectRoot
8469
+ );
8470
+ await writeFileSafe(
8471
+ eslintConfigPath,
8472
+ renderEslintConfig(tailwindCssConfigPath)
8473
+ );
8320
8474
  logger.debug(`Wrote eslint.config.js \u2192 ${eslintConfigPath}`);
8321
8475
  wroteEslint = true;
8322
8476
  }
@@ -8329,7 +8483,7 @@ async function runLintInit(options) {
8329
8483
  let stylelintIgnoreFilesWarning = false;
8330
8484
  if (!stylelintNeedsWrite && stylelintTemplateExists) {
8331
8485
  try {
8332
- const existingContent = fs28.readFileSync(stylelintConfigPath, "utf-8");
8486
+ const existingContent = fs29.readFileSync(stylelintConfigPath, "utf-8");
8333
8487
  const usesTeamixPreset = existingContent.includes("@teamix-evo/stylelint-config/presets/") || existingContent.includes("@teamix-evo/stylelint-config/preset/");
8334
8488
  const hasTokenIgnore = existingContent.includes("tokens.theme.css") && existingContent.includes("tokens.overrides.css");
8335
8489
  if (!usesTeamixPreset && !hasTokenIgnore) {
@@ -8366,8 +8520,8 @@ async function runLintInit(options) {
8366
8520
  };
8367
8521
  }
8368
8522
  function detectPm(projectRoot) {
8369
- if (fs28.existsSync(path35.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
8370
- if (fs28.existsSync(path35.join(projectRoot, "yarn.lock"))) return "yarn";
8523
+ if (fs29.existsSync(path35.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
8524
+ if (fs29.existsSync(path35.join(projectRoot, "yarn.lock"))) return "yarn";
8371
8525
  return "npm";
8372
8526
  }
8373
8527
  async function patchPackageJsonScripts(projectRoot) {
@@ -8458,12 +8612,13 @@ lintCommand.addCommand(initCommand4);
8458
8612
  // src/commands/init/index.ts
8459
8613
  import { Command as Command36 } from "commander";
8460
8614
  import * as path39 from "path";
8615
+ import { realpath } from "fs/promises";
8461
8616
  import { execa as execa2 } from "execa";
8462
8617
 
8463
8618
  // src/core/project-state.ts
8464
8619
  init_fs();
8465
8620
  init_state();
8466
- import * as fs29 from "fs/promises";
8621
+ import * as fs30 from "fs/promises";
8467
8622
  import * as path36 from "path";
8468
8623
  var IGNORED_TOP_LEVEL = /* @__PURE__ */ new Set([
8469
8624
  ".git",
@@ -8476,6 +8631,7 @@ var IGNORED_TOP_LEVEL = /* @__PURE__ */ new Set([
8476
8631
  ".vscode",
8477
8632
  ".qoder",
8478
8633
  ".claude",
8634
+ ".agents",
8479
8635
  "README.md",
8480
8636
  "README",
8481
8637
  "README.txt",
@@ -8524,7 +8680,7 @@ async function detectProjectState(cwd) {
8524
8680
  }
8525
8681
  let entries;
8526
8682
  try {
8527
- entries = await fs29.readdir(absCwd);
8683
+ entries = await fs30.readdir(absCwd);
8528
8684
  } catch (err) {
8529
8685
  if (err.code === "ENOENT") {
8530
8686
  return {
@@ -8646,7 +8802,7 @@ function assertCommandPrecondition(command, state, options) {
8646
8802
  // src/core/deps-install.ts
8647
8803
  init_fs();
8648
8804
  init_logger();
8649
- import * as fs30 from "fs/promises";
8805
+ import * as fs31 from "fs/promises";
8650
8806
  import * as path37 from "path";
8651
8807
  import { exec as exec4 } from "child_process";
8652
8808
  import { promisify as promisify4 } from "util";
@@ -8703,7 +8859,7 @@ async function installProjectDeps(options) {
8703
8859
  pkg.dependencies = Object.fromEntries(
8704
8860
  Object.entries(pkg.dependencies).sort(([a], [b]) => a.localeCompare(b))
8705
8861
  );
8706
- await fs30.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
8862
+ await fs31.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
8707
8863
  logger.info(
8708
8864
  ` patched package.json: +${Object.keys(added).length} dependencies`
8709
8865
  );
@@ -8890,9 +9046,9 @@ async function runProjectInit(options) {
8890
9046
  name: "skills",
8891
9047
  status: "ok",
8892
9048
  detail: `${result.skillCount} skills, ${result.fileCount} files (added: ${result.addedSkillIds.join(", ") || "none"})`,
8893
- changes: result.addedSkillIds.map((id) => ({
9049
+ changes: result.resources.map((resource) => ({
8894
9050
  kind: "created",
8895
- path: `.${ides[0] ?? "qoder"}/skills/${id}/SKILL.md`,
9051
+ path: resource.target,
8896
9052
  step: "skills",
8897
9053
  detail: "skill installed"
8898
9054
  }))
@@ -9297,7 +9453,7 @@ async function runInitWizard(options) {
9297
9453
  message: "\u6CE8\u5165\u6280\u80FD\u7684 AI IDE\uFF08\u81F3\u5C11\u4E00\u4E2A\uFF09",
9298
9454
  options: ALL_IDE_KINDS.map((k) => ({
9299
9455
  value: k,
9300
- label: k === "qoder" ? "Qoder" : "Claude Code"
9456
+ label: getIdeDisplayName(k)
9301
9457
  })),
9302
9458
  initialValues: [...ALL_IDE_KINDS],
9303
9459
  required: true
@@ -9415,7 +9571,9 @@ var initCommand5 = new Command36("init").description("\u521D\u59CB\u5316 Teamix
9415
9571
  }
9416
9572
  }
9417
9573
  if (result.status === "installed") {
9418
- await autoCommitAfterInit(cwd);
9574
+ if (shouldAutoCommitAfterInit(state.state, opts.git)) {
9575
+ await autoCommitAfterInit(cwd);
9576
+ }
9419
9577
  logger.info("");
9420
9578
  logger.info("Next steps:");
9421
9579
  logger.info(" \u2022 \u542F\u52A8 dev server \u9A8C\u8BC1\uFF1A`npm run dev`");
@@ -9449,11 +9607,11 @@ async function runScaffoldPhase(cwd, variant, opts) {
9449
9607
  projectName: path39.basename(cwd)
9450
9608
  });
9451
9609
  if (pm === "pnpm") {
9452
- const fs33 = await import("fs/promises");
9610
+ const fs34 = await import("fs/promises");
9453
9611
  const pkgPath = path39.join(cwd, "package.json");
9454
- const pkg = JSON.parse(await fs33.readFile(pkgPath, "utf-8"));
9612
+ const pkg = JSON.parse(await fs34.readFile(pkgPath, "utf-8"));
9455
9613
  pkg.packageManager = `pnpm@${PACKAGE_VERSIONS.pnpm}`;
9456
- await fs33.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
9614
+ await fs34.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
9457
9615
  }
9458
9616
  logger.info(
9459
9617
  ` \u2714 \u6A21\u677F ${result.preset.displayName}\uFF08variant: ${result.variant}\uFF09`
@@ -9478,12 +9636,27 @@ async function runScaffoldPhase(cwd, variant, opts) {
9478
9636
  }
9479
9637
  logger.info("");
9480
9638
  }
9639
+ function shouldAutoCommitAfterInit(initialState, gitEnabled) {
9640
+ return initialState === "empty" && gitEnabled !== false;
9641
+ }
9481
9642
  async function autoCommitAfterInit(cwd) {
9643
+ let gitTopLevel;
9644
+ let canonicalCwd;
9482
9645
  try {
9483
- await execa2("git", ["rev-parse", "--is-inside-work-tree"], { cwd });
9646
+ const result = await execa2("git", ["rev-parse", "--show-toplevel"], { cwd });
9647
+ [gitTopLevel, canonicalCwd] = await Promise.all([
9648
+ realpath(result.stdout.trim()),
9649
+ realpath(cwd)
9650
+ ]);
9484
9651
  } catch {
9485
9652
  return;
9486
9653
  }
9654
+ if (gitTopLevel !== canonicalCwd) {
9655
+ logger.warn(
9656
+ "\u8DF3\u8FC7\u81EA\u52A8\u63D0\u4EA4\uFF1A\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u72EC\u7ACB Git \u4ED3\u5E93\uFF0C\u907F\u514D\u8BEF\u63D0\u4EA4\u7236\u4ED3\u5E93\u5185\u5BB9\u3002"
9657
+ );
9658
+ return;
9659
+ }
9487
9660
  try {
9488
9661
  await execa2("git", ["add", "."], { cwd });
9489
9662
  await execa2(
@@ -9491,8 +9664,23 @@ async function autoCommitAfterInit(cwd) {
9491
9664
  ["commit", "-m", "chore: init teamix-evo", "--allow-empty"],
9492
9665
  { cwd }
9493
9666
  );
9667
+ const { stdout: worktreeStatus } = await execa2(
9668
+ "git",
9669
+ ["status", "--porcelain", "--untracked-files=all"],
9670
+ { cwd }
9671
+ );
9494
9672
  logger.info("");
9495
- logger.success("\u5DF2\u81EA\u52A8\u63D0\u4EA4 init \u4EA7\u7269\uFF1Achore: init teamix-evo");
9673
+ if (worktreeStatus.trim()) {
9674
+ logger.warn("init \u5DF2\u81EA\u52A8\u63D0\u4EA4\uFF0C\u4F46\u5DE5\u4F5C\u533A\u4ECD\u6709\u672A\u63D0\u4EA4\u5185\u5BB9\uFF1A");
9675
+ for (const line of worktreeStatus.trim().split("\n")) {
9676
+ logger.warn(` ${line}`);
9677
+ }
9678
+ logger.warn("\u8BF7\u5904\u7406\u4E0A\u8FF0\u6587\u4EF6\u540E\u518D\u6B21\u786E\u8BA4 `git status --short` \u4E3A\u7A7A\u3002");
9679
+ } else {
9680
+ logger.success(
9681
+ "\u5DF2\u81EA\u52A8\u63D0\u4EA4 init \u4EA7\u7269\uFF1Achore: init teamix-evo\uFF08\u5DE5\u4F5C\u533A\u5E72\u51C0\uFF09"
9682
+ );
9683
+ }
9496
9684
  } catch (err) {
9497
9685
  logger.warn(
9498
9686
  `\u81EA\u52A8\u63D0\u4EA4\u5931\u8D25\uFF08\u975E\u5173\u952E\uFF09\uFF1A${err instanceof Error ? err.message : String(err)}`
@@ -9700,7 +9888,7 @@ var migrateCommand = new Command38("migrate").description(
9700
9888
  // src/commands/graft/index.ts
9701
9889
  import { Command as Command39 } from "commander";
9702
9890
  import * as path45 from "path";
9703
- import * as fs32 from "fs/promises";
9891
+ import * as fs33 from "fs/promises";
9704
9892
  import * as prompts7 from "@clack/prompts";
9705
9893
 
9706
9894
  // src/core/graft-init.ts
@@ -9709,7 +9897,7 @@ init_state();
9709
9897
 
9710
9898
  // src/core/snapshot.ts
9711
9899
  init_logger();
9712
- import * as fs31 from "fs/promises";
9900
+ import * as fs32 from "fs/promises";
9713
9901
  import * as path43 from "path";
9714
9902
  var TEAMIX_DIR6 = ".teamix-evo";
9715
9903
  var SNAPSHOTS_DIR = ".snapshots";
@@ -9728,7 +9916,7 @@ function fsSafeToIso(safe) {
9728
9916
  async function createSnapshot(projectRoot, opts = {}) {
9729
9917
  const teamixDir = path43.join(projectRoot, TEAMIX_DIR6);
9730
9918
  try {
9731
- const stat6 = await fs31.stat(teamixDir);
9919
+ const stat6 = await fs32.stat(teamixDir);
9732
9920
  if (!stat6.isDirectory()) return null;
9733
9921
  } catch (err) {
9734
9922
  if (err.code === "ENOENT") return null;
@@ -9738,19 +9926,19 @@ async function createSnapshot(projectRoot, opts = {}) {
9738
9926
  const ts = isoToFsSafe3(isoTs);
9739
9927
  const snapshotRoot = path43.join(teamixDir, SNAPSHOTS_DIR);
9740
9928
  const target = path43.join(snapshotRoot, ts);
9741
- await fs31.mkdir(target, { recursive: true });
9742
- const entries = await fs31.readdir(teamixDir, { withFileTypes: true });
9929
+ await fs32.mkdir(target, { recursive: true });
9930
+ const entries = await fs32.readdir(teamixDir, { withFileTypes: true });
9743
9931
  for (const entry of entries) {
9744
9932
  if (entry.name === SNAPSHOTS_DIR) continue;
9745
9933
  const src = path43.join(teamixDir, entry.name);
9746
9934
  const dst = path43.join(target, entry.name);
9747
- await fs31.cp(src, dst, { recursive: true });
9935
+ await fs32.cp(src, dst, { recursive: true });
9748
9936
  }
9749
9937
  const meta = {
9750
9938
  ts: isoTs,
9751
9939
  reason: opts.reason ?? "manual"
9752
9940
  };
9753
- await fs31.writeFile(
9941
+ await fs32.writeFile(
9754
9942
  path43.join(target, META_FILE),
9755
9943
  JSON.stringify(meta, null, 2) + "\n",
9756
9944
  "utf-8"
@@ -9766,7 +9954,7 @@ async function listSnapshots(projectRoot) {
9766
9954
  const snapshotRoot = path43.join(projectRoot, TEAMIX_DIR6, SNAPSHOTS_DIR);
9767
9955
  let entries;
9768
9956
  try {
9769
- entries = await fs31.readdir(snapshotRoot, { withFileTypes: true });
9957
+ entries = await fs32.readdir(snapshotRoot, { withFileTypes: true });
9770
9958
  } catch (err) {
9771
9959
  if (err.code === "ENOENT") return [];
9772
9960
  throw err;
@@ -9778,7 +9966,7 @@ async function listSnapshots(projectRoot) {
9778
9966
  let isoTs = null;
9779
9967
  let reason = null;
9780
9968
  try {
9781
- const raw = await fs31.readFile(path43.join(dir, META_FILE), "utf-8");
9969
+ const raw = await fs32.readFile(path43.join(dir, META_FILE), "utf-8");
9782
9970
  const parsed = JSON.parse(raw);
9783
9971
  if (typeof parsed.ts === "string") isoTs = parsed.ts;
9784
9972
  if (typeof parsed.reason === "string" && SNAPSHOT_REASONS.includes(
@@ -9803,7 +9991,7 @@ async function pruneSnapshots(projectRoot, keep = DEFAULT_KEEP, opts = {}) {
9803
9991
  const toRemove = opts.protectedTs ? tail.filter((s) => s.ts !== opts.protectedTs) : tail;
9804
9992
  const removed = [];
9805
9993
  for (const snap of toRemove) {
9806
- await fs31.rm(snap.path, { recursive: true, force: true });
9994
+ await fs32.rm(snap.path, { recursive: true, force: true });
9807
9995
  removed.push(snap.ts);
9808
9996
  logger.debug(`Pruned snapshot ${snap.ts}`);
9809
9997
  }
@@ -9854,7 +10042,7 @@ async function runGraftInit(options) {
9854
10042
  onStep
9855
10043
  } = options;
9856
10044
  const ide = options.ide ?? "qoder";
9857
- const ides = options.ides ?? ["qoder", "claude"];
10045
+ const ides = options.ides ?? [...ALL_IDE_KINDS];
9858
10046
  const scope = options.scope ?? "project";
9859
10047
  const steps = [];
9860
10048
  let aborted = false;
@@ -10198,7 +10386,7 @@ async function detectConflicts(cwd) {
10198
10386
  for (const entry of CONFLICT_PATHS) {
10199
10387
  const full = path45.join(cwd, entry.path);
10200
10388
  try {
10201
- const stat6 = await fs32.stat(full);
10389
+ const stat6 = await fs33.stat(full);
10202
10390
  if (entry.type === "directory" && stat6.isDirectory() || entry.type === "file" && stat6.isFile()) {
10203
10391
  conflicts.push(entry);
10204
10392
  }
@@ -10366,8 +10554,8 @@ function createSwitchCommand() {
10366
10554
  var switchCommand = createSwitchCommand();
10367
10555
 
10368
10556
  // src/index.ts
10369
- var require9 = createRequire9(import.meta.url);
10370
- var { version } = require9("../package.json");
10557
+ var require8 = createRequire8(import.meta.url);
10558
+ var { version } = require8("../package.json");
10371
10559
  var program = new Command42();
10372
10560
  program.name("teamix-evo").description("Where ideas evolve. \u2014 AI Coding \u5957\u4EF6").version(version);
10373
10561
  program.addCommand(tokensCommand);