teamix-evo 0.19.2 → 0.20.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 +16 -9
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +170 -140
- package/dist/core/index.js.map +1 -1
- package/dist/index.js +332 -214
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -40,12 +40,12 @@ var init_logger = __esm({
|
|
|
40
40
|
|
|
41
41
|
// src/utils/fs.ts
|
|
42
42
|
import * as fs from "fs/promises";
|
|
43
|
-
import * as
|
|
43
|
+
import * as path4 from "path";
|
|
44
44
|
async function ensureDir(dir) {
|
|
45
45
|
await fs.mkdir(dir, { recursive: true });
|
|
46
46
|
}
|
|
47
47
|
async function writeFileSafe(filePath, content) {
|
|
48
|
-
const dir =
|
|
48
|
+
const dir = path4.dirname(filePath);
|
|
49
49
|
await ensureDir(dir);
|
|
50
50
|
const tmp = filePath + ".tmp";
|
|
51
51
|
await fs.writeFile(tmp, content, "utf-8");
|
|
@@ -67,17 +67,17 @@ async function backupFile(filePath, projectRoot) {
|
|
|
67
67
|
logger.debug(`Skip backup: ${filePath} does not exist`);
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
|
-
const rel2 =
|
|
70
|
+
const rel2 = path4.relative(projectRoot, filePath);
|
|
71
71
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
72
|
-
const backupPath =
|
|
72
|
+
const backupPath = path4.join(
|
|
73
73
|
projectRoot,
|
|
74
74
|
".teamix-evo",
|
|
75
75
|
".backups",
|
|
76
76
|
`${rel2}.${timestamp}.bak`
|
|
77
77
|
);
|
|
78
|
-
await ensureDir(
|
|
78
|
+
await ensureDir(path4.dirname(backupPath));
|
|
79
79
|
await fs.writeFile(backupPath, content, "utf-8");
|
|
80
|
-
logger.debug(`Backed up ${rel2} \u2192 ${
|
|
80
|
+
logger.debug(`Backed up ${rel2} \u2192 ${path4.relative(projectRoot, backupPath)}`);
|
|
81
81
|
}
|
|
82
82
|
async function fileExists(filePath) {
|
|
83
83
|
try {
|
|
@@ -126,7 +126,7 @@ __export(state_exports, {
|
|
|
126
126
|
writeProjectConfig: () => writeProjectConfig,
|
|
127
127
|
writeSkillsLock: () => writeSkillsLock
|
|
128
128
|
});
|
|
129
|
-
import * as
|
|
129
|
+
import * as path5 from "path";
|
|
130
130
|
import {
|
|
131
131
|
validateConfig,
|
|
132
132
|
validateInstalled,
|
|
@@ -135,7 +135,7 @@ import {
|
|
|
135
135
|
} from "@teamix-evo/registry";
|
|
136
136
|
import * as fs2 from "fs/promises";
|
|
137
137
|
function getTeamixDir(projectRoot) {
|
|
138
|
-
return
|
|
138
|
+
return path5.join(projectRoot, TEAMIX_DIR);
|
|
139
139
|
}
|
|
140
140
|
async function ensureTeamixDir(projectRoot) {
|
|
141
141
|
const dir = getTeamixDir(projectRoot);
|
|
@@ -143,7 +143,7 @@ async function ensureTeamixDir(projectRoot) {
|
|
|
143
143
|
return dir;
|
|
144
144
|
}
|
|
145
145
|
async function readProjectConfig(projectRoot) {
|
|
146
|
-
const configPath =
|
|
146
|
+
const configPath = path5.join(projectRoot, TEAMIX_DIR, CONFIG_FILE);
|
|
147
147
|
const raw = await readFileOrNull(configPath);
|
|
148
148
|
if (raw === null) return null;
|
|
149
149
|
let data;
|
|
@@ -163,12 +163,12 @@ async function readProjectConfig(projectRoot) {
|
|
|
163
163
|
return result.data;
|
|
164
164
|
}
|
|
165
165
|
async function writeProjectConfig(projectRoot, config) {
|
|
166
|
-
const configPath =
|
|
166
|
+
const configPath = path5.join(projectRoot, TEAMIX_DIR, CONFIG_FILE);
|
|
167
167
|
await writeFileSafe(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
168
168
|
logger.debug(`Wrote config \u2192 ${configPath}`);
|
|
169
169
|
}
|
|
170
170
|
async function readInstalledManifest(projectRoot) {
|
|
171
|
-
const manifestPath =
|
|
171
|
+
const manifestPath = path5.join(projectRoot, TEAMIX_DIR, MANIFEST_FILE);
|
|
172
172
|
const raw = await readFileOrNull(manifestPath);
|
|
173
173
|
if (raw === null) return null;
|
|
174
174
|
let data;
|
|
@@ -216,12 +216,12 @@ function migrateManifest(data) {
|
|
|
216
216
|
return obj;
|
|
217
217
|
}
|
|
218
218
|
async function writeInstalledManifest(projectRoot, manifest) {
|
|
219
|
-
const manifestPath =
|
|
219
|
+
const manifestPath = path5.join(projectRoot, TEAMIX_DIR, MANIFEST_FILE);
|
|
220
220
|
await writeFileSafe(manifestPath, JSON.stringify(manifest, null, 2) + "\n");
|
|
221
221
|
logger.debug(`Wrote manifest \u2192 ${manifestPath}`);
|
|
222
222
|
}
|
|
223
223
|
async function readTokensLock(projectRoot) {
|
|
224
|
-
const lockPath =
|
|
224
|
+
const lockPath = path5.join(projectRoot, TEAMIX_DIR, TOKENS_LOCK_FILE);
|
|
225
225
|
const raw = await readFileOrNull(lockPath);
|
|
226
226
|
if (raw === null) return null;
|
|
227
227
|
try {
|
|
@@ -241,7 +241,7 @@ async function readTokensVariant(projectRoot) {
|
|
|
241
241
|
return lock?.variant.name ?? null;
|
|
242
242
|
}
|
|
243
243
|
async function readSkillsLock(projectRoot) {
|
|
244
|
-
const lockPath =
|
|
244
|
+
const lockPath = path5.join(projectRoot, TEAMIX_DIR, SKILLS_LOCK_FILE);
|
|
245
245
|
const raw = await readFileOrNull(lockPath);
|
|
246
246
|
if (raw === null) return null;
|
|
247
247
|
try {
|
|
@@ -260,20 +260,20 @@ async function readSkillsLock(projectRoot) {
|
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
async function writeSkillsLock(projectRoot, lock) {
|
|
263
|
-
const lockPath =
|
|
263
|
+
const lockPath = path5.join(projectRoot, TEAMIX_DIR, SKILLS_LOCK_FILE);
|
|
264
264
|
await writeFileSafe(lockPath, JSON.stringify(lock, null, 2) + "\n");
|
|
265
265
|
logger.debug(`Wrote skills lock \u2192 ${lockPath}`);
|
|
266
266
|
}
|
|
267
267
|
async function migrateSkillsLockLocation(projectRoot) {
|
|
268
|
-
const newPath =
|
|
268
|
+
const newPath = path5.join(projectRoot, TEAMIX_DIR, SKILLS_LOCK_FILE);
|
|
269
269
|
try {
|
|
270
270
|
await fs2.access(newPath);
|
|
271
271
|
} catch {
|
|
272
272
|
for (const legacyRel of LEGACY_SKILLS_LOCK_PATHS) {
|
|
273
|
-
const legacyPath =
|
|
273
|
+
const legacyPath = path5.join(projectRoot, TEAMIX_DIR, legacyRel);
|
|
274
274
|
try {
|
|
275
275
|
await fs2.access(legacyPath);
|
|
276
|
-
await ensureDir(
|
|
276
|
+
await ensureDir(path5.dirname(newPath));
|
|
277
277
|
await fs2.rename(legacyPath, newPath);
|
|
278
278
|
logger.debug(`Migrated skills lock: ${legacyRel} \u2192 ${SKILLS_LOCK_FILE}`);
|
|
279
279
|
break;
|
|
@@ -283,7 +283,7 @@ async function migrateSkillsLockLocation(projectRoot) {
|
|
|
283
283
|
}
|
|
284
284
|
}
|
|
285
285
|
for (const staleDir of ["skills-source", "skills"]) {
|
|
286
|
-
const abs =
|
|
286
|
+
const abs = path5.join(projectRoot, TEAMIX_DIR, staleDir);
|
|
287
287
|
try {
|
|
288
288
|
await fs2.rm(abs, { recursive: true, force: true });
|
|
289
289
|
logger.debug(`Cleaned up stale dir: .teamix-evo/${staleDir}/`);
|
|
@@ -310,8 +310,8 @@ var init_state = __esm({
|
|
|
310
310
|
TOKENS_LOCK_FILE = "tokens-lock.json";
|
|
311
311
|
SKILLS_LOCK_FILE = "skills-lock.json";
|
|
312
312
|
LEGACY_SKILLS_LOCK_PATHS = [
|
|
313
|
-
|
|
314
|
-
|
|
313
|
+
path5.join("skills-source", "manifest.lock.json"),
|
|
314
|
+
path5.join("skills", "manifest.lock.json")
|
|
315
315
|
];
|
|
316
316
|
}
|
|
317
317
|
});
|
|
@@ -583,7 +583,7 @@ var init_registry = __esm({
|
|
|
583
583
|
|
|
584
584
|
// src/index.ts
|
|
585
585
|
import { Command as Command42 } from "commander";
|
|
586
|
-
import { createRequire as
|
|
586
|
+
import { createRequire as createRequire8 } from "module";
|
|
587
587
|
|
|
588
588
|
// src/commands/tokens/index.ts
|
|
589
589
|
import { Command as Command12 } from "commander";
|
|
@@ -627,14 +627,50 @@ var ClaudeAdapter = class {
|
|
|
627
627
|
}
|
|
628
628
|
};
|
|
629
629
|
|
|
630
|
+
// src/ide/CodexAdapter.ts
|
|
631
|
+
import * as os3 from "os";
|
|
632
|
+
import * as path3 from "path";
|
|
633
|
+
var CodexAdapter = class {
|
|
634
|
+
kind = "codex";
|
|
635
|
+
name = "codex";
|
|
636
|
+
getProjectRoot() {
|
|
637
|
+
return process.cwd();
|
|
638
|
+
}
|
|
639
|
+
detectIde() {
|
|
640
|
+
return Boolean(
|
|
641
|
+
process.env.CODEX_HOME || process.env.CODEX_SANDBOX || process.env.CODEX_THREAD_ID || process.env.CODEX_CI
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
getSkillTargetDir(skillName, scope, projectRoot) {
|
|
645
|
+
const base = scope === "global" ? path3.join(os3.homedir(), ".agents") : path3.join(projectRoot ?? this.getProjectRoot(), ".agents");
|
|
646
|
+
return path3.join(base, "skills", skillName);
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
|
|
630
650
|
// src/ide/index.ts
|
|
631
|
-
var ALL_IDE_KINDS = [
|
|
651
|
+
var ALL_IDE_KINDS = [
|
|
652
|
+
"qoder",
|
|
653
|
+
"claude",
|
|
654
|
+
"codex"
|
|
655
|
+
];
|
|
656
|
+
function getIdeDisplayName(kind) {
|
|
657
|
+
switch (kind) {
|
|
658
|
+
case "qoder":
|
|
659
|
+
return "Qoder";
|
|
660
|
+
case "claude":
|
|
661
|
+
return "Claude Code";
|
|
662
|
+
case "codex":
|
|
663
|
+
return "Codex / ChatGPT";
|
|
664
|
+
}
|
|
665
|
+
}
|
|
632
666
|
function getAdapter(kind) {
|
|
633
667
|
switch (kind) {
|
|
634
668
|
case "qoder":
|
|
635
669
|
return new QoderAdapter();
|
|
636
670
|
case "claude":
|
|
637
671
|
return new ClaudeAdapter();
|
|
672
|
+
case "codex":
|
|
673
|
+
return new CodexAdapter();
|
|
638
674
|
default: {
|
|
639
675
|
const _exhaustive = kind;
|
|
640
676
|
throw new Error(`Unsupported IDE kind: ${_exhaustive}`);
|
|
@@ -644,12 +680,14 @@ function getAdapter(kind) {
|
|
|
644
680
|
function detectIde() {
|
|
645
681
|
const claude = new ClaudeAdapter();
|
|
646
682
|
if (claude.detectIde()) return claude;
|
|
683
|
+
const codex = new CodexAdapter();
|
|
684
|
+
if (codex.detectIde()) return codex;
|
|
647
685
|
return new QoderAdapter();
|
|
648
686
|
}
|
|
649
687
|
|
|
650
688
|
// src/core/tokens-init.ts
|
|
651
689
|
init_fs();
|
|
652
|
-
import * as
|
|
690
|
+
import * as path9 from "path";
|
|
653
691
|
import * as fs7 from "fs/promises";
|
|
654
692
|
import {
|
|
655
693
|
loadTokensPackageManifest,
|
|
@@ -668,21 +706,21 @@ init_state();
|
|
|
668
706
|
|
|
669
707
|
// src/core/skills-client.ts
|
|
670
708
|
init_logger();
|
|
671
|
-
import * as
|
|
709
|
+
import * as path6 from "path";
|
|
672
710
|
import * as fs3 from "fs/promises";
|
|
673
711
|
import { createRequire } from "module";
|
|
674
712
|
import { loadSkillsPackageManifest } from "@teamix-evo/registry";
|
|
675
713
|
var require2 = createRequire(import.meta.url);
|
|
676
714
|
function resolvePackageRoot(packageName) {
|
|
677
715
|
const pkgJsonPath = require2.resolve(`${packageName}/package.json`);
|
|
678
|
-
return
|
|
716
|
+
return path6.dirname(pkgJsonPath);
|
|
679
717
|
}
|
|
680
718
|
async function loadSkillsData(packageName) {
|
|
681
719
|
const packageRoot = resolvePackageRoot(packageName);
|
|
682
720
|
logger.debug(`Resolved skills package root: ${packageRoot}`);
|
|
683
721
|
const manifest = await loadSkillsPackageManifest(packageRoot);
|
|
684
722
|
let data = {};
|
|
685
|
-
const dataPath =
|
|
723
|
+
const dataPath = path6.join(packageRoot, "_data.json");
|
|
686
724
|
try {
|
|
687
725
|
const raw = await fs3.readFile(dataPath, "utf-8");
|
|
688
726
|
data = JSON.parse(raw);
|
|
@@ -696,7 +734,7 @@ async function loadSkillsData(packageName) {
|
|
|
696
734
|
}
|
|
697
735
|
|
|
698
736
|
// src/core/skills-installer.ts
|
|
699
|
-
import * as
|
|
737
|
+
import * as path8 from "path";
|
|
700
738
|
import * as fs6 from "fs/promises";
|
|
701
739
|
import {
|
|
702
740
|
replaceManagedRegion,
|
|
@@ -739,7 +777,7 @@ init_logger();
|
|
|
739
777
|
init_error();
|
|
740
778
|
|
|
741
779
|
// src/utils/path.ts
|
|
742
|
-
import * as
|
|
780
|
+
import * as path7 from "path";
|
|
743
781
|
import * as fs5 from "fs/promises";
|
|
744
782
|
import { createRequire as createRequire2 } from "module";
|
|
745
783
|
var require3 = createRequire2(import.meta.url);
|
|
@@ -753,7 +791,7 @@ async function walkDir(dir, skipDirs) {
|
|
|
753
791
|
const files = [];
|
|
754
792
|
const entries = await fs5.readdir(dir, { withFileTypes: true });
|
|
755
793
|
for (const entry of entries) {
|
|
756
|
-
const fullPath =
|
|
794
|
+
const fullPath = path7.join(dir, entry.name);
|
|
757
795
|
if (entry.isDirectory()) {
|
|
758
796
|
if (skipDirs && skipDirs.has(entry.name)) continue;
|
|
759
797
|
files.push(...await walkDir(fullPath, skipDirs));
|
|
@@ -765,10 +803,10 @@ async function walkDir(dir, skipDirs) {
|
|
|
765
803
|
}
|
|
766
804
|
function resolveTokensPackageRoot(packageName) {
|
|
767
805
|
const pkgJson = require3.resolve(`${packageName}/package.json`);
|
|
768
|
-
return
|
|
806
|
+
return path7.dirname(pkgJson);
|
|
769
807
|
}
|
|
770
808
|
function resolveResourceTarget(projectRoot, target) {
|
|
771
|
-
return
|
|
809
|
+
return path7.isAbsolute(target) ? target : path7.resolve(projectRoot, target);
|
|
772
810
|
}
|
|
773
811
|
|
|
774
812
|
// src/core/skills-installer.ts
|
|
@@ -806,7 +844,7 @@ async function installSkills(options) {
|
|
|
806
844
|
}
|
|
807
845
|
async function renderSkillFiles(skill, options) {
|
|
808
846
|
const { data, packageRoot } = options;
|
|
809
|
-
const sourceAbs =
|
|
847
|
+
const sourceAbs = path8.resolve(packageRoot, skill.source);
|
|
810
848
|
const stat6 = await fs6.stat(sourceAbs);
|
|
811
849
|
const rendered = /* @__PURE__ */ new Map();
|
|
812
850
|
if (stat6.isFile()) {
|
|
@@ -816,7 +854,7 @@ async function renderSkillFiles(skill, options) {
|
|
|
816
854
|
}
|
|
817
855
|
const entries = await walkDir(sourceAbs);
|
|
818
856
|
for (const entry of entries) {
|
|
819
|
-
let rel2 =
|
|
857
|
+
let rel2 = path8.relative(sourceAbs, entry);
|
|
820
858
|
if (skill.template && rel2.endsWith(".hbs")) {
|
|
821
859
|
rel2 = rel2.slice(0, -4);
|
|
822
860
|
}
|
|
@@ -831,7 +869,7 @@ async function writeRenderedToIde(skill, rendered, ide, scope, projectRoot) {
|
|
|
831
869
|
const records = [];
|
|
832
870
|
await ensureDir(targetDir);
|
|
833
871
|
for (const [rel2, sourceContent] of rendered) {
|
|
834
|
-
const targetFile =
|
|
872
|
+
const targetFile = path8.join(targetDir, rel2);
|
|
835
873
|
const writtenContent = await writeMirrorContent(
|
|
836
874
|
targetFile,
|
|
837
875
|
sourceContent,
|
|
@@ -903,7 +941,7 @@ function makeMirrorRecord(skill, projectRoot, targetAbs, content, ide, scope, re
|
|
|
903
941
|
const id = rel2 && rel2 !== "SKILL.md" ? `${skill.id}:${rel2}` : skill.id;
|
|
904
942
|
return {
|
|
905
943
|
id,
|
|
906
|
-
target:
|
|
944
|
+
target: path8.relative(projectRoot, targetAbs),
|
|
907
945
|
hash: computeHash(content),
|
|
908
946
|
strategy: skill.updateStrategy,
|
|
909
947
|
ide,
|
|
@@ -940,7 +978,7 @@ async function updateRenderedInIde(skill, rendered, ide, scope, projectRoot, sum
|
|
|
940
978
|
const records = [];
|
|
941
979
|
await ensureDir(targetDir);
|
|
942
980
|
for (const [rel2, newContent] of rendered) {
|
|
943
|
-
const targetFile =
|
|
981
|
+
const targetFile = path8.join(targetDir, rel2);
|
|
944
982
|
const exists = await fileExists(targetFile);
|
|
945
983
|
const written = await rewriteSingleFile({
|
|
946
984
|
targetFile,
|
|
@@ -1030,12 +1068,13 @@ async function reinstallSkillsToIdes(options) {
|
|
|
1030
1068
|
continue;
|
|
1031
1069
|
}
|
|
1032
1070
|
const rendered = await renderSkillFiles(entry, { data, packageRoot });
|
|
1033
|
-
|
|
1071
|
+
const supportedIdes = entry.ides.filter((ide) => ides.includes(ide));
|
|
1072
|
+
for (const ide of supportedIdes) {
|
|
1034
1073
|
const adapter = getAdapter(ide);
|
|
1035
1074
|
const targetDir = adapter.getSkillTargetDir(skill.name, scope, projectRoot);
|
|
1036
1075
|
await ensureDir(targetDir);
|
|
1037
1076
|
for (const [rel2, sourceContent] of rendered) {
|
|
1038
|
-
const targetFile =
|
|
1077
|
+
const targetFile = path8.join(targetDir, rel2);
|
|
1039
1078
|
const writtenContent = await writeMirrorContent(
|
|
1040
1079
|
targetFile,
|
|
1041
1080
|
sourceContent,
|
|
@@ -1043,7 +1082,7 @@ async function reinstallSkillsToIdes(options) {
|
|
|
1043
1082
|
);
|
|
1044
1083
|
out.push({
|
|
1045
1084
|
id: rel2 === "SKILL.md" ? skill.id : `${skill.id}:${rel2}`,
|
|
1046
|
-
target:
|
|
1085
|
+
target: path8.relative(projectRoot, targetFile),
|
|
1047
1086
|
hash: computeHash(writtenContent),
|
|
1048
1087
|
strategy: skill.updateStrategy,
|
|
1049
1088
|
ide,
|
|
@@ -1063,7 +1102,7 @@ async function pruneEmptyIdeSkillDirs(args) {
|
|
|
1063
1102
|
args.scope,
|
|
1064
1103
|
args.projectRoot
|
|
1065
1104
|
);
|
|
1066
|
-
const skillsRoot =
|
|
1105
|
+
const skillsRoot = path8.dirname(placeholderDir);
|
|
1067
1106
|
let entries;
|
|
1068
1107
|
try {
|
|
1069
1108
|
entries = await fs6.readdir(skillsRoot);
|
|
@@ -1071,7 +1110,7 @@ async function pruneEmptyIdeSkillDirs(args) {
|
|
|
1071
1110
|
continue;
|
|
1072
1111
|
}
|
|
1073
1112
|
for (const name of entries) {
|
|
1074
|
-
const dir =
|
|
1113
|
+
const dir = path8.join(skillsRoot, name);
|
|
1075
1114
|
let stat6;
|
|
1076
1115
|
try {
|
|
1077
1116
|
stat6 = await fs6.stat(dir);
|
|
@@ -1111,7 +1150,7 @@ async function removeSkillFiles(records, projectRoot) {
|
|
|
1111
1150
|
}
|
|
1112
1151
|
}
|
|
1113
1152
|
const startDirs = new Set(
|
|
1114
|
-
records.map((r) =>
|
|
1153
|
+
records.map((r) => path8.dirname(resolveResourceTarget(projectRoot, r.target)))
|
|
1115
1154
|
);
|
|
1116
1155
|
for (const startDir of startDirs) {
|
|
1117
1156
|
let dir = startDir;
|
|
@@ -1123,7 +1162,7 @@ async function removeSkillFiles(records, projectRoot) {
|
|
|
1123
1162
|
} catch {
|
|
1124
1163
|
break;
|
|
1125
1164
|
}
|
|
1126
|
-
dir =
|
|
1165
|
+
dir = path8.dirname(dir);
|
|
1127
1166
|
}
|
|
1128
1167
|
}
|
|
1129
1168
|
return removed;
|
|
@@ -1556,7 +1595,7 @@ async function autoUpgradeOutdatedSkills(args) {
|
|
|
1556
1595
|
init_logger();
|
|
1557
1596
|
init_error();
|
|
1558
1597
|
var DEFAULT_SKILLS_PACKAGE2 = "@teamix-evo/skills";
|
|
1559
|
-
var DEFAULT_AUTO_SKILL_IDES = [
|
|
1598
|
+
var DEFAULT_AUTO_SKILL_IDES = [...ALL_IDE_KINDS];
|
|
1560
1599
|
var DEFAULT_AUTO_SKILL_SCOPE = "project";
|
|
1561
1600
|
var DEFAULT_TOKENS_PACKAGE = "@teamix-evo/tokens";
|
|
1562
1601
|
var CONSUMER_TOKENS_DIR = "tokens";
|
|
@@ -1596,7 +1635,7 @@ Run \`npx teamix-evo@latest tokens list-variants\` to see all options.`
|
|
|
1596
1635
|
const result = await installVariantFile(fileRel, packageRoot, projectRoot);
|
|
1597
1636
|
if (result) installed.push(result);
|
|
1598
1637
|
}
|
|
1599
|
-
const overridesAbs =
|
|
1638
|
+
const overridesAbs = path9.join(
|
|
1600
1639
|
projectRoot,
|
|
1601
1640
|
CONSUMER_TOKENS_DIR,
|
|
1602
1641
|
CONSUMER_OVERRIDES_FILE
|
|
@@ -1609,7 +1648,7 @@ Run \`npx teamix-evo@latest tokens list-variants\` to see all options.`
|
|
|
1609
1648
|
const overridesContent = await fs7.readFile(overridesAbs, "utf-8");
|
|
1610
1649
|
installed.push({
|
|
1611
1650
|
id: overridesId,
|
|
1612
|
-
target:
|
|
1651
|
+
target: path9.posix.join(CONSUMER_TOKENS_DIR, CONSUMER_OVERRIDES_FILE),
|
|
1613
1652
|
hash: computeHash(overridesContent),
|
|
1614
1653
|
strategy: "frozen"
|
|
1615
1654
|
});
|
|
@@ -1627,7 +1666,7 @@ Run \`npx teamix-evo@latest tokens list-variants\` to see all options.`
|
|
|
1627
1666
|
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1628
1667
|
};
|
|
1629
1668
|
await writeFileSafe(
|
|
1630
|
-
|
|
1669
|
+
path9.join(projectRoot, ".teamix-evo", "tokens-lock.json"),
|
|
1631
1670
|
JSON.stringify(lock, null, 2) + "\n"
|
|
1632
1671
|
);
|
|
1633
1672
|
const config = {
|
|
@@ -1747,11 +1786,11 @@ async function tryAutoInstallVariantSkills(args) {
|
|
|
1747
1786
|
}
|
|
1748
1787
|
}
|
|
1749
1788
|
async function installVariantFile(fileRelToPackage, packageRoot, projectRoot) {
|
|
1750
|
-
const sourceAbs =
|
|
1751
|
-
const base =
|
|
1789
|
+
const sourceAbs = path9.join(packageRoot, fileRelToPackage);
|
|
1790
|
+
const base = path9.basename(fileRelToPackage);
|
|
1752
1791
|
if (base === "theme.css") {
|
|
1753
|
-
const targetRel =
|
|
1754
|
-
const targetAbs =
|
|
1792
|
+
const targetRel = path9.posix.join(CONSUMER_TOKENS_DIR, CONSUMER_THEME_FILE);
|
|
1793
|
+
const targetAbs = path9.join(projectRoot, targetRel);
|
|
1755
1794
|
const content = await fs7.readFile(sourceAbs, "utf-8");
|
|
1756
1795
|
if (await fileExists(targetAbs)) {
|
|
1757
1796
|
await backupFile(targetAbs, projectRoot);
|
|
@@ -1765,11 +1804,11 @@ async function installVariantFile(fileRelToPackage, packageRoot, projectRoot) {
|
|
|
1765
1804
|
};
|
|
1766
1805
|
}
|
|
1767
1806
|
if (base === "overrides.css" || base === "tokens.overrides.css") {
|
|
1768
|
-
const targetRel =
|
|
1807
|
+
const targetRel = path9.posix.join(
|
|
1769
1808
|
CONSUMER_TOKENS_DIR,
|
|
1770
1809
|
CONSUMER_OVERRIDES_FILE
|
|
1771
1810
|
);
|
|
1772
|
-
const targetAbs =
|
|
1811
|
+
const targetAbs = path9.join(projectRoot, targetRel);
|
|
1773
1812
|
if (await fileExists(targetAbs)) {
|
|
1774
1813
|
const existing = await fs7.readFile(targetAbs, "utf-8");
|
|
1775
1814
|
return {
|
|
@@ -1808,9 +1847,9 @@ async function listTokenVariants(packageName = DEFAULT_TOKENS_PACKAGE, packageRo
|
|
|
1808
1847
|
|
|
1809
1848
|
// src/core/html-theme-patch.ts
|
|
1810
1849
|
init_fs();
|
|
1811
|
-
import * as
|
|
1850
|
+
import * as path10 from "path";
|
|
1812
1851
|
async function patchHtmlDataTheme(projectRoot, variant) {
|
|
1813
|
-
const htmlPath =
|
|
1852
|
+
const htmlPath = path10.join(projectRoot, "index.html");
|
|
1814
1853
|
const content = await readFileOrNull(htmlPath);
|
|
1815
1854
|
if (content === null) {
|
|
1816
1855
|
return { status: "not-found", htmlPath };
|
|
@@ -1832,16 +1871,16 @@ async function patchHtmlDataTheme(projectRoot, variant) {
|
|
|
1832
1871
|
// src/utils/global-root.ts
|
|
1833
1872
|
import { existsSync } from "fs";
|
|
1834
1873
|
import * as fs8 from "fs/promises";
|
|
1835
|
-
import * as
|
|
1836
|
-
import * as
|
|
1874
|
+
import * as os4 from "os";
|
|
1875
|
+
import * as path11 from "path";
|
|
1837
1876
|
var GLOBAL_META_DIR = ".teamix-evo-global";
|
|
1838
1877
|
var TEAMIX_DIR2 = ".teamix-evo";
|
|
1839
1878
|
var CONFIG_FILE2 = "config.json";
|
|
1840
1879
|
function getGlobalMetaRoot() {
|
|
1841
|
-
return
|
|
1880
|
+
return path11.join(os4.homedir(), GLOBAL_META_DIR);
|
|
1842
1881
|
}
|
|
1843
1882
|
function isTeamixEvoProject(dir) {
|
|
1844
|
-
return existsSync(
|
|
1883
|
+
return existsSync(path11.join(dir, TEAMIX_DIR2, CONFIG_FILE2));
|
|
1845
1884
|
}
|
|
1846
1885
|
async function ensureGlobalMetaRoot() {
|
|
1847
1886
|
const root = getGlobalMetaRoot();
|
|
@@ -1849,7 +1888,7 @@ async function ensureGlobalMetaRoot() {
|
|
|
1849
1888
|
return root;
|
|
1850
1889
|
}
|
|
1851
1890
|
function hasPackageJson(projectRoot) {
|
|
1852
|
-
return existsSync(
|
|
1891
|
+
return existsSync(path11.join(projectRoot, "package.json"));
|
|
1853
1892
|
}
|
|
1854
1893
|
function resolveSkillsMaintenanceRoot(cwd) {
|
|
1855
1894
|
if (isTeamixEvoProject(cwd)) return cwd;
|
|
@@ -1954,7 +1993,7 @@ import { Command as Command2 } from "commander";
|
|
|
1954
1993
|
|
|
1955
1994
|
// src/core/tokens-update.ts
|
|
1956
1995
|
init_fs();
|
|
1957
|
-
import * as
|
|
1996
|
+
import * as path13 from "path";
|
|
1958
1997
|
import * as fs9 from "fs/promises";
|
|
1959
1998
|
import {
|
|
1960
1999
|
loadTokensPackageManifest as loadTokensPackageManifest2,
|
|
@@ -1964,7 +2003,7 @@ init_state();
|
|
|
1964
2003
|
|
|
1965
2004
|
// src/core/upgrade-hints.ts
|
|
1966
2005
|
init_fs();
|
|
1967
|
-
import * as
|
|
2006
|
+
import * as path12 from "path";
|
|
1968
2007
|
var TEAMIX_DIR3 = ".teamix-evo";
|
|
1969
2008
|
var HINTS_DIR = ".upgrade-hints";
|
|
1970
2009
|
function isoToFsSafe(iso) {
|
|
@@ -1975,7 +2014,7 @@ async function writeTokensUpgradeHint(options) {
|
|
|
1975
2014
|
const isoTs = options.isoTs ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
1976
2015
|
const fsTs = isoToFsSafe(isoTs);
|
|
1977
2016
|
const filename = `tokens-${fsTs}.json`;
|
|
1978
|
-
const target =
|
|
2017
|
+
const target = path12.join(
|
|
1979
2018
|
options.projectRoot,
|
|
1980
2019
|
TEAMIX_DIR3,
|
|
1981
2020
|
HINTS_DIR,
|
|
@@ -2064,8 +2103,8 @@ async function runTokensUpdate(options) {
|
|
|
2064
2103
|
const upstreamByBasename = /* @__PURE__ */ new Map();
|
|
2065
2104
|
for (const fileRel of variantEntry.files) {
|
|
2066
2105
|
upstreamByBasename.set(
|
|
2067
|
-
|
|
2068
|
-
|
|
2106
|
+
path13.basename(fileRel),
|
|
2107
|
+
path13.join(packageRoot, fileRel)
|
|
2069
2108
|
);
|
|
2070
2109
|
}
|
|
2071
2110
|
const prior = await readInstalledManifest(projectRoot) ?? {
|
|
@@ -2082,8 +2121,8 @@ async function runTokensUpdate(options) {
|
|
|
2082
2121
|
const frozenDrift = [];
|
|
2083
2122
|
const refreshedResources = [];
|
|
2084
2123
|
for (const resource of priorResources) {
|
|
2085
|
-
const consumerAbs =
|
|
2086
|
-
const consumerBasename =
|
|
2124
|
+
const consumerAbs = path13.isAbsolute(resource.target) ? resource.target : path13.join(projectRoot, resource.target);
|
|
2125
|
+
const consumerBasename = path13.basename(resource.target);
|
|
2087
2126
|
const upstreamBasename = lookupUpstreamBasename(consumerBasename);
|
|
2088
2127
|
const upstreamAbs = upstreamBasename ? upstreamByBasename.get(upstreamBasename) : void 0;
|
|
2089
2128
|
if (resource.strategy === "regenerable") {
|
|
@@ -2160,7 +2199,7 @@ async function runTokensUpdate(options) {
|
|
|
2160
2199
|
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2161
2200
|
};
|
|
2162
2201
|
await writeFileSafe(
|
|
2163
|
-
|
|
2202
|
+
path13.join(projectRoot, ".teamix-evo", "tokens-lock.json"),
|
|
2164
2203
|
JSON.stringify(lock, null, 2) + "\n"
|
|
2165
2204
|
);
|
|
2166
2205
|
config.packages.tokens.version = variantEntry.version;
|
|
@@ -2361,7 +2400,7 @@ var listVariantsCommand = new Command4("list-variants").description("\u5217\u51F
|
|
|
2361
2400
|
// src/commands/tokens/uninstall.ts
|
|
2362
2401
|
import { Command as Command5 } from "commander";
|
|
2363
2402
|
import * as fs10 from "fs/promises";
|
|
2364
|
-
import * as
|
|
2403
|
+
import * as path14 from "path";
|
|
2365
2404
|
import * as prompts from "@clack/prompts";
|
|
2366
2405
|
init_state();
|
|
2367
2406
|
init_logger();
|
|
@@ -2406,7 +2445,7 @@ var uninstallCommand = new Command5("uninstall").description(
|
|
|
2406
2445
|
}
|
|
2407
2446
|
let removed = 0;
|
|
2408
2447
|
for (const r of removable) {
|
|
2409
|
-
const target =
|
|
2448
|
+
const target = path14.isAbsolute(r.target) ? r.target : path14.join(projectRoot, r.target);
|
|
2410
2449
|
try {
|
|
2411
2450
|
await fs10.unlink(target);
|
|
2412
2451
|
removed++;
|
|
@@ -2424,7 +2463,7 @@ var uninstallCommand = new Command5("uninstall").description(
|
|
|
2424
2463
|
}
|
|
2425
2464
|
delete config.packages.tokens;
|
|
2426
2465
|
await writeProjectConfig(projectRoot, config);
|
|
2427
|
-
const lockPath =
|
|
2466
|
+
const lockPath = path14.join(
|
|
2428
2467
|
projectRoot,
|
|
2429
2468
|
".teamix-evo",
|
|
2430
2469
|
"tokens-lock.json"
|
|
@@ -2458,12 +2497,12 @@ init_error();
|
|
|
2458
2497
|
|
|
2459
2498
|
// src/core/tokens-audit.ts
|
|
2460
2499
|
import * as fs11 from "fs/promises";
|
|
2461
|
-
import * as
|
|
2500
|
+
import * as path15 from "path";
|
|
2462
2501
|
var THEME_REL = "tokens/tokens.theme.css";
|
|
2463
2502
|
var OVERRIDES_REL = "tokens/tokens.overrides.css";
|
|
2464
2503
|
async function runTokensAudit(options) {
|
|
2465
|
-
const themePath =
|
|
2466
|
-
const overridesPath =
|
|
2504
|
+
const themePath = path15.join(options.projectRoot, THEME_REL);
|
|
2505
|
+
const overridesPath = path15.join(options.projectRoot, OVERRIDES_REL);
|
|
2467
2506
|
const themeSrc = await safeRead(themePath);
|
|
2468
2507
|
if (themeSrc === null) {
|
|
2469
2508
|
return { status: "no-theme", themePath, overridesPath };
|
|
@@ -2682,7 +2721,7 @@ init_registry();
|
|
|
2682
2721
|
|
|
2683
2722
|
// src/codemods/runner.ts
|
|
2684
2723
|
import * as fs12 from "fs/promises";
|
|
2685
|
-
import * as
|
|
2724
|
+
import * as path16 from "path";
|
|
2686
2725
|
init_registry();
|
|
2687
2726
|
async function runCodemod(options) {
|
|
2688
2727
|
const { projectRoot, codemodId, dryRun = true } = options;
|
|
@@ -2692,7 +2731,7 @@ async function runCodemod(options) {
|
|
|
2692
2731
|
`Unknown codemod "${codemodId}". Available: ${(await Promise.resolve().then(() => (init_registry(), registry_exports))).listCodemodIds().join(", ")}`
|
|
2693
2732
|
);
|
|
2694
2733
|
}
|
|
2695
|
-
const scanRoot =
|
|
2734
|
+
const scanRoot = path16.join(projectRoot, "src");
|
|
2696
2735
|
let allFiles;
|
|
2697
2736
|
try {
|
|
2698
2737
|
allFiles = await walkDir(scanRoot, DEFAULT_SKIP_DIRS);
|
|
@@ -2700,14 +2739,14 @@ async function runCodemod(options) {
|
|
|
2700
2739
|
allFiles = [];
|
|
2701
2740
|
}
|
|
2702
2741
|
const files = allFiles.filter((abs) => {
|
|
2703
|
-
const ext =
|
|
2742
|
+
const ext = path16.extname(abs).slice(1);
|
|
2704
2743
|
return codemod.extensions.includes(ext);
|
|
2705
2744
|
});
|
|
2706
2745
|
const results = [];
|
|
2707
2746
|
let scanned = 0;
|
|
2708
2747
|
for (const absPath of files) {
|
|
2709
2748
|
scanned++;
|
|
2710
|
-
const relFile =
|
|
2749
|
+
const relFile = path16.relative(projectRoot, absPath);
|
|
2711
2750
|
const content = await fs12.readFile(absPath, "utf-8");
|
|
2712
2751
|
const result = codemod.transform(content, relFile, options.tokenMap);
|
|
2713
2752
|
if (result) {
|
|
@@ -2731,7 +2770,7 @@ async function runCodemod(options) {
|
|
|
2731
2770
|
// src/core/tokens-treat.ts
|
|
2732
2771
|
init_fs();
|
|
2733
2772
|
import * as fs13 from "fs/promises";
|
|
2734
|
-
import * as
|
|
2773
|
+
import * as path17 from "path";
|
|
2735
2774
|
|
|
2736
2775
|
// src/utils/lint.ts
|
|
2737
2776
|
import { exec } from "child_process";
|
|
@@ -2864,14 +2903,14 @@ async function captureBaseline(projectRoot) {
|
|
|
2864
2903
|
};
|
|
2865
2904
|
}
|
|
2866
2905
|
async function generateTreatmentReport(projectRoot, pre, post, deltas, codemodResults) {
|
|
2867
|
-
const reportsDir =
|
|
2906
|
+
const reportsDir = path17.join(
|
|
2868
2907
|
projectRoot,
|
|
2869
2908
|
".teamix-evo",
|
|
2870
2909
|
".treatment-reports"
|
|
2871
2910
|
);
|
|
2872
2911
|
await ensureDir(reportsDir);
|
|
2873
2912
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
2874
|
-
const reportPath =
|
|
2913
|
+
const reportPath = path17.join(reportsDir, `${ts}.md`);
|
|
2875
2914
|
let content = `# Token \u6CBB\u7406\u62A5\u544A
|
|
2876
2915
|
|
|
2877
2916
|
> \u6267\u884C\u65F6\u95F4: ${post.timestamp}
|
|
@@ -2906,7 +2945,7 @@ async function generateTreatmentReport(projectRoot, pre, post, deltas, codemodRe
|
|
|
2906
2945
|
return reportPath;
|
|
2907
2946
|
}
|
|
2908
2947
|
async function lockBaselineFile(projectRoot, baseline) {
|
|
2909
|
-
const baselinePath =
|
|
2948
|
+
const baselinePath = path17.join(
|
|
2910
2949
|
projectRoot,
|
|
2911
2950
|
".teamix-evo",
|
|
2912
2951
|
"tokens-baseline.json"
|
|
@@ -2920,8 +2959,8 @@ async function lockBaselineFile(projectRoot, baseline) {
|
|
|
2920
2959
|
async function buildTokenMapFromProject(projectRoot) {
|
|
2921
2960
|
const map = /* @__PURE__ */ new Map();
|
|
2922
2961
|
const tokenFiles = [
|
|
2923
|
-
|
|
2924
|
-
|
|
2962
|
+
path17.join(projectRoot, "tokens", "tokens.theme.css"),
|
|
2963
|
+
path17.join(projectRoot, "tokens", "tokens.overrides.css")
|
|
2925
2964
|
];
|
|
2926
2965
|
for (const file of tokenFiles) {
|
|
2927
2966
|
const content = await readFileOrNull(file);
|
|
@@ -3007,7 +3046,7 @@ import { Command as Command8 } from "commander";
|
|
|
3007
3046
|
init_fs();
|
|
3008
3047
|
init_logger();
|
|
3009
3048
|
import * as fs14 from "fs/promises";
|
|
3010
|
-
import * as
|
|
3049
|
+
import * as path18 from "path";
|
|
3011
3050
|
import { exec as exec2 } from "child_process";
|
|
3012
3051
|
import { promisify as promisify2 } from "util";
|
|
3013
3052
|
var execAsync2 = promisify2(exec2);
|
|
@@ -3118,7 +3157,7 @@ async function collectLintViolations(projectRoot) {
|
|
|
3118
3157
|
for (const msg of result.messages) {
|
|
3119
3158
|
violations.push({
|
|
3120
3159
|
ruleId: msg.ruleId,
|
|
3121
|
-
file:
|
|
3160
|
+
file: path18.relative(projectRoot, result.filePath),
|
|
3122
3161
|
line: msg.line
|
|
3123
3162
|
});
|
|
3124
3163
|
}
|
|
@@ -3133,9 +3172,9 @@ async function collectLintViolations(projectRoot) {
|
|
|
3133
3172
|
return violations;
|
|
3134
3173
|
}
|
|
3135
3174
|
async function generateTreatmentPlan(projectRoot, entries, totalViolations, phaseSummary) {
|
|
3136
|
-
const teamixDir =
|
|
3175
|
+
const teamixDir = path18.join(projectRoot, ".teamix-evo");
|
|
3137
3176
|
await ensureDir(teamixDir);
|
|
3138
|
-
const planPath =
|
|
3177
|
+
const planPath = path18.join(teamixDir, ".treatment-plan.md");
|
|
3139
3178
|
const now = (/* @__PURE__ */ new Date()).toISOString().slice(0, 19).replace("T", " ");
|
|
3140
3179
|
const phases = [
|
|
3141
3180
|
{
|
|
@@ -3293,7 +3332,7 @@ var treatCommand = new Command9("treat").description("\u4E00\u952E token \u6CBB\
|
|
|
3293
3332
|
import { Command as Command10 } from "commander";
|
|
3294
3333
|
|
|
3295
3334
|
// src/core/tokens-reflect.ts
|
|
3296
|
-
import * as
|
|
3335
|
+
import * as path19 from "path";
|
|
3297
3336
|
import { exec as exec3 } from "child_process";
|
|
3298
3337
|
import { promisify as promisify3 } from "util";
|
|
3299
3338
|
var execAsync3 = promisify3(exec3);
|
|
@@ -3314,7 +3353,7 @@ async function runTokensReflect(options) {
|
|
|
3314
3353
|
const colorMatch = msg.message.match(/#[0-9a-fA-F]{3,8}/);
|
|
3315
3354
|
if (!colorMatch) continue;
|
|
3316
3355
|
const color = normaliseHex2(colorMatch[0]);
|
|
3317
|
-
const relFile =
|
|
3356
|
+
const relFile = path19.relative(projectRoot, result.filePath);
|
|
3318
3357
|
const entry = colorMap.get(color) ?? {
|
|
3319
3358
|
frequency: 0,
|
|
3320
3359
|
files: /* @__PURE__ */ new Set()
|
|
@@ -3422,10 +3461,10 @@ import { Command as Command11 } from "commander";
|
|
|
3422
3461
|
|
|
3423
3462
|
// src/core/baseline-check.ts
|
|
3424
3463
|
init_fs();
|
|
3425
|
-
import * as
|
|
3464
|
+
import * as path20 from "path";
|
|
3426
3465
|
init_logger();
|
|
3427
3466
|
async function checkBaseline(projectRoot) {
|
|
3428
|
-
const baselinePath =
|
|
3467
|
+
const baselinePath = path20.join(
|
|
3429
3468
|
projectRoot,
|
|
3430
3469
|
".teamix-evo",
|
|
3431
3470
|
"tokens-baseline.json"
|
|
@@ -3561,8 +3600,9 @@ function parseIdeList(input) {
|
|
|
3561
3600
|
const parts = input.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
3562
3601
|
const result = [];
|
|
3563
3602
|
for (const p2 of parts) {
|
|
3564
|
-
if (p2
|
|
3565
|
-
|
|
3603
|
+
if (ALL_IDE_KINDS.includes(p2)) {
|
|
3604
|
+
const ide = p2;
|
|
3605
|
+
if (!result.includes(ide)) result.push(ide);
|
|
3566
3606
|
} else {
|
|
3567
3607
|
throw new Error(
|
|
3568
3608
|
`Unknown IDE: "${p2}". Expected one of: ${ALL_IDE_KINDS.join(", ")}.`
|
|
@@ -3580,7 +3620,7 @@ function parseScope(input) {
|
|
|
3580
3620
|
// src/commands/skills/init.ts
|
|
3581
3621
|
var initCommand2 = new Command13("init").description(
|
|
3582
3622
|
"\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"
|
|
3583
|
-
).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) => {
|
|
3623
|
+
).option("--ide <list>", '\u9017\u53F7\u5206\u9694\u7684 IDE \u5217\u8868\uFF0C\u5982 "qoder,claude,codex"').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) => {
|
|
3584
3624
|
try {
|
|
3585
3625
|
const ide = detectIde();
|
|
3586
3626
|
const cwd = ide.getProjectRoot();
|
|
@@ -3660,7 +3700,7 @@ async function resolveIdesAndScope(args) {
|
|
|
3660
3700
|
message: "\u9009\u62E9\u8981\u6CE8\u5165\u6280\u80FD\u7684 AI IDE\uFF08\u81F3\u5C11\u4E00\u4E2A\uFF09",
|
|
3661
3701
|
options: ALL_IDE_KINDS.map((k) => ({
|
|
3662
3702
|
value: k,
|
|
3663
|
-
label: k
|
|
3703
|
+
label: getIdeDisplayName(k)
|
|
3664
3704
|
})),
|
|
3665
3705
|
initialValues: [...ALL_IDE_KINDS],
|
|
3666
3706
|
required: true
|
|
@@ -3671,8 +3711,8 @@ async function resolveIdesAndScope(args) {
|
|
|
3671
3711
|
const scopeAns = await prompts2.select({
|
|
3672
3712
|
message: "\u5B89\u88C5\u8303\u56F4\uFF1F",
|
|
3673
3713
|
options: [
|
|
3674
|
-
{ value: "project", label: "\u9879\u76EE\u7EA7\uFF08
|
|
3675
|
-
{ value: "global", label: "\u5168\u5C40\uFF08
|
|
3714
|
+
{ value: "project", label: "\u9879\u76EE\u7EA7\uFF08\u5199\u5165\u6240\u9009 IDE \u7684\u9879\u76EE skill \u76EE\u5F55\uFF09" },
|
|
3715
|
+
{ value: "global", label: "\u5168\u5C40\uFF08\u5199\u5165\u6240\u9009 IDE \u7684\u7528\u6237 skill \u76EE\u5F55\uFF09" }
|
|
3676
3716
|
],
|
|
3677
3717
|
initialValue: "project"
|
|
3678
3718
|
});
|
|
@@ -3690,7 +3730,7 @@ init_logger();
|
|
|
3690
3730
|
init_error();
|
|
3691
3731
|
var addCommand = new Command14("add").description(
|
|
3692
3732
|
"\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"
|
|
3693
|
-
).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(
|
|
3733
|
+
).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,codex"').option(
|
|
3694
3734
|
"--scope <scope>",
|
|
3695
3735
|
"project | global\uFF08\u9ED8\u8BA4\u6CBF\u7528\u65E2\u6709 skills \u914D\u7F6E\uFF1B\u9996\u6B21\u5B89\u88C5\u9ED8\u8BA4 project\uFF09"
|
|
3696
3736
|
).option("-y, --yes", "\u4F7F\u7528\u9ED8\u8BA4\u503C\uFF0C\u8DF3\u8FC7\u4EA4\u4E92").action(async (names, opts) => {
|
|
@@ -3803,7 +3843,7 @@ async function resolveIdesAndScope2(args) {
|
|
|
3803
3843
|
message: "\u9009\u62E9\u8981\u6CE8\u5165\u6280\u80FD\u7684 AI IDE\uFF08\u81F3\u5C11\u4E00\u4E2A\uFF09",
|
|
3804
3844
|
options: ALL_IDE_KINDS.map((k) => ({
|
|
3805
3845
|
value: k,
|
|
3806
|
-
label: k
|
|
3846
|
+
label: getIdeDisplayName(k)
|
|
3807
3847
|
})),
|
|
3808
3848
|
initialValues: [...ALL_IDE_KINDS],
|
|
3809
3849
|
required: true
|
|
@@ -3814,8 +3854,8 @@ async function resolveIdesAndScope2(args) {
|
|
|
3814
3854
|
const scopeAns = await prompts3.select({
|
|
3815
3855
|
message: "\u5B89\u88C5\u8303\u56F4\uFF1F",
|
|
3816
3856
|
options: [
|
|
3817
|
-
{ value: "project", label: "\u9879\u76EE\u7EA7\uFF08
|
|
3818
|
-
{ value: "global", label: "\u5168\u5C40\uFF08
|
|
3857
|
+
{ value: "project", label: "\u9879\u76EE\u7EA7\uFF08\u5199\u5165\u6240\u9009 IDE \u7684\u9879\u76EE skill \u76EE\u5F55\uFF09" },
|
|
3858
|
+
{ value: "global", label: "\u5168\u5C40\uFF08\u5199\u5165\u6240\u9009 IDE \u7684\u7528\u6237 skill \u76EE\u5F55\uFF09" }
|
|
3819
3859
|
],
|
|
3820
3860
|
initialValue: "project"
|
|
3821
3861
|
});
|
|
@@ -3935,7 +3975,7 @@ init_state();
|
|
|
3935
3975
|
|
|
3936
3976
|
// src/core/agents-md.ts
|
|
3937
3977
|
import * as fs15 from "fs/promises";
|
|
3938
|
-
import * as
|
|
3978
|
+
import * as path21 from "path";
|
|
3939
3979
|
import { hasManagedRegion as hasManagedRegion3, replaceManagedRegion as replaceManagedRegion3 } from "@teamix-evo/registry";
|
|
3940
3980
|
init_fs();
|
|
3941
3981
|
init_state();
|
|
@@ -3946,7 +3986,7 @@ async function runGenerateAgentsMd(options) {
|
|
|
3946
3986
|
const mode = options.mode ?? "overwrite";
|
|
3947
3987
|
const config = await readProjectConfig(projectRoot);
|
|
3948
3988
|
const lock = await readSkillsLock(projectRoot);
|
|
3949
|
-
const ides = config?.packages?.skills?.ides ?? [
|
|
3989
|
+
const ides = config?.packages?.skills?.ides ?? [...ALL_IDE_KINDS];
|
|
3950
3990
|
const scope = config?.packages?.skills?.scope ?? lock?.skills[skillIds[0] ?? ""]?.scope ?? "project";
|
|
3951
3991
|
const skillScopeMap = /* @__PURE__ */ new Map();
|
|
3952
3992
|
for (const id of skillIds) skillScopeMap.set(id, scope);
|
|
@@ -3963,7 +4003,7 @@ async function runGenerateAgentsMd(options) {
|
|
|
3963
4003
|
sections.push(section);
|
|
3964
4004
|
if (missing) missingSkillIds.push(id);
|
|
3965
4005
|
}
|
|
3966
|
-
const target =
|
|
4006
|
+
const target = path21.join(projectRoot, "AGENTS.md");
|
|
3967
4007
|
const targetExists = await fileExists(target);
|
|
3968
4008
|
const fullTemplate = renderAgentsMd({ variant, sections });
|
|
3969
4009
|
const managedBody = renderManagedBlockBody({ variant, sections });
|
|
@@ -4018,7 +4058,7 @@ async function renderSkillSection(projectRoot, skillId, ides, scope) {
|
|
|
4018
4058
|
let missing = false;
|
|
4019
4059
|
for (const ide of ides) {
|
|
4020
4060
|
const adapter = getAdapter(ide);
|
|
4021
|
-
const skillPath =
|
|
4061
|
+
const skillPath = path21.join(
|
|
4022
4062
|
adapter.getSkillTargetDir(skillId, scope, projectRoot),
|
|
4023
4063
|
"SKILL.md"
|
|
4024
4064
|
);
|
|
@@ -4193,7 +4233,7 @@ async function runSkillsUpdate(options) {
|
|
|
4193
4233
|
if (!skillsCfg) {
|
|
4194
4234
|
return { status: "no-skills" };
|
|
4195
4235
|
}
|
|
4196
|
-
const ides = skillsCfg.ides ?? [
|
|
4236
|
+
const ides = skillsCfg.ides ?? [...ALL_IDE_KINDS];
|
|
4197
4237
|
const scope = skillsCfg.scope ?? "project";
|
|
4198
4238
|
let existingLock = await readSkillsLock(projectRoot);
|
|
4199
4239
|
if (!existingLock || Object.keys(existingLock.skills).length === 0) {
|
|
@@ -4523,7 +4563,7 @@ async function printVersionBanner() {
|
|
|
4523
4563
|
// src/commands/skills/uninstall.ts
|
|
4524
4564
|
import { Command as Command17 } from "commander";
|
|
4525
4565
|
import * as prompts4 from "@clack/prompts";
|
|
4526
|
-
import * as
|
|
4566
|
+
import * as path22 from "path";
|
|
4527
4567
|
import * as fs16 from "fs/promises";
|
|
4528
4568
|
init_error();
|
|
4529
4569
|
init_state();
|
|
@@ -4616,7 +4656,7 @@ async function runFullUninstall(args) {
|
|
|
4616
4656
|
logger.info(` Removed: ${removed.length} files`);
|
|
4617
4657
|
if (cleanedMirrorDirs.length > 0) {
|
|
4618
4658
|
logger.info(
|
|
4619
|
-
` Mirrors: ${cleanedMirrorDirs.map((d) =>
|
|
4659
|
+
` Mirrors: ${cleanedMirrorDirs.map((d) => path22.relative(projectRoot, d)).join(", ")} (cleaned)`
|
|
4620
4660
|
);
|
|
4621
4661
|
}
|
|
4622
4662
|
}
|
|
@@ -4671,7 +4711,7 @@ async function runPartialUninstall(args) {
|
|
|
4671
4711
|
logger.info(` Files: ${removed.length}`);
|
|
4672
4712
|
if (cleanedMirrorDirs.length > 0) {
|
|
4673
4713
|
logger.info(
|
|
4674
|
-
` Mirrors: ${cleanedMirrorDirs.map((d) =>
|
|
4714
|
+
` Mirrors: ${cleanedMirrorDirs.map((d) => path22.relative(projectRoot, d)).join(", ")} (cleaned)`
|
|
4675
4715
|
);
|
|
4676
4716
|
}
|
|
4677
4717
|
if (missing.length > 0) {
|
|
@@ -4687,7 +4727,9 @@ function collectSkillNames(args) {
|
|
|
4687
4727
|
}
|
|
4688
4728
|
async function removeMirrorDirs(projectRoot, scope, ides, skillNames) {
|
|
4689
4729
|
if (skillNames.length === 0) return [];
|
|
4690
|
-
const targetIdes = ides && ides.length > 0 ? ides.filter(
|
|
4730
|
+
const targetIdes = ides && ides.length > 0 ? ides.filter(
|
|
4731
|
+
(i) => ALL_IDE_KINDS.includes(i)
|
|
4732
|
+
) : [...ALL_IDE_KINDS];
|
|
4691
4733
|
const targetScope = scope === "global" ? "global" : "project";
|
|
4692
4734
|
const removed = [];
|
|
4693
4735
|
for (const ide of targetIdes) {
|
|
@@ -4710,7 +4752,7 @@ async function removeMirrorDirs(projectRoot, scope, ides, skillNames) {
|
|
|
4710
4752
|
}
|
|
4711
4753
|
}
|
|
4712
4754
|
if (removed.length > 0) {
|
|
4713
|
-
const skillsParent =
|
|
4755
|
+
const skillsParent = path22.dirname(
|
|
4714
4756
|
adapter.getSkillTargetDir("placeholder", targetScope, projectRoot)
|
|
4715
4757
|
);
|
|
4716
4758
|
try {
|
|
@@ -4761,30 +4803,18 @@ function resolveUninstallRoot(cwd, scopeFlag) {
|
|
|
4761
4803
|
import { Command as Command18 } from "commander";
|
|
4762
4804
|
|
|
4763
4805
|
// src/core/skills-sync.ts
|
|
4764
|
-
import * as
|
|
4765
|
-
import { createRequire as createRequire4 } from "module";
|
|
4766
|
-
import { loadSkillsPackageManifest as loadSkillsPackageManifest2 } from "@teamix-evo/registry";
|
|
4806
|
+
import * as fs17 from "fs/promises";
|
|
4767
4807
|
init_state();
|
|
4768
4808
|
init_logger();
|
|
4769
|
-
var require5 = createRequire4(import.meta.url);
|
|
4770
|
-
async function readSkillMetaFromUpstream(skillId) {
|
|
4771
|
-
try {
|
|
4772
|
-
const pkgJson = require5.resolve("@teamix-evo/skills/package.json");
|
|
4773
|
-
const packageRoot = path22.dirname(pkgJson);
|
|
4774
|
-
const manifest = await loadSkillsPackageManifest2(packageRoot);
|
|
4775
|
-
const entry = manifest.skills.find((s) => s.id === skillId);
|
|
4776
|
-
if (!entry) return null;
|
|
4777
|
-
return {
|
|
4778
|
-
updateStrategy: entry.updateStrategy,
|
|
4779
|
-
managedRegions: entry.managedRegions
|
|
4780
|
-
};
|
|
4781
|
-
} catch {
|
|
4782
|
-
return null;
|
|
4783
|
-
}
|
|
4784
|
-
}
|
|
4785
4809
|
var SKILLS_PACKAGE_DEFAULT = "@teamix-evo/skills";
|
|
4786
4810
|
async function runSkillsSync(options) {
|
|
4787
4811
|
const { projectRoot, names } = options;
|
|
4812
|
+
const reconfiguring = options.ides !== void 0 || options.scope !== void 0;
|
|
4813
|
+
if (reconfiguring && names && names.length > 0) {
|
|
4814
|
+
throw new Error(
|
|
4815
|
+
"IDE/scope overrides reconfigure the whole skills installation. Omit skill names and retry."
|
|
4816
|
+
);
|
|
4817
|
+
}
|
|
4788
4818
|
const lock = await readSkillsLock(projectRoot);
|
|
4789
4819
|
if (!lock || Object.keys(lock.skills).length === 0) {
|
|
4790
4820
|
return {
|
|
@@ -4807,26 +4837,78 @@ async function runSkillsSync(options) {
|
|
|
4807
4837
|
}
|
|
4808
4838
|
const skillIds = Object.keys(lock.skills);
|
|
4809
4839
|
const targets = names ? skillIds.filter((id) => names.includes(id)) : skillIds;
|
|
4840
|
+
if (reconfiguring) {
|
|
4841
|
+
const missing = targets.filter(
|
|
4842
|
+
(skillId) => !pkgData.manifest.skills.some((entry) => entry.id === skillId)
|
|
4843
|
+
);
|
|
4844
|
+
if (missing.length > 0) {
|
|
4845
|
+
throw new Error(
|
|
4846
|
+
`Cannot reconfigure skills missing from the upstream package: ${missing.join(", ")}. Run \`skills update\` and retry.`
|
|
4847
|
+
);
|
|
4848
|
+
}
|
|
4849
|
+
}
|
|
4850
|
+
const config = reconfiguring ? await readProjectConfig(projectRoot) : null;
|
|
4851
|
+
const skillsConfig = config?.packages.skills;
|
|
4852
|
+
if (reconfiguring && (!config || !skillsConfig)) {
|
|
4853
|
+
throw new Error(
|
|
4854
|
+
"Cannot persist IDE reconfiguration: .teamix-evo/config.json has no skills entry. Run `skills init` first."
|
|
4855
|
+
);
|
|
4856
|
+
}
|
|
4857
|
+
const configuredIdes = reconfiguring ? [
|
|
4858
|
+
...options.ides ?? skillsConfig?.ides ?? [...new Set(skillIds.flatMap((id) => lock.skills[id]?.mirroredTo ?? []))]
|
|
4859
|
+
] : null;
|
|
4860
|
+
const configuredScope = reconfiguring ? options.scope ?? skillsConfig?.scope ?? lock.skills[skillIds[0] ?? ""]?.scope ?? "project" : null;
|
|
4861
|
+
if (configuredIdes && configuredIdes.length === 0) {
|
|
4862
|
+
throw new Error("At least one IDE must be selected.");
|
|
4863
|
+
}
|
|
4864
|
+
const priorTargets = reconfiguring ? skillIds.flatMap((skillId) => {
|
|
4865
|
+
const entry = lock.skills[skillId];
|
|
4866
|
+
if (!entry) return [];
|
|
4867
|
+
return entry.mirroredTo.map((ide) => ({
|
|
4868
|
+
skillId,
|
|
4869
|
+
ide,
|
|
4870
|
+
scope: entry.scope
|
|
4871
|
+
}));
|
|
4872
|
+
}) : [];
|
|
4810
4873
|
const allResources = [];
|
|
4811
4874
|
const synced = [];
|
|
4812
4875
|
for (const skillId of targets) {
|
|
4813
4876
|
const lockEntry = lock.skills[skillId];
|
|
4814
4877
|
if (!lockEntry) continue;
|
|
4815
|
-
const
|
|
4816
|
-
const scope =
|
|
4878
|
+
const requestedIdes = configuredIdes ?? lockEntry.mirroredTo;
|
|
4879
|
+
const scope = configuredScope ?? lockEntry.scope;
|
|
4880
|
+
const upstreamEntry = pkgData.manifest.skills.find(
|
|
4881
|
+
(entry) => entry.id === skillId
|
|
4882
|
+
);
|
|
4883
|
+
if (!upstreamEntry) {
|
|
4884
|
+
logger.warn(`Skill "${skillId}" not found in npm package manifest; skipped.`);
|
|
4885
|
+
continue;
|
|
4886
|
+
}
|
|
4887
|
+
const ides = upstreamEntry.ides.filter(
|
|
4888
|
+
(ide) => requestedIdes.includes(ide)
|
|
4889
|
+
);
|
|
4817
4890
|
if (ides.length === 0) {
|
|
4818
|
-
logger.warn(
|
|
4891
|
+
logger.warn(
|
|
4892
|
+
`Skill "${skillId}" supports none of [${requestedIdes.join(", ")}]; no mirror written.`
|
|
4893
|
+
);
|
|
4894
|
+
if (reconfiguring) {
|
|
4895
|
+
lock.skills[skillId] = {
|
|
4896
|
+
...lockEntry,
|
|
4897
|
+
mirroredTo: [],
|
|
4898
|
+
scope,
|
|
4899
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4900
|
+
};
|
|
4901
|
+
}
|
|
4819
4902
|
continue;
|
|
4820
4903
|
}
|
|
4821
|
-
const upstreamMeta = await readSkillMetaFromUpstream(skillId);
|
|
4822
4904
|
const result = await reinstallSkillsToIdes({
|
|
4823
4905
|
projectRoot,
|
|
4824
4906
|
skills: [
|
|
4825
4907
|
{
|
|
4826
4908
|
id: skillId,
|
|
4827
|
-
name:
|
|
4828
|
-
updateStrategy:
|
|
4829
|
-
managedRegions:
|
|
4909
|
+
name: upstreamEntry.name,
|
|
4910
|
+
updateStrategy: upstreamEntry.updateStrategy,
|
|
4911
|
+
managedRegions: upstreamEntry.managedRegions
|
|
4830
4912
|
}
|
|
4831
4913
|
],
|
|
4832
4914
|
manifest: pkgData.manifest,
|
|
@@ -4836,7 +4918,7 @@ async function runSkillsSync(options) {
|
|
|
4836
4918
|
scope
|
|
4837
4919
|
});
|
|
4838
4920
|
allResources.push(...result.resources);
|
|
4839
|
-
synced.push(skillId);
|
|
4921
|
+
if (result.count > 0) synced.push(skillId);
|
|
4840
4922
|
lock.skills[skillId] = {
|
|
4841
4923
|
...lockEntry,
|
|
4842
4924
|
mirroredTo: ides,
|
|
@@ -4845,7 +4927,24 @@ async function runSkillsSync(options) {
|
|
|
4845
4927
|
};
|
|
4846
4928
|
}
|
|
4847
4929
|
await writeSkillsLock(projectRoot, lock);
|
|
4848
|
-
await refreshMirrorRecords(
|
|
4930
|
+
await refreshMirrorRecords(
|
|
4931
|
+
projectRoot,
|
|
4932
|
+
allResources,
|
|
4933
|
+
reconfiguring ? targets : void 0
|
|
4934
|
+
);
|
|
4935
|
+
if (reconfiguring && config && skillsConfig && configuredIdes && configuredScope) {
|
|
4936
|
+
config.packages.skills = {
|
|
4937
|
+
...skillsConfig,
|
|
4938
|
+
ides: configuredIdes,
|
|
4939
|
+
scope: configuredScope
|
|
4940
|
+
};
|
|
4941
|
+
await writeProjectConfig(projectRoot, config);
|
|
4942
|
+
await removeDeselectedMirrors({
|
|
4943
|
+
projectRoot,
|
|
4944
|
+
priorTargets,
|
|
4945
|
+
retainedTargets: lock.skills
|
|
4946
|
+
});
|
|
4947
|
+
}
|
|
4849
4948
|
return {
|
|
4850
4949
|
status: "synced",
|
|
4851
4950
|
syncedSkillIds: synced,
|
|
@@ -4853,13 +4952,28 @@ async function runSkillsSync(options) {
|
|
|
4853
4952
|
resources: allResources
|
|
4854
4953
|
};
|
|
4855
4954
|
}
|
|
4856
|
-
async function
|
|
4955
|
+
async function removeDeselectedMirrors(args) {
|
|
4956
|
+
for (const target of args.priorTargets) {
|
|
4957
|
+
const retained = args.retainedTargets[target.skillId];
|
|
4958
|
+
if (retained && target.scope === retained.scope && retained.mirroredTo.includes(target.ide)) {
|
|
4959
|
+
continue;
|
|
4960
|
+
}
|
|
4961
|
+
const dir = getAdapter(target.ide).getSkillTargetDir(
|
|
4962
|
+
target.skillId,
|
|
4963
|
+
target.scope,
|
|
4964
|
+
args.projectRoot
|
|
4965
|
+
);
|
|
4966
|
+
await fs17.rm(dir, { recursive: true, force: true });
|
|
4967
|
+
logger.debug(`Removed deselected IDE mirror: ${dir}`);
|
|
4968
|
+
}
|
|
4969
|
+
}
|
|
4970
|
+
async function refreshMirrorRecords(projectRoot, newRecords, touchedIds) {
|
|
4857
4971
|
const installed = await readInstalledManifest(projectRoot);
|
|
4858
4972
|
if (!installed) return;
|
|
4859
4973
|
const pkg = installed.installed.find((p2) => p2.package === SKILLS_PACKAGE_DEFAULT);
|
|
4860
4974
|
if (!pkg) return;
|
|
4861
4975
|
const touchedSkillIds = new Set(
|
|
4862
|
-
newRecords.map((r) => r.id.split(":")[0] ?? r.id)
|
|
4976
|
+
touchedIds ?? newRecords.map((r) => r.id.split(":")[0] ?? r.id)
|
|
4863
4977
|
);
|
|
4864
4978
|
const preserved = (pkg.resources ?? []).filter((r) => {
|
|
4865
4979
|
const skillId = r.id.split(":")[0] ?? r.id;
|
|
@@ -4874,14 +4988,17 @@ async function refreshMirrorRecords(projectRoot, newRecords) {
|
|
|
4874
4988
|
init_logger();
|
|
4875
4989
|
init_error();
|
|
4876
4990
|
var syncCommand = new Command18("sync").description(
|
|
4877
|
-
"\u4ECE npm \u5305\u91CD\u65B0\u5B89\u88C5 skills \u5230 IDE \u8DEF\u5F84\uFF08.qoder / .claude\uFF09"
|
|
4991
|
+
"\u4ECE npm \u5305\u91CD\u65B0\u5B89\u88C5 skills \u5230 IDE \u8DEF\u5F84\uFF08.qoder / .claude / .agents\uFF09"
|
|
4878
4992
|
).argument(
|
|
4879
4993
|
"[names...]",
|
|
4880
4994
|
"\u53EF\u9009\uFF1A\u4EC5\u540C\u6B65\u6307\u5B9A skill id\uFF1B\u7701\u7565\u5219\u540C\u6B65\u5168\u90E8\u5DF2\u8BB0\u5F55\u5728 lock \u5185\u7684 skill"
|
|
4881
4995
|
).option(
|
|
4882
4996
|
"--ide <list>",
|
|
4883
|
-
"\u9017\u53F7\u5206\u9694\u7684 IDE \u5217\u8868\uFF08\
|
|
4884
|
-
).option(
|
|
4997
|
+
"\u9017\u53F7\u5206\u9694\u7684 IDE \u5217\u8868\uFF08\u6301\u4E45\u91CD\u914D\u5168\u90E8 skills \u7684 config + lock\uFF09"
|
|
4998
|
+
).option(
|
|
4999
|
+
"--scope <scope>",
|
|
5000
|
+
"project | global\uFF08\u6301\u4E45\u91CD\u914D\u5168\u90E8 skills \u7684 config + lock\uFF09"
|
|
5001
|
+
).action(async (names, opts) => {
|
|
4885
5002
|
try {
|
|
4886
5003
|
const ide = detectIde();
|
|
4887
5004
|
const cwd = ide.getProjectRoot();
|
|
@@ -4928,7 +5045,7 @@ import { Command as Command19 } from "commander";
|
|
|
4928
5045
|
|
|
4929
5046
|
// src/core/skills-doctor.ts
|
|
4930
5047
|
import * as path23 from "path";
|
|
4931
|
-
import * as
|
|
5048
|
+
import * as fs18 from "fs/promises";
|
|
4932
5049
|
init_fs();
|
|
4933
5050
|
init_state();
|
|
4934
5051
|
init_logger();
|
|
@@ -4995,7 +5112,7 @@ async function runSkillsDoctor(options) {
|
|
|
4995
5112
|
});
|
|
4996
5113
|
continue;
|
|
4997
5114
|
}
|
|
4998
|
-
const mirrorContent = await
|
|
5115
|
+
const mirrorContent = await fs18.readFile(mirrorFile, "utf-8");
|
|
4999
5116
|
if (computeHash(mirrorContent) !== computeHash(expectedContent)) {
|
|
5000
5117
|
findings.push({
|
|
5001
5118
|
kind: "mirror-drift",
|
|
@@ -5016,7 +5133,7 @@ async function runSkillsDoctor(options) {
|
|
|
5016
5133
|
}
|
|
5017
5134
|
async function dirExists(p2) {
|
|
5018
5135
|
try {
|
|
5019
|
-
const stat6 = await
|
|
5136
|
+
const stat6 = await fs18.stat(p2);
|
|
5020
5137
|
return stat6.isDirectory();
|
|
5021
5138
|
} catch {
|
|
5022
5139
|
return false;
|
|
@@ -5066,7 +5183,7 @@ var doctorCommand = new Command19("doctor").description(
|
|
|
5066
5183
|
|
|
5067
5184
|
// src/commands/skills/index.ts
|
|
5068
5185
|
var skillsCommand = new Command20("skills").description(
|
|
5069
|
-
"\u7BA1\u7406 teamix-evo skills\uFF08\u5411 AI IDE \u6CE8\u5165\u6280\u80FD\
|
|
5186
|
+
"\u7BA1\u7406 teamix-evo skills\uFF08\u4ECE npm \u5305\u5411 AI IDE \u6CE8\u5165\u6280\u80FD\uFF1Bdirect-mirror \u6A21\u578B\u89C1 ADR 0048\uFF09"
|
|
5070
5187
|
);
|
|
5071
5188
|
skillsCommand.addCommand(initCommand2);
|
|
5072
5189
|
skillsCommand.addCommand(addCommand);
|
|
@@ -5260,12 +5377,12 @@ import { Command as Command22 } from "commander";
|
|
|
5260
5377
|
// src/core/ui-client.ts
|
|
5261
5378
|
init_logger();
|
|
5262
5379
|
import * as path24 from "path";
|
|
5263
|
-
import * as
|
|
5264
|
-
import { createRequire as
|
|
5380
|
+
import * as fs19 from "fs/promises";
|
|
5381
|
+
import { createRequire as createRequire4 } from "module";
|
|
5265
5382
|
import { loadUiPackageManifest } from "@teamix-evo/registry";
|
|
5266
|
-
var
|
|
5383
|
+
var require5 = createRequire4(import.meta.url);
|
|
5267
5384
|
function resolvePackageRoot2(packageName) {
|
|
5268
|
-
const pkgJsonPath =
|
|
5385
|
+
const pkgJsonPath = require5.resolve(`${packageName}/package.json`);
|
|
5269
5386
|
return path24.dirname(pkgJsonPath);
|
|
5270
5387
|
}
|
|
5271
5388
|
async function loadUiData(packageName) {
|
|
@@ -5273,13 +5390,13 @@ async function loadUiData(packageName) {
|
|
|
5273
5390
|
logger.debug(`Resolved ui package root: ${packageRoot}`);
|
|
5274
5391
|
const manifest = await loadUiPackageManifest(packageRoot);
|
|
5275
5392
|
const pkgJson = JSON.parse(
|
|
5276
|
-
await
|
|
5393
|
+
await fs19.readFile(path24.join(packageRoot, "package.json"), "utf-8")
|
|
5277
5394
|
);
|
|
5278
5395
|
manifest.version = pkgJson.version;
|
|
5279
5396
|
let data = {};
|
|
5280
5397
|
const dataPath = path24.join(packageRoot, "_data.json");
|
|
5281
5398
|
try {
|
|
5282
|
-
const raw = await
|
|
5399
|
+
const raw = await fs19.readFile(dataPath, "utf-8");
|
|
5283
5400
|
data = JSON.parse(raw);
|
|
5284
5401
|
} catch (err) {
|
|
5285
5402
|
if (err.code !== "ENOENT") {
|
|
@@ -5293,7 +5410,7 @@ async function loadUiData(packageName) {
|
|
|
5293
5410
|
// src/core/ui-installer.ts
|
|
5294
5411
|
init_fs();
|
|
5295
5412
|
import * as path25 from "path";
|
|
5296
|
-
import * as
|
|
5413
|
+
import * as fs20 from "fs/promises";
|
|
5297
5414
|
import { resolveUiEntryOrder } from "@teamix-evo/registry";
|
|
5298
5415
|
|
|
5299
5416
|
// src/utils/transform-imports.ts
|
|
@@ -5377,10 +5494,10 @@ async function installUiEntries(options) {
|
|
|
5377
5494
|
}
|
|
5378
5495
|
const rootForEntry = entryPackageRoot?.get(entry.id) ?? packageRoot;
|
|
5379
5496
|
const sourceAbs = path25.resolve(rootForEntry, file.source);
|
|
5380
|
-
const raw = await
|
|
5497
|
+
const raw = await fs20.readFile(sourceAbs, "utf-8");
|
|
5381
5498
|
const transformed = rewriteImports(raw, aliases, { flatten });
|
|
5382
5499
|
if (exists) {
|
|
5383
|
-
const current = await
|
|
5500
|
+
const current = await fs20.readFile(targetAbs, "utf-8");
|
|
5384
5501
|
if (current === transformed) {
|
|
5385
5502
|
logger.info(` skip (identical): ${rel(projectRoot, targetAbs)}`);
|
|
5386
5503
|
skipped++;
|
|
@@ -5538,7 +5655,7 @@ function mergeResources(prior, next) {
|
|
|
5538
5655
|
|
|
5539
5656
|
// src/core/ui-adopt.ts
|
|
5540
5657
|
import * as path26 from "path";
|
|
5541
|
-
import * as
|
|
5658
|
+
import * as fs21 from "fs/promises";
|
|
5542
5659
|
init_state();
|
|
5543
5660
|
init_logger();
|
|
5544
5661
|
var DEFAULT_UI_PACKAGE2 = "@teamix-evo/ui";
|
|
@@ -5578,7 +5695,7 @@ async function runUiAdopt(options) {
|
|
|
5578
5695
|
const files = await listSourceFiles(root.abs);
|
|
5579
5696
|
for (const abs of files) {
|
|
5580
5697
|
const rel2 = toPosixRel(projectRoot, abs);
|
|
5581
|
-
const content = await
|
|
5698
|
+
const content = await fs21.readFile(abs, "utf-8");
|
|
5582
5699
|
const fileType = classifyFile(abs, content);
|
|
5583
5700
|
const id = inferEntryId(abs);
|
|
5584
5701
|
if (fileType === "type") {
|
|
@@ -5659,7 +5776,7 @@ async function listSourceFiles(dir) {
|
|
|
5659
5776
|
const current = stack.pop();
|
|
5660
5777
|
let entries;
|
|
5661
5778
|
try {
|
|
5662
|
-
entries = await
|
|
5779
|
+
entries = await fs21.readdir(current, { withFileTypes: true });
|
|
5663
5780
|
} catch (err) {
|
|
5664
5781
|
if (err.code === "ENOENT") continue;
|
|
5665
5782
|
throw err;
|
|
@@ -5714,7 +5831,7 @@ async function readUpstreamContent(packageRoot, entry, aliases) {
|
|
|
5714
5831
|
const sourceAbs = path26.resolve(packageRoot, file.source);
|
|
5715
5832
|
let raw;
|
|
5716
5833
|
try {
|
|
5717
|
-
raw = await
|
|
5834
|
+
raw = await fs21.readFile(sourceAbs, "utf-8");
|
|
5718
5835
|
} catch {
|
|
5719
5836
|
return null;
|
|
5720
5837
|
}
|
|
@@ -5767,16 +5884,16 @@ init_state();
|
|
|
5767
5884
|
init_fs();
|
|
5768
5885
|
init_logger();
|
|
5769
5886
|
import * as path27 from "path";
|
|
5770
|
-
import * as
|
|
5771
|
-
import { createRequire as
|
|
5887
|
+
import * as fs22 from "fs/promises";
|
|
5888
|
+
import { createRequire as createRequire5 } from "module";
|
|
5772
5889
|
import {
|
|
5773
5890
|
loadUiPackageManifest as loadUiPackageManifest2,
|
|
5774
5891
|
loadVariantUiPackageManifest
|
|
5775
5892
|
} from "@teamix-evo/registry";
|
|
5776
|
-
var
|
|
5893
|
+
var require6 = createRequire5(import.meta.url);
|
|
5777
5894
|
var META_DIR = "meta";
|
|
5778
5895
|
function resolvePackageRoot3(packageName) {
|
|
5779
|
-
const pkgJsonPath =
|
|
5896
|
+
const pkgJsonPath = require6.resolve(`${packageName}/package.json`);
|
|
5780
5897
|
return path27.dirname(pkgJsonPath);
|
|
5781
5898
|
}
|
|
5782
5899
|
function getMetaDir(projectRoot, category) {
|
|
@@ -5811,7 +5928,7 @@ async function landManifestMeta(opts) {
|
|
|
5811
5928
|
await ensureDir(metaDir);
|
|
5812
5929
|
const manifestDest = path27.join(metaDir, "manifest.json");
|
|
5813
5930
|
const manifestSrc = path27.join(packageRoot, "manifest.json");
|
|
5814
|
-
await
|
|
5931
|
+
await fs22.copyFile(manifestSrc, manifestDest);
|
|
5815
5932
|
logger.debug(`meta: copied manifest.json \u2192 ${manifestDest}`);
|
|
5816
5933
|
let written = 0;
|
|
5817
5934
|
let total = 0;
|
|
@@ -5821,7 +5938,7 @@ async function landManifestMeta(opts) {
|
|
|
5821
5938
|
const srcPath = path27.join(packageRoot, entry.meta);
|
|
5822
5939
|
const destPath = path27.join(metaDir, `${entry.id}.md`);
|
|
5823
5940
|
try {
|
|
5824
|
-
await
|
|
5941
|
+
await fs22.copyFile(srcPath, destPath);
|
|
5825
5942
|
written++;
|
|
5826
5943
|
logger.debug(`meta: ${entry.id} \u2192 ${destPath}`);
|
|
5827
5944
|
} catch (err) {
|
|
@@ -6054,8 +6171,8 @@ import { Command as Command24 } from "commander";
|
|
|
6054
6171
|
// src/core/ui-upgrade.ts
|
|
6055
6172
|
init_state();
|
|
6056
6173
|
import * as path30 from "path";
|
|
6057
|
-
import * as
|
|
6058
|
-
import { createRequire as
|
|
6174
|
+
import * as fs24 from "fs/promises";
|
|
6175
|
+
import { createRequire as createRequire6 } from "module";
|
|
6059
6176
|
import {
|
|
6060
6177
|
loadUiPackageManifest as loadUiPackageManifest3,
|
|
6061
6178
|
loadVariantUiPackageManifest as loadVariantUiPackageManifest2
|
|
@@ -6064,7 +6181,7 @@ import {
|
|
|
6064
6181
|
// src/core/ui-upgrade-detector.ts
|
|
6065
6182
|
init_fs();
|
|
6066
6183
|
init_state();
|
|
6067
|
-
import * as
|
|
6184
|
+
import * as fs23 from "fs/promises";
|
|
6068
6185
|
import * as path28 from "path";
|
|
6069
6186
|
var PACKAGE_NAME = {
|
|
6070
6187
|
ui: "@teamix-evo/ui",
|
|
@@ -6125,14 +6242,14 @@ function extractIds(pkg) {
|
|
|
6125
6242
|
}
|
|
6126
6243
|
async function directoryExists(p2) {
|
|
6127
6244
|
try {
|
|
6128
|
-
const stat6 = await
|
|
6245
|
+
const stat6 = await fs23.stat(p2);
|
|
6129
6246
|
return stat6.isDirectory();
|
|
6130
6247
|
} catch {
|
|
6131
6248
|
return false;
|
|
6132
6249
|
}
|
|
6133
6250
|
}
|
|
6134
6251
|
async function listComponentIds(installDirAbs, layout = "flat") {
|
|
6135
|
-
const entries = await
|
|
6252
|
+
const entries = await fs23.readdir(installDirAbs, { withFileTypes: true });
|
|
6136
6253
|
const ids = [];
|
|
6137
6254
|
if (layout === "directory") {
|
|
6138
6255
|
for (const e of entries) {
|
|
@@ -6683,7 +6800,7 @@ function extractDefaultParamList(src) {
|
|
|
6683
6800
|
}
|
|
6684
6801
|
|
|
6685
6802
|
// src/core/ui-upgrade.ts
|
|
6686
|
-
var nodeRequire =
|
|
6803
|
+
var nodeRequire = createRequire6(import.meta.url);
|
|
6687
6804
|
function resolvePackageRoot4(packageName) {
|
|
6688
6805
|
const pkgJsonPath = nodeRequire.resolve(`${packageName}/package.json`);
|
|
6689
6806
|
return path30.dirname(pkgJsonPath);
|
|
@@ -6808,7 +6925,7 @@ async function buildStaging(args) {
|
|
|
6808
6925
|
});
|
|
6809
6926
|
}
|
|
6810
6927
|
async function readPkgVersion(packageRoot) {
|
|
6811
|
-
const raw = await
|
|
6928
|
+
const raw = await fs24.readFile(
|
|
6812
6929
|
path30.join(packageRoot, "package.json"),
|
|
6813
6930
|
"utf-8"
|
|
6814
6931
|
);
|
|
@@ -6931,7 +7048,7 @@ import { Command as Command25 } from "commander";
|
|
|
6931
7048
|
|
|
6932
7049
|
// src/core/ui-promote.ts
|
|
6933
7050
|
init_fs();
|
|
6934
|
-
import * as
|
|
7051
|
+
import * as fs26 from "fs/promises";
|
|
6935
7052
|
import * as path32 from "path";
|
|
6936
7053
|
init_logger();
|
|
6937
7054
|
init_error();
|
|
@@ -6939,7 +7056,7 @@ init_state();
|
|
|
6939
7056
|
|
|
6940
7057
|
// src/core/ui-promote-imports.ts
|
|
6941
7058
|
init_fs();
|
|
6942
|
-
import * as
|
|
7059
|
+
import * as fs25 from "fs/promises";
|
|
6943
7060
|
import * as path31 from "path";
|
|
6944
7061
|
var SOURCE_FILE_EXT = /\.(tsx?|jsx?|mts|cts)$/;
|
|
6945
7062
|
var STATIC_IMPORT_FROM = /^(\s*(?:import|export)\s[\s\S]*?from\s+['"])([^'"\n]+)(['"])/;
|
|
@@ -7046,7 +7163,7 @@ async function collectTsFiles(root) {
|
|
|
7046
7163
|
async function walk(dir) {
|
|
7047
7164
|
let entries;
|
|
7048
7165
|
try {
|
|
7049
|
-
entries = await
|
|
7166
|
+
entries = await fs25.readdir(dir, { withFileTypes: true });
|
|
7050
7167
|
} catch (err) {
|
|
7051
7168
|
if (err.code === "ENOENT") return;
|
|
7052
7169
|
throw err;
|
|
@@ -7451,7 +7568,7 @@ async function findLatestUiStagingDir(projectRoot) {
|
|
|
7451
7568
|
const base = path32.join(projectRoot, TEAMIX_DIR5, STAGING_DIR2);
|
|
7452
7569
|
let entries;
|
|
7453
7570
|
try {
|
|
7454
|
-
entries = await
|
|
7571
|
+
entries = await fs26.readdir(base, { withFileTypes: true });
|
|
7455
7572
|
} catch (err) {
|
|
7456
7573
|
if (err.code === "ENOENT") return null;
|
|
7457
7574
|
throw err;
|
|
@@ -7548,7 +7665,7 @@ function posix2(p2) {
|
|
|
7548
7665
|
}
|
|
7549
7666
|
|
|
7550
7667
|
// src/core/file-changes.ts
|
|
7551
|
-
import * as
|
|
7668
|
+
import * as fs27 from "fs/promises";
|
|
7552
7669
|
import * as path33 from "path";
|
|
7553
7670
|
function toRelativePosix(p2, projectRoot) {
|
|
7554
7671
|
let rel2 = p2;
|
|
@@ -7740,17 +7857,17 @@ import { Command as Command27 } from "commander";
|
|
|
7740
7857
|
|
|
7741
7858
|
// src/core/variant-ui-add.ts
|
|
7742
7859
|
import * as path34 from "path";
|
|
7743
|
-
import * as
|
|
7744
|
-
import { createRequire as
|
|
7860
|
+
import * as fs28 from "fs/promises";
|
|
7861
|
+
import { createRequire as createRequire7 } from "module";
|
|
7745
7862
|
import {
|
|
7746
7863
|
loadUiPackageManifest as loadUiPackageManifest4,
|
|
7747
7864
|
loadVariantUiPackageCatalog,
|
|
7748
7865
|
loadVariantUiPackageManifest as loadVariantUiPackageManifest3
|
|
7749
7866
|
} from "@teamix-evo/registry";
|
|
7750
7867
|
init_state();
|
|
7751
|
-
var
|
|
7868
|
+
var require7 = createRequire7(import.meta.url);
|
|
7752
7869
|
function resolvePackageRoot5(packageName) {
|
|
7753
|
-
const pkgJsonPath =
|
|
7870
|
+
const pkgJsonPath = require7.resolve(`${packageName}/package.json`);
|
|
7754
7871
|
return path34.dirname(pkgJsonPath);
|
|
7755
7872
|
}
|
|
7756
7873
|
async function runVariantUiAdd(packageName, options) {
|
|
@@ -7777,7 +7894,7 @@ async function runVariantUiAdd(packageName, options) {
|
|
|
7777
7894
|
const variantDir = path34.join(packageRoot, "variants", variant);
|
|
7778
7895
|
const variantManifest = await loadVariantUiPackageManifest3(variantDir);
|
|
7779
7896
|
const pkgJson = JSON.parse(
|
|
7780
|
-
await
|
|
7897
|
+
await fs28.readFile(path34.join(packageRoot, "package.json"), "utf-8")
|
|
7781
7898
|
);
|
|
7782
7899
|
const packageVersion = pkgJson.version;
|
|
7783
7900
|
const knownIds = new Set(variantManifest.entries.map((e) => e.id));
|
|
@@ -8237,7 +8354,7 @@ import * as prompts6 from "@clack/prompts";
|
|
|
8237
8354
|
init_fs();
|
|
8238
8355
|
init_logger();
|
|
8239
8356
|
import * as path35 from "path";
|
|
8240
|
-
import * as
|
|
8357
|
+
import * as fs29 from "fs";
|
|
8241
8358
|
import { execa } from "execa";
|
|
8242
8359
|
var ESLINT_CONFIG_CONTENT = `/**
|
|
8243
8360
|
* teamix-evo consumer ESLint preset \u2014 9 token-discipline rules.
|
|
@@ -8329,7 +8446,7 @@ async function runLintInit(options) {
|
|
|
8329
8446
|
let stylelintIgnoreFilesWarning = false;
|
|
8330
8447
|
if (!stylelintNeedsWrite && stylelintTemplateExists) {
|
|
8331
8448
|
try {
|
|
8332
|
-
const existingContent =
|
|
8449
|
+
const existingContent = fs29.readFileSync(stylelintConfigPath, "utf-8");
|
|
8333
8450
|
const usesTeamixPreset = existingContent.includes("@teamix-evo/stylelint-config/presets/") || existingContent.includes("@teamix-evo/stylelint-config/preset/");
|
|
8334
8451
|
const hasTokenIgnore = existingContent.includes("tokens.theme.css") && existingContent.includes("tokens.overrides.css");
|
|
8335
8452
|
if (!usesTeamixPreset && !hasTokenIgnore) {
|
|
@@ -8366,8 +8483,8 @@ async function runLintInit(options) {
|
|
|
8366
8483
|
};
|
|
8367
8484
|
}
|
|
8368
8485
|
function detectPm(projectRoot) {
|
|
8369
|
-
if (
|
|
8370
|
-
if (
|
|
8486
|
+
if (fs29.existsSync(path35.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
|
|
8487
|
+
if (fs29.existsSync(path35.join(projectRoot, "yarn.lock"))) return "yarn";
|
|
8371
8488
|
return "npm";
|
|
8372
8489
|
}
|
|
8373
8490
|
async function patchPackageJsonScripts(projectRoot) {
|
|
@@ -8463,7 +8580,7 @@ import { execa as execa2 } from "execa";
|
|
|
8463
8580
|
// src/core/project-state.ts
|
|
8464
8581
|
init_fs();
|
|
8465
8582
|
init_state();
|
|
8466
|
-
import * as
|
|
8583
|
+
import * as fs30 from "fs/promises";
|
|
8467
8584
|
import * as path36 from "path";
|
|
8468
8585
|
var IGNORED_TOP_LEVEL = /* @__PURE__ */ new Set([
|
|
8469
8586
|
".git",
|
|
@@ -8476,6 +8593,7 @@ var IGNORED_TOP_LEVEL = /* @__PURE__ */ new Set([
|
|
|
8476
8593
|
".vscode",
|
|
8477
8594
|
".qoder",
|
|
8478
8595
|
".claude",
|
|
8596
|
+
".agents",
|
|
8479
8597
|
"README.md",
|
|
8480
8598
|
"README",
|
|
8481
8599
|
"README.txt",
|
|
@@ -8524,7 +8642,7 @@ async function detectProjectState(cwd) {
|
|
|
8524
8642
|
}
|
|
8525
8643
|
let entries;
|
|
8526
8644
|
try {
|
|
8527
|
-
entries = await
|
|
8645
|
+
entries = await fs30.readdir(absCwd);
|
|
8528
8646
|
} catch (err) {
|
|
8529
8647
|
if (err.code === "ENOENT") {
|
|
8530
8648
|
return {
|
|
@@ -8646,7 +8764,7 @@ function assertCommandPrecondition(command, state, options) {
|
|
|
8646
8764
|
// src/core/deps-install.ts
|
|
8647
8765
|
init_fs();
|
|
8648
8766
|
init_logger();
|
|
8649
|
-
import * as
|
|
8767
|
+
import * as fs31 from "fs/promises";
|
|
8650
8768
|
import * as path37 from "path";
|
|
8651
8769
|
import { exec as exec4 } from "child_process";
|
|
8652
8770
|
import { promisify as promisify4 } from "util";
|
|
@@ -8703,7 +8821,7 @@ async function installProjectDeps(options) {
|
|
|
8703
8821
|
pkg.dependencies = Object.fromEntries(
|
|
8704
8822
|
Object.entries(pkg.dependencies).sort(([a], [b]) => a.localeCompare(b))
|
|
8705
8823
|
);
|
|
8706
|
-
await
|
|
8824
|
+
await fs31.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
|
|
8707
8825
|
logger.info(
|
|
8708
8826
|
` patched package.json: +${Object.keys(added).length} dependencies`
|
|
8709
8827
|
);
|
|
@@ -8890,9 +9008,9 @@ async function runProjectInit(options) {
|
|
|
8890
9008
|
name: "skills",
|
|
8891
9009
|
status: "ok",
|
|
8892
9010
|
detail: `${result.skillCount} skills, ${result.fileCount} files (added: ${result.addedSkillIds.join(", ") || "none"})`,
|
|
8893
|
-
changes: result.
|
|
9011
|
+
changes: result.resources.map((resource) => ({
|
|
8894
9012
|
kind: "created",
|
|
8895
|
-
path:
|
|
9013
|
+
path: resource.target,
|
|
8896
9014
|
step: "skills",
|
|
8897
9015
|
detail: "skill installed"
|
|
8898
9016
|
}))
|
|
@@ -9297,7 +9415,7 @@ async function runInitWizard(options) {
|
|
|
9297
9415
|
message: "\u6CE8\u5165\u6280\u80FD\u7684 AI IDE\uFF08\u81F3\u5C11\u4E00\u4E2A\uFF09",
|
|
9298
9416
|
options: ALL_IDE_KINDS.map((k) => ({
|
|
9299
9417
|
value: k,
|
|
9300
|
-
label: k
|
|
9418
|
+
label: getIdeDisplayName(k)
|
|
9301
9419
|
})),
|
|
9302
9420
|
initialValues: [...ALL_IDE_KINDS],
|
|
9303
9421
|
required: true
|
|
@@ -9449,11 +9567,11 @@ async function runScaffoldPhase(cwd, variant, opts) {
|
|
|
9449
9567
|
projectName: path39.basename(cwd)
|
|
9450
9568
|
});
|
|
9451
9569
|
if (pm === "pnpm") {
|
|
9452
|
-
const
|
|
9570
|
+
const fs34 = await import("fs/promises");
|
|
9453
9571
|
const pkgPath = path39.join(cwd, "package.json");
|
|
9454
|
-
const pkg = JSON.parse(await
|
|
9572
|
+
const pkg = JSON.parse(await fs34.readFile(pkgPath, "utf-8"));
|
|
9455
9573
|
pkg.packageManager = `pnpm@${PACKAGE_VERSIONS.pnpm}`;
|
|
9456
|
-
await
|
|
9574
|
+
await fs34.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
|
|
9457
9575
|
}
|
|
9458
9576
|
logger.info(
|
|
9459
9577
|
` \u2714 \u6A21\u677F ${result.preset.displayName}\uFF08variant: ${result.variant}\uFF09`
|
|
@@ -9700,7 +9818,7 @@ var migrateCommand = new Command38("migrate").description(
|
|
|
9700
9818
|
// src/commands/graft/index.ts
|
|
9701
9819
|
import { Command as Command39 } from "commander";
|
|
9702
9820
|
import * as path45 from "path";
|
|
9703
|
-
import * as
|
|
9821
|
+
import * as fs33 from "fs/promises";
|
|
9704
9822
|
import * as prompts7 from "@clack/prompts";
|
|
9705
9823
|
|
|
9706
9824
|
// src/core/graft-init.ts
|
|
@@ -9709,7 +9827,7 @@ init_state();
|
|
|
9709
9827
|
|
|
9710
9828
|
// src/core/snapshot.ts
|
|
9711
9829
|
init_logger();
|
|
9712
|
-
import * as
|
|
9830
|
+
import * as fs32 from "fs/promises";
|
|
9713
9831
|
import * as path43 from "path";
|
|
9714
9832
|
var TEAMIX_DIR6 = ".teamix-evo";
|
|
9715
9833
|
var SNAPSHOTS_DIR = ".snapshots";
|
|
@@ -9728,7 +9846,7 @@ function fsSafeToIso(safe) {
|
|
|
9728
9846
|
async function createSnapshot(projectRoot, opts = {}) {
|
|
9729
9847
|
const teamixDir = path43.join(projectRoot, TEAMIX_DIR6);
|
|
9730
9848
|
try {
|
|
9731
|
-
const stat6 = await
|
|
9849
|
+
const stat6 = await fs32.stat(teamixDir);
|
|
9732
9850
|
if (!stat6.isDirectory()) return null;
|
|
9733
9851
|
} catch (err) {
|
|
9734
9852
|
if (err.code === "ENOENT") return null;
|
|
@@ -9738,19 +9856,19 @@ async function createSnapshot(projectRoot, opts = {}) {
|
|
|
9738
9856
|
const ts = isoToFsSafe3(isoTs);
|
|
9739
9857
|
const snapshotRoot = path43.join(teamixDir, SNAPSHOTS_DIR);
|
|
9740
9858
|
const target = path43.join(snapshotRoot, ts);
|
|
9741
|
-
await
|
|
9742
|
-
const entries = await
|
|
9859
|
+
await fs32.mkdir(target, { recursive: true });
|
|
9860
|
+
const entries = await fs32.readdir(teamixDir, { withFileTypes: true });
|
|
9743
9861
|
for (const entry of entries) {
|
|
9744
9862
|
if (entry.name === SNAPSHOTS_DIR) continue;
|
|
9745
9863
|
const src = path43.join(teamixDir, entry.name);
|
|
9746
9864
|
const dst = path43.join(target, entry.name);
|
|
9747
|
-
await
|
|
9865
|
+
await fs32.cp(src, dst, { recursive: true });
|
|
9748
9866
|
}
|
|
9749
9867
|
const meta = {
|
|
9750
9868
|
ts: isoTs,
|
|
9751
9869
|
reason: opts.reason ?? "manual"
|
|
9752
9870
|
};
|
|
9753
|
-
await
|
|
9871
|
+
await fs32.writeFile(
|
|
9754
9872
|
path43.join(target, META_FILE),
|
|
9755
9873
|
JSON.stringify(meta, null, 2) + "\n",
|
|
9756
9874
|
"utf-8"
|
|
@@ -9766,7 +9884,7 @@ async function listSnapshots(projectRoot) {
|
|
|
9766
9884
|
const snapshotRoot = path43.join(projectRoot, TEAMIX_DIR6, SNAPSHOTS_DIR);
|
|
9767
9885
|
let entries;
|
|
9768
9886
|
try {
|
|
9769
|
-
entries = await
|
|
9887
|
+
entries = await fs32.readdir(snapshotRoot, { withFileTypes: true });
|
|
9770
9888
|
} catch (err) {
|
|
9771
9889
|
if (err.code === "ENOENT") return [];
|
|
9772
9890
|
throw err;
|
|
@@ -9778,7 +9896,7 @@ async function listSnapshots(projectRoot) {
|
|
|
9778
9896
|
let isoTs = null;
|
|
9779
9897
|
let reason = null;
|
|
9780
9898
|
try {
|
|
9781
|
-
const raw = await
|
|
9899
|
+
const raw = await fs32.readFile(path43.join(dir, META_FILE), "utf-8");
|
|
9782
9900
|
const parsed = JSON.parse(raw);
|
|
9783
9901
|
if (typeof parsed.ts === "string") isoTs = parsed.ts;
|
|
9784
9902
|
if (typeof parsed.reason === "string" && SNAPSHOT_REASONS.includes(
|
|
@@ -9803,7 +9921,7 @@ async function pruneSnapshots(projectRoot, keep = DEFAULT_KEEP, opts = {}) {
|
|
|
9803
9921
|
const toRemove = opts.protectedTs ? tail.filter((s) => s.ts !== opts.protectedTs) : tail;
|
|
9804
9922
|
const removed = [];
|
|
9805
9923
|
for (const snap of toRemove) {
|
|
9806
|
-
await
|
|
9924
|
+
await fs32.rm(snap.path, { recursive: true, force: true });
|
|
9807
9925
|
removed.push(snap.ts);
|
|
9808
9926
|
logger.debug(`Pruned snapshot ${snap.ts}`);
|
|
9809
9927
|
}
|
|
@@ -9854,7 +9972,7 @@ async function runGraftInit(options) {
|
|
|
9854
9972
|
onStep
|
|
9855
9973
|
} = options;
|
|
9856
9974
|
const ide = options.ide ?? "qoder";
|
|
9857
|
-
const ides = options.ides ?? [
|
|
9975
|
+
const ides = options.ides ?? [...ALL_IDE_KINDS];
|
|
9858
9976
|
const scope = options.scope ?? "project";
|
|
9859
9977
|
const steps = [];
|
|
9860
9978
|
let aborted = false;
|
|
@@ -10198,7 +10316,7 @@ async function detectConflicts(cwd) {
|
|
|
10198
10316
|
for (const entry of CONFLICT_PATHS) {
|
|
10199
10317
|
const full = path45.join(cwd, entry.path);
|
|
10200
10318
|
try {
|
|
10201
|
-
const stat6 = await
|
|
10319
|
+
const stat6 = await fs33.stat(full);
|
|
10202
10320
|
if (entry.type === "directory" && stat6.isDirectory() || entry.type === "file" && stat6.isFile()) {
|
|
10203
10321
|
conflicts.push(entry);
|
|
10204
10322
|
}
|
|
@@ -10366,8 +10484,8 @@ function createSwitchCommand() {
|
|
|
10366
10484
|
var switchCommand = createSwitchCommand();
|
|
10367
10485
|
|
|
10368
10486
|
// src/index.ts
|
|
10369
|
-
var
|
|
10370
|
-
var { version } =
|
|
10487
|
+
var require8 = createRequire8(import.meta.url);
|
|
10488
|
+
var { version } = require8("../package.json");
|
|
10371
10489
|
var program = new Command42();
|
|
10372
10490
|
program.name("teamix-evo").description("Where ideas evolve. \u2014 AI Coding \u5957\u4EF6").version(version);
|
|
10373
10491
|
program.addCommand(tokensCommand);
|