teamix-evo 0.6.1 → 0.7.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/dist/index.js CHANGED
@@ -467,7 +467,7 @@ async function writeMirrorContent(targetFile, sourceContent, managedRegions, sou
467
467
  if (matchedRegions.length === 0) {
468
468
  if (existing !== sourceContent) {
469
469
  logger.warn(
470
- `Mirror drift detected at ${targetFile} \u2014 overwriting from source. Edit ${sourceFile} (not the mirror) and re-run \`teamix-evo skills sync\`.`
470
+ `Mirror drift detected at ${targetFile} \u2014 overwriting from source. Edit ${sourceFile} (not the mirror) and re-run \`npx teamix-evo@latest skills sync\`.`
471
471
  );
472
472
  await writeFileSafe(targetFile, sourceContent);
473
473
  return sourceContent;
@@ -569,34 +569,56 @@ async function rewriteSkillSource(skill, options, summary) {
569
569
  if (skill.template && targetFile2.endsWith(".hbs")) {
570
570
  targetFile2 = targetFile2.slice(0, -4);
571
571
  }
572
- const content = skill.template && entry.endsWith(".hbs") ? renderTemplate(await loadTemplateFile(entry), { ...data, skill }) : await fs5.readFile(entry, "utf-8");
572
+ const newContent2 = skill.template && entry.endsWith(".hbs") ? renderTemplate(await loadTemplateFile(entry), { ...data, skill }) : await fs5.readFile(entry, "utf-8");
573
573
  const exists2 = await fileExists(targetFile2);
574
- if (exists2) {
575
- await backupFile(targetFile2, projectRoot);
576
- summary.overwritten++;
577
- } else {
578
- summary.created++;
579
- }
580
- await writeFileSafe(targetFile2, content);
574
+ const written2 = await rewriteSingleFile({
575
+ targetFile: targetFile2,
576
+ newContent: newContent2,
577
+ exists: exists2,
578
+ updateStrategy: skill.updateStrategy,
579
+ managedRegions: skill.managedRegions,
580
+ projectRoot,
581
+ summary
582
+ });
581
583
  const relWritten = path7.relative(targetDir, targetFile2);
582
- records.push(makeSourceRecord(skill, targetFile2, content, relWritten));
584
+ records.push(makeSourceRecord(skill, targetFile2, written2, relWritten));
583
585
  }
584
586
  return records;
585
587
  }
586
588
  const targetFile = path7.join(targetDir, "SKILL.md");
587
589
  const newContent = await renderSkillContent(sourceAbs, skill, data);
588
590
  const exists = await fileExists(targetFile);
589
- if (skill.updateStrategy === "frozen") {
591
+ const written = await rewriteSingleFile({
592
+ targetFile,
593
+ newContent,
594
+ exists,
595
+ updateStrategy: skill.updateStrategy,
596
+ managedRegions: skill.managedRegions,
597
+ projectRoot,
598
+ summary
599
+ });
600
+ return [makeSourceRecord(skill, targetFile, written)];
601
+ }
602
+ async function rewriteSingleFile(args) {
603
+ const {
604
+ targetFile,
605
+ newContent,
606
+ exists,
607
+ updateStrategy,
608
+ managedRegions,
609
+ projectRoot,
610
+ summary
611
+ } = args;
612
+ if (updateStrategy === "frozen") {
590
613
  if (exists) {
591
614
  summary.skipped++;
592
- const current2 = await readFileOrNull(targetFile) ?? newContent;
593
- return [makeSourceRecord(skill, targetFile, current2)];
615
+ return await readFileOrNull(targetFile) ?? newContent;
594
616
  }
595
617
  await writeFileSafe(targetFile, newContent);
596
618
  summary.created++;
597
- return [makeSourceRecord(skill, targetFile, newContent)];
619
+ return newContent;
598
620
  }
599
- if (skill.updateStrategy === "regenerable" || !exists) {
621
+ if (updateStrategy === "regenerable" || !exists) {
600
622
  if (exists) {
601
623
  await backupFile(targetFile, projectRoot);
602
624
  summary.overwritten++;
@@ -604,11 +626,11 @@ async function rewriteSkillSource(skill, options, summary) {
604
626
  summary.created++;
605
627
  }
606
628
  await writeFileSafe(targetFile, newContent);
607
- return [makeSourceRecord(skill, targetFile, newContent)];
629
+ return newContent;
608
630
  }
609
631
  const current = await readFileOrNull(targetFile);
610
632
  let merged = current ?? newContent;
611
- for (const regionId of skill.managedRegions ?? []) {
633
+ for (const regionId of managedRegions ?? []) {
612
634
  const re = new RegExp(
613
635
  `<!-- teamix-evo:managed:start id="${escapeRegExp(
614
636
  regionId
@@ -628,10 +650,12 @@ async function rewriteSkillSource(skill, options, summary) {
628
650
  }
629
651
  }
630
652
  }
631
- await backupFile(targetFile, projectRoot);
632
- await writeFileSafe(targetFile, merged);
653
+ if (merged !== current) {
654
+ await backupFile(targetFile, projectRoot);
655
+ await writeFileSafe(targetFile, merged);
656
+ }
633
657
  summary.managed++;
634
- return [makeSourceRecord(skill, targetFile, merged)];
658
+ return merged;
635
659
  }
636
660
  function escapeRegExp(str) {
637
661
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -996,7 +1020,7 @@ async function runTokensInit(options) {
996
1020
  const known = catalog.variants.map((v) => v.name).join(", ");
997
1021
  throw new Error(
998
1022
  `Unknown variant "${variant}". Available variants: ${known || "(none)"}.
999
- Run \`teamix-evo tokens list-variants\` to see all options.`
1023
+ Run \`npx teamix-evo@latest tokens list-variants\` to see all options.`
1000
1024
  );
1001
1025
  }
1002
1026
  const existingConfig = await readProjectConfig(projectRoot);
@@ -1264,7 +1288,8 @@ var initCommand = new Command("init").description("\u521D\u59CB\u5316\u8BBE\u8BA
1264
1288
  logger.error(
1265
1289
  "No package.json found in current directory. Please run this command in a valid project root."
1266
1290
  );
1267
- process.exit(1);
1291
+ process.exitCode = 1;
1292
+ return;
1268
1293
  }
1269
1294
  logger.info(`Initializing design system: variant="${variant}"`);
1270
1295
  logger.debug(`Project root: ${projectRoot}`);
@@ -1278,7 +1303,7 @@ var initCommand = new Command("init").description("\u521D\u59CB\u5316\u8BBE\u8BA
1278
1303
  });
1279
1304
  if (result.status === "already-initialized") {
1280
1305
  logger.info(
1281
- `Design system already initialized (variant: ${result.existingVariant}). Use "teamix-evo tokens update" to refresh resources.`
1306
+ `Design system already initialized (variant: ${result.existingVariant}). Use "npx teamix-evo@latest tokens update" to refresh resources.`
1282
1307
  );
1283
1308
  return;
1284
1309
  }
@@ -1287,8 +1312,8 @@ var initCommand = new Command("init").description("\u521D\u59CB\u5316\u8BBE\u8BA
1287
1312
  `Cannot switch tokens variant in place. Currently installed: "${result.existingVariant}"; requested: "${result.requestedVariant}".`
1288
1313
  );
1289
1314
  logger.info("To switch variants:");
1290
- logger.info(" 1. teamix-evo tokens uninstall --yes");
1291
- logger.info(` 2. teamix-evo tokens init ${result.requestedVariant}`);
1315
+ logger.info(" 1. npx teamix-evo@latest tokens uninstall --yes");
1316
+ logger.info(` 2. npx teamix-evo@latest tokens init ${result.requestedVariant}`);
1292
1317
  logger.info(
1293
1318
  "Note: tokens.overrides.css (frozen) is preserved across uninstall/init by default."
1294
1319
  );
@@ -1320,9 +1345,9 @@ var initCommand = new Command("init").description("\u521D\u59CB\u5316\u8BBE\u8BA
1320
1345
  }
1321
1346
  }
1322
1347
  logger.info("");
1323
- logger.info('Run "teamix-evo tokens update" to update resources later.');
1348
+ logger.info('Run "npx teamix-evo@latest tokens update" to update resources later.');
1324
1349
  logger.info(
1325
- 'Run "teamix-evo tokens list-variants" to see all available variants.'
1350
+ 'Run "npx teamix-evo@latest tokens list-variants" to see all available variants.'
1326
1351
  );
1327
1352
  } catch (err) {
1328
1353
  logger.error(`Failed to initialize: ${err.message}`);
@@ -1360,7 +1385,7 @@ async function runTokensUpdate(options) {
1360
1385
  const variantEntry = getVariantEntry2(catalog, currentVariant);
1361
1386
  if (!variantEntry) {
1362
1387
  throw new Error(
1363
- `Currently installed variant "${currentVariant}" no longer exists in ${packageName}@${catalog.version}. Available: ${catalog.variants.map((v) => v.name).join(", ")}. Run \`teamix-evo tokens uninstall\` then \`teamix-evo tokens init <variant>\` to switch.`
1388
+ `Currently installed variant "${currentVariant}" no longer exists in ${packageName}@${catalog.version}. Available: ${catalog.variants.map((v) => v.name).join(", ")}. Run \`npx teamix-evo@latest tokens uninstall\` then \`npx teamix-evo@latest tokens init <variant>\` to switch.`
1364
1389
  );
1365
1390
  }
1366
1391
  if (variantEntry.version === currentVersion) {
@@ -1462,7 +1487,7 @@ var updateCommand = new Command2("update").description(
1462
1487
  const result = await runTokensUpdate({ projectRoot });
1463
1488
  if (result.status === "not-initialized") {
1464
1489
  logger.error(
1465
- "No tokens variant installed. Run `teamix-evo tokens init <variant>` first."
1490
+ "No tokens variant installed. Run `npx teamix-evo@latest tokens init <variant>` first."
1466
1491
  );
1467
1492
  process.exitCode = 1;
1468
1493
  return;
@@ -1503,7 +1528,7 @@ var listCommand = new Command3("list").description("\u5217\u51FA\u5DF2\u5B89\u88
1503
1528
  const config = await readProjectConfig(projectRoot);
1504
1529
  if (!config?.packages?.tokens) {
1505
1530
  logger.info("No tokens variant installed.");
1506
- logger.info('Run "teamix-evo tokens init [variant]" to get started.');
1531
+ logger.info('Run "npx teamix-evo@latest tokens init [variant]" to get started.');
1507
1532
  return;
1508
1533
  }
1509
1534
  const { variant, version: version2 } = config.packages.tokens;
@@ -1555,7 +1580,7 @@ var listVariantsCommand = new Command4("list-variants").description("\u5217\u51F
1555
1580
  }
1556
1581
  logger.info("");
1557
1582
  }
1558
- logger.info("Install a variant: teamix-evo tokens init <name>");
1583
+ logger.info("Install a variant: npx teamix-evo@latest tokens init <name>");
1559
1584
  } catch (err) {
1560
1585
  logger.error(`Failed to list variants: ${err.message}`);
1561
1586
  logger.debug(err.stack ?? "");
@@ -1669,6 +1694,29 @@ import { Command as Command14 } from "commander";
1669
1694
  // src/commands/skills/init.ts
1670
1695
  import { Command as Command7 } from "commander";
1671
1696
  import * as prompts2 from "@clack/prompts";
1697
+
1698
+ // src/commands/skills/_parse.ts
1699
+ function parseIdeList(input) {
1700
+ const parts = input.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
1701
+ const result = [];
1702
+ for (const p of parts) {
1703
+ if (p === "qoder" || p === "claude") {
1704
+ if (!result.includes(p)) result.push(p);
1705
+ } else {
1706
+ throw new Error(
1707
+ `Unknown IDE: "${p}". Expected one of: ${ALL_IDE_KINDS.join(", ")}.`
1708
+ );
1709
+ }
1710
+ }
1711
+ return result;
1712
+ }
1713
+ function parseScope(input) {
1714
+ const v = (input ?? "project").toLowerCase();
1715
+ if (v === "project" || v === "global") return v;
1716
+ throw new Error(`Invalid --scope: "${input}". Expected project | global.`);
1717
+ }
1718
+
1719
+ // src/commands/skills/init.ts
1672
1720
  var initCommand2 = new Command7("init").description(
1673
1721
  "\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"
1674
1722
  ).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) => {
@@ -1684,7 +1732,8 @@ var initCommand2 = new Command7("init").description(
1684
1732
  logger.error(
1685
1733
  "No package.json found in current directory. Please run this command in a valid project root."
1686
1734
  );
1687
- process.exit(1);
1735
+ process.exitCode = 1;
1736
+ return;
1688
1737
  }
1689
1738
  logger.info(
1690
1739
  `Initializing skills (bulk): ides=[${ides.join(",")}], scope="${scope}"`
@@ -1698,7 +1747,7 @@ var initCommand2 = new Command7("init").description(
1698
1747
  });
1699
1748
  if (result.status === "already-initialized") {
1700
1749
  logger.warn(
1701
- `Skills already initialized. Use "teamix-evo skills add <name>" to add specific skills, "teamix-evo skills update" to refresh, or "teamix-evo skills uninstall" to remove.`
1750
+ `Skills already initialized. Use "npx teamix-evo@latest skills add <name>" to add specific skills, "npx teamix-evo@latest skills update" to refresh, or "npx teamix-evo@latest skills uninstall" to remove.`
1702
1751
  );
1703
1752
  return;
1704
1753
  }
@@ -1715,7 +1764,7 @@ var initCommand2 = new Command7("init").description(
1715
1764
  }
1716
1765
  logger.info(` Files: ${result.fileCount}`);
1717
1766
  logger.info("");
1718
- logger.info('Run "teamix-evo skills list" to see installed skills.');
1767
+ logger.info('Run "npx teamix-evo@latest skills list" to see installed skills.');
1719
1768
  } catch (err) {
1720
1769
  logger.error(`Failed to init skills: ${err.message}`);
1721
1770
  logger.debug(err.stack ?? "");
@@ -1758,23 +1807,6 @@ async function resolveIdesAndScope(args) {
1758
1807
  }
1759
1808
  return { ides: idesAns, scope: scopeAns };
1760
1809
  }
1761
- function parseIdeList(input) {
1762
- const parts = input.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
1763
- const result = [];
1764
- for (const p of parts) {
1765
- if (p === "qoder" || p === "claude") {
1766
- if (!result.includes(p)) result.push(p);
1767
- } else {
1768
- throw new Error(`Unknown IDE: "${p}". Expected qoder | claude.`);
1769
- }
1770
- }
1771
- return result;
1772
- }
1773
- function parseScope(input) {
1774
- const v = (input ?? "project").toLowerCase();
1775
- if (v === "project" || v === "global") return v;
1776
- throw new Error(`Invalid --scope: "${input}". Expected project | global.`);
1777
- }
1778
1810
 
1779
1811
  // src/commands/skills/add.ts
1780
1812
  import { Command as Command8 } from "commander";
@@ -1800,7 +1832,8 @@ var addCommand = new Command8("add").description(
1800
1832
  logger.error(
1801
1833
  "No package.json found in current directory. Please run this command in a valid project root."
1802
1834
  );
1803
- process.exit(1);
1835
+ process.exitCode = 1;
1836
+ return;
1804
1837
  }
1805
1838
  logger.info(
1806
1839
  `Adding skills [${names.join(",")}]: ides=[${ides.join(
@@ -1819,7 +1852,7 @@ var addCommand = new Command8("add").description(
1819
1852
  logger.warn(
1820
1853
  `\u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u6DFB\u52A0\uFF1A${result.skippedSkillIds.join(
1821
1854
  ", "
1822
- )}\u3002\u5982\u9700\u5237\u65B0\u5185\u5BB9\u8BF7\u8FD0\u884C "teamix-evo skills update"\u3002`
1855
+ )}\u3002\u5982\u9700\u5237\u65B0\u5185\u5BB9\u8BF7\u8FD0\u884C "npx teamix-evo@latest skills update"\u3002`
1823
1856
  );
1824
1857
  return;
1825
1858
  }
@@ -1836,7 +1869,7 @@ var addCommand = new Command8("add").description(
1836
1869
  }
1837
1870
  logger.info(` Files: ${result.fileCount}`);
1838
1871
  logger.info("");
1839
- logger.info('Run "teamix-evo skills list" to see installed skills.');
1872
+ logger.info('Run "npx teamix-evo@latest skills list" to see installed skills.');
1840
1873
  } catch (err) {
1841
1874
  logger.error(`Failed to add skills: ${err.message}`);
1842
1875
  logger.debug(err.stack ?? "");
@@ -1859,8 +1892,8 @@ async function resolveIdesAndScope2(args) {
1859
1892
  }
1860
1893
  }
1861
1894
  if (opts.ide || opts.yes) {
1862
- const ides = opts.ide ? parseIdeList2(opts.ide) : [...ALL_IDE_KINDS];
1863
- const scope = parseScope2(opts.scope);
1895
+ const ides = opts.ide ? parseIdeList(opts.ide) : [...ALL_IDE_KINDS];
1896
+ const scope = parseScope(opts.scope);
1864
1897
  if (ides.length === 0) {
1865
1898
  throw new Error("At least one IDE must be selected.");
1866
1899
  }
@@ -1891,23 +1924,6 @@ async function resolveIdesAndScope2(args) {
1891
1924
  }
1892
1925
  return { ides: idesAns, scope: scopeAns };
1893
1926
  }
1894
- function parseIdeList2(input) {
1895
- const parts = input.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
1896
- const result = [];
1897
- for (const p of parts) {
1898
- if (p === "qoder" || p === "claude") {
1899
- if (!result.includes(p)) result.push(p);
1900
- } else {
1901
- throw new Error(`Unknown IDE: "${p}". Expected qoder | claude.`);
1902
- }
1903
- }
1904
- return result;
1905
- }
1906
- function parseScope2(input) {
1907
- const v = (input ?? "project").toLowerCase();
1908
- if (v === "project" || v === "global") return v;
1909
- throw new Error(`Invalid --scope: "${input}". Expected project | global.`);
1910
- }
1911
1927
 
1912
1928
  // src/commands/skills/list.ts
1913
1929
  import { Command as Command9 } from "commander";
@@ -1941,7 +1957,7 @@ var listCommand2 = new Command9("list").alias("ls").description(
1941
1957
  if (opts.installed) {
1942
1958
  if (!config?.packages?.skills || !pkg) {
1943
1959
  logger.info("No skills installed.");
1944
- logger.info('Run "teamix-evo skills init" to get started.');
1960
+ logger.info('Run "npx teamix-evo@latest skills init" to get started.');
1945
1961
  return;
1946
1962
  }
1947
1963
  printInstalledHeader(config.packages.skills, pkg.installedAt);
@@ -1965,12 +1981,12 @@ var listCommand2 = new Command9("list").alias("ls").description(
1965
1981
  printInstalledHeader(config.packages.skills, pkg.installedAt);
1966
1982
  } else if (isInstalled) {
1967
1983
  logger.info(
1968
- `Installed (${installedBySkill.size} skill(s)) \u2014 config or manifest record missing; run "teamix-evo skills doctor" to repair.`
1984
+ `Installed (${installedBySkill.size} skill(s)) \u2014 config or manifest record missing; run "npx teamix-evo@latest skills doctor" to repair.`
1969
1985
  );
1970
1986
  } else {
1971
1987
  logger.info("Skills package not yet added.");
1972
1988
  logger.info(
1973
- 'Run "teamix-evo skills init" to bootstrap, or "teamix-evo skills add <id...>" for specific skills.'
1989
+ 'Run "npx teamix-evo@latest skills init" to bootstrap, or "npx teamix-evo@latest skills add <id...>" for specific skills.'
1974
1990
  );
1975
1991
  }
1976
1992
  logger.info("");
@@ -1981,7 +1997,7 @@ var listCommand2 = new Command9("list").alias("ls").description(
1981
1997
  const installed = fileCount !== void 0;
1982
1998
  if (installed) installedCount++;
1983
1999
  const mark = installed ? "\u2713" : "\u25CB";
1984
- const tail = installed ? `[installed, ${fileCount} file${fileCount > 1 ? "s" : ""}]` : `[not installed \u2014 run "teamix-evo skills add ${s.id}"]`;
2000
+ const tail = installed ? `[installed, ${fileCount} file${fileCount > 1 ? "s" : ""}]` : `[not installed \u2014 run "npx teamix-evo@latest skills add ${s.id}"]`;
1985
2001
  logger.info(` ${mark} ${s.id}@${s.version} ${tail}`);
1986
2002
  if (s.description) {
1987
2003
  logger.info(` ${s.description}`);
@@ -2201,7 +2217,7 @@ var updateCommand2 = new Command10("update").description(
2201
2217
  switch (result.status) {
2202
2218
  case "no-skills":
2203
2219
  logger.error(
2204
- 'Skills not added. Run "teamix-evo skills init" first.'
2220
+ 'Skills not added. Run "npx teamix-evo@latest skills init" first.'
2205
2221
  );
2206
2222
  process.exitCode = 1;
2207
2223
  return;
@@ -2658,8 +2674,8 @@ var syncCommand = new Command12("sync").description(
2658
2674
  if (projectRoot !== cwd) {
2659
2675
  logger.info(`Using global skills meta root: ${projectRoot}`);
2660
2676
  }
2661
- const ides = opts.ide ? parseIdeList3(opts.ide) : void 0;
2662
- const scope = opts.scope ? parseScope3(opts.scope) : void 0;
2677
+ const ides = opts.ide ? parseIdeList(opts.ide) : void 0;
2678
+ const scope = opts.scope ? parseScope(opts.scope) : void 0;
2663
2679
  const result = await runSkillsSync({
2664
2680
  projectRoot,
2665
2681
  ides,
@@ -2691,25 +2707,6 @@ var syncCommand = new Command12("sync").description(
2691
2707
  process.exitCode = 1;
2692
2708
  }
2693
2709
  });
2694
- function parseIdeList3(input) {
2695
- const parts = input.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
2696
- const result = [];
2697
- for (const p of parts) {
2698
- if (p === "qoder" || p === "claude") {
2699
- if (!result.includes(p)) result.push(p);
2700
- } else {
2701
- throw new Error(
2702
- `Unknown IDE: "${p}". Expected one of: ${ALL_IDE_KINDS.join(", ")}.`
2703
- );
2704
- }
2705
- }
2706
- return result;
2707
- }
2708
- function parseScope3(input) {
2709
- const v = input.toLowerCase();
2710
- if (v === "project" || v === "global") return v;
2711
- throw new Error(`Invalid --scope: "${input}". Expected project | global.`);
2712
- }
2713
2710
 
2714
2711
  // src/commands/skills/doctor.ts
2715
2712
  import { Command as Command13 } from "commander";
@@ -2731,7 +2728,7 @@ async function runSkillsDoctor(options) {
2731
2728
  kind: "missing-source",
2732
2729
  skillId,
2733
2730
  path: sourceDir,
2734
- detail: 'Run "teamix-evo skills init" to reinstall.'
2731
+ detail: 'Run "npx teamix-evo@latest skills init" to reinstall.'
2735
2732
  });
2736
2733
  continue;
2737
2734
  }
@@ -2755,7 +2752,7 @@ async function runSkillsDoctor(options) {
2755
2752
  ide,
2756
2753
  scope: entry.scope,
2757
2754
  path: mirrorDir,
2758
- detail: 'Run "teamix-evo skills sync" to re-mirror.'
2755
+ detail: 'Run "npx teamix-evo@latest skills sync" to re-mirror.'
2759
2756
  });
2760
2757
  continue;
2761
2758
  }
@@ -2768,7 +2765,7 @@ async function runSkillsDoctor(options) {
2768
2765
  ide,
2769
2766
  scope: entry.scope,
2770
2767
  path: mirrorFile,
2771
- detail: 'Run "teamix-evo skills sync" to re-mirror.'
2768
+ detail: 'Run "npx teamix-evo@latest skills sync" to re-mirror.'
2772
2769
  });
2773
2770
  continue;
2774
2771
  }
@@ -2780,7 +2777,7 @@ async function runSkillsDoctor(options) {
2780
2777
  ide,
2781
2778
  scope: entry.scope,
2782
2779
  path: mirrorFile,
2783
- detail: 'Mirror differs from source. Re-run "teamix-evo skills sync" to overwrite.'
2780
+ detail: 'Mirror differs from source. Re-run "npx teamix-evo@latest skills sync" to overwrite.'
2784
2781
  });
2785
2782
  }
2786
2783
  }
@@ -2814,7 +2811,7 @@ var doctorCommand = new Command13("doctor").description(
2814
2811
  const result = await runSkillsDoctor({ projectRoot });
2815
2812
  if (result.status === "no-skills") {
2816
2813
  logger.info(
2817
- 'No skills recorded. Run "teamix-evo skills init" first.'
2814
+ 'No skills recorded. Run "npx teamix-evo@latest skills init" first.'
2818
2815
  );
2819
2816
  return;
2820
2817
  }
@@ -2823,7 +2820,7 @@ var doctorCommand = new Command13("doctor").description(
2823
2820
  return;
2824
2821
  }
2825
2822
  logger.warn(
2826
- `Found ${result.findings.length} drift issue(s). Run "teamix-evo skills sync" to repair mirrors.`
2823
+ `Found ${result.findings.length} drift issue(s). Run "npx teamix-evo@latest skills sync" to repair mirrors.`
2827
2824
  );
2828
2825
  for (const f of result.findings) {
2829
2826
  const idePart = f.ide ? ` [${f.ide}]` : "";
@@ -2927,7 +2924,8 @@ var initCommand3 = new Command15("init").description(
2927
2924
  logger.error(
2928
2925
  "No package.json found in current directory. Please run this command in a valid project root."
2929
2926
  );
2930
- process.exit(1);
2927
+ process.exitCode = 1;
2928
+ return;
2931
2929
  }
2932
2930
  const cfg = await resolveConfig(opts);
2933
2931
  const result = await runUiInit({
@@ -2940,7 +2938,7 @@ var initCommand3 = new Command15("init").description(
2940
2938
  });
2941
2939
  if (result.status === "already-initialized") {
2942
2940
  logger.warn(
2943
- "UI already initialized. Edit `.teamix-evo/config.json` directly to change aliases, or run `teamix-evo ui list`."
2941
+ "UI already initialized. Edit `.teamix-evo/config.json` directly to change aliases, or run `npx teamix-evo@latest ui list`."
2944
2942
  );
2945
2943
  return;
2946
2944
  }
@@ -2952,7 +2950,7 @@ var initCommand3 = new Command15("init").description(
2952
2950
  logger.info(` iconLibrary: ${result.iconLibrary}`);
2953
2951
  logger.info(` tsx: ${result.tsx}, rsc: ${result.rsc}`);
2954
2952
  logger.info("");
2955
- logger.info("Next: `npx teamix-evo ui add button`");
2953
+ logger.info("Next: `npx teamix-evo@latest ui add button`");
2956
2954
  } catch (err) {
2957
2955
  logger.error(`Failed to initialize ui: ${err.message}`);
2958
2956
  logger.debug(err.stack ?? "");
@@ -3636,7 +3634,7 @@ var listCommand4 = new Command20("list").description("\u5217\u51FA\u6307\u5B9A\u
3636
3634
  logger.info("");
3637
3635
  }
3638
3636
  logger.info(
3639
- `Install: teamix-evo biz-ui add <id> --variant ${result.variant}`
3637
+ `Install: npx teamix-evo@latest biz-ui add <id> --variant ${result.variant}`
3640
3638
  );
3641
3639
  } catch (err) {
3642
3640
  logger.error(`Failed: ${err.message}`);
@@ -3660,7 +3658,7 @@ var listVariantsCommand2 = new Command21("list-variants").description("\u5217\u5
3660
3658
  if (v.description) logger.info(` ${v.description}`);
3661
3659
  logger.info("");
3662
3660
  }
3663
- logger.info("Install from a variant: teamix-evo biz-ui add <id> --variant <name>");
3661
+ logger.info("Install from a variant: npx teamix-evo@latest biz-ui add <id> --variant <name>");
3664
3662
  } catch (err) {
3665
3663
  logger.error(`Failed: ${err.message}`);
3666
3664
  process.exitCode = 1;
@@ -3746,7 +3744,7 @@ var listCommand5 = new Command24("list").description("\u5217\u51FA\u6307\u5B9A\u
3746
3744
  logger.info("");
3747
3745
  }
3748
3746
  logger.info(
3749
- `Install: teamix-evo templates add <id> --variant ${result.variant}`
3747
+ `Install: npx teamix-evo@latest templates add <id> --variant ${result.variant}`
3750
3748
  );
3751
3749
  } catch (err) {
3752
3750
  logger.error(`Failed: ${err.message}`);
@@ -3770,7 +3768,7 @@ var listVariantsCommand3 = new Command25("list-variants").description("\u5217\u5
3770
3768
  if (v.description) logger.info(` ${v.description}`);
3771
3769
  logger.info("");
3772
3770
  }
3773
- logger.info("Install from a variant: teamix-evo templates add <id> --variant <name>");
3771
+ logger.info("Install from a variant: npx teamix-evo@latest templates add <id> --variant <name>");
3774
3772
  } catch (err) {
3775
3773
  logger.error(`Failed: ${err.message}`);
3776
3774
  process.exitCode = 1;
@@ -3790,27 +3788,19 @@ import { Command as Command29 } from "commander";
3790
3788
 
3791
3789
  // src/commands/logs/analyze.ts
3792
3790
  import { Command as Command27 } from "commander";
3793
- import { readFileSync, readdirSync, existsSync as existsSync2, statSync } from "fs";
3794
- import { resolve as resolve3, join as join17 } from "path";
3791
+ import { existsSync as existsSync2 } from "fs";
3792
+ import { resolve as resolve3, join as join18 } from "path";
3793
+
3794
+ // src/commands/logs/_io.ts
3795
+ import { readFileSync, readdirSync, statSync } from "fs";
3796
+ import { join as join17 } from "path";
3795
3797
  var DATE_DIR_RE = /^\d{4}-\d{2}-\d{2}$/;
3796
- var logsAnalyzeCommand = new Command27("analyze").description(
3797
- "\u6C47\u603B vibe-logger \u8F93\u51FA (.teamix-evo/logs/ai/**/*.jsonl) \u2014 \u5DE5\u5177 / \u5305\u6807\u7B7E / MCP \u8C03\u7528\u9891\u7387,\u8F85\u52A9\u751F\u6001\u4F18\u5316"
3798
- ).option("--dir <path>", "log \u76EE\u5F55 (\u9ED8\u8BA4 <project>/.teamix-evo/logs/ai)").option(
3799
- "--days <n>",
3800
- "\u53EA\u770B\u6700\u8FD1 N \u5929\u7684\u76EE\u5F55 (\u9ED8\u8BA4\u5168\u90E8;\u6309\u76EE\u5F55\u540D YYYY-MM-DD \u6BD4\u5BF9,\u4E0D\u89E3\u6790\u8BB0\u5F55 ts)"
3801
- ).option("--top <n>", "\u6BCF\u4E2A\u6392\u884C\u5C55\u793A\u524D N \u9879 (\u9ED8\u8BA4 10)", "10").option("--json", "\u4EE5 JSON \u8F93\u51FA (CI/\u5DE5\u5177\u53CB\u597D)").action((opts) => {
3802
- const baseDir = resolve3(
3803
- opts.dir ?? join17(process.cwd(), ".teamix-evo", "logs", "ai")
3804
- );
3805
- if (!existsSync2(baseDir)) {
3806
- logger.warn(`No log directory at ${baseDir}.`);
3807
- logger.info(
3808
- "\u8FD0\u884C vibe-logger hook \u89E6\u53D1\u540E\u4F1A\u5728\u6B64\u76EE\u5F55\u751F\u6210 JSONL \u2014 \u89C1 .claude/scripts/vibe-logger.mjs\uFF08\u9ED8\u8BA4\u8DEF\u5F84 .teamix-evo/logs/ai\uFF09"
3809
- );
3810
- return;
3811
- }
3812
- const dayLimit = parseIntOrUndef(opts.days);
3813
- const top = parseIntOrUndef(opts.top) ?? 10;
3798
+ function parseIntOrUndef(v) {
3799
+ if (v === void 0) return void 0;
3800
+ const n = Number.parseInt(v, 10);
3801
+ return Number.isFinite(n) && n > 0 ? n : void 0;
3802
+ }
3803
+ function readRecords(baseDir, dayLimit) {
3814
3804
  const dayDirs = readdirSync(baseDir, { withFileTypes: true }).filter((e) => e.isDirectory() && DATE_DIR_RE.test(e.name)).map((e) => e.name).sort().reverse();
3815
3805
  const selected = dayLimit !== void 0 ? dayDirs.slice(0, dayLimit) : dayDirs;
3816
3806
  const records = [];
@@ -3840,12 +3830,35 @@ var logsAnalyzeCommand = new Command27("analyze").description(
3840
3830
  }
3841
3831
  }
3842
3832
  }
3833
+ return records;
3834
+ }
3835
+
3836
+ // src/commands/logs/analyze.ts
3837
+ var logsAnalyzeCommand = new Command27("analyze").description(
3838
+ "\u6C47\u603B vibe-logger \u8F93\u51FA (.teamix-evo/logs/ai/**/*.jsonl) \u2014 \u5DE5\u5177 / \u5305\u6807\u7B7E / MCP \u8C03\u7528\u9891\u7387,\u8F85\u52A9\u751F\u6001\u4F18\u5316"
3839
+ ).option("--dir <path>", "log \u76EE\u5F55 (\u9ED8\u8BA4 <project>/.teamix-evo/logs/ai)").option(
3840
+ "--days <n>",
3841
+ "\u53EA\u770B\u6700\u8FD1 N \u5929\u7684\u76EE\u5F55 (\u9ED8\u8BA4\u5168\u90E8;\u6309\u76EE\u5F55\u540D YYYY-MM-DD \u6BD4\u5BF9,\u4E0D\u89E3\u6790\u8BB0\u5F55 ts)"
3842
+ ).option("--top <n>", "\u6BCF\u4E2A\u6392\u884C\u5C55\u793A\u524D N \u9879 (\u9ED8\u8BA4 10)", "10").option("--json", "\u4EE5 JSON \u8F93\u51FA (CI/\u5DE5\u5177\u53CB\u597D)").action((opts) => {
3843
+ const baseDir = resolve3(
3844
+ opts.dir ?? join18(process.cwd(), ".teamix-evo", "logs", "ai")
3845
+ );
3846
+ if (!existsSync2(baseDir)) {
3847
+ logger.warn(`No log directory at ${baseDir}.`);
3848
+ logger.info(
3849
+ "\u8FD0\u884C vibe-logger hook \u89E6\u53D1\u540E\u4F1A\u5728\u6B64\u76EE\u5F55\u751F\u6210 JSONL \u2014 \u89C1 .claude/scripts/vibe-logger.mjs\uFF08\u9ED8\u8BA4\u8DEF\u5F84 .teamix-evo/logs/ai\uFF09"
3850
+ );
3851
+ return;
3852
+ }
3853
+ const dayLimit = parseIntOrUndef(opts.days);
3854
+ const top = parseIntOrUndef(opts.top) ?? 10;
3855
+ const records = readRecords(baseDir, dayLimit);
3843
3856
  const report = buildReport(records, top);
3844
3857
  if (opts.json) {
3845
3858
  process.stdout.write(JSON.stringify(report, null, 2) + "\n");
3846
3859
  return;
3847
3860
  }
3848
- printReport(baseDir, selected.length, report);
3861
+ printReport(baseDir, dayLimit, report);
3849
3862
  });
3850
3863
  function buildReport(records, top) {
3851
3864
  const byAgent = {};
@@ -3920,10 +3933,10 @@ function buildReport(records, top) {
3920
3933
  function sortAndSlice(m, top) {
3921
3934
  return [...m.entries()].sort((a, b) => b[1] - a[1]).slice(0, top);
3922
3935
  }
3923
- function printReport(baseDir, dayCount, r) {
3936
+ function printReport(baseDir, dayLimit, r) {
3924
3937
  logger.info(`vibe-logger \u5206\u6790\u62A5\u544A`);
3925
3938
  logger.info(` \u76EE\u5F55: ${baseDir}`);
3926
- logger.info(` \u5929\u6570: ${dayCount}`);
3939
+ logger.info(` \u5929\u6570: ${dayLimit ?? "all"}`);
3927
3940
  logger.info(` \u65F6\u95F4: ${r.range.from ?? "-"} \u2192 ${r.range.to ?? "-"}`);
3928
3941
  logger.info("");
3929
3942
  logger.info(
@@ -3968,22 +3981,16 @@ function pad(n, width) {
3968
3981
  const s = String(n);
3969
3982
  return s.length >= width ? s : " ".repeat(width - s.length) + s;
3970
3983
  }
3971
- function parseIntOrUndef(v) {
3972
- if (v === void 0) return void 0;
3973
- const n = Number.parseInt(v, 10);
3974
- return Number.isFinite(n) && n > 0 ? n : void 0;
3975
- }
3976
3984
 
3977
3985
  // src/commands/logs/trace.ts
3978
3986
  import { Command as Command28 } from "commander";
3979
- import { readFileSync as readFileSync2, readdirSync as readdirSync2, existsSync as existsSync3, statSync as statSync2 } from "fs";
3980
- import { resolve as resolve4, join as join18 } from "path";
3981
- var DATE_DIR_RE2 = /^\d{4}-\d{2}-\d{2}$/;
3987
+ import { existsSync as existsSync3 } from "fs";
3988
+ import { resolve as resolve4, join as join19 } from "path";
3982
3989
  var logsTraceCommand = new Command28("trace").description(
3983
3990
  "\u6309\u4F1A\u8BDD\u8FD8\u539F AI \u8C03\u7528\u94FE\u8DEF:\u4ECE\u7528\u6237 prompt \u8D77\u59CB,\u4E32\u8054\u540E\u7EED PreToolUse/PostToolUse \u76F4\u5230\u4E0B\u4E00\u4E2A prompt \u6216 Stop"
3984
3991
  ).option("--prompt <keyword>", "\u6309\u7528\u6237\u8F93\u5165\u5173\u952E\u5B57\u8FC7\u6EE4 (\u5B50\u4E32\u5339\u914D,\u4E0D\u533A\u5206\u5927\u5C0F\u5199)").option("--session <id>", "\u6307\u5B9A\u4F1A\u8BDD ID (\u524D\u7F00\u5339\u914D)").option("--days <n>", "\u53EA\u770B\u6700\u8FD1 N \u5929\u7684\u76EE\u5F55 (\u9ED8\u8BA4 7)", "7").option("--dir <path>", "log \u76EE\u5F55 (\u9ED8\u8BA4 <project>/.teamix-evo/logs/ai)").option("--json", "\u4EE5 JSON \u8F93\u51FA (CI/\u5DE5\u5177\u53CB\u597D)").action((opts) => {
3985
3992
  const baseDir = resolve4(
3986
- opts.dir ?? join18(process.cwd(), ".teamix-evo", "logs", "ai")
3993
+ opts.dir ?? join19(process.cwd(), ".teamix-evo", "logs", "ai")
3987
3994
  );
3988
3995
  if (!existsSync3(baseDir)) {
3989
3996
  logger.warn(`No log directory at ${baseDir}.`);
@@ -3992,7 +3999,7 @@ var logsTraceCommand = new Command28("trace").description(
3992
3999
  );
3993
4000
  return;
3994
4001
  }
3995
- const dayLimit = parseIntOrUndef2(opts.days) ?? 7;
4002
+ const dayLimit = parseIntOrUndef(opts.days) ?? 7;
3996
4003
  const records = readRecords(baseDir, dayLimit);
3997
4004
  const report = buildTrace(records, {
3998
4005
  prompt: opts.prompt,
@@ -4004,38 +4011,6 @@ var logsTraceCommand = new Command28("trace").description(
4004
4011
  }
4005
4012
  printTrace(baseDir, report);
4006
4013
  });
4007
- function readRecords(baseDir, dayLimit) {
4008
- const dayDirs = readdirSync2(baseDir, { withFileTypes: true }).filter((e) => e.isDirectory() && DATE_DIR_RE2.test(e.name)).map((e) => e.name).sort().reverse();
4009
- const selected = dayDirs.slice(0, dayLimit);
4010
- const records = [];
4011
- for (const day of selected) {
4012
- const dayPath = join18(baseDir, day);
4013
- let entries;
4014
- try {
4015
- entries = readdirSync2(dayPath);
4016
- } catch {
4017
- continue;
4018
- }
4019
- for (const entry of entries) {
4020
- if (!entry.endsWith(".jsonl")) continue;
4021
- const fp = join18(dayPath, entry);
4022
- try {
4023
- if (!statSync2(fp).isFile()) continue;
4024
- } catch {
4025
- continue;
4026
- }
4027
- const text2 = readFileSync2(fp, "utf8");
4028
- for (const line of text2.split("\n")) {
4029
- if (!line.trim()) continue;
4030
- try {
4031
- records.push(JSON.parse(line));
4032
- } catch {
4033
- }
4034
- }
4035
- }
4036
- }
4037
- return records;
4038
- }
4039
4014
  function buildTrace(records, filter = {}) {
4040
4015
  const groups = /* @__PURE__ */ new Map();
4041
4016
  for (const r of records) {
@@ -4182,11 +4157,6 @@ function padRight(s, n) {
4182
4157
  function padLeft(s, n) {
4183
4158
  return s.length >= n ? s : " ".repeat(n - s.length) + s;
4184
4159
  }
4185
- function parseIntOrUndef2(v) {
4186
- if (v === void 0) return void 0;
4187
- const n = Number.parseInt(v, 10);
4188
- return Number.isFinite(n) && n > 0 ? n : void 0;
4189
- }
4190
4160
 
4191
4161
  // src/commands/logs/index.ts
4192
4162
  var logsCommand = new Command29("logs").description(
@@ -4313,7 +4283,8 @@ var initCommand4 = new Command30("init").description(
4313
4283
  logger.error(
4314
4284
  "No package.json found in current directory. Please run this command in a valid project root."
4315
4285
  );
4316
- process.exit(1);
4286
+ process.exitCode = 1;
4287
+ return;
4317
4288
  }
4318
4289
  const isInteractive = Boolean(process.stdin.isTTY);
4319
4290
  if (!opts.yes && isInteractive) {