teamix-evo 0.3.0 → 0.3.1

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
@@ -1321,6 +1321,12 @@ async function ensureGlobalMetaRoot() {
1321
1321
  await fs8.mkdir(root, { recursive: true });
1322
1322
  return root;
1323
1323
  }
1324
+ function resolveSkillsMaintenanceRoot(cwd) {
1325
+ if (isTeamixEvoProject(cwd)) return cwd;
1326
+ const globalRoot = getGlobalMetaRoot();
1327
+ if (isTeamixEvoProject(globalRoot)) return globalRoot;
1328
+ return cwd;
1329
+ }
1324
1330
 
1325
1331
  // src/commands/skills/add.ts
1326
1332
  var addCommand = new Command7("add").description(
@@ -1467,7 +1473,11 @@ var listCommand2 = new Command8("list").alias("ls").description(
1467
1473
  ).option("--installed", "\u4EC5\u5C55\u793A\u5DF2\u5B89\u88C5\u7684 skill\uFF08\u9690\u85CF\u672A\u5B89\u88C5\u9879\uFF09").action(async (opts) => {
1468
1474
  try {
1469
1475
  const ide = detectIde();
1470
- const projectRoot = ide.getProjectRoot();
1476
+ const cwd = ide.getProjectRoot();
1477
+ const projectRoot = resolveSkillsMaintenanceRoot(cwd);
1478
+ if (projectRoot !== cwd) {
1479
+ logger.info(`Using global skills meta root: ${projectRoot}`);
1480
+ }
1471
1481
  const config = await readProjectConfig(projectRoot);
1472
1482
  const installedManifest = await readInstalledManifest(projectRoot);
1473
1483
  const pkg = installedManifest?.installed.find(
@@ -1548,7 +1558,11 @@ var FLAT_VARIANT2 = "_flat";
1548
1558
  var updateCommand2 = new Command9("update").description("\u66F4\u65B0\u5DF2\u5B89\u88C5\u7684 teamix-evo skills").action(async () => {
1549
1559
  try {
1550
1560
  const ide = detectIde();
1551
- const projectRoot = ide.getProjectRoot();
1561
+ const cwd = ide.getProjectRoot();
1562
+ const projectRoot = resolveSkillsMaintenanceRoot(cwd);
1563
+ if (projectRoot !== cwd) {
1564
+ logger.info(`Using global skills meta root: ${projectRoot}`);
1565
+ }
1552
1566
  const config = await readProjectConfig(projectRoot);
1553
1567
  if (!config?.packages?.skills) {
1554
1568
  logger.error('Skills not added. Run "teamix-evo skills add" first.');
@@ -1637,10 +1651,19 @@ import * as prompts3 from "@clack/prompts";
1637
1651
  import * as path12 from "path";
1638
1652
  import * as fs9 from "fs/promises";
1639
1653
  var SKILLS_PACKAGE3 = "@teamix-evo/skills";
1640
- var uninstallCommand2 = new Command10("uninstall").description("\u5378\u8F7D\u5DF2\u5B89\u88C5\u7684 teamix-evo skills\uFF08\u5220\u9664\u6CE8\u5165\u5230 IDE \u7684\u6280\u80FD\u6587\u4EF6\uFF09").option("-y, --yes", "\u8DF3\u8FC7\u786E\u8BA4").action(async (opts) => {
1654
+ var uninstallCommand2 = new Command10("uninstall").description(
1655
+ "\u5378\u8F7D\u5DF2\u5B89\u88C5\u7684 teamix-evo skills\uFF1B\u4E0D\u4F20 ids \u5219\u5378\u8F7D\u6574\u5305\uFF0C\u4F20 ids \u5219\u6309 skill \u5220\u9664"
1656
+ ).argument(
1657
+ "[ids...]",
1658
+ "\u53EF\u9009\uFF1A\u4EC5\u5378\u8F7D\u6307\u5B9A skill id\uFF1B\u7701\u7565\u5219\u5378\u8F7D\u6574\u4E2A skills \u5305"
1659
+ ).option("-y, --yes", "\u8DF3\u8FC7\u786E\u8BA4").action(async (ids, opts) => {
1641
1660
  try {
1642
1661
  const ide = detectIde();
1643
- const projectRoot = ide.getProjectRoot();
1662
+ const cwd = ide.getProjectRoot();
1663
+ const projectRoot = resolveSkillsMaintenanceRoot(cwd);
1664
+ if (projectRoot !== cwd) {
1665
+ logger.info(`Using global skills meta root: ${projectRoot}`);
1666
+ }
1644
1667
  const config = await readProjectConfig(projectRoot);
1645
1668
  if (!config?.packages?.skills) {
1646
1669
  logger.info("Skills are not installed. Nothing to do.");
@@ -1651,47 +1674,142 @@ var uninstallCommand2 = new Command10("uninstall").description("\u5378\u8F7D\u5D
1651
1674
  (p) => p.package === SKILLS_PACKAGE3
1652
1675
  );
1653
1676
  const resources = pkg?.resources ?? [];
1654
- logger.info(
1655
- `Will remove ${resources.length} skill file(s) installed by ${SKILLS_PACKAGE3}.`
1656
- );
1657
- if (!opts.yes) {
1658
- const confirm4 = await prompts3.confirm({
1659
- message: "\u786E\u8BA4\u5378\u8F7D\uFF1F\u6B64\u64CD\u4F5C\u4F1A\u5220\u9664\u4E0A\u8FF0\u6587\u4EF6\u3002",
1660
- initialValue: false
1677
+ if (ids.length === 0) {
1678
+ await runFullUninstall({
1679
+ projectRoot,
1680
+ config,
1681
+ installedManifest,
1682
+ pkg,
1683
+ resources,
1684
+ opts
1661
1685
  });
1662
- if (prompts3.isCancel(confirm4) || !confirm4) {
1663
- logger.info("Cancelled.");
1664
- return;
1665
- }
1666
- }
1667
- const removed = await removeSkillFiles(resources);
1668
- logger.debug(`Removed ${removed.length} files`);
1669
- const skillsRoot = getSkillsSourceDir(projectRoot);
1670
- try {
1671
- await fs9.rm(skillsRoot, { recursive: true, force: true });
1672
- logger.debug(`Removed source dir ${skillsRoot}`);
1673
- } catch (err) {
1674
- logger.warn(
1675
- `Failed to remove ${skillsRoot}: ${err.message}`
1676
- );
1677
- }
1678
- if (installedManifest && pkg) {
1679
- installedManifest.installed = installedManifest.installed.filter(
1680
- (p) => p.package !== SKILLS_PACKAGE3
1681
- );
1682
- await writeInstalledManifest(projectRoot, installedManifest);
1686
+ return;
1683
1687
  }
1684
- delete config.packages.skills;
1685
- await writeProjectConfig(projectRoot, config);
1686
- logger.success(`Uninstalled ${SKILLS_PACKAGE3}`);
1687
- logger.info(` Removed: ${removed.length} files`);
1688
- logger.info(` Source: ${path12.relative(projectRoot, skillsRoot)} (cleaned)`);
1688
+ await runPartialUninstall({
1689
+ projectRoot,
1690
+ installedManifest,
1691
+ pkg,
1692
+ resources,
1693
+ ids,
1694
+ opts
1695
+ });
1689
1696
  } catch (err) {
1690
1697
  logger.error(`Failed to uninstall: ${err.message}`);
1691
1698
  logger.debug(err.stack ?? "");
1692
1699
  process.exitCode = 1;
1693
1700
  }
1694
1701
  });
1702
+ async function runFullUninstall(args) {
1703
+ const { projectRoot, config, installedManifest, pkg, resources, opts } = args;
1704
+ logger.info(
1705
+ `Will remove ${resources.length} skill file(s) installed by ${SKILLS_PACKAGE3}.`
1706
+ );
1707
+ if (!opts.yes) {
1708
+ const confirm4 = await prompts3.confirm({
1709
+ message: "\u786E\u8BA4\u5378\u8F7D\uFF1F\u6B64\u64CD\u4F5C\u4F1A\u5220\u9664\u4E0A\u8FF0\u6587\u4EF6\u3002",
1710
+ initialValue: false
1711
+ });
1712
+ if (prompts3.isCancel(confirm4) || !confirm4) {
1713
+ logger.info("Cancelled.");
1714
+ return;
1715
+ }
1716
+ }
1717
+ const removed = await removeSkillFiles(resources);
1718
+ logger.debug(`Removed ${removed.length} files`);
1719
+ const skillsRoot = getSkillsSourceDir(projectRoot);
1720
+ try {
1721
+ await fs9.rm(skillsRoot, { recursive: true, force: true });
1722
+ logger.debug(`Removed source dir ${skillsRoot}`);
1723
+ } catch (err) {
1724
+ logger.warn(
1725
+ `Failed to remove ${skillsRoot}: ${err.message}`
1726
+ );
1727
+ }
1728
+ if (installedManifest && pkg) {
1729
+ installedManifest.installed = installedManifest.installed.filter(
1730
+ (p) => p.package !== SKILLS_PACKAGE3
1731
+ );
1732
+ await writeInstalledManifest(projectRoot, installedManifest);
1733
+ }
1734
+ delete config.packages.skills;
1735
+ await writeProjectConfig(projectRoot, config);
1736
+ logger.success(`Uninstalled ${SKILLS_PACKAGE3}`);
1737
+ logger.info(` Removed: ${removed.length} files`);
1738
+ logger.info(` Source: ${path12.relative(projectRoot, skillsRoot)} (cleaned)`);
1739
+ }
1740
+ async function runPartialUninstall(args) {
1741
+ const { projectRoot, installedManifest, pkg, resources, ids, opts } = args;
1742
+ const grouped = groupBySkillId(resources);
1743
+ const requested = dedupe(ids);
1744
+ const matched = requested.filter((id) => grouped.has(id));
1745
+ const missing = requested.filter((id) => !grouped.has(id));
1746
+ if (missing.length > 0) {
1747
+ logger.warn(`Not installed (skipped): ${missing.join(", ")}`);
1748
+ }
1749
+ if (matched.length === 0) {
1750
+ logger.info("Nothing to remove.");
1751
+ return;
1752
+ }
1753
+ const toRemove = matched.flatMap(
1754
+ (id) => grouped.get(id) ?? []
1755
+ );
1756
+ logger.info(
1757
+ `Will remove ${matched.length} skill(s): ${matched.join(", ")} (${toRemove.length} file(s)).`
1758
+ );
1759
+ if (!opts.yes) {
1760
+ const confirm4 = await prompts3.confirm({
1761
+ message: "\u786E\u8BA4\u5378\u8F7D\uFF1F\u6B64\u64CD\u4F5C\u4F1A\u5220\u9664\u4E0A\u8FF0\u6587\u4EF6\u3002",
1762
+ initialValue: false
1763
+ });
1764
+ if (prompts3.isCancel(confirm4) || !confirm4) {
1765
+ logger.info("Cancelled.");
1766
+ return;
1767
+ }
1768
+ }
1769
+ const removed = await removeSkillFiles(toRemove);
1770
+ logger.debug(`Removed ${removed.length} files`);
1771
+ for (const id of matched) {
1772
+ const dir = getSkillsSourceDir(projectRoot, id);
1773
+ try {
1774
+ await fs9.rm(dir, { recursive: true, force: true });
1775
+ logger.debug(`Removed source dir ${dir}`);
1776
+ } catch (err) {
1777
+ logger.warn(`Failed to remove ${dir}: ${err.message}`);
1778
+ }
1779
+ }
1780
+ const lock = await readSkillsLock(projectRoot);
1781
+ if (lock) {
1782
+ for (const id of matched) delete lock.skills[id];
1783
+ await writeSkillsLock(projectRoot, lock);
1784
+ }
1785
+ if (installedManifest && pkg) {
1786
+ pkg.resources = resources.filter((r) => !matched.includes(skillIdOf(r)));
1787
+ await writeInstalledManifest(projectRoot, installedManifest);
1788
+ }
1789
+ logger.success(
1790
+ `Removed ${matched.length} skill(s): ${matched.join(", ")}`
1791
+ );
1792
+ logger.info(` Files: ${removed.length}`);
1793
+ if (missing.length > 0) {
1794
+ logger.info(` Skipped: ${missing.join(", ")} (not installed)`);
1795
+ }
1796
+ }
1797
+ function skillIdOf(r) {
1798
+ return r.id.split(":")[0];
1799
+ }
1800
+ function groupBySkillId(records) {
1801
+ const map = /* @__PURE__ */ new Map();
1802
+ for (const r of records) {
1803
+ const id = skillIdOf(r);
1804
+ const bucket = map.get(id);
1805
+ if (bucket) bucket.push(r);
1806
+ else map.set(id, [r]);
1807
+ }
1808
+ return map;
1809
+ }
1810
+ function dedupe(values) {
1811
+ return Array.from(new Set(values));
1812
+ }
1695
1813
 
1696
1814
  // src/commands/skills/sync.ts
1697
1815
  import { Command as Command11 } from "commander";
@@ -1796,7 +1914,11 @@ var syncCommand = new Command11("sync").description(
1796
1914
  ).action(async (names, opts) => {
1797
1915
  try {
1798
1916
  const ide = detectIde();
1799
- const projectRoot = ide.getProjectRoot();
1917
+ const cwd = ide.getProjectRoot();
1918
+ const projectRoot = resolveSkillsMaintenanceRoot(cwd);
1919
+ if (projectRoot !== cwd) {
1920
+ logger.info(`Using global skills meta root: ${projectRoot}`);
1921
+ }
1800
1922
  const ides = opts.ide ? parseIdeList2(opts.ide) : void 0;
1801
1923
  const scope = opts.scope ? parseScope2(opts.scope) : void 0;
1802
1924
  const result = await runSkillsSync({
@@ -1945,7 +2067,11 @@ var doctorCommand = new Command12("doctor").description(
1945
2067
  ).action(async () => {
1946
2068
  try {
1947
2069
  const ide = detectIde();
1948
- const projectRoot = ide.getProjectRoot();
2070
+ const cwd = ide.getProjectRoot();
2071
+ const projectRoot = resolveSkillsMaintenanceRoot(cwd);
2072
+ if (projectRoot !== cwd) {
2073
+ logger.info(`Using global skills meta root: ${projectRoot}`);
2074
+ }
1949
2075
  const result = await runSkillsDoctor({ projectRoot });
1950
2076
  if (result.status === "no-skills") {
1951
2077
  logger.info(