teamix-evo 0.6.0 → 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 ?? "");
@@ -1724,7 +1773,8 @@ var initCommand2 = new Command7("init").description(
1724
1773
  });
1725
1774
  async function resolveIdesAndScope(args) {
1726
1775
  const { opts } = args;
1727
- if (opts.ide || opts.yes) {
1776
+ const isInteractive = Boolean(process.stdin.isTTY);
1777
+ if (opts.ide || opts.yes || !isInteractive) {
1728
1778
  const ides = opts.ide ? parseIdeList(opts.ide) : [...ALL_IDE_KINDS];
1729
1779
  const scope = parseScope(opts.scope);
1730
1780
  if (ides.length === 0) {
@@ -1757,23 +1807,6 @@ async function resolveIdesAndScope(args) {
1757
1807
  }
1758
1808
  return { ides: idesAns, scope: scopeAns };
1759
1809
  }
1760
- function parseIdeList(input) {
1761
- const parts = input.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
1762
- const result = [];
1763
- for (const p of parts) {
1764
- if (p === "qoder" || p === "claude") {
1765
- if (!result.includes(p)) result.push(p);
1766
- } else {
1767
- throw new Error(`Unknown IDE: "${p}". Expected qoder | claude.`);
1768
- }
1769
- }
1770
- return result;
1771
- }
1772
- function parseScope(input) {
1773
- const v = (input ?? "project").toLowerCase();
1774
- if (v === "project" || v === "global") return v;
1775
- throw new Error(`Invalid --scope: "${input}". Expected project | global.`);
1776
- }
1777
1810
 
1778
1811
  // src/commands/skills/add.ts
1779
1812
  import { Command as Command8 } from "commander";
@@ -1799,7 +1832,8 @@ var addCommand = new Command8("add").description(
1799
1832
  logger.error(
1800
1833
  "No package.json found in current directory. Please run this command in a valid project root."
1801
1834
  );
1802
- process.exit(1);
1835
+ process.exitCode = 1;
1836
+ return;
1803
1837
  }
1804
1838
  logger.info(
1805
1839
  `Adding skills [${names.join(",")}]: ides=[${ides.join(
@@ -1818,7 +1852,7 @@ var addCommand = new Command8("add").description(
1818
1852
  logger.warn(
1819
1853
  `\u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u6DFB\u52A0\uFF1A${result.skippedSkillIds.join(
1820
1854
  ", "
1821
- )}\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`
1822
1856
  );
1823
1857
  return;
1824
1858
  }
@@ -1835,7 +1869,7 @@ var addCommand = new Command8("add").description(
1835
1869
  }
1836
1870
  logger.info(` Files: ${result.fileCount}`);
1837
1871
  logger.info("");
1838
- 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.');
1839
1873
  } catch (err) {
1840
1874
  logger.error(`Failed to add skills: ${err.message}`);
1841
1875
  logger.debug(err.stack ?? "");
@@ -1858,8 +1892,8 @@ async function resolveIdesAndScope2(args) {
1858
1892
  }
1859
1893
  }
1860
1894
  if (opts.ide || opts.yes) {
1861
- const ides = opts.ide ? parseIdeList2(opts.ide) : [...ALL_IDE_KINDS];
1862
- const scope = parseScope2(opts.scope);
1895
+ const ides = opts.ide ? parseIdeList(opts.ide) : [...ALL_IDE_KINDS];
1896
+ const scope = parseScope(opts.scope);
1863
1897
  if (ides.length === 0) {
1864
1898
  throw new Error("At least one IDE must be selected.");
1865
1899
  }
@@ -1890,23 +1924,6 @@ async function resolveIdesAndScope2(args) {
1890
1924
  }
1891
1925
  return { ides: idesAns, scope: scopeAns };
1892
1926
  }
1893
- function parseIdeList2(input) {
1894
- const parts = input.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
1895
- const result = [];
1896
- for (const p of parts) {
1897
- if (p === "qoder" || p === "claude") {
1898
- if (!result.includes(p)) result.push(p);
1899
- } else {
1900
- throw new Error(`Unknown IDE: "${p}". Expected qoder | claude.`);
1901
- }
1902
- }
1903
- return result;
1904
- }
1905
- function parseScope2(input) {
1906
- const v = (input ?? "project").toLowerCase();
1907
- if (v === "project" || v === "global") return v;
1908
- throw new Error(`Invalid --scope: "${input}". Expected project | global.`);
1909
- }
1910
1927
 
1911
1928
  // src/commands/skills/list.ts
1912
1929
  import { Command as Command9 } from "commander";
@@ -1940,7 +1957,7 @@ var listCommand2 = new Command9("list").alias("ls").description(
1940
1957
  if (opts.installed) {
1941
1958
  if (!config?.packages?.skills || !pkg) {
1942
1959
  logger.info("No skills installed.");
1943
- logger.info('Run "teamix-evo skills init" to get started.');
1960
+ logger.info('Run "npx teamix-evo@latest skills init" to get started.');
1944
1961
  return;
1945
1962
  }
1946
1963
  printInstalledHeader(config.packages.skills, pkg.installedAt);
@@ -1964,12 +1981,12 @@ var listCommand2 = new Command9("list").alias("ls").description(
1964
1981
  printInstalledHeader(config.packages.skills, pkg.installedAt);
1965
1982
  } else if (isInstalled) {
1966
1983
  logger.info(
1967
- `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.`
1968
1985
  );
1969
1986
  } else {
1970
1987
  logger.info("Skills package not yet added.");
1971
1988
  logger.info(
1972
- '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.'
1973
1990
  );
1974
1991
  }
1975
1992
  logger.info("");
@@ -1980,7 +1997,7 @@ var listCommand2 = new Command9("list").alias("ls").description(
1980
1997
  const installed = fileCount !== void 0;
1981
1998
  if (installed) installedCount++;
1982
1999
  const mark = installed ? "\u2713" : "\u25CB";
1983
- 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}"]`;
1984
2001
  logger.info(` ${mark} ${s.id}@${s.version} ${tail}`);
1985
2002
  if (s.description) {
1986
2003
  logger.info(` ${s.description}`);
@@ -2200,7 +2217,7 @@ var updateCommand2 = new Command10("update").description(
2200
2217
  switch (result.status) {
2201
2218
  case "no-skills":
2202
2219
  logger.error(
2203
- 'Skills not added. Run "teamix-evo skills init" first.'
2220
+ 'Skills not added. Run "npx teamix-evo@latest skills init" first.'
2204
2221
  );
2205
2222
  process.exitCode = 1;
2206
2223
  return;
@@ -2657,8 +2674,8 @@ var syncCommand = new Command12("sync").description(
2657
2674
  if (projectRoot !== cwd) {
2658
2675
  logger.info(`Using global skills meta root: ${projectRoot}`);
2659
2676
  }
2660
- const ides = opts.ide ? parseIdeList3(opts.ide) : void 0;
2661
- 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;
2662
2679
  const result = await runSkillsSync({
2663
2680
  projectRoot,
2664
2681
  ides,
@@ -2690,25 +2707,6 @@ var syncCommand = new Command12("sync").description(
2690
2707
  process.exitCode = 1;
2691
2708
  }
2692
2709
  });
2693
- function parseIdeList3(input) {
2694
- const parts = input.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
2695
- const result = [];
2696
- for (const p of parts) {
2697
- if (p === "qoder" || p === "claude") {
2698
- if (!result.includes(p)) result.push(p);
2699
- } else {
2700
- throw new Error(
2701
- `Unknown IDE: "${p}". Expected one of: ${ALL_IDE_KINDS.join(", ")}.`
2702
- );
2703
- }
2704
- }
2705
- return result;
2706
- }
2707
- function parseScope3(input) {
2708
- const v = input.toLowerCase();
2709
- if (v === "project" || v === "global") return v;
2710
- throw new Error(`Invalid --scope: "${input}". Expected project | global.`);
2711
- }
2712
2710
 
2713
2711
  // src/commands/skills/doctor.ts
2714
2712
  import { Command as Command13 } from "commander";
@@ -2730,7 +2728,7 @@ async function runSkillsDoctor(options) {
2730
2728
  kind: "missing-source",
2731
2729
  skillId,
2732
2730
  path: sourceDir,
2733
- detail: 'Run "teamix-evo skills init" to reinstall.'
2731
+ detail: 'Run "npx teamix-evo@latest skills init" to reinstall.'
2734
2732
  });
2735
2733
  continue;
2736
2734
  }
@@ -2754,7 +2752,7 @@ async function runSkillsDoctor(options) {
2754
2752
  ide,
2755
2753
  scope: entry.scope,
2756
2754
  path: mirrorDir,
2757
- detail: 'Run "teamix-evo skills sync" to re-mirror.'
2755
+ detail: 'Run "npx teamix-evo@latest skills sync" to re-mirror.'
2758
2756
  });
2759
2757
  continue;
2760
2758
  }
@@ -2767,7 +2765,7 @@ async function runSkillsDoctor(options) {
2767
2765
  ide,
2768
2766
  scope: entry.scope,
2769
2767
  path: mirrorFile,
2770
- detail: 'Run "teamix-evo skills sync" to re-mirror.'
2768
+ detail: 'Run "npx teamix-evo@latest skills sync" to re-mirror.'
2771
2769
  });
2772
2770
  continue;
2773
2771
  }
@@ -2779,7 +2777,7 @@ async function runSkillsDoctor(options) {
2779
2777
  ide,
2780
2778
  scope: entry.scope,
2781
2779
  path: mirrorFile,
2782
- 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.'
2783
2781
  });
2784
2782
  }
2785
2783
  }
@@ -2813,7 +2811,7 @@ var doctorCommand = new Command13("doctor").description(
2813
2811
  const result = await runSkillsDoctor({ projectRoot });
2814
2812
  if (result.status === "no-skills") {
2815
2813
  logger.info(
2816
- 'No skills recorded. Run "teamix-evo skills init" first.'
2814
+ 'No skills recorded. Run "npx teamix-evo@latest skills init" first.'
2817
2815
  );
2818
2816
  return;
2819
2817
  }
@@ -2822,7 +2820,7 @@ var doctorCommand = new Command13("doctor").description(
2822
2820
  return;
2823
2821
  }
2824
2822
  logger.warn(
2825
- `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.`
2826
2824
  );
2827
2825
  for (const f of result.findings) {
2828
2826
  const idePart = f.ide ? ` [${f.ide}]` : "";
@@ -2926,7 +2924,8 @@ var initCommand3 = new Command15("init").description(
2926
2924
  logger.error(
2927
2925
  "No package.json found in current directory. Please run this command in a valid project root."
2928
2926
  );
2929
- process.exit(1);
2927
+ process.exitCode = 1;
2928
+ return;
2930
2929
  }
2931
2930
  const cfg = await resolveConfig(opts);
2932
2931
  const result = await runUiInit({
@@ -2939,7 +2938,7 @@ var initCommand3 = new Command15("init").description(
2939
2938
  });
2940
2939
  if (result.status === "already-initialized") {
2941
2940
  logger.warn(
2942
- "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`."
2943
2942
  );
2944
2943
  return;
2945
2944
  }
@@ -2951,7 +2950,7 @@ var initCommand3 = new Command15("init").description(
2951
2950
  logger.info(` iconLibrary: ${result.iconLibrary}`);
2952
2951
  logger.info(` tsx: ${result.tsx}, rsc: ${result.rsc}`);
2953
2952
  logger.info("");
2954
- logger.info("Next: `npx teamix-evo ui add button`");
2953
+ logger.info("Next: `npx teamix-evo@latest ui add button`");
2955
2954
  } catch (err) {
2956
2955
  logger.error(`Failed to initialize ui: ${err.message}`);
2957
2956
  logger.debug(err.stack ?? "");
@@ -2959,7 +2958,8 @@ var initCommand3 = new Command15("init").description(
2959
2958
  }
2960
2959
  });
2961
2960
  async function resolveConfig(opts) {
2962
- if (opts.yes) {
2961
+ const isInteractive = Boolean(process.stdin.isTTY);
2962
+ if (opts.yes || !isInteractive) {
2963
2963
  return {
2964
2964
  aliases: {
2965
2965
  components: opts.components ?? DEFAULT_UI_ALIASES.components,
@@ -3634,7 +3634,7 @@ var listCommand4 = new Command20("list").description("\u5217\u51FA\u6307\u5B9A\u
3634
3634
  logger.info("");
3635
3635
  }
3636
3636
  logger.info(
3637
- `Install: teamix-evo biz-ui add <id> --variant ${result.variant}`
3637
+ `Install: npx teamix-evo@latest biz-ui add <id> --variant ${result.variant}`
3638
3638
  );
3639
3639
  } catch (err) {
3640
3640
  logger.error(`Failed: ${err.message}`);
@@ -3658,7 +3658,7 @@ var listVariantsCommand2 = new Command21("list-variants").description("\u5217\u5
3658
3658
  if (v.description) logger.info(` ${v.description}`);
3659
3659
  logger.info("");
3660
3660
  }
3661
- 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>");
3662
3662
  } catch (err) {
3663
3663
  logger.error(`Failed: ${err.message}`);
3664
3664
  process.exitCode = 1;
@@ -3744,7 +3744,7 @@ var listCommand5 = new Command24("list").description("\u5217\u51FA\u6307\u5B9A\u
3744
3744
  logger.info("");
3745
3745
  }
3746
3746
  logger.info(
3747
- `Install: teamix-evo templates add <id> --variant ${result.variant}`
3747
+ `Install: npx teamix-evo@latest templates add <id> --variant ${result.variant}`
3748
3748
  );
3749
3749
  } catch (err) {
3750
3750
  logger.error(`Failed: ${err.message}`);
@@ -3768,7 +3768,7 @@ var listVariantsCommand3 = new Command25("list-variants").description("\u5217\u5
3768
3768
  if (v.description) logger.info(` ${v.description}`);
3769
3769
  logger.info("");
3770
3770
  }
3771
- 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>");
3772
3772
  } catch (err) {
3773
3773
  logger.error(`Failed: ${err.message}`);
3774
3774
  process.exitCode = 1;
@@ -3788,27 +3788,19 @@ import { Command as Command29 } from "commander";
3788
3788
 
3789
3789
  // src/commands/logs/analyze.ts
3790
3790
  import { Command as Command27 } from "commander";
3791
- import { readFileSync, readdirSync, existsSync as existsSync2, statSync } from "fs";
3792
- 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";
3793
3797
  var DATE_DIR_RE = /^\d{4}-\d{2}-\d{2}$/;
3794
- var logsAnalyzeCommand = new Command27("analyze").description(
3795
- "\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"
3796
- ).option("--dir <path>", "log \u76EE\u5F55 (\u9ED8\u8BA4 <project>/.teamix-evo/logs/ai)").option(
3797
- "--days <n>",
3798
- "\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)"
3799
- ).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) => {
3800
- const baseDir = resolve3(
3801
- opts.dir ?? join17(process.cwd(), ".teamix-evo", "logs", "ai")
3802
- );
3803
- if (!existsSync2(baseDir)) {
3804
- logger.warn(`No log directory at ${baseDir}.`);
3805
- logger.info(
3806
- "\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"
3807
- );
3808
- return;
3809
- }
3810
- const dayLimit = parseIntOrUndef(opts.days);
3811
- 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) {
3812
3804
  const dayDirs = readdirSync(baseDir, { withFileTypes: true }).filter((e) => e.isDirectory() && DATE_DIR_RE.test(e.name)).map((e) => e.name).sort().reverse();
3813
3805
  const selected = dayLimit !== void 0 ? dayDirs.slice(0, dayLimit) : dayDirs;
3814
3806
  const records = [];
@@ -3838,12 +3830,35 @@ var logsAnalyzeCommand = new Command27("analyze").description(
3838
3830
  }
3839
3831
  }
3840
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);
3841
3856
  const report = buildReport(records, top);
3842
3857
  if (opts.json) {
3843
3858
  process.stdout.write(JSON.stringify(report, null, 2) + "\n");
3844
3859
  return;
3845
3860
  }
3846
- printReport(baseDir, selected.length, report);
3861
+ printReport(baseDir, dayLimit, report);
3847
3862
  });
3848
3863
  function buildReport(records, top) {
3849
3864
  const byAgent = {};
@@ -3918,10 +3933,10 @@ function buildReport(records, top) {
3918
3933
  function sortAndSlice(m, top) {
3919
3934
  return [...m.entries()].sort((a, b) => b[1] - a[1]).slice(0, top);
3920
3935
  }
3921
- function printReport(baseDir, dayCount, r) {
3936
+ function printReport(baseDir, dayLimit, r) {
3922
3937
  logger.info(`vibe-logger \u5206\u6790\u62A5\u544A`);
3923
3938
  logger.info(` \u76EE\u5F55: ${baseDir}`);
3924
- logger.info(` \u5929\u6570: ${dayCount}`);
3939
+ logger.info(` \u5929\u6570: ${dayLimit ?? "all"}`);
3925
3940
  logger.info(` \u65F6\u95F4: ${r.range.from ?? "-"} \u2192 ${r.range.to ?? "-"}`);
3926
3941
  logger.info("");
3927
3942
  logger.info(
@@ -3966,22 +3981,16 @@ function pad(n, width) {
3966
3981
  const s = String(n);
3967
3982
  return s.length >= width ? s : " ".repeat(width - s.length) + s;
3968
3983
  }
3969
- function parseIntOrUndef(v) {
3970
- if (v === void 0) return void 0;
3971
- const n = Number.parseInt(v, 10);
3972
- return Number.isFinite(n) && n > 0 ? n : void 0;
3973
- }
3974
3984
 
3975
3985
  // src/commands/logs/trace.ts
3976
3986
  import { Command as Command28 } from "commander";
3977
- import { readFileSync as readFileSync2, readdirSync as readdirSync2, existsSync as existsSync3, statSync as statSync2 } from "fs";
3978
- import { resolve as resolve4, join as join18 } from "path";
3979
- 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";
3980
3989
  var logsTraceCommand = new Command28("trace").description(
3981
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"
3982
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) => {
3983
3992
  const baseDir = resolve4(
3984
- opts.dir ?? join18(process.cwd(), ".teamix-evo", "logs", "ai")
3993
+ opts.dir ?? join19(process.cwd(), ".teamix-evo", "logs", "ai")
3985
3994
  );
3986
3995
  if (!existsSync3(baseDir)) {
3987
3996
  logger.warn(`No log directory at ${baseDir}.`);
@@ -3990,7 +3999,7 @@ var logsTraceCommand = new Command28("trace").description(
3990
3999
  );
3991
4000
  return;
3992
4001
  }
3993
- const dayLimit = parseIntOrUndef2(opts.days) ?? 7;
4002
+ const dayLimit = parseIntOrUndef(opts.days) ?? 7;
3994
4003
  const records = readRecords(baseDir, dayLimit);
3995
4004
  const report = buildTrace(records, {
3996
4005
  prompt: opts.prompt,
@@ -4002,38 +4011,6 @@ var logsTraceCommand = new Command28("trace").description(
4002
4011
  }
4003
4012
  printTrace(baseDir, report);
4004
4013
  });
4005
- function readRecords(baseDir, dayLimit) {
4006
- const dayDirs = readdirSync2(baseDir, { withFileTypes: true }).filter((e) => e.isDirectory() && DATE_DIR_RE2.test(e.name)).map((e) => e.name).sort().reverse();
4007
- const selected = dayDirs.slice(0, dayLimit);
4008
- const records = [];
4009
- for (const day of selected) {
4010
- const dayPath = join18(baseDir, day);
4011
- let entries;
4012
- try {
4013
- entries = readdirSync2(dayPath);
4014
- } catch {
4015
- continue;
4016
- }
4017
- for (const entry of entries) {
4018
- if (!entry.endsWith(".jsonl")) continue;
4019
- const fp = join18(dayPath, entry);
4020
- try {
4021
- if (!statSync2(fp).isFile()) continue;
4022
- } catch {
4023
- continue;
4024
- }
4025
- const text2 = readFileSync2(fp, "utf8");
4026
- for (const line of text2.split("\n")) {
4027
- if (!line.trim()) continue;
4028
- try {
4029
- records.push(JSON.parse(line));
4030
- } catch {
4031
- }
4032
- }
4033
- }
4034
- }
4035
- return records;
4036
- }
4037
4014
  function buildTrace(records, filter = {}) {
4038
4015
  const groups = /* @__PURE__ */ new Map();
4039
4016
  for (const r of records) {
@@ -4180,11 +4157,6 @@ function padRight(s, n) {
4180
4157
  function padLeft(s, n) {
4181
4158
  return s.length >= n ? s : " ".repeat(n - s.length) + s;
4182
4159
  }
4183
- function parseIntOrUndef2(v) {
4184
- if (v === void 0) return void 0;
4185
- const n = Number.parseInt(v, 10);
4186
- return Number.isFinite(n) && n > 0 ? n : void 0;
4187
- }
4188
4160
 
4189
4161
  // src/commands/logs/index.ts
4190
4162
  var logsCommand = new Command29("logs").description(
@@ -4311,9 +4283,11 @@ var initCommand4 = new Command30("init").description(
4311
4283
  logger.error(
4312
4284
  "No package.json found in current directory. Please run this command in a valid project root."
4313
4285
  );
4314
- process.exit(1);
4286
+ process.exitCode = 1;
4287
+ return;
4315
4288
  }
4316
- if (!opts.yes) {
4289
+ const isInteractive = Boolean(process.stdin.isTTY);
4290
+ if (!opts.yes && isInteractive) {
4317
4291
  const shouldContinue = await prompts6.confirm({
4318
4292
  message: "\u5373\u5C06\u5B89\u88C5 ESLint + Stylelint token-discipline \u89C4\u5219\u96C6\u5E76\u751F\u6210\u914D\u7F6E\u6587\u4EF6\uFF0C\u662F\u5426\u7EE7\u7EED\uFF1F"
4319
4293
  });