teamix-evo 0.5.0 → 0.6.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/README.md +5 -3
- package/dist/core/index.d.ts +150 -24
- package/dist/core/index.js +416 -67
- package/dist/core/index.js.map +1 -1
- package/dist/index.js +780 -253
- 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,132 @@ 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
|
+
if (opts.ide || opts.yes) {
|
|
1728
|
+
const ides = opts.ide ? parseIdeList(opts.ide) : [...ALL_IDE_KINDS];
|
|
1729
|
+
const scope = parseScope(opts.scope);
|
|
1730
|
+
if (ides.length === 0) {
|
|
1731
|
+
throw new Error("At least one IDE must be selected.");
|
|
1732
|
+
}
|
|
1733
|
+
return { ides, scope };
|
|
1734
|
+
}
|
|
1735
|
+
const idesAns = await prompts2.multiselect({
|
|
1736
|
+
message: "\u9009\u62E9\u8981\u6CE8\u5165\u6280\u80FD\u7684 AI IDE\uFF08\u81F3\u5C11\u4E00\u4E2A\uFF09",
|
|
1737
|
+
options: ALL_IDE_KINDS.map((k) => ({
|
|
1738
|
+
value: k,
|
|
1739
|
+
label: k === "qoder" ? "Qoder" : "Claude Code"
|
|
1740
|
+
})),
|
|
1741
|
+
initialValues: [...ALL_IDE_KINDS],
|
|
1742
|
+
required: true
|
|
1743
|
+
});
|
|
1744
|
+
if (prompts2.isCancel(idesAns)) {
|
|
1745
|
+
throw new Error("Cancelled by user.");
|
|
1746
|
+
}
|
|
1747
|
+
const scopeAns = await prompts2.select({
|
|
1748
|
+
message: "\u5B89\u88C5\u8303\u56F4\uFF1F",
|
|
1749
|
+
options: [
|
|
1750
|
+
{ value: "project", label: "\u9879\u76EE\u7EA7\uFF08.qoder/.claude \u5728\u5F53\u524D\u9879\u76EE\uFF09" },
|
|
1751
|
+
{ value: "global", label: "\u5168\u5C40\uFF08~/.qoder/~/.claude\uFF09" }
|
|
1752
|
+
],
|
|
1753
|
+
initialValue: "project"
|
|
1754
|
+
});
|
|
1755
|
+
if (prompts2.isCancel(scopeAns)) {
|
|
1756
|
+
throw new Error("Cancelled by user.");
|
|
1757
|
+
}
|
|
1758
|
+
return { ides: idesAns, scope: scopeAns };
|
|
1759
|
+
}
|
|
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
|
+
|
|
1778
|
+
// src/commands/skills/add.ts
|
|
1779
|
+
import { Command as Command8 } from "commander";
|
|
1780
|
+
import * as prompts3 from "@clack/prompts";
|
|
1781
|
+
var addCommand = new Command8("add").description(
|
|
1782
|
+
"\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"
|
|
1783
|
+
).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
1784
|
"--scope <scope>",
|
|
1603
|
-
"project | global\uFF08\u9ED8\u8BA4
|
|
1785
|
+
"project | global\uFF08\u9ED8\u8BA4\u6CBF\u7528\u65E2\u6709 skills \u914D\u7F6E\uFF1B\u9996\u6B21\u5B89\u88C5\u9ED8\u8BA4 project\uFF09"
|
|
1604
1786
|
).option("-y, --yes", "\u4F7F\u7528\u9ED8\u8BA4\u503C\uFF0C\u8DF3\u8FC7\u4EA4\u4E92").action(async (names, opts) => {
|
|
1605
1787
|
try {
|
|
1606
1788
|
const ide = detectIde();
|
|
1607
1789
|
const cwd = ide.getProjectRoot();
|
|
1608
|
-
const
|
|
1609
|
-
const { ides, scope } = await resolveIdesAndScope({
|
|
1790
|
+
const { ides, scope } = await resolveIdesAndScope2({
|
|
1610
1791
|
opts,
|
|
1611
|
-
projectRoot: cwd
|
|
1612
|
-
isIncremental
|
|
1792
|
+
projectRoot: cwd
|
|
1613
1793
|
});
|
|
1614
1794
|
let projectRoot = cwd;
|
|
1615
1795
|
if (scope === "global" && !isTeamixEvoProject(cwd)) {
|
|
@@ -1622,9 +1802,9 @@ var addCommand = new Command7("add").description(
|
|
|
1622
1802
|
process.exit(1);
|
|
1623
1803
|
}
|
|
1624
1804
|
logger.info(
|
|
1625
|
-
|
|
1805
|
+
`Adding skills [${names.join(",")}]: ides=[${ides.join(
|
|
1626
1806
|
","
|
|
1627
|
-
)}], scope="${scope}"`
|
|
1807
|
+
)}], scope="${scope}"`
|
|
1628
1808
|
);
|
|
1629
1809
|
logger.debug(`Project root: ${projectRoot}`);
|
|
1630
1810
|
const result = await runSkillsAdd({
|
|
@@ -1632,14 +1812,8 @@ var addCommand = new Command7("add").description(
|
|
|
1632
1812
|
ides,
|
|
1633
1813
|
scope,
|
|
1634
1814
|
ide: ide.name,
|
|
1635
|
-
names
|
|
1815
|
+
names
|
|
1636
1816
|
});
|
|
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
1817
|
if (result.addedSkillIds.length === 0 && result.skippedSkillIds.length > 0) {
|
|
1644
1818
|
logger.warn(
|
|
1645
1819
|
`\u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u6DFB\u52A0\uFF1A${result.skippedSkillIds.join(
|
|
@@ -1668,9 +1842,9 @@ var addCommand = new Command7("add").description(
|
|
|
1668
1842
|
process.exitCode = 1;
|
|
1669
1843
|
}
|
|
1670
1844
|
});
|
|
1671
|
-
async function
|
|
1672
|
-
const { opts, projectRoot
|
|
1673
|
-
if (
|
|
1845
|
+
async function resolveIdesAndScope2(args) {
|
|
1846
|
+
const { opts, projectRoot } = args;
|
|
1847
|
+
if (!opts.ide && !opts.scope && !opts.yes) {
|
|
1674
1848
|
const existing = await readProjectConfig(projectRoot);
|
|
1675
1849
|
const cfg = existing?.packages?.skills;
|
|
1676
1850
|
if (cfg && cfg.ides && cfg.ides.length > 0 && cfg.scope) {
|
|
@@ -1684,14 +1858,14 @@ async function resolveIdesAndScope(args) {
|
|
|
1684
1858
|
}
|
|
1685
1859
|
}
|
|
1686
1860
|
if (opts.ide || opts.yes) {
|
|
1687
|
-
const ides = opts.ide ?
|
|
1688
|
-
const scope =
|
|
1861
|
+
const ides = opts.ide ? parseIdeList2(opts.ide) : [...ALL_IDE_KINDS];
|
|
1862
|
+
const scope = parseScope2(opts.scope);
|
|
1689
1863
|
if (ides.length === 0) {
|
|
1690
1864
|
throw new Error("At least one IDE must be selected.");
|
|
1691
1865
|
}
|
|
1692
1866
|
return { ides, scope };
|
|
1693
1867
|
}
|
|
1694
|
-
const idesAns = await
|
|
1868
|
+
const idesAns = await prompts3.multiselect({
|
|
1695
1869
|
message: "\u9009\u62E9\u8981\u6CE8\u5165\u6280\u80FD\u7684 AI IDE\uFF08\u81F3\u5C11\u4E00\u4E2A\uFF09",
|
|
1696
1870
|
options: ALL_IDE_KINDS.map((k) => ({
|
|
1697
1871
|
value: k,
|
|
@@ -1700,10 +1874,10 @@ async function resolveIdesAndScope(args) {
|
|
|
1700
1874
|
initialValues: [...ALL_IDE_KINDS],
|
|
1701
1875
|
required: true
|
|
1702
1876
|
});
|
|
1703
|
-
if (
|
|
1877
|
+
if (prompts3.isCancel(idesAns)) {
|
|
1704
1878
|
throw new Error("Cancelled by user.");
|
|
1705
1879
|
}
|
|
1706
|
-
const scopeAns = await
|
|
1880
|
+
const scopeAns = await prompts3.select({
|
|
1707
1881
|
message: "\u5B89\u88C5\u8303\u56F4\uFF1F",
|
|
1708
1882
|
options: [
|
|
1709
1883
|
{ value: "project", label: "\u9879\u76EE\u7EA7\uFF08.qoder/.claude \u5728\u5F53\u524D\u9879\u76EE\uFF09" },
|
|
@@ -1711,12 +1885,12 @@ async function resolveIdesAndScope(args) {
|
|
|
1711
1885
|
],
|
|
1712
1886
|
initialValue: "project"
|
|
1713
1887
|
});
|
|
1714
|
-
if (
|
|
1888
|
+
if (prompts3.isCancel(scopeAns)) {
|
|
1715
1889
|
throw new Error("Cancelled by user.");
|
|
1716
1890
|
}
|
|
1717
1891
|
return { ides: idesAns, scope: scopeAns };
|
|
1718
1892
|
}
|
|
1719
|
-
function
|
|
1893
|
+
function parseIdeList2(input) {
|
|
1720
1894
|
const parts = input.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
1721
1895
|
const result = [];
|
|
1722
1896
|
for (const p of parts) {
|
|
@@ -1728,16 +1902,16 @@ function parseIdeList(input) {
|
|
|
1728
1902
|
}
|
|
1729
1903
|
return result;
|
|
1730
1904
|
}
|
|
1731
|
-
function
|
|
1905
|
+
function parseScope2(input) {
|
|
1732
1906
|
const v = (input ?? "project").toLowerCase();
|
|
1733
1907
|
if (v === "project" || v === "global") return v;
|
|
1734
1908
|
throw new Error(`Invalid --scope: "${input}". Expected project | global.`);
|
|
1735
1909
|
}
|
|
1736
1910
|
|
|
1737
1911
|
// src/commands/skills/list.ts
|
|
1738
|
-
import { Command as
|
|
1912
|
+
import { Command as Command9 } from "commander";
|
|
1739
1913
|
var SKILLS_PACKAGE = "@teamix-evo/skills";
|
|
1740
|
-
var listCommand2 = new
|
|
1914
|
+
var listCommand2 = new Command9("list").alias("ls").description(
|
|
1741
1915
|
"\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
1916
|
).option("--installed", "\u4EC5\u5C55\u793A\u5DF2\u5B89\u88C5\u7684 skill\uFF08\u9690\u85CF\u672A\u5B89\u88C5\u9879\uFF09").action(async (opts) => {
|
|
1743
1917
|
try {
|
|
@@ -1766,7 +1940,7 @@ var listCommand2 = new Command8("list").alias("ls").description(
|
|
|
1766
1940
|
if (opts.installed) {
|
|
1767
1941
|
if (!config?.packages?.skills || !pkg) {
|
|
1768
1942
|
logger.info("No skills installed.");
|
|
1769
|
-
logger.info('Run "teamix-evo skills
|
|
1943
|
+
logger.info('Run "teamix-evo skills init" to get started.');
|
|
1770
1944
|
return;
|
|
1771
1945
|
}
|
|
1772
1946
|
printInstalledHeader(config.packages.skills, pkg.installedAt);
|
|
@@ -1795,7 +1969,7 @@ var listCommand2 = new Command8("list").alias("ls").description(
|
|
|
1795
1969
|
} else {
|
|
1796
1970
|
logger.info("Skills package not yet added.");
|
|
1797
1971
|
logger.info(
|
|
1798
|
-
'Run "teamix-evo skills
|
|
1972
|
+
'Run "teamix-evo skills init" to bootstrap, or "teamix-evo skills add <id...>" for specific skills.'
|
|
1799
1973
|
);
|
|
1800
1974
|
}
|
|
1801
1975
|
logger.info("");
|
|
@@ -1831,10 +2005,185 @@ function printInstalledHeader(cfg, installedAt) {
|
|
|
1831
2005
|
}
|
|
1832
2006
|
|
|
1833
2007
|
// src/commands/skills/update.ts
|
|
1834
|
-
import { Command as
|
|
1835
|
-
|
|
2008
|
+
import { Command as Command10 } from "commander";
|
|
2009
|
+
import { createRequire as createRequire4 } from "module";
|
|
2010
|
+
|
|
2011
|
+
// src/core/skills-update.ts
|
|
2012
|
+
var DEFAULT_SKILLS_PACKAGE3 = "@teamix-evo/skills";
|
|
1836
2013
|
var FLAT_VARIANT2 = "_flat";
|
|
1837
|
-
|
|
2014
|
+
async function runSkillsUpdate(options) {
|
|
2015
|
+
const { projectRoot, names: requestedNames, dryRun } = options;
|
|
2016
|
+
const packageName = options.packageName ?? DEFAULT_SKILLS_PACKAGE3;
|
|
2017
|
+
const config = await readProjectConfig(projectRoot);
|
|
2018
|
+
const skillsCfg = config?.packages?.skills;
|
|
2019
|
+
if (!skillsCfg) {
|
|
2020
|
+
return { status: "no-skills" };
|
|
2021
|
+
}
|
|
2022
|
+
const ides = skillsCfg.ides ?? ["qoder", "claude"];
|
|
2023
|
+
const scope = skillsCfg.scope ?? "project";
|
|
2024
|
+
const existingLock = await readSkillsLock(projectRoot);
|
|
2025
|
+
if (!existingLock || Object.keys(existingLock.skills).length === 0) {
|
|
2026
|
+
return { status: "no-skills" };
|
|
2027
|
+
}
|
|
2028
|
+
const { manifest, data, packageRoot } = await loadSkillsData(packageName);
|
|
2029
|
+
const manifestById = new Map(manifest.skills.map((s) => [s.id, s]));
|
|
2030
|
+
const lockIds = Object.keys(existingLock.skills);
|
|
2031
|
+
const requestedSet = requestedNames ? new Set(requestedNames) : null;
|
|
2032
|
+
if (requestedSet) {
|
|
2033
|
+
const unknown = requestedNames.filter(
|
|
2034
|
+
(n) => !lockIds.includes(n) && !manifestById.has(n)
|
|
2035
|
+
);
|
|
2036
|
+
if (unknown.length > 0) {
|
|
2037
|
+
throw new Error(
|
|
2038
|
+
`Unknown skill id(s): ${unknown.join(
|
|
2039
|
+
", "
|
|
2040
|
+
)}. Available (installed): ${lockIds.join(", ") || "(none)"}.`
|
|
2041
|
+
);
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
const targetIds = [];
|
|
2045
|
+
const skippedSkillIds = [];
|
|
2046
|
+
for (const id of lockIds) {
|
|
2047
|
+
if (requestedSet && !requestedSet.has(id)) continue;
|
|
2048
|
+
const entry2 = manifestById.get(id);
|
|
2049
|
+
if (!entry2) {
|
|
2050
|
+
logger.debug(
|
|
2051
|
+
`Skipping "${id}": no longer in upstream manifest. Use \`skills uninstall ${id}\` to remove.`
|
|
2052
|
+
);
|
|
2053
|
+
skippedSkillIds.push(id);
|
|
2054
|
+
continue;
|
|
2055
|
+
}
|
|
2056
|
+
const effectiveScope = entry2.scope ?? "project";
|
|
2057
|
+
if (effectiveScope !== scope) {
|
|
2058
|
+
logger.debug(
|
|
2059
|
+
`Skipping "${id}" (scope=${effectiveScope}): current install scope is "${scope}".`
|
|
2060
|
+
);
|
|
2061
|
+
skippedSkillIds.push(id);
|
|
2062
|
+
continue;
|
|
2063
|
+
}
|
|
2064
|
+
targetIds.push(id);
|
|
2065
|
+
}
|
|
2066
|
+
const allSame = targetIds.every((id) => {
|
|
2067
|
+
const lockVer = existingLock.skills[id].version;
|
|
2068
|
+
const manVer = manifestById.get(id).version;
|
|
2069
|
+
return lockVer === manVer;
|
|
2070
|
+
});
|
|
2071
|
+
if (targetIds.length > 0 && allSame && !dryRun) {
|
|
2072
|
+
return {
|
|
2073
|
+
status: "no-changes",
|
|
2074
|
+
packageName,
|
|
2075
|
+
version: manifest.version,
|
|
2076
|
+
checkedSkillIds: targetIds
|
|
2077
|
+
};
|
|
2078
|
+
}
|
|
2079
|
+
if (dryRun) {
|
|
2080
|
+
const plan = targetIds.map((id) => {
|
|
2081
|
+
const lockVer = existingLock.skills[id].version;
|
|
2082
|
+
const entry2 = manifestById.get(id);
|
|
2083
|
+
const sameVersion = lockVer === entry2.version;
|
|
2084
|
+
return {
|
|
2085
|
+
id,
|
|
2086
|
+
current: lockVer,
|
|
2087
|
+
next: entry2.version,
|
|
2088
|
+
strategy: entry2.updateStrategy ?? "managed",
|
|
2089
|
+
action: sameVersion ? "up-to-date" : "version-bump"
|
|
2090
|
+
};
|
|
2091
|
+
});
|
|
2092
|
+
return {
|
|
2093
|
+
status: "dry-run",
|
|
2094
|
+
packageName,
|
|
2095
|
+
currentVersion: skillsCfg.version,
|
|
2096
|
+
availableVersion: manifest.version,
|
|
2097
|
+
plan
|
|
2098
|
+
};
|
|
2099
|
+
}
|
|
2100
|
+
if (targetIds.length === 0) {
|
|
2101
|
+
return {
|
|
2102
|
+
status: "updated",
|
|
2103
|
+
packageName,
|
|
2104
|
+
version: manifest.version,
|
|
2105
|
+
ides,
|
|
2106
|
+
scope,
|
|
2107
|
+
updatedSkillIds: [],
|
|
2108
|
+
skippedSkillIds,
|
|
2109
|
+
summary: { overwritten: 0, managed: 0, skipped: 0, created: 0 },
|
|
2110
|
+
resources: []
|
|
2111
|
+
};
|
|
2112
|
+
}
|
|
2113
|
+
const result = await updateSkills({
|
|
2114
|
+
projectRoot,
|
|
2115
|
+
manifest,
|
|
2116
|
+
data,
|
|
2117
|
+
packageRoot,
|
|
2118
|
+
ides,
|
|
2119
|
+
scope,
|
|
2120
|
+
onlyIds: targetIds
|
|
2121
|
+
});
|
|
2122
|
+
config.packages.skills = {
|
|
2123
|
+
...skillsCfg,
|
|
2124
|
+
version: manifest.version
|
|
2125
|
+
};
|
|
2126
|
+
await writeProjectConfig(projectRoot, config);
|
|
2127
|
+
const installedManifest = await readInstalledManifest(projectRoot) ?? {
|
|
2128
|
+
schemaVersion: 1,
|
|
2129
|
+
installed: []
|
|
2130
|
+
};
|
|
2131
|
+
const idx = installedManifest.installed.findIndex(
|
|
2132
|
+
(p) => p.package === packageName
|
|
2133
|
+
);
|
|
2134
|
+
const installedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2135
|
+
const prior = idx >= 0 ? installedManifest.installed[idx].resources : [];
|
|
2136
|
+
const targetSet = new Set(targetIds);
|
|
2137
|
+
const preserved = prior.filter((r) => {
|
|
2138
|
+
const skillId = r.id.split(":")[0];
|
|
2139
|
+
return skillId ? !targetSet.has(skillId) : true;
|
|
2140
|
+
});
|
|
2141
|
+
const entry = {
|
|
2142
|
+
package: packageName,
|
|
2143
|
+
variant: FLAT_VARIANT2,
|
|
2144
|
+
version: manifest.version,
|
|
2145
|
+
installedAt,
|
|
2146
|
+
resources: [...preserved, ...result.resources]
|
|
2147
|
+
};
|
|
2148
|
+
if (idx >= 0) installedManifest.installed[idx] = entry;
|
|
2149
|
+
else installedManifest.installed.push(entry);
|
|
2150
|
+
await writeInstalledManifest(projectRoot, installedManifest);
|
|
2151
|
+
const lock = {
|
|
2152
|
+
schemaVersion: 1,
|
|
2153
|
+
skills: { ...existingLock.skills }
|
|
2154
|
+
};
|
|
2155
|
+
for (const id of targetIds) {
|
|
2156
|
+
const skillDef = manifestById.get(id);
|
|
2157
|
+
if (!skillDef) continue;
|
|
2158
|
+
const mirroredTo = skillDef.ides.filter((i) => ides.includes(i));
|
|
2159
|
+
lock.skills[id] = {
|
|
2160
|
+
version: skillDef.version,
|
|
2161
|
+
from: packageName,
|
|
2162
|
+
installedAt,
|
|
2163
|
+
scope,
|
|
2164
|
+
mirroredTo
|
|
2165
|
+
};
|
|
2166
|
+
}
|
|
2167
|
+
await writeSkillsLock(projectRoot, lock);
|
|
2168
|
+
return {
|
|
2169
|
+
status: "updated",
|
|
2170
|
+
packageName,
|
|
2171
|
+
version: manifest.version,
|
|
2172
|
+
ides,
|
|
2173
|
+
scope,
|
|
2174
|
+
updatedSkillIds: targetIds,
|
|
2175
|
+
skippedSkillIds,
|
|
2176
|
+
summary: result.summary,
|
|
2177
|
+
resources: result.resources
|
|
2178
|
+
};
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2181
|
+
// src/commands/skills/update.ts
|
|
2182
|
+
var require5 = createRequire4(import.meta.url);
|
|
2183
|
+
var SKILLS_PACKAGE2 = "@teamix-evo/skills";
|
|
2184
|
+
var updateCommand2 = new Command10("update").description(
|
|
2185
|
+
"\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"
|
|
2186
|
+
).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
2187
|
try {
|
|
1839
2188
|
const ide = detectIde();
|
|
1840
2189
|
const cwd = ide.getProjectRoot();
|
|
@@ -1842,95 +2191,101 @@ var updateCommand2 = new Command9("update").description("\u66F4\u65B0\u5DF2\u5B8
|
|
|
1842
2191
|
if (projectRoot !== cwd) {
|
|
1843
2192
|
logger.info(`Using global skills meta root: ${projectRoot}`);
|
|
1844
2193
|
}
|
|
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({
|
|
2194
|
+
await printVersionBanner();
|
|
2195
|
+
const result = await runSkillsUpdate({
|
|
1871
2196
|
projectRoot,
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
packageRoot,
|
|
1875
|
-
ides,
|
|
1876
|
-
scope
|
|
2197
|
+
names: names.length > 0 ? names : void 0,
|
|
2198
|
+
dryRun: opts.dryRun
|
|
1877
2199
|
});
|
|
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
|
-
|
|
2200
|
+
switch (result.status) {
|
|
2201
|
+
case "no-skills":
|
|
2202
|
+
logger.error(
|
|
2203
|
+
'Skills not added. Run "teamix-evo skills init" first.'
|
|
2204
|
+
);
|
|
2205
|
+
process.exitCode = 1;
|
|
2206
|
+
return;
|
|
2207
|
+
case "no-changes":
|
|
2208
|
+
logger.success(
|
|
2209
|
+
`Already up-to-date (skills package v${result.version}).`
|
|
2210
|
+
);
|
|
2211
|
+
logger.info(
|
|
2212
|
+
` Checked: ${result.checkedSkillIds.join(", ") || "(none)"}`
|
|
2213
|
+
);
|
|
2214
|
+
return;
|
|
2215
|
+
case "dry-run":
|
|
2216
|
+
logger.info(
|
|
2217
|
+
`Plan (${result.currentVersion} \u2192 ${result.availableVersion}):`
|
|
2218
|
+
);
|
|
2219
|
+
if (result.plan.length === 0) {
|
|
2220
|
+
logger.info(" (no skills to update)");
|
|
2221
|
+
} else {
|
|
2222
|
+
for (const item of result.plan) {
|
|
2223
|
+
logger.info(formatPlanItem(item));
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
logger.info("");
|
|
2227
|
+
logger.info("Re-run without --dry-run to apply.");
|
|
2228
|
+
return;
|
|
2229
|
+
case "updated": {
|
|
2230
|
+
const { summary } = result;
|
|
2231
|
+
logger.success(
|
|
2232
|
+
`Skills updated to v${result.version} (${result.updatedSkillIds.length} skill(s)).`
|
|
2233
|
+
);
|
|
2234
|
+
if (result.updatedSkillIds.length > 0) {
|
|
2235
|
+
logger.info(
|
|
2236
|
+
` Updated: ${result.updatedSkillIds.join(", ")}`
|
|
2237
|
+
);
|
|
2238
|
+
}
|
|
2239
|
+
if (result.skippedSkillIds.length > 0) {
|
|
2240
|
+
logger.info(
|
|
2241
|
+
` Skipped: ${result.skippedSkillIds.join(", ")} (scope mismatch / removed upstream)`
|
|
2242
|
+
);
|
|
2243
|
+
}
|
|
2244
|
+
logger.info(` Created: ${summary.created}`);
|
|
2245
|
+
logger.info(` Overwritten: ${summary.overwritten}`);
|
|
2246
|
+
logger.info(` Managed: ${summary.managed}`);
|
|
2247
|
+
logger.info(` Skipped: ${summary.skipped}`);
|
|
2248
|
+
return;
|
|
2249
|
+
}
|
|
1912
2250
|
}
|
|
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
2251
|
} catch (err) {
|
|
1921
2252
|
logger.error(`Failed to update skills: ${err.message}`);
|
|
1922
2253
|
logger.debug(err.stack ?? "");
|
|
1923
2254
|
process.exitCode = 1;
|
|
1924
2255
|
}
|
|
1925
2256
|
});
|
|
2257
|
+
function formatPlanItem(item) {
|
|
2258
|
+
const tag = item.action === "up-to-date" ? " =" : item.strategy === "frozen" ? " \u2298 " : item.strategy === "managed" ? " \u2295 " : " \u2192 ";
|
|
2259
|
+
const ver = item.action === "up-to-date" ? `v${item.current} (no change)` : `v${item.current} \u2192 v${item.next} [${item.strategy}]`;
|
|
2260
|
+
return `${tag}${item.id} ${ver}`;
|
|
2261
|
+
}
|
|
2262
|
+
async function printVersionBanner() {
|
|
2263
|
+
let cliVersion;
|
|
2264
|
+
try {
|
|
2265
|
+
const pkg = require5("../package.json");
|
|
2266
|
+
cliVersion = pkg.version;
|
|
2267
|
+
} catch {
|
|
2268
|
+
}
|
|
2269
|
+
try {
|
|
2270
|
+
const { manifest } = await loadSkillsData(SKILLS_PACKAGE2);
|
|
2271
|
+
if (cliVersion) {
|
|
2272
|
+
logger.info(
|
|
2273
|
+
`teamix-evo CLI v${cliVersion} \xB7 skills package v${manifest.version}`
|
|
2274
|
+
);
|
|
2275
|
+
} else {
|
|
2276
|
+
logger.info(`skills package v${manifest.version}`);
|
|
2277
|
+
}
|
|
2278
|
+
} catch {
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
1926
2281
|
|
|
1927
2282
|
// src/commands/skills/uninstall.ts
|
|
1928
|
-
import { Command as
|
|
1929
|
-
import * as
|
|
2283
|
+
import { Command as Command11 } from "commander";
|
|
2284
|
+
import * as prompts4 from "@clack/prompts";
|
|
1930
2285
|
import * as path13 from "path";
|
|
1931
2286
|
import * as fs10 from "fs/promises";
|
|
1932
2287
|
var SKILLS_PACKAGE3 = "@teamix-evo/skills";
|
|
1933
|
-
var uninstallCommand2 = new
|
|
2288
|
+
var uninstallCommand2 = new Command11("uninstall").description(
|
|
1934
2289
|
"\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
2290
|
).argument(
|
|
1936
2291
|
"[ids...]",
|
|
@@ -1984,11 +2339,11 @@ async function runFullUninstall(args) {
|
|
|
1984
2339
|
`Will remove ${resources.length} skill file(s) installed by ${SKILLS_PACKAGE3}.`
|
|
1985
2340
|
);
|
|
1986
2341
|
if (!opts.yes) {
|
|
1987
|
-
const
|
|
2342
|
+
const confirm5 = await prompts4.confirm({
|
|
1988
2343
|
message: "\u786E\u8BA4\u5378\u8F7D\uFF1F\u6B64\u64CD\u4F5C\u4F1A\u5220\u9664\u4E0A\u8FF0\u6587\u4EF6\u3002",
|
|
1989
2344
|
initialValue: false
|
|
1990
2345
|
});
|
|
1991
|
-
if (
|
|
2346
|
+
if (prompts4.isCancel(confirm5) || !confirm5) {
|
|
1992
2347
|
logger.info("Cancelled.");
|
|
1993
2348
|
return;
|
|
1994
2349
|
}
|
|
@@ -2053,11 +2408,11 @@ async function runPartialUninstall(args) {
|
|
|
2053
2408
|
`Will remove ${matched.length} skill(s): ${matched.join(", ")} (${toRemove.length} file(s)).`
|
|
2054
2409
|
);
|
|
2055
2410
|
if (!opts.yes) {
|
|
2056
|
-
const
|
|
2411
|
+
const confirm5 = await prompts4.confirm({
|
|
2057
2412
|
message: "\u786E\u8BA4\u5378\u8F7D\uFF1F\u6B64\u64CD\u4F5C\u4F1A\u5220\u9664\u4E0A\u8FF0\u6587\u4EF6\u3002",
|
|
2058
2413
|
initialValue: false
|
|
2059
2414
|
});
|
|
2060
|
-
if (
|
|
2415
|
+
if (prompts4.isCancel(confirm5) || !confirm5) {
|
|
2061
2416
|
logger.info("Cancelled.");
|
|
2062
2417
|
return;
|
|
2063
2418
|
}
|
|
@@ -2174,17 +2529,17 @@ function dedupe(values) {
|
|
|
2174
2529
|
}
|
|
2175
2530
|
|
|
2176
2531
|
// src/commands/skills/sync.ts
|
|
2177
|
-
import { Command as
|
|
2532
|
+
import { Command as Command12 } from "commander";
|
|
2178
2533
|
|
|
2179
2534
|
// src/core/skills-sync.ts
|
|
2180
2535
|
import * as path14 from "path";
|
|
2181
2536
|
import * as fs11 from "fs/promises";
|
|
2182
|
-
import { createRequire as
|
|
2537
|
+
import { createRequire as createRequire5 } from "module";
|
|
2183
2538
|
import { loadSkillsPackageManifest as loadSkillsPackageManifest2 } from "@teamix-evo/registry";
|
|
2184
|
-
var
|
|
2539
|
+
var require6 = createRequire5(import.meta.url);
|
|
2185
2540
|
async function readSkillMetaFromUpstream(skillId) {
|
|
2186
2541
|
try {
|
|
2187
|
-
const pkgJson =
|
|
2542
|
+
const pkgJson = require6.resolve("@teamix-evo/skills/package.json");
|
|
2188
2543
|
const packageRoot = path14.dirname(pkgJson);
|
|
2189
2544
|
const manifest = await loadSkillsPackageManifest2(packageRoot);
|
|
2190
2545
|
const entry = manifest.skills.find((s) => s.id === skillId);
|
|
@@ -2283,7 +2638,7 @@ async function refreshMirrorRecords(projectRoot, newMirrorRecords) {
|
|
|
2283
2638
|
}
|
|
2284
2639
|
|
|
2285
2640
|
// src/commands/skills/sync.ts
|
|
2286
|
-
var syncCommand = new
|
|
2641
|
+
var syncCommand = new Command12("sync").description(
|
|
2287
2642
|
"\u628A .teamix-evo/skills/ \u4E0B\u7684\u6E90\u91CD\u65B0\u955C\u50CF\u5230 IDE \u8DEF\u5F84\uFF08.qoder / .claude\uFF09"
|
|
2288
2643
|
).argument(
|
|
2289
2644
|
"[names...]",
|
|
@@ -2302,8 +2657,8 @@ var syncCommand = new Command11("sync").description(
|
|
|
2302
2657
|
if (projectRoot !== cwd) {
|
|
2303
2658
|
logger.info(`Using global skills meta root: ${projectRoot}`);
|
|
2304
2659
|
}
|
|
2305
|
-
const ides = opts.ide ?
|
|
2306
|
-
const scope = opts.scope ?
|
|
2660
|
+
const ides = opts.ide ? parseIdeList3(opts.ide) : void 0;
|
|
2661
|
+
const scope = opts.scope ? parseScope3(opts.scope) : void 0;
|
|
2307
2662
|
const result = await runSkillsSync({
|
|
2308
2663
|
projectRoot,
|
|
2309
2664
|
ides,
|
|
@@ -2335,7 +2690,7 @@ var syncCommand = new Command11("sync").description(
|
|
|
2335
2690
|
process.exitCode = 1;
|
|
2336
2691
|
}
|
|
2337
2692
|
});
|
|
2338
|
-
function
|
|
2693
|
+
function parseIdeList3(input) {
|
|
2339
2694
|
const parts = input.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
2340
2695
|
const result = [];
|
|
2341
2696
|
for (const p of parts) {
|
|
@@ -2349,14 +2704,14 @@ function parseIdeList2(input) {
|
|
|
2349
2704
|
}
|
|
2350
2705
|
return result;
|
|
2351
2706
|
}
|
|
2352
|
-
function
|
|
2707
|
+
function parseScope3(input) {
|
|
2353
2708
|
const v = input.toLowerCase();
|
|
2354
2709
|
if (v === "project" || v === "global") return v;
|
|
2355
2710
|
throw new Error(`Invalid --scope: "${input}". Expected project | global.`);
|
|
2356
2711
|
}
|
|
2357
2712
|
|
|
2358
2713
|
// src/commands/skills/doctor.ts
|
|
2359
|
-
import { Command as
|
|
2714
|
+
import { Command as Command13 } from "commander";
|
|
2360
2715
|
|
|
2361
2716
|
// src/core/skills-doctor.ts
|
|
2362
2717
|
import * as path15 from "path";
|
|
@@ -2375,7 +2730,7 @@ async function runSkillsDoctor(options) {
|
|
|
2375
2730
|
kind: "missing-source",
|
|
2376
2731
|
skillId,
|
|
2377
2732
|
path: sourceDir,
|
|
2378
|
-
detail: 'Run "teamix-evo skills
|
|
2733
|
+
detail: 'Run "teamix-evo skills init" to reinstall.'
|
|
2379
2734
|
});
|
|
2380
2735
|
continue;
|
|
2381
2736
|
}
|
|
@@ -2445,7 +2800,7 @@ async function dirExists2(p) {
|
|
|
2445
2800
|
}
|
|
2446
2801
|
|
|
2447
2802
|
// src/commands/skills/doctor.ts
|
|
2448
|
-
var doctorCommand = new
|
|
2803
|
+
var doctorCommand = new Command13("doctor").description(
|
|
2449
2804
|
"\u68C0\u67E5 .teamix-evo/skills/ \u6E90\u4E0E IDE \u955C\u50CF\u662F\u5426\u6F02\u79FB\uFF1B\u63D0\u793A\u5982\u4F55\u4FEE\u590D"
|
|
2450
2805
|
).action(async () => {
|
|
2451
2806
|
try {
|
|
@@ -2458,7 +2813,7 @@ var doctorCommand = new Command12("doctor").description(
|
|
|
2458
2813
|
const result = await runSkillsDoctor({ projectRoot });
|
|
2459
2814
|
if (result.status === "no-skills") {
|
|
2460
2815
|
logger.info(
|
|
2461
|
-
'No skills recorded. Run "teamix-evo skills
|
|
2816
|
+
'No skills recorded. Run "teamix-evo skills init" first.'
|
|
2462
2817
|
);
|
|
2463
2818
|
return;
|
|
2464
2819
|
}
|
|
@@ -2484,9 +2839,10 @@ var doctorCommand = new Command12("doctor").description(
|
|
|
2484
2839
|
});
|
|
2485
2840
|
|
|
2486
2841
|
// src/commands/skills/index.ts
|
|
2487
|
-
var skillsCommand = new
|
|
2842
|
+
var skillsCommand = new Command14("skills").description(
|
|
2488
2843
|
"\u7BA1\u7406 teamix-evo skills\uFF08\u5411 AI IDE \u6CE8\u5165\u6280\u80FD\uFF1Bsource-mirror \u6A21\u578B\u89C1 ADR 0013\uFF09"
|
|
2489
2844
|
);
|
|
2845
|
+
skillsCommand.addCommand(initCommand2);
|
|
2490
2846
|
skillsCommand.addCommand(addCommand);
|
|
2491
2847
|
skillsCommand.addCommand(listCommand2);
|
|
2492
2848
|
skillsCommand.addCommand(updateCommand2);
|
|
@@ -2495,11 +2851,11 @@ skillsCommand.addCommand(doctorCommand);
|
|
|
2495
2851
|
skillsCommand.addCommand(uninstallCommand2);
|
|
2496
2852
|
|
|
2497
2853
|
// src/commands/ui/index.ts
|
|
2498
|
-
import { Command as
|
|
2854
|
+
import { Command as Command18 } from "commander";
|
|
2499
2855
|
|
|
2500
2856
|
// src/commands/ui/init.ts
|
|
2501
|
-
import { Command as
|
|
2502
|
-
import * as
|
|
2857
|
+
import { Command as Command15 } from "commander";
|
|
2858
|
+
import * as prompts5 from "@clack/prompts";
|
|
2503
2859
|
|
|
2504
2860
|
// src/core/ui-init.ts
|
|
2505
2861
|
var DEFAULT_UI_ALIASES = {
|
|
@@ -2556,7 +2912,7 @@ async function runUiInit(options) {
|
|
|
2556
2912
|
}
|
|
2557
2913
|
|
|
2558
2914
|
// src/commands/ui/init.ts
|
|
2559
|
-
var
|
|
2915
|
+
var initCommand3 = new Command15("init").description(
|
|
2560
2916
|
"\u521D\u59CB\u5316 teamix-evo ui \u914D\u7F6E\uFF08\u8BE2\u95EE aliases / iconLibrary / tsx / rsc\uFF09"
|
|
2561
2917
|
).option("-y, --yes", "\u4F7F\u7528\u9ED8\u8BA4\u503C\uFF0C\u8DF3\u8FC7\u4EA4\u4E92").option(
|
|
2562
2918
|
"--components <path>",
|
|
@@ -2618,41 +2974,41 @@ async function resolveConfig(opts) {
|
|
|
2618
2974
|
rsc: opts.rsc ?? false
|
|
2619
2975
|
};
|
|
2620
2976
|
}
|
|
2621
|
-
const components = await
|
|
2977
|
+
const components = await prompts5.text({
|
|
2622
2978
|
message: "components \u8DEF\u5F84\uFF08\u6CE8\u5165\u6309\u94AE\u7B49\u7EC4\u4EF6\u6E90\u7801\u7684\u76EE\u5F55\uFF09",
|
|
2623
2979
|
initialValue: opts.components ?? DEFAULT_UI_ALIASES.components
|
|
2624
2980
|
});
|
|
2625
|
-
if (
|
|
2626
|
-
const hooks = await
|
|
2981
|
+
if (prompts5.isCancel(components)) throw new Error("Cancelled by user.");
|
|
2982
|
+
const hooks = await prompts5.text({
|
|
2627
2983
|
message: "hooks \u8DEF\u5F84",
|
|
2628
2984
|
initialValue: opts.hooks ?? DEFAULT_UI_ALIASES.hooks
|
|
2629
2985
|
});
|
|
2630
|
-
if (
|
|
2631
|
-
const utils = await
|
|
2986
|
+
if (prompts5.isCancel(hooks)) throw new Error("Cancelled by user.");
|
|
2987
|
+
const utils = await prompts5.text({
|
|
2632
2988
|
message: "utils \u8DEF\u5F84\uFF08cn \u7B49\u5DE5\u5177\uFF09",
|
|
2633
2989
|
initialValue: opts.utils ?? DEFAULT_UI_ALIASES.utils
|
|
2634
2990
|
});
|
|
2635
|
-
if (
|
|
2636
|
-
const lib = await
|
|
2991
|
+
if (prompts5.isCancel(utils)) throw new Error("Cancelled by user.");
|
|
2992
|
+
const lib = await prompts5.text({
|
|
2637
2993
|
message: "lib \u8DEF\u5F84\uFF08\u5171\u4EAB\u4EE3\u7801\u6839\uFF09",
|
|
2638
2994
|
initialValue: opts.lib ?? DEFAULT_UI_ALIASES.lib
|
|
2639
2995
|
});
|
|
2640
|
-
if (
|
|
2641
|
-
const iconLibrary = await
|
|
2996
|
+
if (prompts5.isCancel(lib)) throw new Error("Cancelled by user.");
|
|
2997
|
+
const iconLibrary = await prompts5.text({
|
|
2642
2998
|
message: "icon \u5E93\uFF08\u58F0\u660E\u6027\uFF0C\u7EC4\u4EF6\u6E90\u7801\u5DF2 hardcode lucide-react\uFF09",
|
|
2643
2999
|
initialValue: opts.iconLibrary ?? "lucide"
|
|
2644
3000
|
});
|
|
2645
|
-
if (
|
|
2646
|
-
const tsxAns = await
|
|
3001
|
+
if (prompts5.isCancel(iconLibrary)) throw new Error("Cancelled by user.");
|
|
3002
|
+
const tsxAns = await prompts5.confirm({
|
|
2647
3003
|
message: "\u4F7F\u7528 TSX\uFF1F",
|
|
2648
3004
|
initialValue: opts.tsx ?? true
|
|
2649
3005
|
});
|
|
2650
|
-
if (
|
|
2651
|
-
const rscAns = await
|
|
3006
|
+
if (prompts5.isCancel(tsxAns)) throw new Error("Cancelled by user.");
|
|
3007
|
+
const rscAns = await prompts5.confirm({
|
|
2652
3008
|
message: "\u4F7F\u7528 React Server Components\uFF1F",
|
|
2653
3009
|
initialValue: opts.rsc ?? false
|
|
2654
3010
|
});
|
|
2655
|
-
if (
|
|
3011
|
+
if (prompts5.isCancel(rscAns)) throw new Error("Cancelled by user.");
|
|
2656
3012
|
return {
|
|
2657
3013
|
aliases: {
|
|
2658
3014
|
components,
|
|
@@ -2669,16 +3025,16 @@ async function resolveConfig(opts) {
|
|
|
2669
3025
|
}
|
|
2670
3026
|
|
|
2671
3027
|
// src/commands/ui/add.ts
|
|
2672
|
-
import { Command as
|
|
3028
|
+
import { Command as Command16 } from "commander";
|
|
2673
3029
|
|
|
2674
3030
|
// src/core/ui-client.ts
|
|
2675
3031
|
import * as path16 from "path";
|
|
2676
3032
|
import * as fs13 from "fs/promises";
|
|
2677
|
-
import { createRequire as
|
|
3033
|
+
import { createRequire as createRequire6 } from "module";
|
|
2678
3034
|
import { loadUiPackageManifest } from "@teamix-evo/registry";
|
|
2679
|
-
var
|
|
3035
|
+
var require7 = createRequire6(import.meta.url);
|
|
2680
3036
|
function resolvePackageRoot2(packageName) {
|
|
2681
|
-
const pkgJsonPath =
|
|
3037
|
+
const pkgJsonPath = require7.resolve(`${packageName}/package.json`);
|
|
2682
3038
|
return path16.dirname(pkgJsonPath);
|
|
2683
3039
|
}
|
|
2684
3040
|
async function loadUiData(packageName) {
|
|
@@ -2894,7 +3250,7 @@ function mergeResources(prior, next) {
|
|
|
2894
3250
|
}
|
|
2895
3251
|
|
|
2896
3252
|
// src/commands/ui/add.ts
|
|
2897
|
-
var addCommand2 = new
|
|
3253
|
+
var addCommand2 = new Command16("add").description(
|
|
2898
3254
|
"\u5B89\u88C5\u4E00\u4E2A\u6216\u591A\u4E2A ui entry\uFF08\u6309 id\uFF0C\u81EA\u52A8\u5C55\u5F00 registryDependencies\uFF09"
|
|
2899
3255
|
).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
3256
|
"--include-deprecated",
|
|
@@ -2940,7 +3296,7 @@ var addCommand2 = new Command15("add").description(
|
|
|
2940
3296
|
);
|
|
2941
3297
|
|
|
2942
3298
|
// src/commands/ui/list.ts
|
|
2943
|
-
import { Command as
|
|
3299
|
+
import { Command as Command17 } from "commander";
|
|
2944
3300
|
|
|
2945
3301
|
// src/core/ui-list.ts
|
|
2946
3302
|
var DEFAULT_UI_PACKAGE2 = "@teamix-evo/ui";
|
|
@@ -2978,7 +3334,7 @@ async function runUiList(options) {
|
|
|
2978
3334
|
}
|
|
2979
3335
|
|
|
2980
3336
|
// src/commands/ui/list.ts
|
|
2981
|
-
var listCommand3 = new
|
|
3337
|
+
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
3338
|
"--include-deprecated",
|
|
2983
3339
|
"\u540C\u65F6\u5217\u51FA\u5DF2\u5F52\u6863\u7684 deprecated entry\uFF08\u9ED8\u8BA4\u9690\u85CF\uFF0CADR 0028\uFF09"
|
|
2984
3340
|
).action(
|
|
@@ -3030,30 +3386,30 @@ var listCommand3 = new Command16("list").description("\u5217\u51FA @teamix-evo/u
|
|
|
3030
3386
|
);
|
|
3031
3387
|
|
|
3032
3388
|
// src/commands/ui/index.ts
|
|
3033
|
-
var uiCommand = new
|
|
3389
|
+
var uiCommand = new Command18("ui").description(
|
|
3034
3390
|
"\u7BA1\u7406 teamix-evo ui \u7EC4\u4EF6\uFF08\u6E90\u7801\u6CE8\u5165\u5F0F\u5B89\u88C5\uFF0Cshadcn \u98CE\u683C\uFF09"
|
|
3035
3391
|
);
|
|
3036
|
-
uiCommand.addCommand(
|
|
3392
|
+
uiCommand.addCommand(initCommand3);
|
|
3037
3393
|
uiCommand.addCommand(addCommand2);
|
|
3038
3394
|
uiCommand.addCommand(listCommand3);
|
|
3039
3395
|
|
|
3040
3396
|
// src/commands/biz-ui/index.ts
|
|
3041
|
-
import { Command as
|
|
3397
|
+
import { Command as Command22 } from "commander";
|
|
3042
3398
|
|
|
3043
3399
|
// src/commands/biz-ui/add.ts
|
|
3044
|
-
import { Command as
|
|
3400
|
+
import { Command as Command19 } from "commander";
|
|
3045
3401
|
|
|
3046
3402
|
// src/core/variant-ui-add.ts
|
|
3047
3403
|
import * as path18 from "path";
|
|
3048
|
-
import { createRequire as
|
|
3404
|
+
import { createRequire as createRequire7 } from "module";
|
|
3049
3405
|
import {
|
|
3050
3406
|
loadUiPackageManifest as loadUiPackageManifest2,
|
|
3051
3407
|
loadVariantUiPackageCatalog,
|
|
3052
3408
|
loadVariantUiPackageManifest
|
|
3053
3409
|
} from "@teamix-evo/registry";
|
|
3054
|
-
var
|
|
3410
|
+
var require8 = createRequire7(import.meta.url);
|
|
3055
3411
|
function resolvePackageRoot3(packageName) {
|
|
3056
|
-
const pkgJsonPath =
|
|
3412
|
+
const pkgJsonPath = require8.resolve(`${packageName}/package.json`);
|
|
3057
3413
|
return path18.dirname(pkgJsonPath);
|
|
3058
3414
|
}
|
|
3059
3415
|
async function runVariantUiAdd(packageName, options) {
|
|
@@ -3212,7 +3568,7 @@ async function listTemplatesEntries(variant, packageRoot) {
|
|
|
3212
3568
|
}
|
|
3213
3569
|
|
|
3214
3570
|
// src/commands/biz-ui/add.ts
|
|
3215
|
-
var addCommand3 = new
|
|
3571
|
+
var addCommand3 = new Command19("add").description(
|
|
3216
3572
|
"\u5B89\u88C5\u4E00\u4E2A\u6216\u591A\u4E2A\u4E1A\u52A1 UI \u7EC4\u4EF6(\u6309 id,\u81EA\u52A8\u5C55\u5F00 ui \u5305\u7684 registryDependencies)"
|
|
3217
3573
|
).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
3574
|
async (ids, opts) => {
|
|
@@ -3261,8 +3617,8 @@ var addCommand3 = new Command18("add").description(
|
|
|
3261
3617
|
);
|
|
3262
3618
|
|
|
3263
3619
|
// src/commands/biz-ui/list.ts
|
|
3264
|
-
import { Command as
|
|
3265
|
-
var listCommand4 = new
|
|
3620
|
+
import { Command as Command20 } from "commander";
|
|
3621
|
+
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
3622
|
try {
|
|
3267
3623
|
const result = await listBizUiEntries(opts.variant);
|
|
3268
3624
|
logger.info(`${result.packageName}#${result.variant} entries:`);
|
|
@@ -3287,8 +3643,8 @@ var listCommand4 = new Command19("list").description("\u5217\u51FA\u6307\u5B9A\u
|
|
|
3287
3643
|
});
|
|
3288
3644
|
|
|
3289
3645
|
// src/commands/biz-ui/list-variants.ts
|
|
3290
|
-
import { Command as
|
|
3291
|
-
var listVariantsCommand2 = new
|
|
3646
|
+
import { Command as Command21 } from "commander";
|
|
3647
|
+
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
3648
|
try {
|
|
3293
3649
|
const result = await listBizUiVariants();
|
|
3294
3650
|
logger.info(`Available biz-ui variants in ${result.packageName}:`);
|
|
@@ -3310,7 +3666,7 @@ var listVariantsCommand2 = new Command20("list-variants").description("\u5217\u5
|
|
|
3310
3666
|
});
|
|
3311
3667
|
|
|
3312
3668
|
// src/commands/biz-ui/index.ts
|
|
3313
|
-
var bizUiCommand = new
|
|
3669
|
+
var bizUiCommand = new Command22("biz-ui").description(
|
|
3314
3670
|
"\u7BA1\u7406\u4E1A\u52A1 UI \u7EC4\u4EF6(\u53D8\u4F53\u611F\u77E5 \u2014 \u4E0E design / templates \u540C\u53D8\u4F53\u540D\u7A7A\u95F4)"
|
|
3315
3671
|
);
|
|
3316
3672
|
bizUiCommand.addCommand(addCommand3);
|
|
@@ -3318,11 +3674,11 @@ bizUiCommand.addCommand(listCommand4);
|
|
|
3318
3674
|
bizUiCommand.addCommand(listVariantsCommand2);
|
|
3319
3675
|
|
|
3320
3676
|
// src/commands/templates/index.ts
|
|
3321
|
-
import { Command as
|
|
3677
|
+
import { Command as Command26 } from "commander";
|
|
3322
3678
|
|
|
3323
3679
|
// src/commands/templates/add.ts
|
|
3324
|
-
import { Command as
|
|
3325
|
-
var addCommand4 = new
|
|
3680
|
+
import { Command as Command23 } from "commander";
|
|
3681
|
+
var addCommand4 = new Command23("add").description(
|
|
3326
3682
|
"\u5B89\u88C5\u4E00\u4E2A\u6216\u591A\u4E2A\u9875\u9762\u6A21\u677F(\u6309 id,\u81EA\u52A8\u5C55\u5F00 ui \u5305\u7684 registryDependencies)"
|
|
3327
3683
|
).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
3684
|
async (ids, opts) => {
|
|
@@ -3371,8 +3727,8 @@ var addCommand4 = new Command22("add").description(
|
|
|
3371
3727
|
);
|
|
3372
3728
|
|
|
3373
3729
|
// src/commands/templates/list.ts
|
|
3374
|
-
import { Command as
|
|
3375
|
-
var listCommand5 = new
|
|
3730
|
+
import { Command as Command24 } from "commander";
|
|
3731
|
+
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
3732
|
try {
|
|
3377
3733
|
const result = await listTemplatesEntries(opts.variant);
|
|
3378
3734
|
logger.info(`${result.packageName}#${result.variant} entries:`);
|
|
@@ -3397,8 +3753,8 @@ var listCommand5 = new Command23("list").description("\u5217\u51FA\u6307\u5B9A\u
|
|
|
3397
3753
|
});
|
|
3398
3754
|
|
|
3399
3755
|
// src/commands/templates/list-variants.ts
|
|
3400
|
-
import { Command as
|
|
3401
|
-
var listVariantsCommand3 = new
|
|
3756
|
+
import { Command as Command25 } from "commander";
|
|
3757
|
+
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
3758
|
try {
|
|
3403
3759
|
const result = await listTemplatesVariants();
|
|
3404
3760
|
logger.info(`Available templates variants in ${result.packageName}:`);
|
|
@@ -3420,7 +3776,7 @@ var listVariantsCommand3 = new Command24("list-variants").description("\u5217\u5
|
|
|
3420
3776
|
});
|
|
3421
3777
|
|
|
3422
3778
|
// src/commands/templates/index.ts
|
|
3423
|
-
var templatesCommand = new
|
|
3779
|
+
var templatesCommand = new Command26("templates").description(
|
|
3424
3780
|
"\u7BA1\u7406\u9875\u9762\u6A21\u677F(\u53D8\u4F53\u611F\u77E5 \u2014 \u4E0E design / biz-ui \u540C\u53D8\u4F53\u540D\u7A7A\u95F4)"
|
|
3425
3781
|
);
|
|
3426
3782
|
templatesCommand.addCommand(addCommand4);
|
|
@@ -3428,24 +3784,26 @@ templatesCommand.addCommand(listCommand5);
|
|
|
3428
3784
|
templatesCommand.addCommand(listVariantsCommand3);
|
|
3429
3785
|
|
|
3430
3786
|
// src/commands/logs/index.ts
|
|
3431
|
-
import { Command as
|
|
3787
|
+
import { Command as Command29 } from "commander";
|
|
3432
3788
|
|
|
3433
3789
|
// src/commands/logs/analyze.ts
|
|
3434
|
-
import { Command as
|
|
3790
|
+
import { Command as Command27 } from "commander";
|
|
3435
3791
|
import { readFileSync, readdirSync, existsSync as existsSync2, statSync } from "fs";
|
|
3436
3792
|
import { resolve as resolve3, join as join17 } from "path";
|
|
3437
3793
|
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>/.
|
|
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(
|
|
3441
3797
|
"--days <n>",
|
|
3442
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)"
|
|
3443
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) => {
|
|
3444
|
-
const baseDir = resolve3(
|
|
3800
|
+
const baseDir = resolve3(
|
|
3801
|
+
opts.dir ?? join17(process.cwd(), ".teamix-evo", "logs", "ai")
|
|
3802
|
+
);
|
|
3445
3803
|
if (!existsSync2(baseDir)) {
|
|
3446
3804
|
logger.warn(`No log directory at ${baseDir}.`);
|
|
3447
3805
|
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"
|
|
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"
|
|
3449
3807
|
);
|
|
3450
3808
|
return;
|
|
3451
3809
|
}
|
|
@@ -3615,18 +3973,20 @@ function parseIntOrUndef(v) {
|
|
|
3615
3973
|
}
|
|
3616
3974
|
|
|
3617
3975
|
// src/commands/logs/trace.ts
|
|
3618
|
-
import { Command as
|
|
3976
|
+
import { Command as Command28 } from "commander";
|
|
3619
3977
|
import { readFileSync as readFileSync2, readdirSync as readdirSync2, existsSync as existsSync3, statSync as statSync2 } from "fs";
|
|
3620
3978
|
import { resolve as resolve4, join as join18 } from "path";
|
|
3621
3979
|
var DATE_DIR_RE2 = /^\d{4}-\d{2}-\d{2}$/;
|
|
3622
|
-
var logsTraceCommand = new
|
|
3980
|
+
var logsTraceCommand = new Command28("trace").description(
|
|
3623
3981
|
"\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(
|
|
3982
|
+
).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
|
+
const baseDir = resolve4(
|
|
3984
|
+
opts.dir ?? join18(process.cwd(), ".teamix-evo", "logs", "ai")
|
|
3985
|
+
);
|
|
3626
3986
|
if (!existsSync3(baseDir)) {
|
|
3627
3987
|
logger.warn(`No log directory at ${baseDir}.`);
|
|
3628
3988
|
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"
|
|
3989
|
+
"\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
3990
|
);
|
|
3631
3991
|
return;
|
|
3632
3992
|
}
|
|
@@ -3778,7 +4138,9 @@ function printTrace(baseDir, r) {
|
|
|
3778
4138
|
logger.info("");
|
|
3779
4139
|
for (const c of s.chains) {
|
|
3780
4140
|
logger.info(
|
|
3781
|
-
`[${formatTime(c.promptTs)}] \u{1F4AC} Prompt: ${quote(
|
|
4141
|
+
`[${formatTime(c.promptTs)}] \u{1F4AC} Prompt: ${quote(
|
|
4142
|
+
truncate(c.prompt, 200)
|
|
4143
|
+
)}`
|
|
3782
4144
|
);
|
|
3783
4145
|
for (const step of c.steps) {
|
|
3784
4146
|
logger.info(` ${formatStep(step)}`);
|
|
@@ -3825,16 +4187,175 @@ function parseIntOrUndef2(v) {
|
|
|
3825
4187
|
}
|
|
3826
4188
|
|
|
3827
4189
|
// src/commands/logs/index.ts
|
|
3828
|
-
var logsCommand = new
|
|
3829
|
-
"\u67E5\u8BE2 vibe-logger \u8F93\u51FA (.
|
|
4190
|
+
var logsCommand = new Command29("logs").description(
|
|
4191
|
+
"\u67E5\u8BE2 vibe-logger \u8F93\u51FA (.teamix-evo/logs/ai/**/*.jsonl) \u2014 AI \u8C03\u7528\u94FE\u5206\u6790"
|
|
3830
4192
|
);
|
|
3831
4193
|
logsCommand.addCommand(logsAnalyzeCommand);
|
|
3832
4194
|
logsCommand.addCommand(logsTraceCommand);
|
|
3833
4195
|
|
|
4196
|
+
// src/commands/lint/index.ts
|
|
4197
|
+
import { Command as Command31 } from "commander";
|
|
4198
|
+
|
|
4199
|
+
// src/commands/lint/init.ts
|
|
4200
|
+
import { Command as Command30 } from "commander";
|
|
4201
|
+
import * as prompts6 from "@clack/prompts";
|
|
4202
|
+
|
|
4203
|
+
// src/core/lint-init.ts
|
|
4204
|
+
import * as path19 from "path";
|
|
4205
|
+
import * as fs15 from "fs";
|
|
4206
|
+
import { execa } from "execa";
|
|
4207
|
+
var ESLINT_CONFIG_CONTENT = `/**
|
|
4208
|
+
* teamix-evo consumer ESLint preset \u2014 9 token-discipline rules.
|
|
4209
|
+
* - Repo-wide: no-color-literal / no-arbitrary-tw-value / no-raw-color-scale /
|
|
4210
|
+
* no-large-radius / prefer-gap-over-space / no-manual-dark-classnames /
|
|
4211
|
+
* dialog-must-have-title (all error)
|
|
4212
|
+
* - src/components/ui/** only: no-relative-ui-import / icon-from-lucide (error)
|
|
4213
|
+
*
|
|
4214
|
+
* See ADR 0008 / docs/principles.md \xA7P4.
|
|
4215
|
+
*/
|
|
4216
|
+
import consumerPreset from '@teamix-evo/eslint-config/presets/consumer';
|
|
4217
|
+
|
|
4218
|
+
export default [...consumerPreset];
|
|
4219
|
+
`;
|
|
4220
|
+
var STYLELINT_CONFIG_CONTENT = `/** @type {import('stylelint').Config} */
|
|
4221
|
+
module.exports = {
|
|
4222
|
+
extends: ['@teamix-evo/stylelint-config/presets/consumer'],
|
|
4223
|
+
};
|
|
4224
|
+
`;
|
|
4225
|
+
var ESLINT_DEPS = [
|
|
4226
|
+
"@teamix-evo/eslint-config",
|
|
4227
|
+
"eslint",
|
|
4228
|
+
"@typescript-eslint/parser"
|
|
4229
|
+
];
|
|
4230
|
+
var STYLELINT_DEPS = ["@teamix-evo/stylelint-config", "stylelint"];
|
|
4231
|
+
async function runLintInit(options) {
|
|
4232
|
+
const { projectRoot, skipInstall } = options;
|
|
4233
|
+
const eslintConfigPath = path19.join(projectRoot, "eslint.config.js");
|
|
4234
|
+
const stylelintConfigPath = path19.join(projectRoot, "stylelint.config.cjs");
|
|
4235
|
+
const eslintExists = await fileExists(eslintConfigPath);
|
|
4236
|
+
const stylelintExists = await fileExists(stylelintConfigPath);
|
|
4237
|
+
if (eslintExists && stylelintExists) {
|
|
4238
|
+
return { status: "already-initialized" };
|
|
4239
|
+
}
|
|
4240
|
+
if (!skipInstall) {
|
|
4241
|
+
const depsToInstall = [
|
|
4242
|
+
...eslintExists ? [] : ESLINT_DEPS,
|
|
4243
|
+
...stylelintExists ? [] : STYLELINT_DEPS
|
|
4244
|
+
];
|
|
4245
|
+
if (depsToInstall.length > 0) {
|
|
4246
|
+
const pm = detectPm(projectRoot);
|
|
4247
|
+
const args = pm === "yarn" ? ["add", "--dev", ...depsToInstall] : pm === "pnpm" ? ["add", "-D", ...depsToInstall] : ["install", "--save-dev", ...depsToInstall];
|
|
4248
|
+
logger.info(`Installing lint deps via ${pm}...`);
|
|
4249
|
+
await execa(pm, args, { cwd: projectRoot, stdio: "inherit" });
|
|
4250
|
+
}
|
|
4251
|
+
}
|
|
4252
|
+
let wroteEslint = false;
|
|
4253
|
+
let wroteStylelint = false;
|
|
4254
|
+
if (!eslintExists) {
|
|
4255
|
+
await writeFileSafe(eslintConfigPath, ESLINT_CONFIG_CONTENT);
|
|
4256
|
+
logger.debug(`Wrote eslint.config.js \u2192 ${eslintConfigPath}`);
|
|
4257
|
+
wroteEslint = true;
|
|
4258
|
+
}
|
|
4259
|
+
if (!stylelintExists) {
|
|
4260
|
+
await writeFileSafe(stylelintConfigPath, STYLELINT_CONFIG_CONTENT);
|
|
4261
|
+
logger.debug(`Wrote stylelint.config.cjs \u2192 ${stylelintConfigPath}`);
|
|
4262
|
+
wroteStylelint = true;
|
|
4263
|
+
}
|
|
4264
|
+
await patchPackageJsonScripts(projectRoot);
|
|
4265
|
+
return {
|
|
4266
|
+
status: "installed",
|
|
4267
|
+
eslint: wroteEslint,
|
|
4268
|
+
stylelint: wroteStylelint
|
|
4269
|
+
};
|
|
4270
|
+
}
|
|
4271
|
+
function detectPm(projectRoot) {
|
|
4272
|
+
if (fs15.existsSync(path19.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
|
|
4273
|
+
if (fs15.existsSync(path19.join(projectRoot, "yarn.lock"))) return "yarn";
|
|
4274
|
+
return "npm";
|
|
4275
|
+
}
|
|
4276
|
+
async function patchPackageJsonScripts(projectRoot) {
|
|
4277
|
+
const pkgPath = path19.join(projectRoot, "package.json");
|
|
4278
|
+
const raw = await readFileOrNull(pkgPath);
|
|
4279
|
+
if (!raw) return;
|
|
4280
|
+
let pkg;
|
|
4281
|
+
try {
|
|
4282
|
+
pkg = JSON.parse(raw);
|
|
4283
|
+
} catch {
|
|
4284
|
+
return;
|
|
4285
|
+
}
|
|
4286
|
+
const scripts = pkg.scripts ?? {};
|
|
4287
|
+
let changed = false;
|
|
4288
|
+
if (!scripts.lint) {
|
|
4289
|
+
scripts.lint = "eslint src/";
|
|
4290
|
+
changed = true;
|
|
4291
|
+
}
|
|
4292
|
+
if (!scripts["lint:css"]) {
|
|
4293
|
+
scripts["lint:css"] = "stylelint 'src/**/*.css'";
|
|
4294
|
+
changed = true;
|
|
4295
|
+
}
|
|
4296
|
+
if (changed) {
|
|
4297
|
+
pkg.scripts = scripts;
|
|
4298
|
+
await writeFileSafe(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
4299
|
+
logger.debug("Patched package.json scripts with lint / lint:css");
|
|
4300
|
+
}
|
|
4301
|
+
}
|
|
4302
|
+
|
|
4303
|
+
// src/commands/lint/init.ts
|
|
4304
|
+
var initCommand4 = new Command30("init").description(
|
|
4305
|
+
"\u521D\u59CB\u5316 ESLint + Stylelint \u5DE5\u7A0B\u89C4\u8303\uFF08\u5B89\u88C5\u4F9D\u8D56 + \u751F\u6210\u914D\u7F6E\u6587\u4EF6 + \u6CE8\u5165 scripts\uFF09"
|
|
4306
|
+
).option("-y, --yes", "\u8DF3\u8FC7\u786E\u8BA4\uFF0C\u76F4\u63A5\u6267\u884C").action(async (opts) => {
|
|
4307
|
+
try {
|
|
4308
|
+
const ide = detectIde();
|
|
4309
|
+
const projectRoot = ide.getProjectRoot();
|
|
4310
|
+
if (!hasPackageJson(projectRoot)) {
|
|
4311
|
+
logger.error(
|
|
4312
|
+
"No package.json found in current directory. Please run this command in a valid project root."
|
|
4313
|
+
);
|
|
4314
|
+
process.exit(1);
|
|
4315
|
+
}
|
|
4316
|
+
if (!opts.yes) {
|
|
4317
|
+
const shouldContinue = await prompts6.confirm({
|
|
4318
|
+
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
|
+
});
|
|
4320
|
+
if (prompts6.isCancel(shouldContinue) || !shouldContinue) {
|
|
4321
|
+
logger.info("Cancelled.");
|
|
4322
|
+
return;
|
|
4323
|
+
}
|
|
4324
|
+
}
|
|
4325
|
+
const result = await runLintInit({ projectRoot });
|
|
4326
|
+
if (result.status === "already-initialized") {
|
|
4327
|
+
logger.warn(
|
|
4328
|
+
"Lint already initialized. eslint.config.js and stylelint.config.cjs both exist."
|
|
4329
|
+
);
|
|
4330
|
+
return;
|
|
4331
|
+
}
|
|
4332
|
+
logger.success("Lint initialized.");
|
|
4333
|
+
if (result.eslint) {
|
|
4334
|
+
logger.info(" + eslint.config.js");
|
|
4335
|
+
}
|
|
4336
|
+
if (result.stylelint) {
|
|
4337
|
+
logger.info(" + stylelint.config.cjs");
|
|
4338
|
+
}
|
|
4339
|
+
logger.info("");
|
|
4340
|
+
logger.info('Run "npm run lint" to check JSX/TSX token discipline.');
|
|
4341
|
+
logger.info('Run "npm run lint:css" to check CSS token discipline.');
|
|
4342
|
+
} catch (err) {
|
|
4343
|
+
logger.error(`Failed to initialize lint: ${err.message}`);
|
|
4344
|
+
logger.debug(err.stack ?? "");
|
|
4345
|
+
process.exitCode = 1;
|
|
4346
|
+
}
|
|
4347
|
+
});
|
|
4348
|
+
|
|
4349
|
+
// src/commands/lint/index.ts
|
|
4350
|
+
var lintCommand = new Command31("lint").description(
|
|
4351
|
+
"\u7BA1\u7406\u5DE5\u7A0B\u89C4\u8303\uFF08ESLint + Stylelint token-discipline \u89C4\u5219\u96C6\uFF09"
|
|
4352
|
+
);
|
|
4353
|
+
lintCommand.addCommand(initCommand4);
|
|
4354
|
+
|
|
3834
4355
|
// src/index.ts
|
|
3835
|
-
var
|
|
3836
|
-
var { version } =
|
|
3837
|
-
var program = new
|
|
4356
|
+
var require9 = createRequire8(import.meta.url);
|
|
4357
|
+
var { version } = require9("../package.json");
|
|
4358
|
+
var program = new Command32();
|
|
3838
4359
|
program.name("teamix-evo").description("Where ideas evolve. \u2014 AI Coding \u5957\u4EF6").version(version);
|
|
3839
4360
|
program.addCommand(tokensCommand);
|
|
3840
4361
|
program.addCommand(skillsCommand);
|
|
@@ -3842,5 +4363,11 @@ program.addCommand(uiCommand);
|
|
|
3842
4363
|
program.addCommand(bizUiCommand);
|
|
3843
4364
|
program.addCommand(templatesCommand);
|
|
3844
4365
|
program.addCommand(logsCommand);
|
|
4366
|
+
program.addCommand(lintCommand);
|
|
4367
|
+
function enableHelpAfterError(cmd) {
|
|
4368
|
+
cmd.showHelpAfterError(true);
|
|
4369
|
+
for (const child of cmd.commands) enableHelpAfterError(child);
|
|
4370
|
+
}
|
|
4371
|
+
enableHelpAfterError(program);
|
|
3845
4372
|
program.parse();
|
|
3846
4373
|
//# sourceMappingURL=index.js.map
|