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/core/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/core/tokens-init.ts
|
|
2
|
-
import * as
|
|
2
|
+
import * as path9 from "path";
|
|
3
3
|
import * as fs7 from "fs/promises";
|
|
4
4
|
import {
|
|
5
5
|
loadTokensPackageManifest,
|
|
@@ -306,7 +306,7 @@ async function loadSkillsData(packageName) {
|
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
// src/core/skills-installer.ts
|
|
309
|
-
import * as
|
|
309
|
+
import * as path8 from "path";
|
|
310
310
|
import * as fs6 from "fs/promises";
|
|
311
311
|
import {
|
|
312
312
|
replaceManagedRegion,
|
|
@@ -351,13 +351,40 @@ var ClaudeAdapter = class {
|
|
|
351
351
|
}
|
|
352
352
|
};
|
|
353
353
|
|
|
354
|
+
// src/ide/CodexAdapter.ts
|
|
355
|
+
import * as os3 from "os";
|
|
356
|
+
import * as path6 from "path";
|
|
357
|
+
var CodexAdapter = class {
|
|
358
|
+
kind = "codex";
|
|
359
|
+
name = "codex";
|
|
360
|
+
getProjectRoot() {
|
|
361
|
+
return process.cwd();
|
|
362
|
+
}
|
|
363
|
+
detectIde() {
|
|
364
|
+
return Boolean(
|
|
365
|
+
process.env.CODEX_HOME || process.env.CODEX_SANDBOX || process.env.CODEX_THREAD_ID || process.env.CODEX_CI
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
getSkillTargetDir(skillName, scope, projectRoot) {
|
|
369
|
+
const base = scope === "global" ? path6.join(os3.homedir(), ".agents") : path6.join(projectRoot ?? this.getProjectRoot(), ".agents");
|
|
370
|
+
return path6.join(base, "skills", skillName);
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
|
|
354
374
|
// src/ide/index.ts
|
|
375
|
+
var ALL_IDE_KINDS = [
|
|
376
|
+
"qoder",
|
|
377
|
+
"claude",
|
|
378
|
+
"codex"
|
|
379
|
+
];
|
|
355
380
|
function getAdapter(kind) {
|
|
356
381
|
switch (kind) {
|
|
357
382
|
case "qoder":
|
|
358
383
|
return new QoderAdapter();
|
|
359
384
|
case "claude":
|
|
360
385
|
return new ClaudeAdapter();
|
|
386
|
+
case "codex":
|
|
387
|
+
return new CodexAdapter();
|
|
361
388
|
default: {
|
|
362
389
|
const _exhaustive = kind;
|
|
363
390
|
throw new Error(`Unsupported IDE kind: ${_exhaustive}`);
|
|
@@ -394,21 +421,21 @@ async function loadTemplateFile(filePath) {
|
|
|
394
421
|
}
|
|
395
422
|
|
|
396
423
|
// src/utils/path.ts
|
|
397
|
-
import * as
|
|
424
|
+
import * as path7 from "path";
|
|
398
425
|
import * as fs5 from "fs/promises";
|
|
399
426
|
import { createRequire as createRequire2 } from "module";
|
|
400
427
|
var require3 = createRequire2(import.meta.url);
|
|
401
428
|
function resolveSourcePath(source, variantDir, packageRoot) {
|
|
402
429
|
if (source.startsWith("_template/")) {
|
|
403
|
-
return
|
|
430
|
+
return path7.join(packageRoot, source);
|
|
404
431
|
}
|
|
405
|
-
return
|
|
432
|
+
return path7.join(variantDir, source);
|
|
406
433
|
}
|
|
407
434
|
async function walkDir(dir, skipDirs) {
|
|
408
435
|
const files = [];
|
|
409
436
|
const entries = await fs5.readdir(dir, { withFileTypes: true });
|
|
410
437
|
for (const entry of entries) {
|
|
411
|
-
const fullPath =
|
|
438
|
+
const fullPath = path7.join(dir, entry.name);
|
|
412
439
|
if (entry.isDirectory()) {
|
|
413
440
|
if (skipDirs && skipDirs.has(entry.name)) continue;
|
|
414
441
|
files.push(...await walkDir(fullPath, skipDirs));
|
|
@@ -420,10 +447,10 @@ async function walkDir(dir, skipDirs) {
|
|
|
420
447
|
}
|
|
421
448
|
function resolveTokensPackageRoot(packageName) {
|
|
422
449
|
const pkgJson = require3.resolve(`${packageName}/package.json`);
|
|
423
|
-
return
|
|
450
|
+
return path7.dirname(pkgJson);
|
|
424
451
|
}
|
|
425
452
|
function resolveResourceTarget(projectRoot, target) {
|
|
426
|
-
return
|
|
453
|
+
return path7.isAbsolute(target) ? target : path7.resolve(projectRoot, target);
|
|
427
454
|
}
|
|
428
455
|
|
|
429
456
|
// src/core/skills-installer.ts
|
|
@@ -460,7 +487,7 @@ async function installSkills(options) {
|
|
|
460
487
|
}
|
|
461
488
|
async function renderSkillFiles(skill, options) {
|
|
462
489
|
const { data, packageRoot } = options;
|
|
463
|
-
const sourceAbs =
|
|
490
|
+
const sourceAbs = path8.resolve(packageRoot, skill.source);
|
|
464
491
|
const stat4 = await fs6.stat(sourceAbs);
|
|
465
492
|
const rendered = /* @__PURE__ */ new Map();
|
|
466
493
|
if (stat4.isFile()) {
|
|
@@ -470,7 +497,7 @@ async function renderSkillFiles(skill, options) {
|
|
|
470
497
|
}
|
|
471
498
|
const entries = await walkDir(sourceAbs);
|
|
472
499
|
for (const entry of entries) {
|
|
473
|
-
let rel2 =
|
|
500
|
+
let rel2 = path8.relative(sourceAbs, entry);
|
|
474
501
|
if (skill.template && rel2.endsWith(".hbs")) {
|
|
475
502
|
rel2 = rel2.slice(0, -4);
|
|
476
503
|
}
|
|
@@ -485,7 +512,7 @@ async function writeRenderedToIde(skill, rendered, ide, scope, projectRoot) {
|
|
|
485
512
|
const records = [];
|
|
486
513
|
await ensureDir(targetDir);
|
|
487
514
|
for (const [rel2, sourceContent] of rendered) {
|
|
488
|
-
const targetFile =
|
|
515
|
+
const targetFile = path8.join(targetDir, rel2);
|
|
489
516
|
const writtenContent = await writeMirrorContent(
|
|
490
517
|
targetFile,
|
|
491
518
|
sourceContent,
|
|
@@ -557,7 +584,7 @@ function makeMirrorRecord(skill, projectRoot, targetAbs, content, ide, scope, re
|
|
|
557
584
|
const id = rel2 && rel2 !== "SKILL.md" ? `${skill.id}:${rel2}` : skill.id;
|
|
558
585
|
return {
|
|
559
586
|
id,
|
|
560
|
-
target:
|
|
587
|
+
target: path8.relative(projectRoot, targetAbs),
|
|
561
588
|
hash: computeHash(content),
|
|
562
589
|
strategy: skill.updateStrategy,
|
|
563
590
|
ide,
|
|
@@ -594,7 +621,7 @@ async function updateRenderedInIde(skill, rendered, ide, scope, projectRoot, sum
|
|
|
594
621
|
const records = [];
|
|
595
622
|
await ensureDir(targetDir);
|
|
596
623
|
for (const [rel2, newContent] of rendered) {
|
|
597
|
-
const targetFile =
|
|
624
|
+
const targetFile = path8.join(targetDir, rel2);
|
|
598
625
|
const exists = await fileExists(targetFile);
|
|
599
626
|
const written = await rewriteSingleFile({
|
|
600
627
|
targetFile,
|
|
@@ -684,12 +711,13 @@ async function reinstallSkillsToIdes(options) {
|
|
|
684
711
|
continue;
|
|
685
712
|
}
|
|
686
713
|
const rendered = await renderSkillFiles(entry, { data, packageRoot });
|
|
687
|
-
|
|
714
|
+
const supportedIdes = entry.ides.filter((ide) => ides.includes(ide));
|
|
715
|
+
for (const ide of supportedIdes) {
|
|
688
716
|
const adapter = getAdapter(ide);
|
|
689
717
|
const targetDir = adapter.getSkillTargetDir(skill.name, scope, projectRoot);
|
|
690
718
|
await ensureDir(targetDir);
|
|
691
719
|
for (const [rel2, sourceContent] of rendered) {
|
|
692
|
-
const targetFile =
|
|
720
|
+
const targetFile = path8.join(targetDir, rel2);
|
|
693
721
|
const writtenContent = await writeMirrorContent(
|
|
694
722
|
targetFile,
|
|
695
723
|
sourceContent,
|
|
@@ -697,7 +725,7 @@ async function reinstallSkillsToIdes(options) {
|
|
|
697
725
|
);
|
|
698
726
|
out.push({
|
|
699
727
|
id: rel2 === "SKILL.md" ? skill.id : `${skill.id}:${rel2}`,
|
|
700
|
-
target:
|
|
728
|
+
target: path8.relative(projectRoot, targetFile),
|
|
701
729
|
hash: computeHash(writtenContent),
|
|
702
730
|
strategy: skill.updateStrategy,
|
|
703
731
|
ide,
|
|
@@ -717,7 +745,7 @@ async function pruneEmptyIdeSkillDirs(args) {
|
|
|
717
745
|
args.scope,
|
|
718
746
|
args.projectRoot
|
|
719
747
|
);
|
|
720
|
-
const skillsRoot =
|
|
748
|
+
const skillsRoot = path8.dirname(placeholderDir);
|
|
721
749
|
let entries;
|
|
722
750
|
try {
|
|
723
751
|
entries = await fs6.readdir(skillsRoot);
|
|
@@ -725,7 +753,7 @@ async function pruneEmptyIdeSkillDirs(args) {
|
|
|
725
753
|
continue;
|
|
726
754
|
}
|
|
727
755
|
for (const name of entries) {
|
|
728
|
-
const dir =
|
|
756
|
+
const dir = path8.join(skillsRoot, name);
|
|
729
757
|
let stat4;
|
|
730
758
|
try {
|
|
731
759
|
stat4 = await fs6.stat(dir);
|
|
@@ -765,7 +793,7 @@ async function removeSkillFiles(records, projectRoot) {
|
|
|
765
793
|
}
|
|
766
794
|
}
|
|
767
795
|
const startDirs = new Set(
|
|
768
|
-
records.map((r) =>
|
|
796
|
+
records.map((r) => path8.dirname(resolveResourceTarget(projectRoot, r.target)))
|
|
769
797
|
);
|
|
770
798
|
for (const startDir of startDirs) {
|
|
771
799
|
let dir = startDir;
|
|
@@ -777,7 +805,7 @@ async function removeSkillFiles(records, projectRoot) {
|
|
|
777
805
|
} catch {
|
|
778
806
|
break;
|
|
779
807
|
}
|
|
780
|
-
dir =
|
|
808
|
+
dir = path8.dirname(dir);
|
|
781
809
|
}
|
|
782
810
|
}
|
|
783
811
|
return removed;
|
|
@@ -1206,7 +1234,7 @@ async function autoUpgradeOutdatedSkills(args) {
|
|
|
1206
1234
|
|
|
1207
1235
|
// src/core/tokens-init.ts
|
|
1208
1236
|
var DEFAULT_SKILLS_PACKAGE2 = "@teamix-evo/skills";
|
|
1209
|
-
var DEFAULT_AUTO_SKILL_IDES = [
|
|
1237
|
+
var DEFAULT_AUTO_SKILL_IDES = [...ALL_IDE_KINDS];
|
|
1210
1238
|
var DEFAULT_AUTO_SKILL_SCOPE = "project";
|
|
1211
1239
|
var DEFAULT_TOKENS_PACKAGE = "@teamix-evo/tokens";
|
|
1212
1240
|
var CONSUMER_TOKENS_DIR = "tokens";
|
|
@@ -1246,7 +1274,7 @@ Run \`npx teamix-evo@latest tokens list-variants\` to see all options.`
|
|
|
1246
1274
|
const result = await installVariantFile(fileRel, packageRoot, projectRoot);
|
|
1247
1275
|
if (result) installed.push(result);
|
|
1248
1276
|
}
|
|
1249
|
-
const overridesAbs =
|
|
1277
|
+
const overridesAbs = path9.join(
|
|
1250
1278
|
projectRoot,
|
|
1251
1279
|
CONSUMER_TOKENS_DIR,
|
|
1252
1280
|
CONSUMER_OVERRIDES_FILE
|
|
@@ -1259,7 +1287,7 @@ Run \`npx teamix-evo@latest tokens list-variants\` to see all options.`
|
|
|
1259
1287
|
const overridesContent = await fs7.readFile(overridesAbs, "utf-8");
|
|
1260
1288
|
installed.push({
|
|
1261
1289
|
id: overridesId,
|
|
1262
|
-
target:
|
|
1290
|
+
target: path9.posix.join(CONSUMER_TOKENS_DIR, CONSUMER_OVERRIDES_FILE),
|
|
1263
1291
|
hash: computeHash(overridesContent),
|
|
1264
1292
|
strategy: "frozen"
|
|
1265
1293
|
});
|
|
@@ -1277,7 +1305,7 @@ Run \`npx teamix-evo@latest tokens list-variants\` to see all options.`
|
|
|
1277
1305
|
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1278
1306
|
};
|
|
1279
1307
|
await writeFileSafe(
|
|
1280
|
-
|
|
1308
|
+
path9.join(projectRoot, ".teamix-evo", "tokens-lock.json"),
|
|
1281
1309
|
JSON.stringify(lock, null, 2) + "\n"
|
|
1282
1310
|
);
|
|
1283
1311
|
const config = {
|
|
@@ -1397,11 +1425,11 @@ async function tryAutoInstallVariantSkills(args) {
|
|
|
1397
1425
|
}
|
|
1398
1426
|
}
|
|
1399
1427
|
async function installVariantFile(fileRelToPackage, packageRoot, projectRoot) {
|
|
1400
|
-
const sourceAbs =
|
|
1401
|
-
const base =
|
|
1428
|
+
const sourceAbs = path9.join(packageRoot, fileRelToPackage);
|
|
1429
|
+
const base = path9.basename(fileRelToPackage);
|
|
1402
1430
|
if (base === "theme.css") {
|
|
1403
|
-
const targetRel =
|
|
1404
|
-
const targetAbs =
|
|
1431
|
+
const targetRel = path9.posix.join(CONSUMER_TOKENS_DIR, CONSUMER_THEME_FILE);
|
|
1432
|
+
const targetAbs = path9.join(projectRoot, targetRel);
|
|
1405
1433
|
const content = await fs7.readFile(sourceAbs, "utf-8");
|
|
1406
1434
|
if (await fileExists(targetAbs)) {
|
|
1407
1435
|
await backupFile(targetAbs, projectRoot);
|
|
@@ -1415,11 +1443,11 @@ async function installVariantFile(fileRelToPackage, packageRoot, projectRoot) {
|
|
|
1415
1443
|
};
|
|
1416
1444
|
}
|
|
1417
1445
|
if (base === "overrides.css" || base === "tokens.overrides.css") {
|
|
1418
|
-
const targetRel =
|
|
1446
|
+
const targetRel = path9.posix.join(
|
|
1419
1447
|
CONSUMER_TOKENS_DIR,
|
|
1420
1448
|
CONSUMER_OVERRIDES_FILE
|
|
1421
1449
|
);
|
|
1422
|
-
const targetAbs =
|
|
1450
|
+
const targetAbs = path9.join(projectRoot, targetRel);
|
|
1423
1451
|
if (await fileExists(targetAbs)) {
|
|
1424
1452
|
const existing = await fs7.readFile(targetAbs, "utf-8");
|
|
1425
1453
|
return {
|
|
@@ -1458,7 +1486,7 @@ async function listTokenVariants(packageName = DEFAULT_TOKENS_PACKAGE, packageRo
|
|
|
1458
1486
|
|
|
1459
1487
|
// src/core/agents-md.ts
|
|
1460
1488
|
import * as fs8 from "fs/promises";
|
|
1461
|
-
import * as
|
|
1489
|
+
import * as path10 from "path";
|
|
1462
1490
|
import { hasManagedRegion as hasManagedRegion2, replaceManagedRegion as replaceManagedRegion2 } from "@teamix-evo/registry";
|
|
1463
1491
|
var AGENTS_MD_MANAGED_ID = "teamix-evo-skills";
|
|
1464
1492
|
async function runGenerateAgentsMd(options) {
|
|
@@ -1467,7 +1495,7 @@ async function runGenerateAgentsMd(options) {
|
|
|
1467
1495
|
const mode = options.mode ?? "overwrite";
|
|
1468
1496
|
const config = await readProjectConfig(projectRoot);
|
|
1469
1497
|
const lock = await readSkillsLock(projectRoot);
|
|
1470
|
-
const ides = config?.packages?.skills?.ides ?? [
|
|
1498
|
+
const ides = config?.packages?.skills?.ides ?? [...ALL_IDE_KINDS];
|
|
1471
1499
|
const scope = config?.packages?.skills?.scope ?? lock?.skills[skillIds[0] ?? ""]?.scope ?? "project";
|
|
1472
1500
|
const skillScopeMap = /* @__PURE__ */ new Map();
|
|
1473
1501
|
for (const id of skillIds) skillScopeMap.set(id, scope);
|
|
@@ -1484,7 +1512,7 @@ async function runGenerateAgentsMd(options) {
|
|
|
1484
1512
|
sections.push(section);
|
|
1485
1513
|
if (missing) missingSkillIds.push(id);
|
|
1486
1514
|
}
|
|
1487
|
-
const target =
|
|
1515
|
+
const target = path10.join(projectRoot, "AGENTS.md");
|
|
1488
1516
|
const targetExists = await fileExists(target);
|
|
1489
1517
|
const fullTemplate = renderAgentsMd({ variant, sections });
|
|
1490
1518
|
const managedBody = renderManagedBlockBody({ variant, sections });
|
|
@@ -1539,7 +1567,7 @@ async function renderSkillSection(projectRoot, skillId, ides, scope) {
|
|
|
1539
1567
|
let missing = false;
|
|
1540
1568
|
for (const ide of ides) {
|
|
1541
1569
|
const adapter = getAdapter(ide);
|
|
1542
|
-
const skillPath =
|
|
1570
|
+
const skillPath = path10.join(
|
|
1543
1571
|
adapter.getSkillTargetDir(skillId, scope, projectRoot),
|
|
1544
1572
|
"SKILL.md"
|
|
1545
1573
|
);
|
|
@@ -1713,7 +1741,7 @@ async function runSkillsUpdate(options) {
|
|
|
1713
1741
|
if (!skillsCfg) {
|
|
1714
1742
|
return { status: "no-skills" };
|
|
1715
1743
|
}
|
|
1716
|
-
const ides = skillsCfg.ides ?? [
|
|
1744
|
+
const ides = skillsCfg.ides ?? [...ALL_IDE_KINDS];
|
|
1717
1745
|
const scope = skillsCfg.scope ?? "project";
|
|
1718
1746
|
let existingLock = await readSkillsLock(projectRoot);
|
|
1719
1747
|
if (!existingLock || Object.keys(existingLock.skills).length === 0) {
|
|
@@ -1965,25 +1993,25 @@ async function runUiInit(options) {
|
|
|
1965
1993
|
}
|
|
1966
1994
|
|
|
1967
1995
|
// src/core/ui-client.ts
|
|
1968
|
-
import * as
|
|
1996
|
+
import * as path11 from "path";
|
|
1969
1997
|
import * as fs9 from "fs/promises";
|
|
1970
1998
|
import { createRequire as createRequire3 } from "module";
|
|
1971
1999
|
import { loadUiPackageManifest } from "@teamix-evo/registry";
|
|
1972
2000
|
var require4 = createRequire3(import.meta.url);
|
|
1973
2001
|
function resolvePackageRoot2(packageName) {
|
|
1974
2002
|
const pkgJsonPath = require4.resolve(`${packageName}/package.json`);
|
|
1975
|
-
return
|
|
2003
|
+
return path11.dirname(pkgJsonPath);
|
|
1976
2004
|
}
|
|
1977
2005
|
async function loadUiData(packageName) {
|
|
1978
2006
|
const packageRoot = resolvePackageRoot2(packageName);
|
|
1979
2007
|
logger.debug(`Resolved ui package root: ${packageRoot}`);
|
|
1980
2008
|
const manifest = await loadUiPackageManifest(packageRoot);
|
|
1981
2009
|
const pkgJson = JSON.parse(
|
|
1982
|
-
await fs9.readFile(
|
|
2010
|
+
await fs9.readFile(path11.join(packageRoot, "package.json"), "utf-8")
|
|
1983
2011
|
);
|
|
1984
2012
|
manifest.version = pkgJson.version;
|
|
1985
2013
|
let data = {};
|
|
1986
|
-
const dataPath =
|
|
2014
|
+
const dataPath = path11.join(packageRoot, "_data.json");
|
|
1987
2015
|
try {
|
|
1988
2016
|
const raw = await fs9.readFile(dataPath, "utf-8");
|
|
1989
2017
|
data = JSON.parse(raw);
|
|
@@ -1997,7 +2025,7 @@ async function loadUiData(packageName) {
|
|
|
1997
2025
|
}
|
|
1998
2026
|
|
|
1999
2027
|
// src/core/ui-installer.ts
|
|
2000
|
-
import * as
|
|
2028
|
+
import * as path12 from "path";
|
|
2001
2029
|
import * as fs10 from "fs/promises";
|
|
2002
2030
|
import { resolveUiEntryOrder } from "@teamix-evo/registry";
|
|
2003
2031
|
|
|
@@ -2079,7 +2107,7 @@ async function installUiEntries(options) {
|
|
|
2079
2107
|
continue;
|
|
2080
2108
|
}
|
|
2081
2109
|
const rootForEntry = entryPackageRoot?.get(entry.id) ?? packageRoot;
|
|
2082
|
-
const sourceAbs =
|
|
2110
|
+
const sourceAbs = path12.resolve(rootForEntry, file.source);
|
|
2083
2111
|
const raw = await fs10.readFile(sourceAbs, "utf-8");
|
|
2084
2112
|
const transformed = rewriteImports(raw, aliases, { flatten });
|
|
2085
2113
|
if (exists) {
|
|
@@ -2089,13 +2117,13 @@ async function installUiEntries(options) {
|
|
|
2089
2117
|
skipped++;
|
|
2090
2118
|
resources.push({
|
|
2091
2119
|
id: `${entry.id}:${file.targetName}`,
|
|
2092
|
-
target:
|
|
2120
|
+
target: path12.relative(projectRoot, targetAbs),
|
|
2093
2121
|
hash: computeHash(transformed),
|
|
2094
2122
|
strategy: entry.updateStrategy ?? "frozen"
|
|
2095
2123
|
});
|
|
2096
2124
|
continue;
|
|
2097
2125
|
}
|
|
2098
|
-
const relPath =
|
|
2126
|
+
const relPath = path12.relative(projectRoot, targetAbs);
|
|
2099
2127
|
const prior = priorByTarget.get(relPath);
|
|
2100
2128
|
if (prior && prior.hash !== "sha256:legacy-unknown") {
|
|
2101
2129
|
const onDiskHash = computeHash(current);
|
|
@@ -2116,7 +2144,7 @@ async function installUiEntries(options) {
|
|
|
2116
2144
|
await writeFileSafe(targetAbs, transformed);
|
|
2117
2145
|
resources.push({
|
|
2118
2146
|
id: `${entry.id}:${file.targetName}`,
|
|
2119
|
-
target:
|
|
2147
|
+
target: path12.relative(projectRoot, targetAbs),
|
|
2120
2148
|
hash: computeHash(transformed),
|
|
2121
2149
|
strategy: entry.updateStrategy ?? "frozen"
|
|
2122
2150
|
});
|
|
@@ -2140,10 +2168,10 @@ function resolveTargetPath(projectRoot, aliases, entry, file) {
|
|
|
2140
2168
|
`Entry "${entry.id}" requires alias "${file.targetAlias}" but it is not configured.`
|
|
2141
2169
|
);
|
|
2142
2170
|
}
|
|
2143
|
-
return
|
|
2171
|
+
return path12.join(projectRoot, aliasDir, file.targetName);
|
|
2144
2172
|
}
|
|
2145
2173
|
function rel(projectRoot, abs) {
|
|
2146
|
-
return
|
|
2174
|
+
return path12.relative(projectRoot, abs);
|
|
2147
2175
|
}
|
|
2148
2176
|
async function removeUiFiles(records, projectRoot) {
|
|
2149
2177
|
const removed = [];
|
|
@@ -2159,7 +2187,7 @@ async function removeUiFiles(records, projectRoot) {
|
|
|
2159
2187
|
}
|
|
2160
2188
|
}
|
|
2161
2189
|
const parents = new Set(
|
|
2162
|
-
records.map((r) =>
|
|
2190
|
+
records.map((r) => path12.dirname(resolveResourceTarget(projectRoot, r.target)))
|
|
2163
2191
|
);
|
|
2164
2192
|
for (const dir of parents) {
|
|
2165
2193
|
try {
|
|
@@ -2299,7 +2327,7 @@ async function runUiList(options) {
|
|
|
2299
2327
|
}
|
|
2300
2328
|
|
|
2301
2329
|
// src/core/variant-ui-add.ts
|
|
2302
|
-
import * as
|
|
2330
|
+
import * as path13 from "path";
|
|
2303
2331
|
import * as fs11 from "fs/promises";
|
|
2304
2332
|
import { createRequire as createRequire4 } from "module";
|
|
2305
2333
|
import {
|
|
@@ -2310,7 +2338,7 @@ import {
|
|
|
2310
2338
|
var require5 = createRequire4(import.meta.url);
|
|
2311
2339
|
function resolvePackageRoot3(packageName) {
|
|
2312
2340
|
const pkgJsonPath = require5.resolve(`${packageName}/package.json`);
|
|
2313
|
-
return
|
|
2341
|
+
return path13.dirname(pkgJsonPath);
|
|
2314
2342
|
}
|
|
2315
2343
|
async function runVariantUiAdd(packageName, options) {
|
|
2316
2344
|
const { projectRoot, variant, ids, overwrite } = options;
|
|
@@ -2333,10 +2361,10 @@ async function runVariantUiAdd(packageName, options) {
|
|
|
2333
2361
|
`Variant "${variant}" not found in ${fullPackageName}. Known variants: ${known}. Hint: \`teamix-evo ${packageName} list-variants\` shows all.`
|
|
2334
2362
|
);
|
|
2335
2363
|
}
|
|
2336
|
-
const variantDir =
|
|
2364
|
+
const variantDir = path13.join(packageRoot, "variants", variant);
|
|
2337
2365
|
const variantManifest = await loadVariantUiPackageManifest(variantDir);
|
|
2338
2366
|
const pkgJson = JSON.parse(
|
|
2339
|
-
await fs11.readFile(
|
|
2367
|
+
await fs11.readFile(path13.join(packageRoot, "package.json"), "utf-8")
|
|
2340
2368
|
);
|
|
2341
2369
|
const packageVersion = pkgJson.version;
|
|
2342
2370
|
const knownIds = new Set(variantManifest.entries.map((e) => e.id));
|
|
@@ -2452,7 +2480,7 @@ async function listVariantUiEntries(packageName, variant, packageRoot) {
|
|
|
2452
2480
|
`Variant "${variant}" not found in ${fullPackageName}. Known: ${known}.`
|
|
2453
2481
|
);
|
|
2454
2482
|
}
|
|
2455
|
-
const variantDir =
|
|
2483
|
+
const variantDir = path13.join(root, "variants", variant);
|
|
2456
2484
|
const variantManifest = await loadVariantUiPackageManifest(variantDir);
|
|
2457
2485
|
return {
|
|
2458
2486
|
packageName: fullPackageName,
|
|
@@ -2471,7 +2499,7 @@ async function listBizUiEntries(variant, packageRoot) {
|
|
|
2471
2499
|
}
|
|
2472
2500
|
|
|
2473
2501
|
// src/core/lint-init.ts
|
|
2474
|
-
import * as
|
|
2502
|
+
import * as path14 from "path";
|
|
2475
2503
|
import * as fs12 from "fs";
|
|
2476
2504
|
import { execa } from "execa";
|
|
2477
2505
|
var ESLINT_CONFIG_CONTENT = `/**
|
|
@@ -2515,8 +2543,8 @@ async function runLintInit(options) {
|
|
|
2515
2543
|
eslintExistingPaths = [],
|
|
2516
2544
|
stylelintExistingPaths = []
|
|
2517
2545
|
} = options;
|
|
2518
|
-
const eslintConfigPath =
|
|
2519
|
-
const stylelintConfigPath =
|
|
2546
|
+
const eslintConfigPath = path14.join(projectRoot, "eslint.config.js");
|
|
2547
|
+
const stylelintConfigPath = path14.join(projectRoot, "stylelint.config.cjs");
|
|
2520
2548
|
const eslintTemplateExists = await fileExists(eslintConfigPath);
|
|
2521
2549
|
const stylelintTemplateExists = await fileExists(stylelintConfigPath);
|
|
2522
2550
|
const eslintSkipRequested = eslintStrategy === "skip" && eslintExistingPaths.length > 0;
|
|
@@ -2540,12 +2568,12 @@ async function runLintInit(options) {
|
|
|
2540
2568
|
}
|
|
2541
2569
|
if (eslintNeedsWrite && eslintExistingPaths.length > 0) {
|
|
2542
2570
|
for (const rel2 of eslintExistingPaths) {
|
|
2543
|
-
await backupFile(
|
|
2571
|
+
await backupFile(path14.join(projectRoot, rel2), projectRoot);
|
|
2544
2572
|
}
|
|
2545
2573
|
}
|
|
2546
2574
|
if (stylelintNeedsWrite && stylelintExistingPaths.length > 0) {
|
|
2547
2575
|
for (const rel2 of stylelintExistingPaths) {
|
|
2548
|
-
await backupFile(
|
|
2576
|
+
await backupFile(path14.join(projectRoot, rel2), projectRoot);
|
|
2549
2577
|
}
|
|
2550
2578
|
}
|
|
2551
2579
|
let wroteEslint = false;
|
|
@@ -2601,12 +2629,12 @@ async function runLintInit(options) {
|
|
|
2601
2629
|
};
|
|
2602
2630
|
}
|
|
2603
2631
|
function detectPm(projectRoot) {
|
|
2604
|
-
if (fs12.existsSync(
|
|
2605
|
-
if (fs12.existsSync(
|
|
2632
|
+
if (fs12.existsSync(path14.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
|
|
2633
|
+
if (fs12.existsSync(path14.join(projectRoot, "yarn.lock"))) return "yarn";
|
|
2606
2634
|
return "npm";
|
|
2607
2635
|
}
|
|
2608
2636
|
async function patchPackageJsonScripts(projectRoot) {
|
|
2609
|
-
const pkgPath =
|
|
2637
|
+
const pkgPath = path14.join(projectRoot, "package.json");
|
|
2610
2638
|
const raw = await readFileOrNull(pkgPath);
|
|
2611
2639
|
if (!raw) return false;
|
|
2612
2640
|
let pkg;
|
|
@@ -2636,7 +2664,7 @@ async function patchPackageJsonScripts(projectRoot) {
|
|
|
2636
2664
|
|
|
2637
2665
|
// src/core/init-detect.ts
|
|
2638
2666
|
import * as fs13 from "fs/promises";
|
|
2639
|
-
import * as
|
|
2667
|
+
import * as path15 from "path";
|
|
2640
2668
|
var IGNORED_TOP_LEVEL = /* @__PURE__ */ new Set([
|
|
2641
2669
|
".git",
|
|
2642
2670
|
".gitignore",
|
|
@@ -2648,6 +2676,7 @@ var IGNORED_TOP_LEVEL = /* @__PURE__ */ new Set([
|
|
|
2648
2676
|
".vscode",
|
|
2649
2677
|
".qoder",
|
|
2650
2678
|
".claude",
|
|
2679
|
+
".agents",
|
|
2651
2680
|
"README.md",
|
|
2652
2681
|
"README",
|
|
2653
2682
|
"README.txt",
|
|
@@ -2656,7 +2685,7 @@ var IGNORED_TOP_LEVEL = /* @__PURE__ */ new Set([
|
|
|
2656
2685
|
"LICENSE.txt"
|
|
2657
2686
|
]);
|
|
2658
2687
|
async function detectProjectState(cwd) {
|
|
2659
|
-
const absCwd =
|
|
2688
|
+
const absCwd = path15.resolve(cwd);
|
|
2660
2689
|
const teamixDir = getTeamixDir(absCwd);
|
|
2661
2690
|
const hasTeamixDir = await fileExists(teamixDir);
|
|
2662
2691
|
if (hasTeamixDir) {
|
|
@@ -2664,7 +2693,7 @@ async function detectProjectState(cwd) {
|
|
|
2664
2693
|
state: "teamix-evo-installed",
|
|
2665
2694
|
cwd: absCwd,
|
|
2666
2695
|
hasTeamixDir: true,
|
|
2667
|
-
hasPackageJson: await fileExists(
|
|
2696
|
+
hasPackageJson: await fileExists(path15.join(absCwd, "package.json")),
|
|
2668
2697
|
significantEntries: []
|
|
2669
2698
|
};
|
|
2670
2699
|
}
|
|
@@ -2705,7 +2734,7 @@ async function detectProjectState(cwd) {
|
|
|
2705
2734
|
|
|
2706
2735
|
// src/core/project-state.ts
|
|
2707
2736
|
import * as fs14 from "fs/promises";
|
|
2708
|
-
import * as
|
|
2737
|
+
import * as path16 from "path";
|
|
2709
2738
|
var IGNORED_TOP_LEVEL2 = /* @__PURE__ */ new Set([
|
|
2710
2739
|
".git",
|
|
2711
2740
|
".gitignore",
|
|
@@ -2717,6 +2746,7 @@ var IGNORED_TOP_LEVEL2 = /* @__PURE__ */ new Set([
|
|
|
2717
2746
|
".vscode",
|
|
2718
2747
|
".qoder",
|
|
2719
2748
|
".claude",
|
|
2749
|
+
".agents",
|
|
2720
2750
|
"README.md",
|
|
2721
2751
|
"README",
|
|
2722
2752
|
"README.txt",
|
|
@@ -2736,22 +2766,22 @@ async function isShadcnComponentsJson(filePath) {
|
|
|
2736
2766
|
}
|
|
2737
2767
|
}
|
|
2738
2768
|
async function detectProjectState2(cwd) {
|
|
2739
|
-
const absCwd =
|
|
2769
|
+
const absCwd = path16.resolve(cwd);
|
|
2740
2770
|
const teamixDir = getTeamixDir(absCwd);
|
|
2741
2771
|
const hasTeamixDir = await fileExists(teamixDir);
|
|
2742
|
-
const hasTeamixConfig = hasTeamixDir && await fileExists(
|
|
2772
|
+
const hasTeamixConfig = hasTeamixDir && await fileExists(path16.join(teamixDir, "config.json"));
|
|
2743
2773
|
if (hasTeamixDir && hasTeamixConfig) {
|
|
2744
2774
|
return {
|
|
2745
2775
|
state: "teamix-evo",
|
|
2746
2776
|
cwd: absCwd,
|
|
2747
2777
|
hasTeamixDir: true,
|
|
2748
|
-
hasPackageJson: await fileExists(
|
|
2778
|
+
hasPackageJson: await fileExists(path16.join(absCwd, "package.json")),
|
|
2749
2779
|
hasComponentsJson: false,
|
|
2750
2780
|
significantEntries: []
|
|
2751
2781
|
};
|
|
2752
2782
|
}
|
|
2753
|
-
const componentsJsonPath =
|
|
2754
|
-
const hasPackageJson = await fileExists(
|
|
2783
|
+
const componentsJsonPath = path16.join(absCwd, "components.json");
|
|
2784
|
+
const hasPackageJson = await fileExists(path16.join(absCwd, "package.json"));
|
|
2755
2785
|
const hasComponentsJson = await isShadcnComponentsJson(componentsJsonPath);
|
|
2756
2786
|
if (hasPackageJson && hasComponentsJson) {
|
|
2757
2787
|
return {
|
|
@@ -2794,7 +2824,7 @@ async function detectProjectState2(cwd) {
|
|
|
2794
2824
|
let buildTool = "unknown";
|
|
2795
2825
|
let allDeps = {};
|
|
2796
2826
|
if (hasPackageJson) {
|
|
2797
|
-
const pkgRaw = await readFileOrNull(
|
|
2827
|
+
const pkgRaw = await readFileOrNull(path16.join(absCwd, "package.json"));
|
|
2798
2828
|
if (pkgRaw) {
|
|
2799
2829
|
try {
|
|
2800
2830
|
const pkg = JSON.parse(pkgRaw);
|
|
@@ -2810,11 +2840,11 @@ async function detectProjectState2(cwd) {
|
|
|
2810
2840
|
} else if ("element-ui" in allDeps || "element-plus" in allDeps) {
|
|
2811
2841
|
legacyLib = "element";
|
|
2812
2842
|
}
|
|
2813
|
-
if (await fileExists(
|
|
2843
|
+
if (await fileExists(path16.join(absCwd, "build.json"))) {
|
|
2814
2844
|
buildTool = "ice";
|
|
2815
|
-
} else if (await fileExists(
|
|
2845
|
+
} else if (await fileExists(path16.join(absCwd, "vite.config.ts")) || await fileExists(path16.join(absCwd, "vite.config.js")) || await fileExists(path16.join(absCwd, "vite.config.mts"))) {
|
|
2816
2846
|
buildTool = "vite";
|
|
2817
|
-
} else if (await fileExists(
|
|
2847
|
+
} else if (await fileExists(path16.join(absCwd, "webpack.config.js")) || await fileExists(path16.join(absCwd, "webpack.config.ts"))) {
|
|
2818
2848
|
buildTool = "webpack";
|
|
2819
2849
|
} else if ("umi" in allDeps || "@umijs/max" in allDeps) {
|
|
2820
2850
|
buildTool = "umi";
|
|
@@ -2886,7 +2916,7 @@ function assertCommandPrecondition(command, state, options) {
|
|
|
2886
2916
|
// src/core/init-conflicts.ts
|
|
2887
2917
|
import * as crypto from "crypto";
|
|
2888
2918
|
import * as fs15 from "fs/promises";
|
|
2889
|
-
import * as
|
|
2919
|
+
import * as path17 from "path";
|
|
2890
2920
|
var TAILWIND_CONFIG_CANDIDATES = [
|
|
2891
2921
|
"tailwind.config.ts",
|
|
2892
2922
|
"tailwind.config.js",
|
|
@@ -2950,7 +2980,7 @@ function fingerprint(parts) {
|
|
|
2950
2980
|
return `sha256:${hash.digest("hex").slice(0, 16)}`;
|
|
2951
2981
|
}
|
|
2952
2982
|
async function readPackageJson(cwd) {
|
|
2953
|
-
const raw = await readFileOrNull(
|
|
2983
|
+
const raw = await readFileOrNull(path17.join(cwd, "package.json"));
|
|
2954
2984
|
if (raw === null) return null;
|
|
2955
2985
|
try {
|
|
2956
2986
|
return JSON.parse(raw);
|
|
@@ -2970,7 +3000,7 @@ function detectTailwindMajor(pkg) {
|
|
|
2970
3000
|
return null;
|
|
2971
3001
|
}
|
|
2972
3002
|
async function detectAgentsMd(cwd) {
|
|
2973
|
-
const target =
|
|
3003
|
+
const target = path17.join(cwd, "AGENTS.md");
|
|
2974
3004
|
const content = await readFileOrNull(target);
|
|
2975
3005
|
const exists = content !== null;
|
|
2976
3006
|
return {
|
|
@@ -2983,7 +3013,7 @@ async function detectAgentsMd(cwd) {
|
|
|
2983
3013
|
};
|
|
2984
3014
|
}
|
|
2985
3015
|
async function detectComponentsJson(cwd) {
|
|
2986
|
-
const target =
|
|
3016
|
+
const target = path17.join(cwd, "components.json");
|
|
2987
3017
|
const content = await readFileOrNull(target);
|
|
2988
3018
|
const exists = content !== null;
|
|
2989
3019
|
return {
|
|
@@ -2999,7 +3029,7 @@ async function detectTailwindConfig(cwd) {
|
|
|
2999
3029
|
const matched = [];
|
|
3000
3030
|
const contents = [];
|
|
3001
3031
|
for (const rel2 of TAILWIND_CONFIG_CANDIDATES) {
|
|
3002
|
-
const c = await readFileOrNull(
|
|
3032
|
+
const c = await readFileOrNull(path17.join(cwd, rel2));
|
|
3003
3033
|
if (c !== null) {
|
|
3004
3034
|
matched.push(rel2);
|
|
3005
3035
|
contents.push(c);
|
|
@@ -3022,14 +3052,14 @@ async function detectTokens(cwd) {
|
|
|
3022
3052
|
const matched = [];
|
|
3023
3053
|
const contents = [];
|
|
3024
3054
|
for (const rel2 of TOKENS_FILE_CANDIDATES) {
|
|
3025
|
-
const c = await readFileOrNull(
|
|
3055
|
+
const c = await readFileOrNull(path17.join(cwd, rel2));
|
|
3026
3056
|
if (c !== null) {
|
|
3027
3057
|
matched.push(rel2);
|
|
3028
3058
|
contents.push(c);
|
|
3029
3059
|
}
|
|
3030
3060
|
}
|
|
3031
3061
|
for (const rel2 of TOKENS_DIR_CANDIDATES) {
|
|
3032
|
-
const abs =
|
|
3062
|
+
const abs = path17.join(cwd, rel2);
|
|
3033
3063
|
if (await isDir(abs) && await dirHasContent(abs)) {
|
|
3034
3064
|
matched.push(`${rel2}/`);
|
|
3035
3065
|
}
|
|
@@ -3048,7 +3078,7 @@ async function detectIndexCss(cwd) {
|
|
|
3048
3078
|
const matched = [];
|
|
3049
3079
|
const contents = [];
|
|
3050
3080
|
for (const rel2 of INDEX_CSS_CANDIDATES) {
|
|
3051
|
-
const c = await readFileOrNull(
|
|
3081
|
+
const c = await readFileOrNull(path17.join(cwd, rel2));
|
|
3052
3082
|
if (c !== null) {
|
|
3053
3083
|
matched.push(rel2);
|
|
3054
3084
|
contents.push(c);
|
|
@@ -3067,17 +3097,17 @@ async function detectIndexCss(cwd) {
|
|
|
3067
3097
|
async function detectShadcnSource(cwd) {
|
|
3068
3098
|
const matched = [];
|
|
3069
3099
|
for (const rel2 of SHADCN_FILE_CANDIDATES) {
|
|
3070
|
-
if (await fileExists(
|
|
3100
|
+
if (await fileExists(path17.join(cwd, rel2))) matched.push(rel2);
|
|
3071
3101
|
}
|
|
3072
3102
|
for (const rel2 of SHADCN_DIR_CANDIDATES) {
|
|
3073
|
-
const abs =
|
|
3103
|
+
const abs = path17.join(cwd, rel2);
|
|
3074
3104
|
if (await isDir(abs) && await dirHasContent(abs)) {
|
|
3075
3105
|
matched.push(`${rel2}/`);
|
|
3076
3106
|
}
|
|
3077
3107
|
}
|
|
3078
3108
|
let componentCount = 0;
|
|
3079
3109
|
try {
|
|
3080
|
-
const uiDir =
|
|
3110
|
+
const uiDir = path17.join(cwd, "src/components/ui");
|
|
3081
3111
|
if (await isDir(uiDir)) {
|
|
3082
3112
|
const entries = await fs15.readdir(uiDir);
|
|
3083
3113
|
componentCount = entries.filter(
|
|
@@ -3097,7 +3127,7 @@ async function detectShadcnSource(cwd) {
|
|
|
3097
3127
|
};
|
|
3098
3128
|
}
|
|
3099
3129
|
async function detectConflicts(cwd) {
|
|
3100
|
-
const absCwd =
|
|
3130
|
+
const absCwd = path17.resolve(cwd);
|
|
3101
3131
|
const items = await Promise.all([
|
|
3102
3132
|
detectAgentsMd(absCwd),
|
|
3103
3133
|
detectComponentsJson(absCwd),
|
|
@@ -3118,7 +3148,7 @@ async function detectEslintConfig(cwd) {
|
|
|
3118
3148
|
const matched = [];
|
|
3119
3149
|
const contents = [];
|
|
3120
3150
|
for (const rel2 of ESLINT_CONFIG_CANDIDATES) {
|
|
3121
|
-
const c = await readFileOrNull(
|
|
3151
|
+
const c = await readFileOrNull(path17.join(cwd, rel2));
|
|
3122
3152
|
if (c !== null) {
|
|
3123
3153
|
matched.push(rel2);
|
|
3124
3154
|
contents.push(c);
|
|
@@ -3138,7 +3168,7 @@ async function detectStylelintConfig(cwd) {
|
|
|
3138
3168
|
const matched = [];
|
|
3139
3169
|
const contents = [];
|
|
3140
3170
|
for (const rel2 of STYLELINT_CONFIG_CANDIDATES) {
|
|
3141
|
-
const c = await readFileOrNull(
|
|
3171
|
+
const c = await readFileOrNull(path17.join(cwd, rel2));
|
|
3142
3172
|
if (c !== null) {
|
|
3143
3173
|
matched.push(rel2);
|
|
3144
3174
|
contents.push(c);
|
|
@@ -3156,9 +3186,9 @@ async function detectStylelintConfig(cwd) {
|
|
|
3156
3186
|
}
|
|
3157
3187
|
|
|
3158
3188
|
// src/core/html-theme-patch.ts
|
|
3159
|
-
import * as
|
|
3189
|
+
import * as path18 from "path";
|
|
3160
3190
|
async function patchHtmlDataTheme(projectRoot, variant) {
|
|
3161
|
-
const htmlPath =
|
|
3191
|
+
const htmlPath = path18.join(projectRoot, "index.html");
|
|
3162
3192
|
const content = await readFileOrNull(htmlPath);
|
|
3163
3193
|
if (content === null) {
|
|
3164
3194
|
return { status: "not-found", htmlPath };
|
|
@@ -3178,7 +3208,7 @@ async function patchHtmlDataTheme(projectRoot, variant) {
|
|
|
3178
3208
|
}
|
|
3179
3209
|
|
|
3180
3210
|
// src/core/meta-installer.ts
|
|
3181
|
-
import * as
|
|
3211
|
+
import * as path19 from "path";
|
|
3182
3212
|
import * as fs16 from "fs/promises";
|
|
3183
3213
|
import { createRequire as createRequire5 } from "module";
|
|
3184
3214
|
import {
|
|
@@ -3189,11 +3219,11 @@ var require6 = createRequire5(import.meta.url);
|
|
|
3189
3219
|
var META_DIR = "meta";
|
|
3190
3220
|
function resolvePackageRoot4(packageName) {
|
|
3191
3221
|
const pkgJsonPath = require6.resolve(`${packageName}/package.json`);
|
|
3192
|
-
return
|
|
3222
|
+
return path19.dirname(pkgJsonPath);
|
|
3193
3223
|
}
|
|
3194
3224
|
function getMetaDir(projectRoot, category) {
|
|
3195
|
-
const base =
|
|
3196
|
-
return category ?
|
|
3225
|
+
const base = path19.join(getTeamixDir(projectRoot), META_DIR);
|
|
3226
|
+
return category ? path19.join(base, category) : base;
|
|
3197
3227
|
}
|
|
3198
3228
|
async function landUiMeta(projectRoot) {
|
|
3199
3229
|
const packageRoot = resolvePackageRoot4("@teamix-evo/ui");
|
|
@@ -3207,7 +3237,7 @@ async function landUiMeta(projectRoot) {
|
|
|
3207
3237
|
}
|
|
3208
3238
|
async function landBizUiMeta(projectRoot, variant) {
|
|
3209
3239
|
const packageRoot = resolvePackageRoot4("@teamix-evo/biz-ui");
|
|
3210
|
-
const variantRoot =
|
|
3240
|
+
const variantRoot = path19.join(packageRoot, "variants", variant);
|
|
3211
3241
|
const manifest = await loadVariantUiPackageManifest2(variantRoot);
|
|
3212
3242
|
return landManifestMeta({
|
|
3213
3243
|
projectRoot,
|
|
@@ -3221,8 +3251,8 @@ async function landManifestMeta(opts) {
|
|
|
3221
3251
|
await ensureTeamixDir(projectRoot);
|
|
3222
3252
|
const metaDir = getMetaDir(projectRoot, category);
|
|
3223
3253
|
await ensureDir(metaDir);
|
|
3224
|
-
const manifestDest =
|
|
3225
|
-
const manifestSrc =
|
|
3254
|
+
const manifestDest = path19.join(metaDir, "manifest.json");
|
|
3255
|
+
const manifestSrc = path19.join(packageRoot, "manifest.json");
|
|
3226
3256
|
await fs16.copyFile(manifestSrc, manifestDest);
|
|
3227
3257
|
logger.debug(`meta: copied manifest.json \u2192 ${manifestDest}`);
|
|
3228
3258
|
let written = 0;
|
|
@@ -3230,8 +3260,8 @@ async function landManifestMeta(opts) {
|
|
|
3230
3260
|
for (const entry of manifest.entries) {
|
|
3231
3261
|
if (!entry.meta) continue;
|
|
3232
3262
|
total++;
|
|
3233
|
-
const srcPath =
|
|
3234
|
-
const destPath =
|
|
3263
|
+
const srcPath = path19.join(packageRoot, entry.meta);
|
|
3264
|
+
const destPath = path19.join(metaDir, `${entry.id}.md`);
|
|
3235
3265
|
try {
|
|
3236
3266
|
await fs16.copyFile(srcPath, destPath);
|
|
3237
3267
|
written++;
|
|
@@ -3257,17 +3287,17 @@ async function landManifestMeta(opts) {
|
|
|
3257
3287
|
|
|
3258
3288
|
// src/core/deps-install.ts
|
|
3259
3289
|
import * as fs17 from "fs/promises";
|
|
3260
|
-
import * as
|
|
3290
|
+
import * as path20 from "path";
|
|
3261
3291
|
import { exec } from "child_process";
|
|
3262
3292
|
import { promisify } from "util";
|
|
3263
3293
|
var execAsync = promisify(exec);
|
|
3264
3294
|
async function detectPackageManager(projectRoot) {
|
|
3265
|
-
if (await fileExists(
|
|
3266
|
-
if (await fileExists(
|
|
3295
|
+
if (await fileExists(path20.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
|
|
3296
|
+
if (await fileExists(path20.join(projectRoot, "pnpm-workspace.yaml")))
|
|
3267
3297
|
return "pnpm";
|
|
3268
|
-
if (await fileExists(
|
|
3269
|
-
if (await fileExists(
|
|
3270
|
-
if (await fileExists(
|
|
3298
|
+
if (await fileExists(path20.join(projectRoot, "bun.lockb"))) return "bun";
|
|
3299
|
+
if (await fileExists(path20.join(projectRoot, "bun.lock"))) return "bun";
|
|
3300
|
+
if (await fileExists(path20.join(projectRoot, "yarn.lock"))) return "yarn";
|
|
3271
3301
|
return "npm";
|
|
3272
3302
|
}
|
|
3273
3303
|
function getInstallCommand(pm) {
|
|
@@ -3284,7 +3314,7 @@ function getInstallCommand(pm) {
|
|
|
3284
3314
|
}
|
|
3285
3315
|
async function installProjectDeps(options) {
|
|
3286
3316
|
const { projectRoot, npmDependencies, skipInstall = false } = options;
|
|
3287
|
-
const pkgPath =
|
|
3317
|
+
const pkgPath = path20.join(projectRoot, "package.json");
|
|
3288
3318
|
const raw = await readFileOrNull(pkgPath);
|
|
3289
3319
|
if (!raw) {
|
|
3290
3320
|
throw new Error(
|
|
@@ -3376,18 +3406,18 @@ ${stepLines}
|
|
|
3376
3406
|
|
|
3377
3407
|
// src/core/file-changes.ts
|
|
3378
3408
|
import * as fs18 from "fs/promises";
|
|
3379
|
-
import * as
|
|
3409
|
+
import * as path21 from "path";
|
|
3380
3410
|
function toRelativePosix(p, projectRoot) {
|
|
3381
3411
|
let rel2 = p;
|
|
3382
|
-
if (
|
|
3383
|
-
rel2 =
|
|
3412
|
+
if (path21.isAbsolute(p)) {
|
|
3413
|
+
rel2 = path21.relative(projectRoot, p);
|
|
3384
3414
|
}
|
|
3385
|
-
return rel2.split(
|
|
3415
|
+
return rel2.split(path21.sep).join("/");
|
|
3386
3416
|
}
|
|
3387
3417
|
|
|
3388
3418
|
// src/core/project-init.ts
|
|
3389
3419
|
import * as fsNode from "fs/promises";
|
|
3390
|
-
import * as
|
|
3420
|
+
import * as path22 from "path";
|
|
3391
3421
|
var CRITICAL_STEPS = /* @__PURE__ */ new Set([
|
|
3392
3422
|
"tokens",
|
|
3393
3423
|
"skills",
|
|
@@ -3509,9 +3539,9 @@ async function runProjectInit(options) {
|
|
|
3509
3539
|
name: "skills",
|
|
3510
3540
|
status: "ok",
|
|
3511
3541
|
detail: `${result.skillCount} skills, ${result.fileCount} files (added: ${result.addedSkillIds.join(", ") || "none"})`,
|
|
3512
|
-
changes: result.
|
|
3542
|
+
changes: result.resources.map((resource) => ({
|
|
3513
3543
|
kind: "created",
|
|
3514
|
-
path:
|
|
3544
|
+
path: resource.target,
|
|
3515
3545
|
step: "skills",
|
|
3516
3546
|
detail: "skill installed"
|
|
3517
3547
|
}))
|
|
@@ -3761,7 +3791,7 @@ async function runProjectInit(options) {
|
|
|
3761
3791
|
detail: "projectRoot does not exist"
|
|
3762
3792
|
});
|
|
3763
3793
|
} else {
|
|
3764
|
-
const giPath =
|
|
3794
|
+
const giPath = path22.join(projectRoot, ".gitignore");
|
|
3765
3795
|
let giContent = "";
|
|
3766
3796
|
try {
|
|
3767
3797
|
giContent = await fsNode.readFile(giPath, "utf-8");
|
|
@@ -3821,12 +3851,12 @@ async function runProjectInit(options) {
|
|
|
3821
3851
|
if (!dryRun && hasFailures) {
|
|
3822
3852
|
try {
|
|
3823
3853
|
const checklistContent = renderInitChecklist({ variant, status, steps });
|
|
3824
|
-
const checklistPath =
|
|
3854
|
+
const checklistPath = path22.join(
|
|
3825
3855
|
projectRoot,
|
|
3826
3856
|
".teamix-evo",
|
|
3827
3857
|
"init-checklist.md"
|
|
3828
3858
|
);
|
|
3829
|
-
await fsNode.mkdir(
|
|
3859
|
+
await fsNode.mkdir(path22.dirname(checklistPath), { recursive: true });
|
|
3830
3860
|
await fsNode.writeFile(checklistPath, checklistContent, "utf-8");
|
|
3831
3861
|
logger.info(" wrote .teamix-evo/init-checklist.md");
|
|
3832
3862
|
} catch {
|
|
@@ -3870,7 +3900,7 @@ import { hasManagedRegion as hasManagedRegion3, replaceManagedRegion as replaceM
|
|
|
3870
3900
|
|
|
3871
3901
|
// src/core/snapshot.ts
|
|
3872
3902
|
import * as fs19 from "fs/promises";
|
|
3873
|
-
import * as
|
|
3903
|
+
import * as path23 from "path";
|
|
3874
3904
|
var TEAMIX_DIR2 = ".teamix-evo";
|
|
3875
3905
|
var SNAPSHOTS_DIR = ".snapshots";
|
|
3876
3906
|
var META_FILE = "_meta.json";
|
|
@@ -3886,7 +3916,7 @@ function fsSafeToIso(safe) {
|
|
|
3886
3916
|
);
|
|
3887
3917
|
}
|
|
3888
3918
|
async function createSnapshot(projectRoot, opts = {}) {
|
|
3889
|
-
const teamixDir =
|
|
3919
|
+
const teamixDir = path23.join(projectRoot, TEAMIX_DIR2);
|
|
3890
3920
|
try {
|
|
3891
3921
|
const stat4 = await fs19.stat(teamixDir);
|
|
3892
3922
|
if (!stat4.isDirectory()) return null;
|
|
@@ -3896,14 +3926,14 @@ async function createSnapshot(projectRoot, opts = {}) {
|
|
|
3896
3926
|
}
|
|
3897
3927
|
const isoTs = (/* @__PURE__ */ new Date()).toISOString();
|
|
3898
3928
|
const ts = isoToFsSafe(isoTs);
|
|
3899
|
-
const snapshotRoot =
|
|
3900
|
-
const target =
|
|
3929
|
+
const snapshotRoot = path23.join(teamixDir, SNAPSHOTS_DIR);
|
|
3930
|
+
const target = path23.join(snapshotRoot, ts);
|
|
3901
3931
|
await fs19.mkdir(target, { recursive: true });
|
|
3902
3932
|
const entries = await fs19.readdir(teamixDir, { withFileTypes: true });
|
|
3903
3933
|
for (const entry of entries) {
|
|
3904
3934
|
if (entry.name === SNAPSHOTS_DIR) continue;
|
|
3905
|
-
const src =
|
|
3906
|
-
const dst =
|
|
3935
|
+
const src = path23.join(teamixDir, entry.name);
|
|
3936
|
+
const dst = path23.join(target, entry.name);
|
|
3907
3937
|
await fs19.cp(src, dst, { recursive: true });
|
|
3908
3938
|
}
|
|
3909
3939
|
const meta = {
|
|
@@ -3911,19 +3941,19 @@ async function createSnapshot(projectRoot, opts = {}) {
|
|
|
3911
3941
|
reason: opts.reason ?? "manual"
|
|
3912
3942
|
};
|
|
3913
3943
|
await fs19.writeFile(
|
|
3914
|
-
|
|
3944
|
+
path23.join(target, META_FILE),
|
|
3915
3945
|
JSON.stringify(meta, null, 2) + "\n",
|
|
3916
3946
|
"utf-8"
|
|
3917
3947
|
);
|
|
3918
3948
|
logger.debug(
|
|
3919
|
-
`Snapshot created \u2192 ${
|
|
3949
|
+
`Snapshot created \u2192 ${path23.relative(projectRoot, target)} (${meta.reason})`
|
|
3920
3950
|
);
|
|
3921
3951
|
const keep = opts.keep ?? DEFAULT_KEEP;
|
|
3922
3952
|
await pruneSnapshots(projectRoot, keep, { protectedTs: opts.protectedTs });
|
|
3923
3953
|
return { ts, path: target };
|
|
3924
3954
|
}
|
|
3925
3955
|
async function listSnapshots(projectRoot) {
|
|
3926
|
-
const snapshotRoot =
|
|
3956
|
+
const snapshotRoot = path23.join(projectRoot, TEAMIX_DIR2, SNAPSHOTS_DIR);
|
|
3927
3957
|
let entries;
|
|
3928
3958
|
try {
|
|
3929
3959
|
entries = await fs19.readdir(snapshotRoot, { withFileTypes: true });
|
|
@@ -3934,11 +3964,11 @@ async function listSnapshots(projectRoot) {
|
|
|
3934
3964
|
const result = [];
|
|
3935
3965
|
for (const entry of entries) {
|
|
3936
3966
|
if (!entry.isDirectory()) continue;
|
|
3937
|
-
const dir =
|
|
3967
|
+
const dir = path23.join(snapshotRoot, entry.name);
|
|
3938
3968
|
let isoTs = null;
|
|
3939
3969
|
let reason = null;
|
|
3940
3970
|
try {
|
|
3941
|
-
const raw = await fs19.readFile(
|
|
3971
|
+
const raw = await fs19.readFile(path23.join(dir, META_FILE), "utf-8");
|
|
3942
3972
|
const parsed = JSON.parse(raw);
|
|
3943
3973
|
if (typeof parsed.ts === "string") isoTs = parsed.ts;
|
|
3944
3974
|
if (typeof parsed.reason === "string" && SNAPSHOT_REASONS.includes(
|
|
@@ -3972,7 +4002,7 @@ async function pruneSnapshots(projectRoot, keep = DEFAULT_KEEP, opts = {}) {
|
|
|
3972
4002
|
|
|
3973
4003
|
// src/core/graft-init.ts
|
|
3974
4004
|
import * as fsNode2 from "fs/promises";
|
|
3975
|
-
import * as
|
|
4005
|
+
import * as path24 from "path";
|
|
3976
4006
|
var CRITICAL_STEPS2 = /* @__PURE__ */ new Set([
|
|
3977
4007
|
"ensure-teamix-dir",
|
|
3978
4008
|
"tokens",
|
|
@@ -4011,7 +4041,7 @@ async function runGraftInit(options) {
|
|
|
4011
4041
|
onStep
|
|
4012
4042
|
} = options;
|
|
4013
4043
|
const ide = options.ide ?? "qoder";
|
|
4014
|
-
const ides = options.ides ?? [
|
|
4044
|
+
const ides = options.ides ?? [...ALL_IDE_KINDS];
|
|
4015
4045
|
const scope = options.scope ?? "project";
|
|
4016
4046
|
const steps = [];
|
|
4017
4047
|
let aborted = false;
|
|
@@ -4179,7 +4209,7 @@ async function runGraftInit(options) {
|
|
|
4179
4209
|
}
|
|
4180
4210
|
if (!aborted) {
|
|
4181
4211
|
try {
|
|
4182
|
-
const agentsMdPath =
|
|
4212
|
+
const agentsMdPath = path24.join(projectRoot, "AGENTS.md");
|
|
4183
4213
|
const existing = await readFileOrNull(agentsMdPath) ?? "";
|
|
4184
4214
|
const meta = LEGACY_LIB_META[legacyLib] ?? {
|
|
4185
4215
|
displayName: legacyLib,
|
|
@@ -4240,7 +4270,7 @@ async function runGraftInit(options) {
|
|
|
4240
4270
|
}
|
|
4241
4271
|
if (!aborted) {
|
|
4242
4272
|
try {
|
|
4243
|
-
const giPath =
|
|
4273
|
+
const giPath = path24.join(projectRoot, ".gitignore");
|
|
4244
4274
|
let giContent = "";
|
|
4245
4275
|
try {
|
|
4246
4276
|
giContent = await fsNode2.readFile(giPath, "utf-8");
|
|
@@ -4295,7 +4325,7 @@ ${body}
|
|
|
4295
4325
|
}
|
|
4296
4326
|
|
|
4297
4327
|
// src/core/installer.ts
|
|
4298
|
-
import * as
|
|
4328
|
+
import * as path25 from "path";
|
|
4299
4329
|
import * as fs20 from "fs/promises";
|
|
4300
4330
|
async function installResources(options) {
|
|
4301
4331
|
const { projectRoot, manifest, data, variantDir, packageRoot } = options;
|
|
@@ -4333,7 +4363,7 @@ async function installSingleResource(resource, projectRoot, data, variantDir, pa
|
|
|
4333
4363
|
variantDir,
|
|
4334
4364
|
packageRoot
|
|
4335
4365
|
);
|
|
4336
|
-
const targetPath =
|
|
4366
|
+
const targetPath = path25.join(projectRoot, resource.target);
|
|
4337
4367
|
let content;
|
|
4338
4368
|
if (resource.template) {
|
|
4339
4369
|
const templateContent = await loadTemplateFile(sourcePath);
|
|
@@ -4357,13 +4387,13 @@ async function installRecursiveResource(resource, projectRoot, data, variantDir,
|
|
|
4357
4387
|
variantDir,
|
|
4358
4388
|
packageRoot
|
|
4359
4389
|
);
|
|
4360
|
-
const targetDir =
|
|
4390
|
+
const targetDir = path25.join(projectRoot, resource.target);
|
|
4361
4391
|
const results = [];
|
|
4362
4392
|
await ensureDir(targetDir);
|
|
4363
4393
|
const entries = await walkDir(sourcePath);
|
|
4364
4394
|
for (const entry of entries) {
|
|
4365
|
-
const relPath =
|
|
4366
|
-
let targetFile =
|
|
4395
|
+
const relPath = path25.relative(sourcePath, entry);
|
|
4396
|
+
let targetFile = path25.join(targetDir, relPath);
|
|
4367
4397
|
if (resource.template && targetFile.endsWith(".hbs")) {
|
|
4368
4398
|
targetFile = targetFile.slice(0, -4);
|
|
4369
4399
|
}
|
|
@@ -4376,7 +4406,7 @@ async function installRecursiveResource(resource, projectRoot, data, variantDir,
|
|
|
4376
4406
|
}
|
|
4377
4407
|
await writeFileSafe(targetFile, content);
|
|
4378
4408
|
const hash = computeHash(content);
|
|
4379
|
-
const targetRel =
|
|
4409
|
+
const targetRel = path25.relative(projectRoot, targetFile);
|
|
4380
4410
|
results.push({
|
|
4381
4411
|
id: `${resource.id}:${relPath}`,
|
|
4382
4412
|
target: targetRel,
|
|
@@ -4389,23 +4419,23 @@ async function installRecursiveResource(resource, projectRoot, data, variantDir,
|
|
|
4389
4419
|
}
|
|
4390
4420
|
|
|
4391
4421
|
// src/core/registry-client.ts
|
|
4392
|
-
import * as
|
|
4422
|
+
import * as path26 from "path";
|
|
4393
4423
|
import * as fs21 from "fs/promises";
|
|
4394
4424
|
import { createRequire as createRequire6 } from "module";
|
|
4395
4425
|
import { loadVariantManifest } from "@teamix-evo/registry";
|
|
4396
4426
|
var require7 = createRequire6(import.meta.url);
|
|
4397
4427
|
function resolvePackageRoot5(packageName) {
|
|
4398
4428
|
const pkgJsonPath = require7.resolve(`${packageName}/package.json`);
|
|
4399
|
-
return
|
|
4429
|
+
return path26.dirname(pkgJsonPath);
|
|
4400
4430
|
}
|
|
4401
4431
|
async function loadVariantData(packageName, variant) {
|
|
4402
4432
|
const packageRoot = resolvePackageRoot5(packageName);
|
|
4403
|
-
const variantDir =
|
|
4433
|
+
const variantDir = path26.join(packageRoot, "library", variant);
|
|
4404
4434
|
logger.debug(`Resolved variant dir: ${variantDir}`);
|
|
4405
4435
|
logger.debug(`Package root: ${packageRoot}`);
|
|
4406
4436
|
const manifest = await loadVariantManifest(variantDir);
|
|
4407
4437
|
let data = {};
|
|
4408
|
-
const dataPath =
|
|
4438
|
+
const dataPath = path26.join(variantDir, "_data.json");
|
|
4409
4439
|
try {
|
|
4410
4440
|
const raw = await fs21.readFile(dataPath, "utf-8");
|
|
4411
4441
|
data = JSON.parse(raw);
|