teamix-evo 0.5.0 → 0.6.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/README.md +5 -3
- package/dist/core/index.d.ts +205 -24
- package/dist/core/index.js +595 -72
- package/dist/core/index.js.map +1 -1
- package/dist/index.js +784 -254
- package/dist/index.js.map +1 -1
- package/package.json +8 -7
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
5
|
-
import { createRequire as
|
|
4
|
+
import { Command as Command32 } from "commander";
|
|
5
|
+
import { createRequire as createRequire8 } from "module";
|
|
6
6
|
|
|
7
7
|
// src/commands/tokens/index.ts
|
|
8
8
|
import { Command as Command6 } from "commander";
|
|
@@ -529,9 +529,11 @@ function makeMirrorRecord(skill, targetAbs, content, ide, scope, rel2) {
|
|
|
529
529
|
}
|
|
530
530
|
async function updateSkills(options) {
|
|
531
531
|
const { manifest, ides, scope, projectRoot } = options;
|
|
532
|
+
const idFilter = options.onlyIds ? new Set(options.onlyIds) : null;
|
|
532
533
|
const summary = { overwritten: 0, managed: 0, skipped: 0, created: 0 };
|
|
533
534
|
const updated = [];
|
|
534
535
|
for (const skill of manifest.skills) {
|
|
536
|
+
if (idFilter && !idFilter.has(skill.id)) continue;
|
|
535
537
|
const skillIdes = skill.ides.filter((i) => ides.includes(i));
|
|
536
538
|
if (skillIdes.length === 0) continue;
|
|
537
539
|
const sourceRecords = await rewriteSkillSource(
|
|
@@ -733,11 +735,73 @@ async function ensureMcpJson(projectRoot) {
|
|
|
733
735
|
// src/core/skills-add.ts
|
|
734
736
|
var DEFAULT_SKILLS_PACKAGE = "@teamix-evo/skills";
|
|
735
737
|
var FLAT_VARIANT = "_flat";
|
|
738
|
+
async function runSkillsInit(options) {
|
|
739
|
+
const { projectRoot } = options;
|
|
740
|
+
const packageName = options.packageName ?? DEFAULT_SKILLS_PACKAGE;
|
|
741
|
+
const ides = [...options.ides];
|
|
742
|
+
const scope = options.scope;
|
|
743
|
+
if (ides.length === 0) {
|
|
744
|
+
throw new Error("At least one IDE must be selected.");
|
|
745
|
+
}
|
|
746
|
+
await ensureTeamixDir(projectRoot);
|
|
747
|
+
const existingConfig = await readProjectConfig(projectRoot);
|
|
748
|
+
const existingSkillsCfg = existingConfig?.packages?.skills;
|
|
749
|
+
const { manifest, data, packageRoot } = await loadSkillsData(packageName);
|
|
750
|
+
const currentTokensVariant = await readTokensVariant(projectRoot);
|
|
751
|
+
const existing = await readExistingState(projectRoot, packageName);
|
|
752
|
+
const candidateIds = manifest.skills.filter((s) => {
|
|
753
|
+
const effectiveScope = s.scope ?? "project";
|
|
754
|
+
if (effectiveScope !== scope) {
|
|
755
|
+
logger.debug(
|
|
756
|
+
`Skipping skill "${s.id}" (scope=${effectiveScope}): current install scope is "${scope}". Use \`skills add ${s.id} --scope ${effectiveScope}\` to install.`
|
|
757
|
+
);
|
|
758
|
+
return false;
|
|
759
|
+
}
|
|
760
|
+
if (!s.variant) return true;
|
|
761
|
+
if (!currentTokensVariant) {
|
|
762
|
+
logger.debug(
|
|
763
|
+
`Skipping variant-bound skill "${s.id}" (variant=${s.variant}): no tokens variant installed; will be picked up when "tokens init" runs.`
|
|
764
|
+
);
|
|
765
|
+
return false;
|
|
766
|
+
}
|
|
767
|
+
if (s.variant !== currentTokensVariant) {
|
|
768
|
+
logger.debug(
|
|
769
|
+
`Skipping variant-bound skill "${s.id}" (variant=${s.variant}): current tokens variant is "${currentTokensVariant}".`
|
|
770
|
+
);
|
|
771
|
+
return false;
|
|
772
|
+
}
|
|
773
|
+
return true;
|
|
774
|
+
}).map((s) => s.id);
|
|
775
|
+
const skippedSkillIds = candidateIds.filter(
|
|
776
|
+
(id) => existing.skillIds.has(id)
|
|
777
|
+
);
|
|
778
|
+
const onlyIds = candidateIds.filter((id) => !existing.skillIds.has(id));
|
|
779
|
+
if (existingSkillsCfg && onlyIds.length === 0) {
|
|
780
|
+
return { status: "already-initialized" };
|
|
781
|
+
}
|
|
782
|
+
return finalizeSkillsInstall({
|
|
783
|
+
projectRoot,
|
|
784
|
+
packageName,
|
|
785
|
+
ideIdent: options.ide ?? "qoder",
|
|
786
|
+
manifest,
|
|
787
|
+
data,
|
|
788
|
+
packageRoot,
|
|
789
|
+
ides,
|
|
790
|
+
scope,
|
|
791
|
+
onlyIds,
|
|
792
|
+
skippedSkillIds,
|
|
793
|
+
existing,
|
|
794
|
+
existingConfig
|
|
795
|
+
});
|
|
796
|
+
}
|
|
736
797
|
async function runSkillsAdd(options) {
|
|
798
|
+
if (!options.names || options.names.length === 0) {
|
|
799
|
+
throw new Error(
|
|
800
|
+
"runSkillsAdd requires at least one skill id. Use runSkillsInit() for bulk install."
|
|
801
|
+
);
|
|
802
|
+
}
|
|
737
803
|
const { projectRoot, names: requestedNames } = options;
|
|
738
804
|
const packageName = options.packageName ?? DEFAULT_SKILLS_PACKAGE;
|
|
739
|
-
const ideIdent = options.ide ?? "qoder";
|
|
740
|
-
const isIncremental = !!requestedNames && requestedNames.length > 0;
|
|
741
805
|
await ensureTeamixDir(projectRoot);
|
|
742
806
|
const existingConfig = await readProjectConfig(projectRoot);
|
|
743
807
|
const existingSkillsCfg = existingConfig?.packages?.skills;
|
|
@@ -750,57 +814,27 @@ async function runSkillsAdd(options) {
|
|
|
750
814
|
throw new Error("Scope must be specified (project | global).");
|
|
751
815
|
}
|
|
752
816
|
const { manifest, data, packageRoot } = await loadSkillsData(packageName);
|
|
753
|
-
const
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
const
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
817
|
+
const known = new Set(manifest.skills.map((s) => s.id));
|
|
818
|
+
const unknown = requestedNames.filter((n) => !known.has(n));
|
|
819
|
+
if (unknown.length > 0) {
|
|
820
|
+
const available = [...known].join(", ");
|
|
821
|
+
throw new Error(
|
|
822
|
+
`Unknown skill id(s): ${unknown.join(", ")}. Available: ${available || "(none)"}.`
|
|
823
|
+
);
|
|
824
|
+
}
|
|
825
|
+
for (const s of manifest.skills) {
|
|
826
|
+
if (requestedNames.includes(s.id) && s.scope && s.scope !== scope) {
|
|
827
|
+
logger.warn(
|
|
828
|
+
`"${s.id}" \u63A8\u8350 ${s.scope} scope \u5B89\u88C5\u3002\u5F53\u524D\u4EE5 ${scope} scope \u5F3A\u5236\u5B89\u88C5,\u53EF\u80FD\u4E0E\u53E6\u4E00 scope \u7684\u526F\u672C\u51B2\u7A81\u3002\u5EFA\u8BAE\u6539\u7528 \`skills add ${s.id} --scope ${s.scope}\`\u3002`
|
|
761
829
|
);
|
|
762
830
|
}
|
|
763
831
|
}
|
|
764
|
-
const
|
|
765
|
-
const
|
|
766
|
-
(
|
|
832
|
+
const existing = await readExistingState(projectRoot, packageName);
|
|
833
|
+
const skippedSkillIds = requestedNames.filter(
|
|
834
|
+
(n) => existing.skillIds.has(n)
|
|
767
835
|
);
|
|
768
|
-
const
|
|
769
|
-
|
|
770
|
-
...Object.keys(existingLock?.skills ?? {}),
|
|
771
|
-
// Legacy fallback: pre-ADR-0013 installs only had manifest.json. Derive
|
|
772
|
-
// skill ids by stripping the trailing :source / :sub-file suffix.
|
|
773
|
-
...(existingPkg?.resources ?? []).map((r) => r.id.split(":")[0])
|
|
774
|
-
]);
|
|
775
|
-
let onlyIds;
|
|
776
|
-
let skippedSkillIds;
|
|
777
|
-
if (isIncremental) {
|
|
778
|
-
skippedSkillIds = requestedNames.filter((n) => existingSkillIds.has(n));
|
|
779
|
-
onlyIds = requestedNames.filter((n) => !existingSkillIds.has(n));
|
|
780
|
-
} else {
|
|
781
|
-
const candidateIds = manifest.skills.filter((s) => {
|
|
782
|
-
if (!s.variant) return true;
|
|
783
|
-
if (!currentTokensVariant) {
|
|
784
|
-
logger.debug(
|
|
785
|
-
`Skipping variant-bound skill "${s.id}" (variant=${s.variant}): no tokens variant installed; will be picked up when "tokens init" runs.`
|
|
786
|
-
);
|
|
787
|
-
return false;
|
|
788
|
-
}
|
|
789
|
-
if (s.variant !== currentTokensVariant) {
|
|
790
|
-
logger.debug(
|
|
791
|
-
`Skipping variant-bound skill "${s.id}" (variant=${s.variant}): current tokens variant is "${currentTokensVariant}".`
|
|
792
|
-
);
|
|
793
|
-
return false;
|
|
794
|
-
}
|
|
795
|
-
return true;
|
|
796
|
-
}).map((s) => s.id);
|
|
797
|
-
skippedSkillIds = candidateIds.filter((id) => existingSkillIds.has(id));
|
|
798
|
-
onlyIds = candidateIds.filter((id) => !existingSkillIds.has(id));
|
|
799
|
-
}
|
|
800
|
-
if (!isIncremental && existingSkillsCfg && onlyIds.length === 0) {
|
|
801
|
-
return { status: "already-added" };
|
|
802
|
-
}
|
|
803
|
-
if (isIncremental && onlyIds.length === 0) {
|
|
836
|
+
const onlyIds = requestedNames.filter((n) => !existing.skillIds.has(n));
|
|
837
|
+
if (onlyIds.length === 0) {
|
|
804
838
|
return {
|
|
805
839
|
status: "installed",
|
|
806
840
|
packageName,
|
|
@@ -814,6 +848,48 @@ async function runSkillsAdd(options) {
|
|
|
814
848
|
skippedSkillIds
|
|
815
849
|
};
|
|
816
850
|
}
|
|
851
|
+
return finalizeSkillsInstall({
|
|
852
|
+
projectRoot,
|
|
853
|
+
packageName,
|
|
854
|
+
ideIdent: options.ide ?? "qoder",
|
|
855
|
+
manifest,
|
|
856
|
+
data,
|
|
857
|
+
packageRoot,
|
|
858
|
+
ides,
|
|
859
|
+
scope,
|
|
860
|
+
onlyIds,
|
|
861
|
+
skippedSkillIds,
|
|
862
|
+
existing,
|
|
863
|
+
existingConfig
|
|
864
|
+
});
|
|
865
|
+
}
|
|
866
|
+
async function readExistingState(projectRoot, packageName) {
|
|
867
|
+
const installed = await readInstalledManifest(projectRoot);
|
|
868
|
+
const pkg = installed?.installed.find((p) => p.package === packageName);
|
|
869
|
+
const lock = await readSkillsLock(projectRoot);
|
|
870
|
+
const skillIds = /* @__PURE__ */ new Set([
|
|
871
|
+
...Object.keys(lock?.skills ?? {}),
|
|
872
|
+
// Legacy fallback: pre-ADR-0013 installs only had manifest.json. Derive
|
|
873
|
+
// skill ids by stripping the trailing :source / :sub-file suffix.
|
|
874
|
+
...(pkg?.resources ?? []).map((r) => r.id.split(":")[0] ?? r.id)
|
|
875
|
+
]);
|
|
876
|
+
return { installed, pkg, lock, skillIds };
|
|
877
|
+
}
|
|
878
|
+
async function finalizeSkillsInstall(args) {
|
|
879
|
+
const {
|
|
880
|
+
projectRoot,
|
|
881
|
+
packageName,
|
|
882
|
+
ideIdent,
|
|
883
|
+
manifest,
|
|
884
|
+
data,
|
|
885
|
+
packageRoot,
|
|
886
|
+
ides,
|
|
887
|
+
scope,
|
|
888
|
+
onlyIds,
|
|
889
|
+
skippedSkillIds,
|
|
890
|
+
existing,
|
|
891
|
+
existingConfig
|
|
892
|
+
} = args;
|
|
817
893
|
const result = await installSkills({
|
|
818
894
|
projectRoot,
|
|
819
895
|
manifest,
|
|
@@ -837,7 +913,7 @@ async function runSkillsAdd(options) {
|
|
|
837
913
|
};
|
|
838
914
|
await writeProjectConfig(projectRoot, config);
|
|
839
915
|
const installedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
840
|
-
const installedManifest =
|
|
916
|
+
const installedManifest = existing.installed ?? {
|
|
841
917
|
schemaVersion: 1,
|
|
842
918
|
installed: []
|
|
843
919
|
};
|
|
@@ -845,7 +921,7 @@ async function runSkillsAdd(options) {
|
|
|
845
921
|
(p) => p.package === packageName
|
|
846
922
|
);
|
|
847
923
|
const mergedResources = mergeInstalledResources(
|
|
848
|
-
|
|
924
|
+
existing.pkg?.resources ?? [],
|
|
849
925
|
result.resources
|
|
850
926
|
);
|
|
851
927
|
const entry = {
|
|
@@ -858,7 +934,7 @@ async function runSkillsAdd(options) {
|
|
|
858
934
|
if (idx >= 0) installedManifest.installed[idx] = entry;
|
|
859
935
|
else installedManifest.installed.push(entry);
|
|
860
936
|
await writeInstalledManifest(projectRoot, installedManifest);
|
|
861
|
-
const lock =
|
|
937
|
+
const lock = existing.lock ?? {
|
|
862
938
|
schemaVersion: 1,
|
|
863
939
|
skills: {}
|
|
864
940
|
};
|
|
@@ -1521,11 +1597,11 @@ var uninstallCommand = new Command5("uninstall").description(
|
|
|
1521
1597
|
`Will remove ${removable.length} file(s); keep ${kept} managed file(s).`
|
|
1522
1598
|
);
|
|
1523
1599
|
if (!opts.yes) {
|
|
1524
|
-
const
|
|
1600
|
+
const confirm5 = await prompts.confirm({
|
|
1525
1601
|
message: "\u786E\u8BA4\u5378\u8F7D tokens \u53D8\u4F53\uFF1F",
|
|
1526
1602
|
initialValue: false
|
|
1527
1603
|
});
|
|
1528
|
-
if (prompts.isCancel(
|
|
1604
|
+
if (prompts.isCancel(confirm5) || !confirm5) {
|
|
1529
1605
|
logger.info("Cancelled.");
|
|
1530
1606
|
return;
|
|
1531
1607
|
}
|
|
@@ -1588,28 +1664,133 @@ tokensCommand.addCommand(listVariantsCommand);
|
|
|
1588
1664
|
tokensCommand.addCommand(uninstallCommand);
|
|
1589
1665
|
|
|
1590
1666
|
// src/commands/skills/index.ts
|
|
1591
|
-
import { Command as
|
|
1667
|
+
import { Command as Command14 } from "commander";
|
|
1592
1668
|
|
|
1593
|
-
// src/commands/skills/
|
|
1669
|
+
// src/commands/skills/init.ts
|
|
1594
1670
|
import { Command as Command7 } from "commander";
|
|
1595
1671
|
import * as prompts2 from "@clack/prompts";
|
|
1596
|
-
var
|
|
1597
|
-
"\
|
|
1598
|
-
).
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1672
|
+
var initCommand2 = new Command7("init").description(
|
|
1673
|
+
"\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
|
+
).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) => {
|
|
1675
|
+
try {
|
|
1676
|
+
const ide = detectIde();
|
|
1677
|
+
const cwd = ide.getProjectRoot();
|
|
1678
|
+
const { ides, scope } = await resolveIdesAndScope({ opts });
|
|
1679
|
+
let projectRoot = cwd;
|
|
1680
|
+
if (scope === "global" && !isTeamixEvoProject(cwd)) {
|
|
1681
|
+
projectRoot = await ensureGlobalMetaRoot();
|
|
1682
|
+
logger.info(`Global skill install \u2014 meta root: ${projectRoot}`);
|
|
1683
|
+
} else if (scope !== "global" && !hasPackageJson(cwd)) {
|
|
1684
|
+
logger.error(
|
|
1685
|
+
"No package.json found in current directory. Please run this command in a valid project root."
|
|
1686
|
+
);
|
|
1687
|
+
process.exit(1);
|
|
1688
|
+
}
|
|
1689
|
+
logger.info(
|
|
1690
|
+
`Initializing skills (bulk): ides=[${ides.join(",")}], scope="${scope}"`
|
|
1691
|
+
);
|
|
1692
|
+
logger.debug(`Project root: ${projectRoot}`);
|
|
1693
|
+
const result = await runSkillsInit({
|
|
1694
|
+
projectRoot,
|
|
1695
|
+
ides,
|
|
1696
|
+
scope,
|
|
1697
|
+
ide: ide.name
|
|
1698
|
+
});
|
|
1699
|
+
if (result.status === "already-initialized") {
|
|
1700
|
+
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.`
|
|
1702
|
+
);
|
|
1703
|
+
return;
|
|
1704
|
+
}
|
|
1705
|
+
logger.success(`Skills initialized: ${result.skillCount} skill(s)`);
|
|
1706
|
+
logger.info(` IDEs: ${result.ides.join(", ")}`);
|
|
1707
|
+
logger.info(` Scope: ${result.scope}`);
|
|
1708
|
+
if (result.addedSkillIds.length > 0) {
|
|
1709
|
+
logger.info(` Added: ${result.addedSkillIds.join(", ")}`);
|
|
1710
|
+
}
|
|
1711
|
+
if (result.skippedSkillIds.length > 0) {
|
|
1712
|
+
logger.info(
|
|
1713
|
+
` Skipped: ${result.skippedSkillIds.join(", ")} (already added)`
|
|
1714
|
+
);
|
|
1715
|
+
}
|
|
1716
|
+
logger.info(` Files: ${result.fileCount}`);
|
|
1717
|
+
logger.info("");
|
|
1718
|
+
logger.info('Run "teamix-evo skills list" to see installed skills.');
|
|
1719
|
+
} catch (err) {
|
|
1720
|
+
logger.error(`Failed to init skills: ${err.message}`);
|
|
1721
|
+
logger.debug(err.stack ?? "");
|
|
1722
|
+
process.exitCode = 1;
|
|
1723
|
+
}
|
|
1724
|
+
});
|
|
1725
|
+
async function resolveIdesAndScope(args) {
|
|
1726
|
+
const { opts } = args;
|
|
1727
|
+
const isInteractive = Boolean(process.stdin.isTTY);
|
|
1728
|
+
if (opts.ide || opts.yes || !isInteractive) {
|
|
1729
|
+
const ides = opts.ide ? parseIdeList(opts.ide) : [...ALL_IDE_KINDS];
|
|
1730
|
+
const scope = parseScope(opts.scope);
|
|
1731
|
+
if (ides.length === 0) {
|
|
1732
|
+
throw new Error("At least one IDE must be selected.");
|
|
1733
|
+
}
|
|
1734
|
+
return { ides, scope };
|
|
1735
|
+
}
|
|
1736
|
+
const idesAns = await prompts2.multiselect({
|
|
1737
|
+
message: "\u9009\u62E9\u8981\u6CE8\u5165\u6280\u80FD\u7684 AI IDE\uFF08\u81F3\u5C11\u4E00\u4E2A\uFF09",
|
|
1738
|
+
options: ALL_IDE_KINDS.map((k) => ({
|
|
1739
|
+
value: k,
|
|
1740
|
+
label: k === "qoder" ? "Qoder" : "Claude Code"
|
|
1741
|
+
})),
|
|
1742
|
+
initialValues: [...ALL_IDE_KINDS],
|
|
1743
|
+
required: true
|
|
1744
|
+
});
|
|
1745
|
+
if (prompts2.isCancel(idesAns)) {
|
|
1746
|
+
throw new Error("Cancelled by user.");
|
|
1747
|
+
}
|
|
1748
|
+
const scopeAns = await prompts2.select({
|
|
1749
|
+
message: "\u5B89\u88C5\u8303\u56F4\uFF1F",
|
|
1750
|
+
options: [
|
|
1751
|
+
{ value: "project", label: "\u9879\u76EE\u7EA7\uFF08.qoder/.claude \u5728\u5F53\u524D\u9879\u76EE\uFF09" },
|
|
1752
|
+
{ value: "global", label: "\u5168\u5C40\uFF08~/.qoder/~/.claude\uFF09" }
|
|
1753
|
+
],
|
|
1754
|
+
initialValue: "project"
|
|
1755
|
+
});
|
|
1756
|
+
if (prompts2.isCancel(scopeAns)) {
|
|
1757
|
+
throw new Error("Cancelled by user.");
|
|
1758
|
+
}
|
|
1759
|
+
return { ides: idesAns, scope: scopeAns };
|
|
1760
|
+
}
|
|
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
|
+
|
|
1779
|
+
// src/commands/skills/add.ts
|
|
1780
|
+
import { Command as Command8 } from "commander";
|
|
1781
|
+
import * as prompts3 from "@clack/prompts";
|
|
1782
|
+
var addCommand = new Command8("add").description(
|
|
1783
|
+
"\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"
|
|
1784
|
+
).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(
|
|
1602
1785
|
"--scope <scope>",
|
|
1603
|
-
"project | global\uFF08\u9ED8\u8BA4
|
|
1786
|
+
"project | global\uFF08\u9ED8\u8BA4\u6CBF\u7528\u65E2\u6709 skills \u914D\u7F6E\uFF1B\u9996\u6B21\u5B89\u88C5\u9ED8\u8BA4 project\uFF09"
|
|
1604
1787
|
).option("-y, --yes", "\u4F7F\u7528\u9ED8\u8BA4\u503C\uFF0C\u8DF3\u8FC7\u4EA4\u4E92").action(async (names, opts) => {
|
|
1605
1788
|
try {
|
|
1606
1789
|
const ide = detectIde();
|
|
1607
1790
|
const cwd = ide.getProjectRoot();
|
|
1608
|
-
const
|
|
1609
|
-
const { ides, scope } = await resolveIdesAndScope({
|
|
1791
|
+
const { ides, scope } = await resolveIdesAndScope2({
|
|
1610
1792
|
opts,
|
|
1611
|
-
projectRoot: cwd
|
|
1612
|
-
isIncremental
|
|
1793
|
+
projectRoot: cwd
|
|
1613
1794
|
});
|
|
1614
1795
|
let projectRoot = cwd;
|
|
1615
1796
|
if (scope === "global" && !isTeamixEvoProject(cwd)) {
|
|
@@ -1622,9 +1803,9 @@ var addCommand = new Command7("add").description(
|
|
|
1622
1803
|
process.exit(1);
|
|
1623
1804
|
}
|
|
1624
1805
|
logger.info(
|
|
1625
|
-
|
|
1806
|
+
`Adding skills [${names.join(",")}]: ides=[${ides.join(
|
|
1626
1807
|
","
|
|
1627
|
-
)}], scope="${scope}"`
|
|
1808
|
+
)}], scope="${scope}"`
|
|
1628
1809
|
);
|
|
1629
1810
|
logger.debug(`Project root: ${projectRoot}`);
|
|
1630
1811
|
const result = await runSkillsAdd({
|
|
@@ -1632,14 +1813,8 @@ var addCommand = new Command7("add").description(
|
|
|
1632
1813
|
ides,
|
|
1633
1814
|
scope,
|
|
1634
1815
|
ide: ide.name,
|
|
1635
|
-
names
|
|
1816
|
+
names
|
|
1636
1817
|
});
|
|
1637
|
-
if (result.status === "already-added") {
|
|
1638
|
-
logger.warn(
|
|
1639
|
-
`Skills already added. Use "teamix-evo skills add <name>" to add specific skills, "teamix-evo skills update" to refresh, or "teamix-evo skills uninstall" to remove.`
|
|
1640
|
-
);
|
|
1641
|
-
return;
|
|
1642
|
-
}
|
|
1643
1818
|
if (result.addedSkillIds.length === 0 && result.skippedSkillIds.length > 0) {
|
|
1644
1819
|
logger.warn(
|
|
1645
1820
|
`\u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u6DFB\u52A0\uFF1A${result.skippedSkillIds.join(
|
|
@@ -1668,9 +1843,9 @@ var addCommand = new Command7("add").description(
|
|
|
1668
1843
|
process.exitCode = 1;
|
|
1669
1844
|
}
|
|
1670
1845
|
});
|
|
1671
|
-
async function
|
|
1672
|
-
const { opts, projectRoot
|
|
1673
|
-
if (
|
|
1846
|
+
async function resolveIdesAndScope2(args) {
|
|
1847
|
+
const { opts, projectRoot } = args;
|
|
1848
|
+
if (!opts.ide && !opts.scope && !opts.yes) {
|
|
1674
1849
|
const existing = await readProjectConfig(projectRoot);
|
|
1675
1850
|
const cfg = existing?.packages?.skills;
|
|
1676
1851
|
if (cfg && cfg.ides && cfg.ides.length > 0 && cfg.scope) {
|
|
@@ -1684,14 +1859,14 @@ async function resolveIdesAndScope(args) {
|
|
|
1684
1859
|
}
|
|
1685
1860
|
}
|
|
1686
1861
|
if (opts.ide || opts.yes) {
|
|
1687
|
-
const ides = opts.ide ?
|
|
1688
|
-
const scope =
|
|
1862
|
+
const ides = opts.ide ? parseIdeList2(opts.ide) : [...ALL_IDE_KINDS];
|
|
1863
|
+
const scope = parseScope2(opts.scope);
|
|
1689
1864
|
if (ides.length === 0) {
|
|
1690
1865
|
throw new Error("At least one IDE must be selected.");
|
|
1691
1866
|
}
|
|
1692
1867
|
return { ides, scope };
|
|
1693
1868
|
}
|
|
1694
|
-
const idesAns = await
|
|
1869
|
+
const idesAns = await prompts3.multiselect({
|
|
1695
1870
|
message: "\u9009\u62E9\u8981\u6CE8\u5165\u6280\u80FD\u7684 AI IDE\uFF08\u81F3\u5C11\u4E00\u4E2A\uFF09",
|
|
1696
1871
|
options: ALL_IDE_KINDS.map((k) => ({
|
|
1697
1872
|
value: k,
|
|
@@ -1700,10 +1875,10 @@ async function resolveIdesAndScope(args) {
|
|
|
1700
1875
|
initialValues: [...ALL_IDE_KINDS],
|
|
1701
1876
|
required: true
|
|
1702
1877
|
});
|
|
1703
|
-
if (
|
|
1878
|
+
if (prompts3.isCancel(idesAns)) {
|
|
1704
1879
|
throw new Error("Cancelled by user.");
|
|
1705
1880
|
}
|
|
1706
|
-
const scopeAns = await
|
|
1881
|
+
const scopeAns = await prompts3.select({
|
|
1707
1882
|
message: "\u5B89\u88C5\u8303\u56F4\uFF1F",
|
|
1708
1883
|
options: [
|
|
1709
1884
|
{ value: "project", label: "\u9879\u76EE\u7EA7\uFF08.qoder/.claude \u5728\u5F53\u524D\u9879\u76EE\uFF09" },
|
|
@@ -1711,12 +1886,12 @@ async function resolveIdesAndScope(args) {
|
|
|
1711
1886
|
],
|
|
1712
1887
|
initialValue: "project"
|
|
1713
1888
|
});
|
|
1714
|
-
if (
|
|
1889
|
+
if (prompts3.isCancel(scopeAns)) {
|
|
1715
1890
|
throw new Error("Cancelled by user.");
|
|
1716
1891
|
}
|
|
1717
1892
|
return { ides: idesAns, scope: scopeAns };
|
|
1718
1893
|
}
|
|
1719
|
-
function
|
|
1894
|
+
function parseIdeList2(input) {
|
|
1720
1895
|
const parts = input.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
1721
1896
|
const result = [];
|
|
1722
1897
|
for (const p of parts) {
|
|
@@ -1728,16 +1903,16 @@ function parseIdeList(input) {
|
|
|
1728
1903
|
}
|
|
1729
1904
|
return result;
|
|
1730
1905
|
}
|
|
1731
|
-
function
|
|
1906
|
+
function parseScope2(input) {
|
|
1732
1907
|
const v = (input ?? "project").toLowerCase();
|
|
1733
1908
|
if (v === "project" || v === "global") return v;
|
|
1734
1909
|
throw new Error(`Invalid --scope: "${input}". Expected project | global.`);
|
|
1735
1910
|
}
|
|
1736
1911
|
|
|
1737
1912
|
// src/commands/skills/list.ts
|
|
1738
|
-
import { Command as
|
|
1913
|
+
import { Command as Command9 } from "commander";
|
|
1739
1914
|
var SKILLS_PACKAGE = "@teamix-evo/skills";
|
|
1740
|
-
var listCommand2 = new
|
|
1915
|
+
var listCommand2 = new Command9("list").alias("ls").description(
|
|
1741
1916
|
"\u5217\u51FA teamix-evo skills\uFF08\u9ED8\u8BA4\u5C55\u793A\u5168\u90E8 skill \u5E76\u6807\u6CE8\u5DF2\u88C5/\u672A\u88C5\uFF1B--installed \u4EC5\u770B\u5DF2\u88C5\uFF09"
|
|
1742
1917
|
).option("--installed", "\u4EC5\u5C55\u793A\u5DF2\u5B89\u88C5\u7684 skill\uFF08\u9690\u85CF\u672A\u5B89\u88C5\u9879\uFF09").action(async (opts) => {
|
|
1743
1918
|
try {
|
|
@@ -1766,7 +1941,7 @@ var listCommand2 = new Command8("list").alias("ls").description(
|
|
|
1766
1941
|
if (opts.installed) {
|
|
1767
1942
|
if (!config?.packages?.skills || !pkg) {
|
|
1768
1943
|
logger.info("No skills installed.");
|
|
1769
|
-
logger.info('Run "teamix-evo skills
|
|
1944
|
+
logger.info('Run "teamix-evo skills init" to get started.');
|
|
1770
1945
|
return;
|
|
1771
1946
|
}
|
|
1772
1947
|
printInstalledHeader(config.packages.skills, pkg.installedAt);
|
|
@@ -1795,7 +1970,7 @@ var listCommand2 = new Command8("list").alias("ls").description(
|
|
|
1795
1970
|
} else {
|
|
1796
1971
|
logger.info("Skills package not yet added.");
|
|
1797
1972
|
logger.info(
|
|
1798
|
-
'Run "teamix-evo skills
|
|
1973
|
+
'Run "teamix-evo skills init" to bootstrap, or "teamix-evo skills add <id...>" for specific skills.'
|
|
1799
1974
|
);
|
|
1800
1975
|
}
|
|
1801
1976
|
logger.info("");
|
|
@@ -1831,10 +2006,185 @@ function printInstalledHeader(cfg, installedAt) {
|
|
|
1831
2006
|
}
|
|
1832
2007
|
|
|
1833
2008
|
// src/commands/skills/update.ts
|
|
1834
|
-
import { Command as
|
|
1835
|
-
|
|
2009
|
+
import { Command as Command10 } from "commander";
|
|
2010
|
+
import { createRequire as createRequire4 } from "module";
|
|
2011
|
+
|
|
2012
|
+
// src/core/skills-update.ts
|
|
2013
|
+
var DEFAULT_SKILLS_PACKAGE3 = "@teamix-evo/skills";
|
|
1836
2014
|
var FLAT_VARIANT2 = "_flat";
|
|
1837
|
-
|
|
2015
|
+
async function runSkillsUpdate(options) {
|
|
2016
|
+
const { projectRoot, names: requestedNames, dryRun } = options;
|
|
2017
|
+
const packageName = options.packageName ?? DEFAULT_SKILLS_PACKAGE3;
|
|
2018
|
+
const config = await readProjectConfig(projectRoot);
|
|
2019
|
+
const skillsCfg = config?.packages?.skills;
|
|
2020
|
+
if (!skillsCfg) {
|
|
2021
|
+
return { status: "no-skills" };
|
|
2022
|
+
}
|
|
2023
|
+
const ides = skillsCfg.ides ?? ["qoder", "claude"];
|
|
2024
|
+
const scope = skillsCfg.scope ?? "project";
|
|
2025
|
+
const existingLock = await readSkillsLock(projectRoot);
|
|
2026
|
+
if (!existingLock || Object.keys(existingLock.skills).length === 0) {
|
|
2027
|
+
return { status: "no-skills" };
|
|
2028
|
+
}
|
|
2029
|
+
const { manifest, data, packageRoot } = await loadSkillsData(packageName);
|
|
2030
|
+
const manifestById = new Map(manifest.skills.map((s) => [s.id, s]));
|
|
2031
|
+
const lockIds = Object.keys(existingLock.skills);
|
|
2032
|
+
const requestedSet = requestedNames ? new Set(requestedNames) : null;
|
|
2033
|
+
if (requestedSet) {
|
|
2034
|
+
const unknown = requestedNames.filter(
|
|
2035
|
+
(n) => !lockIds.includes(n) && !manifestById.has(n)
|
|
2036
|
+
);
|
|
2037
|
+
if (unknown.length > 0) {
|
|
2038
|
+
throw new Error(
|
|
2039
|
+
`Unknown skill id(s): ${unknown.join(
|
|
2040
|
+
", "
|
|
2041
|
+
)}. Available (installed): ${lockIds.join(", ") || "(none)"}.`
|
|
2042
|
+
);
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
const targetIds = [];
|
|
2046
|
+
const skippedSkillIds = [];
|
|
2047
|
+
for (const id of lockIds) {
|
|
2048
|
+
if (requestedSet && !requestedSet.has(id)) continue;
|
|
2049
|
+
const entry2 = manifestById.get(id);
|
|
2050
|
+
if (!entry2) {
|
|
2051
|
+
logger.debug(
|
|
2052
|
+
`Skipping "${id}": no longer in upstream manifest. Use \`skills uninstall ${id}\` to remove.`
|
|
2053
|
+
);
|
|
2054
|
+
skippedSkillIds.push(id);
|
|
2055
|
+
continue;
|
|
2056
|
+
}
|
|
2057
|
+
const effectiveScope = entry2.scope ?? "project";
|
|
2058
|
+
if (effectiveScope !== scope) {
|
|
2059
|
+
logger.debug(
|
|
2060
|
+
`Skipping "${id}" (scope=${effectiveScope}): current install scope is "${scope}".`
|
|
2061
|
+
);
|
|
2062
|
+
skippedSkillIds.push(id);
|
|
2063
|
+
continue;
|
|
2064
|
+
}
|
|
2065
|
+
targetIds.push(id);
|
|
2066
|
+
}
|
|
2067
|
+
const allSame = targetIds.every((id) => {
|
|
2068
|
+
const lockVer = existingLock.skills[id].version;
|
|
2069
|
+
const manVer = manifestById.get(id).version;
|
|
2070
|
+
return lockVer === manVer;
|
|
2071
|
+
});
|
|
2072
|
+
if (targetIds.length > 0 && allSame && !dryRun) {
|
|
2073
|
+
return {
|
|
2074
|
+
status: "no-changes",
|
|
2075
|
+
packageName,
|
|
2076
|
+
version: manifest.version,
|
|
2077
|
+
checkedSkillIds: targetIds
|
|
2078
|
+
};
|
|
2079
|
+
}
|
|
2080
|
+
if (dryRun) {
|
|
2081
|
+
const plan = targetIds.map((id) => {
|
|
2082
|
+
const lockVer = existingLock.skills[id].version;
|
|
2083
|
+
const entry2 = manifestById.get(id);
|
|
2084
|
+
const sameVersion = lockVer === entry2.version;
|
|
2085
|
+
return {
|
|
2086
|
+
id,
|
|
2087
|
+
current: lockVer,
|
|
2088
|
+
next: entry2.version,
|
|
2089
|
+
strategy: entry2.updateStrategy ?? "managed",
|
|
2090
|
+
action: sameVersion ? "up-to-date" : "version-bump"
|
|
2091
|
+
};
|
|
2092
|
+
});
|
|
2093
|
+
return {
|
|
2094
|
+
status: "dry-run",
|
|
2095
|
+
packageName,
|
|
2096
|
+
currentVersion: skillsCfg.version,
|
|
2097
|
+
availableVersion: manifest.version,
|
|
2098
|
+
plan
|
|
2099
|
+
};
|
|
2100
|
+
}
|
|
2101
|
+
if (targetIds.length === 0) {
|
|
2102
|
+
return {
|
|
2103
|
+
status: "updated",
|
|
2104
|
+
packageName,
|
|
2105
|
+
version: manifest.version,
|
|
2106
|
+
ides,
|
|
2107
|
+
scope,
|
|
2108
|
+
updatedSkillIds: [],
|
|
2109
|
+
skippedSkillIds,
|
|
2110
|
+
summary: { overwritten: 0, managed: 0, skipped: 0, created: 0 },
|
|
2111
|
+
resources: []
|
|
2112
|
+
};
|
|
2113
|
+
}
|
|
2114
|
+
const result = await updateSkills({
|
|
2115
|
+
projectRoot,
|
|
2116
|
+
manifest,
|
|
2117
|
+
data,
|
|
2118
|
+
packageRoot,
|
|
2119
|
+
ides,
|
|
2120
|
+
scope,
|
|
2121
|
+
onlyIds: targetIds
|
|
2122
|
+
});
|
|
2123
|
+
config.packages.skills = {
|
|
2124
|
+
...skillsCfg,
|
|
2125
|
+
version: manifest.version
|
|
2126
|
+
};
|
|
2127
|
+
await writeProjectConfig(projectRoot, config);
|
|
2128
|
+
const installedManifest = await readInstalledManifest(projectRoot) ?? {
|
|
2129
|
+
schemaVersion: 1,
|
|
2130
|
+
installed: []
|
|
2131
|
+
};
|
|
2132
|
+
const idx = installedManifest.installed.findIndex(
|
|
2133
|
+
(p) => p.package === packageName
|
|
2134
|
+
);
|
|
2135
|
+
const installedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2136
|
+
const prior = idx >= 0 ? installedManifest.installed[idx].resources : [];
|
|
2137
|
+
const targetSet = new Set(targetIds);
|
|
2138
|
+
const preserved = prior.filter((r) => {
|
|
2139
|
+
const skillId = r.id.split(":")[0];
|
|
2140
|
+
return skillId ? !targetSet.has(skillId) : true;
|
|
2141
|
+
});
|
|
2142
|
+
const entry = {
|
|
2143
|
+
package: packageName,
|
|
2144
|
+
variant: FLAT_VARIANT2,
|
|
2145
|
+
version: manifest.version,
|
|
2146
|
+
installedAt,
|
|
2147
|
+
resources: [...preserved, ...result.resources]
|
|
2148
|
+
};
|
|
2149
|
+
if (idx >= 0) installedManifest.installed[idx] = entry;
|
|
2150
|
+
else installedManifest.installed.push(entry);
|
|
2151
|
+
await writeInstalledManifest(projectRoot, installedManifest);
|
|
2152
|
+
const lock = {
|
|
2153
|
+
schemaVersion: 1,
|
|
2154
|
+
skills: { ...existingLock.skills }
|
|
2155
|
+
};
|
|
2156
|
+
for (const id of targetIds) {
|
|
2157
|
+
const skillDef = manifestById.get(id);
|
|
2158
|
+
if (!skillDef) continue;
|
|
2159
|
+
const mirroredTo = skillDef.ides.filter((i) => ides.includes(i));
|
|
2160
|
+
lock.skills[id] = {
|
|
2161
|
+
version: skillDef.version,
|
|
2162
|
+
from: packageName,
|
|
2163
|
+
installedAt,
|
|
2164
|
+
scope,
|
|
2165
|
+
mirroredTo
|
|
2166
|
+
};
|
|
2167
|
+
}
|
|
2168
|
+
await writeSkillsLock(projectRoot, lock);
|
|
2169
|
+
return {
|
|
2170
|
+
status: "updated",
|
|
2171
|
+
packageName,
|
|
2172
|
+
version: manifest.version,
|
|
2173
|
+
ides,
|
|
2174
|
+
scope,
|
|
2175
|
+
updatedSkillIds: targetIds,
|
|
2176
|
+
skippedSkillIds,
|
|
2177
|
+
summary: result.summary,
|
|
2178
|
+
resources: result.resources
|
|
2179
|
+
};
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2182
|
+
// src/commands/skills/update.ts
|
|
2183
|
+
var require5 = createRequire4(import.meta.url);
|
|
2184
|
+
var SKILLS_PACKAGE2 = "@teamix-evo/skills";
|
|
2185
|
+
var updateCommand2 = new Command10("update").description(
|
|
2186
|
+
"\u66F4\u65B0\u5DF2\u5B89\u88C5\u7684 teamix-evo skills\uFF08\u4EC5\u5347\u7EA7 lock \u5DF2\u8BB0\u5F55\u4E14 scope \u5339\u914D\u7684 skill \u2014 ADR 0035\uFF09"
|
|
2187
|
+
).argument("[names...]", "\u53EF\u9009\uFF1A\u4EC5\u5347\u7EA7\u6307\u5B9A skill id;\u7701\u7565\u5219\u5347\u7EA7\u5168\u90E8\u5DF2\u88C5").option("--dry-run", "\u9884\u89C8\u53D8\u66F4\uFF0C\u4E0D\u5199\u76D8").action(async (names, opts) => {
|
|
1838
2188
|
try {
|
|
1839
2189
|
const ide = detectIde();
|
|
1840
2190
|
const cwd = ide.getProjectRoot();
|
|
@@ -1842,95 +2192,101 @@ var updateCommand2 = new Command9("update").description("\u66F4\u65B0\u5DF2\u5B8
|
|
|
1842
2192
|
if (projectRoot !== cwd) {
|
|
1843
2193
|
logger.info(`Using global skills meta root: ${projectRoot}`);
|
|
1844
2194
|
}
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
logger.error('Skills not added. Run "teamix-evo skills add" first.');
|
|
1848
|
-
process.exitCode = 1;
|
|
1849
|
-
return;
|
|
1850
|
-
}
|
|
1851
|
-
const installedManifest = await readInstalledManifest(projectRoot);
|
|
1852
|
-
if (!installedManifest) {
|
|
1853
|
-
logger.error("No installed manifest found.");
|
|
1854
|
-
process.exitCode = 1;
|
|
1855
|
-
return;
|
|
1856
|
-
}
|
|
1857
|
-
const skillsEntry = config.packages.skills;
|
|
1858
|
-
const ides = skillsEntry.ides ?? [
|
|
1859
|
-
"qoder",
|
|
1860
|
-
"claude"
|
|
1861
|
-
];
|
|
1862
|
-
const scope = skillsEntry.scope ?? "project";
|
|
1863
|
-
logger.info(`Updating skills (ides=[${ides.join(",")}], scope=${scope})`);
|
|
1864
|
-
const { manifest, data, packageRoot } = await loadSkillsData(
|
|
1865
|
-
SKILLS_PACKAGE2
|
|
1866
|
-
);
|
|
1867
|
-
logger.info(
|
|
1868
|
-
`Current: v${skillsEntry.version} \u2192 Available: v${manifest.version}`
|
|
1869
|
-
);
|
|
1870
|
-
const result = await updateSkills({
|
|
2195
|
+
await printVersionBanner();
|
|
2196
|
+
const result = await runSkillsUpdate({
|
|
1871
2197
|
projectRoot,
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
packageRoot,
|
|
1875
|
-
ides,
|
|
1876
|
-
scope
|
|
2198
|
+
names: names.length > 0 ? names : void 0,
|
|
2199
|
+
dryRun: opts.dryRun
|
|
1877
2200
|
});
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
2201
|
+
switch (result.status) {
|
|
2202
|
+
case "no-skills":
|
|
2203
|
+
logger.error(
|
|
2204
|
+
'Skills not added. Run "teamix-evo skills init" first.'
|
|
2205
|
+
);
|
|
2206
|
+
process.exitCode = 1;
|
|
2207
|
+
return;
|
|
2208
|
+
case "no-changes":
|
|
2209
|
+
logger.success(
|
|
2210
|
+
`Already up-to-date (skills package v${result.version}).`
|
|
2211
|
+
);
|
|
2212
|
+
logger.info(
|
|
2213
|
+
` Checked: ${result.checkedSkillIds.join(", ") || "(none)"}`
|
|
2214
|
+
);
|
|
2215
|
+
return;
|
|
2216
|
+
case "dry-run":
|
|
2217
|
+
logger.info(
|
|
2218
|
+
`Plan (${result.currentVersion} \u2192 ${result.availableVersion}):`
|
|
2219
|
+
);
|
|
2220
|
+
if (result.plan.length === 0) {
|
|
2221
|
+
logger.info(" (no skills to update)");
|
|
2222
|
+
} else {
|
|
2223
|
+
for (const item of result.plan) {
|
|
2224
|
+
logger.info(formatPlanItem(item));
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
logger.info("");
|
|
2228
|
+
logger.info("Re-run without --dry-run to apply.");
|
|
2229
|
+
return;
|
|
2230
|
+
case "updated": {
|
|
2231
|
+
const { summary } = result;
|
|
2232
|
+
logger.success(
|
|
2233
|
+
`Skills updated to v${result.version} (${result.updatedSkillIds.length} skill(s)).`
|
|
2234
|
+
);
|
|
2235
|
+
if (result.updatedSkillIds.length > 0) {
|
|
2236
|
+
logger.info(
|
|
2237
|
+
` Updated: ${result.updatedSkillIds.join(", ")}`
|
|
2238
|
+
);
|
|
2239
|
+
}
|
|
2240
|
+
if (result.skippedSkillIds.length > 0) {
|
|
2241
|
+
logger.info(
|
|
2242
|
+
` Skipped: ${result.skippedSkillIds.join(", ")} (scope mismatch / removed upstream)`
|
|
2243
|
+
);
|
|
2244
|
+
}
|
|
2245
|
+
logger.info(` Created: ${summary.created}`);
|
|
2246
|
+
logger.info(` Overwritten: ${summary.overwritten}`);
|
|
2247
|
+
logger.info(` Managed: ${summary.managed}`);
|
|
2248
|
+
logger.info(` Skipped: ${summary.skipped}`);
|
|
2249
|
+
return;
|
|
2250
|
+
}
|
|
1912
2251
|
}
|
|
1913
|
-
await writeSkillsLock(projectRoot, lock);
|
|
1914
|
-
const { summary } = result;
|
|
1915
|
-
logger.success(`Skills updated to v${manifest.version}`);
|
|
1916
|
-
logger.info(` Created: ${summary.created}`);
|
|
1917
|
-
logger.info(` Overwritten: ${summary.overwritten}`);
|
|
1918
|
-
logger.info(` Managed: ${summary.managed}`);
|
|
1919
|
-
logger.info(` Skipped: ${summary.skipped}`);
|
|
1920
2252
|
} catch (err) {
|
|
1921
2253
|
logger.error(`Failed to update skills: ${err.message}`);
|
|
1922
2254
|
logger.debug(err.stack ?? "");
|
|
1923
2255
|
process.exitCode = 1;
|
|
1924
2256
|
}
|
|
1925
2257
|
});
|
|
2258
|
+
function formatPlanItem(item) {
|
|
2259
|
+
const tag = item.action === "up-to-date" ? " =" : item.strategy === "frozen" ? " \u2298 " : item.strategy === "managed" ? " \u2295 " : " \u2192 ";
|
|
2260
|
+
const ver = item.action === "up-to-date" ? `v${item.current} (no change)` : `v${item.current} \u2192 v${item.next} [${item.strategy}]`;
|
|
2261
|
+
return `${tag}${item.id} ${ver}`;
|
|
2262
|
+
}
|
|
2263
|
+
async function printVersionBanner() {
|
|
2264
|
+
let cliVersion;
|
|
2265
|
+
try {
|
|
2266
|
+
const pkg = require5("../package.json");
|
|
2267
|
+
cliVersion = pkg.version;
|
|
2268
|
+
} catch {
|
|
2269
|
+
}
|
|
2270
|
+
try {
|
|
2271
|
+
const { manifest } = await loadSkillsData(SKILLS_PACKAGE2);
|
|
2272
|
+
if (cliVersion) {
|
|
2273
|
+
logger.info(
|
|
2274
|
+
`teamix-evo CLI v${cliVersion} \xB7 skills package v${manifest.version}`
|
|
2275
|
+
);
|
|
2276
|
+
} else {
|
|
2277
|
+
logger.info(`skills package v${manifest.version}`);
|
|
2278
|
+
}
|
|
2279
|
+
} catch {
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
1926
2282
|
|
|
1927
2283
|
// src/commands/skills/uninstall.ts
|
|
1928
|
-
import { Command as
|
|
1929
|
-
import * as
|
|
2284
|
+
import { Command as Command11 } from "commander";
|
|
2285
|
+
import * as prompts4 from "@clack/prompts";
|
|
1930
2286
|
import * as path13 from "path";
|
|
1931
2287
|
import * as fs10 from "fs/promises";
|
|
1932
2288
|
var SKILLS_PACKAGE3 = "@teamix-evo/skills";
|
|
1933
|
-
var uninstallCommand2 = new
|
|
2289
|
+
var uninstallCommand2 = new Command11("uninstall").description(
|
|
1934
2290
|
"\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"
|
|
1935
2291
|
).argument(
|
|
1936
2292
|
"[ids...]",
|
|
@@ -1984,11 +2340,11 @@ async function runFullUninstall(args) {
|
|
|
1984
2340
|
`Will remove ${resources.length} skill file(s) installed by ${SKILLS_PACKAGE3}.`
|
|
1985
2341
|
);
|
|
1986
2342
|
if (!opts.yes) {
|
|
1987
|
-
const
|
|
2343
|
+
const confirm5 = await prompts4.confirm({
|
|
1988
2344
|
message: "\u786E\u8BA4\u5378\u8F7D\uFF1F\u6B64\u64CD\u4F5C\u4F1A\u5220\u9664\u4E0A\u8FF0\u6587\u4EF6\u3002",
|
|
1989
2345
|
initialValue: false
|
|
1990
2346
|
});
|
|
1991
|
-
if (
|
|
2347
|
+
if (prompts4.isCancel(confirm5) || !confirm5) {
|
|
1992
2348
|
logger.info("Cancelled.");
|
|
1993
2349
|
return;
|
|
1994
2350
|
}
|
|
@@ -2053,11 +2409,11 @@ async function runPartialUninstall(args) {
|
|
|
2053
2409
|
`Will remove ${matched.length} skill(s): ${matched.join(", ")} (${toRemove.length} file(s)).`
|
|
2054
2410
|
);
|
|
2055
2411
|
if (!opts.yes) {
|
|
2056
|
-
const
|
|
2412
|
+
const confirm5 = await prompts4.confirm({
|
|
2057
2413
|
message: "\u786E\u8BA4\u5378\u8F7D\uFF1F\u6B64\u64CD\u4F5C\u4F1A\u5220\u9664\u4E0A\u8FF0\u6587\u4EF6\u3002",
|
|
2058
2414
|
initialValue: false
|
|
2059
2415
|
});
|
|
2060
|
-
if (
|
|
2416
|
+
if (prompts4.isCancel(confirm5) || !confirm5) {
|
|
2061
2417
|
logger.info("Cancelled.");
|
|
2062
2418
|
return;
|
|
2063
2419
|
}
|
|
@@ -2174,17 +2530,17 @@ function dedupe(values) {
|
|
|
2174
2530
|
}
|
|
2175
2531
|
|
|
2176
2532
|
// src/commands/skills/sync.ts
|
|
2177
|
-
import { Command as
|
|
2533
|
+
import { Command as Command12 } from "commander";
|
|
2178
2534
|
|
|
2179
2535
|
// src/core/skills-sync.ts
|
|
2180
2536
|
import * as path14 from "path";
|
|
2181
2537
|
import * as fs11 from "fs/promises";
|
|
2182
|
-
import { createRequire as
|
|
2538
|
+
import { createRequire as createRequire5 } from "module";
|
|
2183
2539
|
import { loadSkillsPackageManifest as loadSkillsPackageManifest2 } from "@teamix-evo/registry";
|
|
2184
|
-
var
|
|
2540
|
+
var require6 = createRequire5(import.meta.url);
|
|
2185
2541
|
async function readSkillMetaFromUpstream(skillId) {
|
|
2186
2542
|
try {
|
|
2187
|
-
const pkgJson =
|
|
2543
|
+
const pkgJson = require6.resolve("@teamix-evo/skills/package.json");
|
|
2188
2544
|
const packageRoot = path14.dirname(pkgJson);
|
|
2189
2545
|
const manifest = await loadSkillsPackageManifest2(packageRoot);
|
|
2190
2546
|
const entry = manifest.skills.find((s) => s.id === skillId);
|
|
@@ -2283,7 +2639,7 @@ async function refreshMirrorRecords(projectRoot, newMirrorRecords) {
|
|
|
2283
2639
|
}
|
|
2284
2640
|
|
|
2285
2641
|
// src/commands/skills/sync.ts
|
|
2286
|
-
var syncCommand = new
|
|
2642
|
+
var syncCommand = new Command12("sync").description(
|
|
2287
2643
|
"\u628A .teamix-evo/skills/ \u4E0B\u7684\u6E90\u91CD\u65B0\u955C\u50CF\u5230 IDE \u8DEF\u5F84\uFF08.qoder / .claude\uFF09"
|
|
2288
2644
|
).argument(
|
|
2289
2645
|
"[names...]",
|
|
@@ -2302,8 +2658,8 @@ var syncCommand = new Command11("sync").description(
|
|
|
2302
2658
|
if (projectRoot !== cwd) {
|
|
2303
2659
|
logger.info(`Using global skills meta root: ${projectRoot}`);
|
|
2304
2660
|
}
|
|
2305
|
-
const ides = opts.ide ?
|
|
2306
|
-
const scope = opts.scope ?
|
|
2661
|
+
const ides = opts.ide ? parseIdeList3(opts.ide) : void 0;
|
|
2662
|
+
const scope = opts.scope ? parseScope3(opts.scope) : void 0;
|
|
2307
2663
|
const result = await runSkillsSync({
|
|
2308
2664
|
projectRoot,
|
|
2309
2665
|
ides,
|
|
@@ -2335,7 +2691,7 @@ var syncCommand = new Command11("sync").description(
|
|
|
2335
2691
|
process.exitCode = 1;
|
|
2336
2692
|
}
|
|
2337
2693
|
});
|
|
2338
|
-
function
|
|
2694
|
+
function parseIdeList3(input) {
|
|
2339
2695
|
const parts = input.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
2340
2696
|
const result = [];
|
|
2341
2697
|
for (const p of parts) {
|
|
@@ -2349,14 +2705,14 @@ function parseIdeList2(input) {
|
|
|
2349
2705
|
}
|
|
2350
2706
|
return result;
|
|
2351
2707
|
}
|
|
2352
|
-
function
|
|
2708
|
+
function parseScope3(input) {
|
|
2353
2709
|
const v = input.toLowerCase();
|
|
2354
2710
|
if (v === "project" || v === "global") return v;
|
|
2355
2711
|
throw new Error(`Invalid --scope: "${input}". Expected project | global.`);
|
|
2356
2712
|
}
|
|
2357
2713
|
|
|
2358
2714
|
// src/commands/skills/doctor.ts
|
|
2359
|
-
import { Command as
|
|
2715
|
+
import { Command as Command13 } from "commander";
|
|
2360
2716
|
|
|
2361
2717
|
// src/core/skills-doctor.ts
|
|
2362
2718
|
import * as path15 from "path";
|
|
@@ -2375,7 +2731,7 @@ async function runSkillsDoctor(options) {
|
|
|
2375
2731
|
kind: "missing-source",
|
|
2376
2732
|
skillId,
|
|
2377
2733
|
path: sourceDir,
|
|
2378
|
-
detail: 'Run "teamix-evo skills
|
|
2734
|
+
detail: 'Run "teamix-evo skills init" to reinstall.'
|
|
2379
2735
|
});
|
|
2380
2736
|
continue;
|
|
2381
2737
|
}
|
|
@@ -2445,7 +2801,7 @@ async function dirExists2(p) {
|
|
|
2445
2801
|
}
|
|
2446
2802
|
|
|
2447
2803
|
// src/commands/skills/doctor.ts
|
|
2448
|
-
var doctorCommand = new
|
|
2804
|
+
var doctorCommand = new Command13("doctor").description(
|
|
2449
2805
|
"\u68C0\u67E5 .teamix-evo/skills/ \u6E90\u4E0E IDE \u955C\u50CF\u662F\u5426\u6F02\u79FB\uFF1B\u63D0\u793A\u5982\u4F55\u4FEE\u590D"
|
|
2450
2806
|
).action(async () => {
|
|
2451
2807
|
try {
|
|
@@ -2458,7 +2814,7 @@ var doctorCommand = new Command12("doctor").description(
|
|
|
2458
2814
|
const result = await runSkillsDoctor({ projectRoot });
|
|
2459
2815
|
if (result.status === "no-skills") {
|
|
2460
2816
|
logger.info(
|
|
2461
|
-
'No skills recorded. Run "teamix-evo skills
|
|
2817
|
+
'No skills recorded. Run "teamix-evo skills init" first.'
|
|
2462
2818
|
);
|
|
2463
2819
|
return;
|
|
2464
2820
|
}
|
|
@@ -2484,9 +2840,10 @@ var doctorCommand = new Command12("doctor").description(
|
|
|
2484
2840
|
});
|
|
2485
2841
|
|
|
2486
2842
|
// src/commands/skills/index.ts
|
|
2487
|
-
var skillsCommand = new
|
|
2843
|
+
var skillsCommand = new Command14("skills").description(
|
|
2488
2844
|
"\u7BA1\u7406 teamix-evo skills\uFF08\u5411 AI IDE \u6CE8\u5165\u6280\u80FD\uFF1Bsource-mirror \u6A21\u578B\u89C1 ADR 0013\uFF09"
|
|
2489
2845
|
);
|
|
2846
|
+
skillsCommand.addCommand(initCommand2);
|
|
2490
2847
|
skillsCommand.addCommand(addCommand);
|
|
2491
2848
|
skillsCommand.addCommand(listCommand2);
|
|
2492
2849
|
skillsCommand.addCommand(updateCommand2);
|
|
@@ -2495,11 +2852,11 @@ skillsCommand.addCommand(doctorCommand);
|
|
|
2495
2852
|
skillsCommand.addCommand(uninstallCommand2);
|
|
2496
2853
|
|
|
2497
2854
|
// src/commands/ui/index.ts
|
|
2498
|
-
import { Command as
|
|
2855
|
+
import { Command as Command18 } from "commander";
|
|
2499
2856
|
|
|
2500
2857
|
// src/commands/ui/init.ts
|
|
2501
|
-
import { Command as
|
|
2502
|
-
import * as
|
|
2858
|
+
import { Command as Command15 } from "commander";
|
|
2859
|
+
import * as prompts5 from "@clack/prompts";
|
|
2503
2860
|
|
|
2504
2861
|
// src/core/ui-init.ts
|
|
2505
2862
|
var DEFAULT_UI_ALIASES = {
|
|
@@ -2556,7 +2913,7 @@ async function runUiInit(options) {
|
|
|
2556
2913
|
}
|
|
2557
2914
|
|
|
2558
2915
|
// src/commands/ui/init.ts
|
|
2559
|
-
var
|
|
2916
|
+
var initCommand3 = new Command15("init").description(
|
|
2560
2917
|
"\u521D\u59CB\u5316 teamix-evo ui \u914D\u7F6E\uFF08\u8BE2\u95EE aliases / iconLibrary / tsx / rsc\uFF09"
|
|
2561
2918
|
).option("-y, --yes", "\u4F7F\u7528\u9ED8\u8BA4\u503C\uFF0C\u8DF3\u8FC7\u4EA4\u4E92").option(
|
|
2562
2919
|
"--components <path>",
|
|
@@ -2603,7 +2960,8 @@ var initCommand2 = new Command14("init").description(
|
|
|
2603
2960
|
}
|
|
2604
2961
|
});
|
|
2605
2962
|
async function resolveConfig(opts) {
|
|
2606
|
-
|
|
2963
|
+
const isInteractive = Boolean(process.stdin.isTTY);
|
|
2964
|
+
if (opts.yes || !isInteractive) {
|
|
2607
2965
|
return {
|
|
2608
2966
|
aliases: {
|
|
2609
2967
|
components: opts.components ?? DEFAULT_UI_ALIASES.components,
|
|
@@ -2618,41 +2976,41 @@ async function resolveConfig(opts) {
|
|
|
2618
2976
|
rsc: opts.rsc ?? false
|
|
2619
2977
|
};
|
|
2620
2978
|
}
|
|
2621
|
-
const components = await
|
|
2979
|
+
const components = await prompts5.text({
|
|
2622
2980
|
message: "components \u8DEF\u5F84\uFF08\u6CE8\u5165\u6309\u94AE\u7B49\u7EC4\u4EF6\u6E90\u7801\u7684\u76EE\u5F55\uFF09",
|
|
2623
2981
|
initialValue: opts.components ?? DEFAULT_UI_ALIASES.components
|
|
2624
2982
|
});
|
|
2625
|
-
if (
|
|
2626
|
-
const hooks = await
|
|
2983
|
+
if (prompts5.isCancel(components)) throw new Error("Cancelled by user.");
|
|
2984
|
+
const hooks = await prompts5.text({
|
|
2627
2985
|
message: "hooks \u8DEF\u5F84",
|
|
2628
2986
|
initialValue: opts.hooks ?? DEFAULT_UI_ALIASES.hooks
|
|
2629
2987
|
});
|
|
2630
|
-
if (
|
|
2631
|
-
const utils = await
|
|
2988
|
+
if (prompts5.isCancel(hooks)) throw new Error("Cancelled by user.");
|
|
2989
|
+
const utils = await prompts5.text({
|
|
2632
2990
|
message: "utils \u8DEF\u5F84\uFF08cn \u7B49\u5DE5\u5177\uFF09",
|
|
2633
2991
|
initialValue: opts.utils ?? DEFAULT_UI_ALIASES.utils
|
|
2634
2992
|
});
|
|
2635
|
-
if (
|
|
2636
|
-
const lib = await
|
|
2993
|
+
if (prompts5.isCancel(utils)) throw new Error("Cancelled by user.");
|
|
2994
|
+
const lib = await prompts5.text({
|
|
2637
2995
|
message: "lib \u8DEF\u5F84\uFF08\u5171\u4EAB\u4EE3\u7801\u6839\uFF09",
|
|
2638
2996
|
initialValue: opts.lib ?? DEFAULT_UI_ALIASES.lib
|
|
2639
2997
|
});
|
|
2640
|
-
if (
|
|
2641
|
-
const iconLibrary = await
|
|
2998
|
+
if (prompts5.isCancel(lib)) throw new Error("Cancelled by user.");
|
|
2999
|
+
const iconLibrary = await prompts5.text({
|
|
2642
3000
|
message: "icon \u5E93\uFF08\u58F0\u660E\u6027\uFF0C\u7EC4\u4EF6\u6E90\u7801\u5DF2 hardcode lucide-react\uFF09",
|
|
2643
3001
|
initialValue: opts.iconLibrary ?? "lucide"
|
|
2644
3002
|
});
|
|
2645
|
-
if (
|
|
2646
|
-
const tsxAns = await
|
|
3003
|
+
if (prompts5.isCancel(iconLibrary)) throw new Error("Cancelled by user.");
|
|
3004
|
+
const tsxAns = await prompts5.confirm({
|
|
2647
3005
|
message: "\u4F7F\u7528 TSX\uFF1F",
|
|
2648
3006
|
initialValue: opts.tsx ?? true
|
|
2649
3007
|
});
|
|
2650
|
-
if (
|
|
2651
|
-
const rscAns = await
|
|
3008
|
+
if (prompts5.isCancel(tsxAns)) throw new Error("Cancelled by user.");
|
|
3009
|
+
const rscAns = await prompts5.confirm({
|
|
2652
3010
|
message: "\u4F7F\u7528 React Server Components\uFF1F",
|
|
2653
3011
|
initialValue: opts.rsc ?? false
|
|
2654
3012
|
});
|
|
2655
|
-
if (
|
|
3013
|
+
if (prompts5.isCancel(rscAns)) throw new Error("Cancelled by user.");
|
|
2656
3014
|
return {
|
|
2657
3015
|
aliases: {
|
|
2658
3016
|
components,
|
|
@@ -2669,16 +3027,16 @@ async function resolveConfig(opts) {
|
|
|
2669
3027
|
}
|
|
2670
3028
|
|
|
2671
3029
|
// src/commands/ui/add.ts
|
|
2672
|
-
import { Command as
|
|
3030
|
+
import { Command as Command16 } from "commander";
|
|
2673
3031
|
|
|
2674
3032
|
// src/core/ui-client.ts
|
|
2675
3033
|
import * as path16 from "path";
|
|
2676
3034
|
import * as fs13 from "fs/promises";
|
|
2677
|
-
import { createRequire as
|
|
3035
|
+
import { createRequire as createRequire6 } from "module";
|
|
2678
3036
|
import { loadUiPackageManifest } from "@teamix-evo/registry";
|
|
2679
|
-
var
|
|
3037
|
+
var require7 = createRequire6(import.meta.url);
|
|
2680
3038
|
function resolvePackageRoot2(packageName) {
|
|
2681
|
-
const pkgJsonPath =
|
|
3039
|
+
const pkgJsonPath = require7.resolve(`${packageName}/package.json`);
|
|
2682
3040
|
return path16.dirname(pkgJsonPath);
|
|
2683
3041
|
}
|
|
2684
3042
|
async function loadUiData(packageName) {
|
|
@@ -2894,7 +3252,7 @@ function mergeResources(prior, next) {
|
|
|
2894
3252
|
}
|
|
2895
3253
|
|
|
2896
3254
|
// src/commands/ui/add.ts
|
|
2897
|
-
var addCommand2 = new
|
|
3255
|
+
var addCommand2 = new Command16("add").description(
|
|
2898
3256
|
"\u5B89\u88C5\u4E00\u4E2A\u6216\u591A\u4E2A ui entry\uFF08\u6309 id\uFF0C\u81EA\u52A8\u5C55\u5F00 registryDependencies\uFF09"
|
|
2899
3257
|
).argument("<ids...>", 'entry id \u5217\u8868\uFF0C\u5982 "button" "dialog"').option("--overwrite", "\u5373\u4F7F\u76EE\u6807\u6587\u4EF6\u5DF2\u5B58\u5728\u4E5F\u8986\u76D6\uFF08\u7ED5\u8FC7 frozen \u8DF3\u8FC7\uFF09").option(
|
|
2900
3258
|
"--include-deprecated",
|
|
@@ -2940,7 +3298,7 @@ var addCommand2 = new Command15("add").description(
|
|
|
2940
3298
|
);
|
|
2941
3299
|
|
|
2942
3300
|
// src/commands/ui/list.ts
|
|
2943
|
-
import { Command as
|
|
3301
|
+
import { Command as Command17 } from "commander";
|
|
2944
3302
|
|
|
2945
3303
|
// src/core/ui-list.ts
|
|
2946
3304
|
var DEFAULT_UI_PACKAGE2 = "@teamix-evo/ui";
|
|
@@ -2978,7 +3336,7 @@ async function runUiList(options) {
|
|
|
2978
3336
|
}
|
|
2979
3337
|
|
|
2980
3338
|
// src/commands/ui/list.ts
|
|
2981
|
-
var listCommand3 = new
|
|
3339
|
+
var listCommand3 = new Command17("list").description("\u5217\u51FA @teamix-evo/ui \u7684\u6240\u6709 entry \u53CA\u5DF2\u5B89\u88C5\u72B6\u6001").option("--installed", "\u4EC5\u5C55\u793A\u5DF2\u5B89\u88C5\u7684 entry").option(
|
|
2982
3340
|
"--include-deprecated",
|
|
2983
3341
|
"\u540C\u65F6\u5217\u51FA\u5DF2\u5F52\u6863\u7684 deprecated entry\uFF08\u9ED8\u8BA4\u9690\u85CF\uFF0CADR 0028\uFF09"
|
|
2984
3342
|
).action(
|
|
@@ -3030,30 +3388,30 @@ var listCommand3 = new Command16("list").description("\u5217\u51FA @teamix-evo/u
|
|
|
3030
3388
|
);
|
|
3031
3389
|
|
|
3032
3390
|
// src/commands/ui/index.ts
|
|
3033
|
-
var uiCommand = new
|
|
3391
|
+
var uiCommand = new Command18("ui").description(
|
|
3034
3392
|
"\u7BA1\u7406 teamix-evo ui \u7EC4\u4EF6\uFF08\u6E90\u7801\u6CE8\u5165\u5F0F\u5B89\u88C5\uFF0Cshadcn \u98CE\u683C\uFF09"
|
|
3035
3393
|
);
|
|
3036
|
-
uiCommand.addCommand(
|
|
3394
|
+
uiCommand.addCommand(initCommand3);
|
|
3037
3395
|
uiCommand.addCommand(addCommand2);
|
|
3038
3396
|
uiCommand.addCommand(listCommand3);
|
|
3039
3397
|
|
|
3040
3398
|
// src/commands/biz-ui/index.ts
|
|
3041
|
-
import { Command as
|
|
3399
|
+
import { Command as Command22 } from "commander";
|
|
3042
3400
|
|
|
3043
3401
|
// src/commands/biz-ui/add.ts
|
|
3044
|
-
import { Command as
|
|
3402
|
+
import { Command as Command19 } from "commander";
|
|
3045
3403
|
|
|
3046
3404
|
// src/core/variant-ui-add.ts
|
|
3047
3405
|
import * as path18 from "path";
|
|
3048
|
-
import { createRequire as
|
|
3406
|
+
import { createRequire as createRequire7 } from "module";
|
|
3049
3407
|
import {
|
|
3050
3408
|
loadUiPackageManifest as loadUiPackageManifest2,
|
|
3051
3409
|
loadVariantUiPackageCatalog,
|
|
3052
3410
|
loadVariantUiPackageManifest
|
|
3053
3411
|
} from "@teamix-evo/registry";
|
|
3054
|
-
var
|
|
3412
|
+
var require8 = createRequire7(import.meta.url);
|
|
3055
3413
|
function resolvePackageRoot3(packageName) {
|
|
3056
|
-
const pkgJsonPath =
|
|
3414
|
+
const pkgJsonPath = require8.resolve(`${packageName}/package.json`);
|
|
3057
3415
|
return path18.dirname(pkgJsonPath);
|
|
3058
3416
|
}
|
|
3059
3417
|
async function runVariantUiAdd(packageName, options) {
|
|
@@ -3212,7 +3570,7 @@ async function listTemplatesEntries(variant, packageRoot) {
|
|
|
3212
3570
|
}
|
|
3213
3571
|
|
|
3214
3572
|
// src/commands/biz-ui/add.ts
|
|
3215
|
-
var addCommand3 = new
|
|
3573
|
+
var addCommand3 = new Command19("add").description(
|
|
3216
3574
|
"\u5B89\u88C5\u4E00\u4E2A\u6216\u591A\u4E2A\u4E1A\u52A1 UI \u7EC4\u4EF6(\u6309 id,\u81EA\u52A8\u5C55\u5F00 ui \u5305\u7684 registryDependencies)"
|
|
3217
3575
|
).argument("<ids...>", '\u7EC4\u4EF6 id \u5217\u8868,\u5982 "tenant-switcher" "org-picker"').option("--variant <name>", '\u53D8\u4F53 id(\u5FC5\u586B,\u5982 "opentrek"\u3001"uni-manager")').option("--overwrite", "\u5373\u4F7F\u76EE\u6807\u6587\u4EF6\u5DF2\u5B58\u5728\u4E5F\u8986\u76D6").action(
|
|
3218
3576
|
async (ids, opts) => {
|
|
@@ -3261,8 +3619,8 @@ var addCommand3 = new Command18("add").description(
|
|
|
3261
3619
|
);
|
|
3262
3620
|
|
|
3263
3621
|
// src/commands/biz-ui/list.ts
|
|
3264
|
-
import { Command as
|
|
3265
|
-
var listCommand4 = new
|
|
3622
|
+
import { Command as Command20 } from "commander";
|
|
3623
|
+
var listCommand4 = new Command20("list").description("\u5217\u51FA\u6307\u5B9A\u53D8\u4F53\u4E0B\u7684 biz-ui entries").requiredOption("--variant <name>", "\u53D8\u4F53\u540D\uFF08\u5982 opentrek / uni-manager\uFF09").action(async (opts) => {
|
|
3266
3624
|
try {
|
|
3267
3625
|
const result = await listBizUiEntries(opts.variant);
|
|
3268
3626
|
logger.info(`${result.packageName}#${result.variant} entries:`);
|
|
@@ -3287,8 +3645,8 @@ var listCommand4 = new Command19("list").description("\u5217\u51FA\u6307\u5B9A\u
|
|
|
3287
3645
|
});
|
|
3288
3646
|
|
|
3289
3647
|
// src/commands/biz-ui/list-variants.ts
|
|
3290
|
-
import { Command as
|
|
3291
|
-
var listVariantsCommand2 = new
|
|
3648
|
+
import { Command as Command21 } from "commander";
|
|
3649
|
+
var listVariantsCommand2 = new Command21("list-variants").description("\u5217\u51FA @teamix-evo/biz-ui \u5305\u5185\u63D0\u4F9B\u7684\u6240\u6709\u4E1A\u52A1\u53D8\u4F53").action(async () => {
|
|
3292
3650
|
try {
|
|
3293
3651
|
const result = await listBizUiVariants();
|
|
3294
3652
|
logger.info(`Available biz-ui variants in ${result.packageName}:`);
|
|
@@ -3310,7 +3668,7 @@ var listVariantsCommand2 = new Command20("list-variants").description("\u5217\u5
|
|
|
3310
3668
|
});
|
|
3311
3669
|
|
|
3312
3670
|
// src/commands/biz-ui/index.ts
|
|
3313
|
-
var bizUiCommand = new
|
|
3671
|
+
var bizUiCommand = new Command22("biz-ui").description(
|
|
3314
3672
|
"\u7BA1\u7406\u4E1A\u52A1 UI \u7EC4\u4EF6(\u53D8\u4F53\u611F\u77E5 \u2014 \u4E0E design / templates \u540C\u53D8\u4F53\u540D\u7A7A\u95F4)"
|
|
3315
3673
|
);
|
|
3316
3674
|
bizUiCommand.addCommand(addCommand3);
|
|
@@ -3318,11 +3676,11 @@ bizUiCommand.addCommand(listCommand4);
|
|
|
3318
3676
|
bizUiCommand.addCommand(listVariantsCommand2);
|
|
3319
3677
|
|
|
3320
3678
|
// src/commands/templates/index.ts
|
|
3321
|
-
import { Command as
|
|
3679
|
+
import { Command as Command26 } from "commander";
|
|
3322
3680
|
|
|
3323
3681
|
// src/commands/templates/add.ts
|
|
3324
|
-
import { Command as
|
|
3325
|
-
var addCommand4 = new
|
|
3682
|
+
import { Command as Command23 } from "commander";
|
|
3683
|
+
var addCommand4 = new Command23("add").description(
|
|
3326
3684
|
"\u5B89\u88C5\u4E00\u4E2A\u6216\u591A\u4E2A\u9875\u9762\u6A21\u677F(\u6309 id,\u81EA\u52A8\u5C55\u5F00 ui \u5305\u7684 registryDependencies)"
|
|
3327
3685
|
).argument("<ids...>", '\u6A21\u677F id \u5217\u8868,\u5982 "list-detail-page"').option("--variant <name>", '\u53D8\u4F53 id(\u5FC5\u586B,\u5982 "opentrek"\u3001"uni-manager")').option("--overwrite", "\u5373\u4F7F\u76EE\u6807\u6587\u4EF6\u5DF2\u5B58\u5728\u4E5F\u8986\u76D6").action(
|
|
3328
3686
|
async (ids, opts) => {
|
|
@@ -3371,8 +3729,8 @@ var addCommand4 = new Command22("add").description(
|
|
|
3371
3729
|
);
|
|
3372
3730
|
|
|
3373
3731
|
// src/commands/templates/list.ts
|
|
3374
|
-
import { Command as
|
|
3375
|
-
var listCommand5 = new
|
|
3732
|
+
import { Command as Command24 } from "commander";
|
|
3733
|
+
var listCommand5 = new Command24("list").description("\u5217\u51FA\u6307\u5B9A\u53D8\u4F53\u4E0B\u7684 templates entries").requiredOption("--variant <name>", "\u53D8\u4F53\u540D\uFF08\u5982 opentrek / uni-manager\uFF09").action(async (opts) => {
|
|
3376
3734
|
try {
|
|
3377
3735
|
const result = await listTemplatesEntries(opts.variant);
|
|
3378
3736
|
logger.info(`${result.packageName}#${result.variant} entries:`);
|
|
@@ -3397,8 +3755,8 @@ var listCommand5 = new Command23("list").description("\u5217\u51FA\u6307\u5B9A\u
|
|
|
3397
3755
|
});
|
|
3398
3756
|
|
|
3399
3757
|
// src/commands/templates/list-variants.ts
|
|
3400
|
-
import { Command as
|
|
3401
|
-
var listVariantsCommand3 = new
|
|
3758
|
+
import { Command as Command25 } from "commander";
|
|
3759
|
+
var listVariantsCommand3 = new Command25("list-variants").description("\u5217\u51FA @teamix-evo/templates \u5305\u5185\u63D0\u4F9B\u7684\u6240\u6709\u9875\u9762\u6A21\u677F\u53D8\u4F53").action(async () => {
|
|
3402
3760
|
try {
|
|
3403
3761
|
const result = await listTemplatesVariants();
|
|
3404
3762
|
logger.info(`Available templates variants in ${result.packageName}:`);
|
|
@@ -3420,7 +3778,7 @@ var listVariantsCommand3 = new Command24("list-variants").description("\u5217\u5
|
|
|
3420
3778
|
});
|
|
3421
3779
|
|
|
3422
3780
|
// src/commands/templates/index.ts
|
|
3423
|
-
var templatesCommand = new
|
|
3781
|
+
var templatesCommand = new Command26("templates").description(
|
|
3424
3782
|
"\u7BA1\u7406\u9875\u9762\u6A21\u677F(\u53D8\u4F53\u611F\u77E5 \u2014 \u4E0E design / biz-ui \u540C\u53D8\u4F53\u540D\u7A7A\u95F4)"
|
|
3425
3783
|
);
|
|
3426
3784
|
templatesCommand.addCommand(addCommand4);
|
|
@@ -3428,24 +3786,26 @@ templatesCommand.addCommand(listCommand5);
|
|
|
3428
3786
|
templatesCommand.addCommand(listVariantsCommand3);
|
|
3429
3787
|
|
|
3430
3788
|
// src/commands/logs/index.ts
|
|
3431
|
-
import { Command as
|
|
3789
|
+
import { Command as Command29 } from "commander";
|
|
3432
3790
|
|
|
3433
3791
|
// src/commands/logs/analyze.ts
|
|
3434
|
-
import { Command as
|
|
3792
|
+
import { Command as Command27 } from "commander";
|
|
3435
3793
|
import { readFileSync, readdirSync, existsSync as existsSync2, statSync } from "fs";
|
|
3436
3794
|
import { resolve as resolve3, join as join17 } from "path";
|
|
3437
3795
|
var DATE_DIR_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
3438
|
-
var logsAnalyzeCommand = new
|
|
3439
|
-
"\u6C47\u603B vibe-logger \u8F93\u51FA (.
|
|
3440
|
-
).option("--dir <path>", "log \u76EE\u5F55 (\u9ED8\u8BA4 <project>/.
|
|
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(
|
|
3441
3799
|
"--days <n>",
|
|
3442
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)"
|
|
3443
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) => {
|
|
3444
|
-
const baseDir = resolve3(
|
|
3802
|
+
const baseDir = resolve3(
|
|
3803
|
+
opts.dir ?? join17(process.cwd(), ".teamix-evo", "logs", "ai")
|
|
3804
|
+
);
|
|
3445
3805
|
if (!existsSync2(baseDir)) {
|
|
3446
3806
|
logger.warn(`No log directory at ${baseDir}.`);
|
|
3447
3807
|
logger.info(
|
|
3448
|
-
"\u8FD0\u884C vibe-logger hook \u89E6\u53D1\u540E\u4F1A\u5728\u6B64\u76EE\u5F55\u751F\u6210 JSONL \u2014 \u89C1 .claude/scripts/vibe-logger.mjs"
|
|
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"
|
|
3449
3809
|
);
|
|
3450
3810
|
return;
|
|
3451
3811
|
}
|
|
@@ -3615,18 +3975,20 @@ function parseIntOrUndef(v) {
|
|
|
3615
3975
|
}
|
|
3616
3976
|
|
|
3617
3977
|
// src/commands/logs/trace.ts
|
|
3618
|
-
import { Command as
|
|
3978
|
+
import { Command as Command28 } from "commander";
|
|
3619
3979
|
import { readFileSync as readFileSync2, readdirSync as readdirSync2, existsSync as existsSync3, statSync as statSync2 } from "fs";
|
|
3620
3980
|
import { resolve as resolve4, join as join18 } from "path";
|
|
3621
3981
|
var DATE_DIR_RE2 = /^\d{4}-\d{2}-\d{2}$/;
|
|
3622
|
-
var logsTraceCommand = new
|
|
3982
|
+
var logsTraceCommand = new Command28("trace").description(
|
|
3623
3983
|
"\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"
|
|
3624
|
-
).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>/.
|
|
3625
|
-
const baseDir = resolve4(
|
|
3984
|
+
).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
|
+
const baseDir = resolve4(
|
|
3986
|
+
opts.dir ?? join18(process.cwd(), ".teamix-evo", "logs", "ai")
|
|
3987
|
+
);
|
|
3626
3988
|
if (!existsSync3(baseDir)) {
|
|
3627
3989
|
logger.warn(`No log directory at ${baseDir}.`);
|
|
3628
3990
|
logger.info(
|
|
3629
|
-
"\u8FD0\u884C vibe-logger hook \u89E6\u53D1\u540E\u4F1A\u5728\u6B64\u76EE\u5F55\u751F\u6210 JSONL \u2014 \u89C1 .claude/scripts/vibe-logger.mjs"
|
|
3991
|
+
"\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"
|
|
3630
3992
|
);
|
|
3631
3993
|
return;
|
|
3632
3994
|
}
|
|
@@ -3778,7 +4140,9 @@ function printTrace(baseDir, r) {
|
|
|
3778
4140
|
logger.info("");
|
|
3779
4141
|
for (const c of s.chains) {
|
|
3780
4142
|
logger.info(
|
|
3781
|
-
`[${formatTime(c.promptTs)}] \u{1F4AC} Prompt: ${quote(
|
|
4143
|
+
`[${formatTime(c.promptTs)}] \u{1F4AC} Prompt: ${quote(
|
|
4144
|
+
truncate(c.prompt, 200)
|
|
4145
|
+
)}`
|
|
3782
4146
|
);
|
|
3783
4147
|
for (const step of c.steps) {
|
|
3784
4148
|
logger.info(` ${formatStep(step)}`);
|
|
@@ -3825,16 +4189,176 @@ function parseIntOrUndef2(v) {
|
|
|
3825
4189
|
}
|
|
3826
4190
|
|
|
3827
4191
|
// src/commands/logs/index.ts
|
|
3828
|
-
var logsCommand = new
|
|
3829
|
-
"\u67E5\u8BE2 vibe-logger \u8F93\u51FA (.
|
|
4192
|
+
var logsCommand = new Command29("logs").description(
|
|
4193
|
+
"\u67E5\u8BE2 vibe-logger \u8F93\u51FA (.teamix-evo/logs/ai/**/*.jsonl) \u2014 AI \u8C03\u7528\u94FE\u5206\u6790"
|
|
3830
4194
|
);
|
|
3831
4195
|
logsCommand.addCommand(logsAnalyzeCommand);
|
|
3832
4196
|
logsCommand.addCommand(logsTraceCommand);
|
|
3833
4197
|
|
|
4198
|
+
// src/commands/lint/index.ts
|
|
4199
|
+
import { Command as Command31 } from "commander";
|
|
4200
|
+
|
|
4201
|
+
// src/commands/lint/init.ts
|
|
4202
|
+
import { Command as Command30 } from "commander";
|
|
4203
|
+
import * as prompts6 from "@clack/prompts";
|
|
4204
|
+
|
|
4205
|
+
// src/core/lint-init.ts
|
|
4206
|
+
import * as path19 from "path";
|
|
4207
|
+
import * as fs15 from "fs";
|
|
4208
|
+
import { execa } from "execa";
|
|
4209
|
+
var ESLINT_CONFIG_CONTENT = `/**
|
|
4210
|
+
* teamix-evo consumer ESLint preset \u2014 9 token-discipline rules.
|
|
4211
|
+
* - Repo-wide: no-color-literal / no-arbitrary-tw-value / no-raw-color-scale /
|
|
4212
|
+
* no-large-radius / prefer-gap-over-space / no-manual-dark-classnames /
|
|
4213
|
+
* dialog-must-have-title (all error)
|
|
4214
|
+
* - src/components/ui/** only: no-relative-ui-import / icon-from-lucide (error)
|
|
4215
|
+
*
|
|
4216
|
+
* See ADR 0008 / docs/principles.md \xA7P4.
|
|
4217
|
+
*/
|
|
4218
|
+
import consumerPreset from '@teamix-evo/eslint-config/presets/consumer';
|
|
4219
|
+
|
|
4220
|
+
export default [...consumerPreset];
|
|
4221
|
+
`;
|
|
4222
|
+
var STYLELINT_CONFIG_CONTENT = `/** @type {import('stylelint').Config} */
|
|
4223
|
+
module.exports = {
|
|
4224
|
+
extends: ['@teamix-evo/stylelint-config/presets/consumer'],
|
|
4225
|
+
};
|
|
4226
|
+
`;
|
|
4227
|
+
var ESLINT_DEPS = [
|
|
4228
|
+
"@teamix-evo/eslint-config",
|
|
4229
|
+
"eslint",
|
|
4230
|
+
"@typescript-eslint/parser"
|
|
4231
|
+
];
|
|
4232
|
+
var STYLELINT_DEPS = ["@teamix-evo/stylelint-config", "stylelint"];
|
|
4233
|
+
async function runLintInit(options) {
|
|
4234
|
+
const { projectRoot, skipInstall } = options;
|
|
4235
|
+
const eslintConfigPath = path19.join(projectRoot, "eslint.config.js");
|
|
4236
|
+
const stylelintConfigPath = path19.join(projectRoot, "stylelint.config.cjs");
|
|
4237
|
+
const eslintExists = await fileExists(eslintConfigPath);
|
|
4238
|
+
const stylelintExists = await fileExists(stylelintConfigPath);
|
|
4239
|
+
if (eslintExists && stylelintExists) {
|
|
4240
|
+
return { status: "already-initialized" };
|
|
4241
|
+
}
|
|
4242
|
+
if (!skipInstall) {
|
|
4243
|
+
const depsToInstall = [
|
|
4244
|
+
...eslintExists ? [] : ESLINT_DEPS,
|
|
4245
|
+
...stylelintExists ? [] : STYLELINT_DEPS
|
|
4246
|
+
];
|
|
4247
|
+
if (depsToInstall.length > 0) {
|
|
4248
|
+
const pm = detectPm(projectRoot);
|
|
4249
|
+
const args = pm === "yarn" ? ["add", "--dev", ...depsToInstall] : pm === "pnpm" ? ["add", "-D", ...depsToInstall] : ["install", "--save-dev", ...depsToInstall];
|
|
4250
|
+
logger.info(`Installing lint deps via ${pm}...`);
|
|
4251
|
+
await execa(pm, args, { cwd: projectRoot, stdio: "inherit" });
|
|
4252
|
+
}
|
|
4253
|
+
}
|
|
4254
|
+
let wroteEslint = false;
|
|
4255
|
+
let wroteStylelint = false;
|
|
4256
|
+
if (!eslintExists) {
|
|
4257
|
+
await writeFileSafe(eslintConfigPath, ESLINT_CONFIG_CONTENT);
|
|
4258
|
+
logger.debug(`Wrote eslint.config.js \u2192 ${eslintConfigPath}`);
|
|
4259
|
+
wroteEslint = true;
|
|
4260
|
+
}
|
|
4261
|
+
if (!stylelintExists) {
|
|
4262
|
+
await writeFileSafe(stylelintConfigPath, STYLELINT_CONFIG_CONTENT);
|
|
4263
|
+
logger.debug(`Wrote stylelint.config.cjs \u2192 ${stylelintConfigPath}`);
|
|
4264
|
+
wroteStylelint = true;
|
|
4265
|
+
}
|
|
4266
|
+
await patchPackageJsonScripts(projectRoot);
|
|
4267
|
+
return {
|
|
4268
|
+
status: "installed",
|
|
4269
|
+
eslint: wroteEslint,
|
|
4270
|
+
stylelint: wroteStylelint
|
|
4271
|
+
};
|
|
4272
|
+
}
|
|
4273
|
+
function detectPm(projectRoot) {
|
|
4274
|
+
if (fs15.existsSync(path19.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
|
|
4275
|
+
if (fs15.existsSync(path19.join(projectRoot, "yarn.lock"))) return "yarn";
|
|
4276
|
+
return "npm";
|
|
4277
|
+
}
|
|
4278
|
+
async function patchPackageJsonScripts(projectRoot) {
|
|
4279
|
+
const pkgPath = path19.join(projectRoot, "package.json");
|
|
4280
|
+
const raw = await readFileOrNull(pkgPath);
|
|
4281
|
+
if (!raw) return;
|
|
4282
|
+
let pkg;
|
|
4283
|
+
try {
|
|
4284
|
+
pkg = JSON.parse(raw);
|
|
4285
|
+
} catch {
|
|
4286
|
+
return;
|
|
4287
|
+
}
|
|
4288
|
+
const scripts = pkg.scripts ?? {};
|
|
4289
|
+
let changed = false;
|
|
4290
|
+
if (!scripts.lint) {
|
|
4291
|
+
scripts.lint = "eslint src/";
|
|
4292
|
+
changed = true;
|
|
4293
|
+
}
|
|
4294
|
+
if (!scripts["lint:css"]) {
|
|
4295
|
+
scripts["lint:css"] = "stylelint 'src/**/*.css'";
|
|
4296
|
+
changed = true;
|
|
4297
|
+
}
|
|
4298
|
+
if (changed) {
|
|
4299
|
+
pkg.scripts = scripts;
|
|
4300
|
+
await writeFileSafe(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
4301
|
+
logger.debug("Patched package.json scripts with lint / lint:css");
|
|
4302
|
+
}
|
|
4303
|
+
}
|
|
4304
|
+
|
|
4305
|
+
// src/commands/lint/init.ts
|
|
4306
|
+
var initCommand4 = new Command30("init").description(
|
|
4307
|
+
"\u521D\u59CB\u5316 ESLint + Stylelint \u5DE5\u7A0B\u89C4\u8303\uFF08\u5B89\u88C5\u4F9D\u8D56 + \u751F\u6210\u914D\u7F6E\u6587\u4EF6 + \u6CE8\u5165 scripts\uFF09"
|
|
4308
|
+
).option("-y, --yes", "\u8DF3\u8FC7\u786E\u8BA4\uFF0C\u76F4\u63A5\u6267\u884C").action(async (opts) => {
|
|
4309
|
+
try {
|
|
4310
|
+
const ide = detectIde();
|
|
4311
|
+
const projectRoot = ide.getProjectRoot();
|
|
4312
|
+
if (!hasPackageJson(projectRoot)) {
|
|
4313
|
+
logger.error(
|
|
4314
|
+
"No package.json found in current directory. Please run this command in a valid project root."
|
|
4315
|
+
);
|
|
4316
|
+
process.exit(1);
|
|
4317
|
+
}
|
|
4318
|
+
const isInteractive = Boolean(process.stdin.isTTY);
|
|
4319
|
+
if (!opts.yes && isInteractive) {
|
|
4320
|
+
const shouldContinue = await prompts6.confirm({
|
|
4321
|
+
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"
|
|
4322
|
+
});
|
|
4323
|
+
if (prompts6.isCancel(shouldContinue) || !shouldContinue) {
|
|
4324
|
+
logger.info("Cancelled.");
|
|
4325
|
+
return;
|
|
4326
|
+
}
|
|
4327
|
+
}
|
|
4328
|
+
const result = await runLintInit({ projectRoot });
|
|
4329
|
+
if (result.status === "already-initialized") {
|
|
4330
|
+
logger.warn(
|
|
4331
|
+
"Lint already initialized. eslint.config.js and stylelint.config.cjs both exist."
|
|
4332
|
+
);
|
|
4333
|
+
return;
|
|
4334
|
+
}
|
|
4335
|
+
logger.success("Lint initialized.");
|
|
4336
|
+
if (result.eslint) {
|
|
4337
|
+
logger.info(" + eslint.config.js");
|
|
4338
|
+
}
|
|
4339
|
+
if (result.stylelint) {
|
|
4340
|
+
logger.info(" + stylelint.config.cjs");
|
|
4341
|
+
}
|
|
4342
|
+
logger.info("");
|
|
4343
|
+
logger.info('Run "npm run lint" to check JSX/TSX token discipline.');
|
|
4344
|
+
logger.info('Run "npm run lint:css" to check CSS token discipline.');
|
|
4345
|
+
} catch (err) {
|
|
4346
|
+
logger.error(`Failed to initialize lint: ${err.message}`);
|
|
4347
|
+
logger.debug(err.stack ?? "");
|
|
4348
|
+
process.exitCode = 1;
|
|
4349
|
+
}
|
|
4350
|
+
});
|
|
4351
|
+
|
|
4352
|
+
// src/commands/lint/index.ts
|
|
4353
|
+
var lintCommand = new Command31("lint").description(
|
|
4354
|
+
"\u7BA1\u7406\u5DE5\u7A0B\u89C4\u8303\uFF08ESLint + Stylelint token-discipline \u89C4\u5219\u96C6\uFF09"
|
|
4355
|
+
);
|
|
4356
|
+
lintCommand.addCommand(initCommand4);
|
|
4357
|
+
|
|
3834
4358
|
// src/index.ts
|
|
3835
|
-
var
|
|
3836
|
-
var { version } =
|
|
3837
|
-
var program = new
|
|
4359
|
+
var require9 = createRequire8(import.meta.url);
|
|
4360
|
+
var { version } = require9("../package.json");
|
|
4361
|
+
var program = new Command32();
|
|
3838
4362
|
program.name("teamix-evo").description("Where ideas evolve. \u2014 AI Coding \u5957\u4EF6").version(version);
|
|
3839
4363
|
program.addCommand(tokensCommand);
|
|
3840
4364
|
program.addCommand(skillsCommand);
|
|
@@ -3842,5 +4366,11 @@ program.addCommand(uiCommand);
|
|
|
3842
4366
|
program.addCommand(bizUiCommand);
|
|
3843
4367
|
program.addCommand(templatesCommand);
|
|
3844
4368
|
program.addCommand(logsCommand);
|
|
4369
|
+
program.addCommand(lintCommand);
|
|
4370
|
+
function enableHelpAfterError(cmd) {
|
|
4371
|
+
cmd.showHelpAfterError(true);
|
|
4372
|
+
for (const child of cmd.commands) enableHelpAfterError(child);
|
|
4373
|
+
}
|
|
4374
|
+
enableHelpAfterError(program);
|
|
3845
4375
|
program.parse();
|
|
3846
4376
|
//# sourceMappingURL=index.js.map
|