teamix-evo 0.19.2 → 0.20.2
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 +17 -10
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +210 -143
- package/dist/core/index.js.map +1 -1
- package/dist/index.js +408 -220
- 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,10 +2499,19 @@ 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
|
+
function renderEslintConfig(tailwindCssConfigPath) {
|
|
2506
|
+
const tailwindSettings = tailwindCssConfigPath ? `
|
|
2507
|
+
{
|
|
2508
|
+
settings: {
|
|
2509
|
+
tailwindcss: {
|
|
2510
|
+
cssConfigPath: '${tailwindCssConfigPath}',
|
|
2511
|
+
},
|
|
2512
|
+
},
|
|
2513
|
+
},` : "";
|
|
2514
|
+
return `/**
|
|
2478
2515
|
* teamix-evo consumer ESLint preset \u2014 9 token-discipline rules.
|
|
2479
2516
|
* - Repo-wide: no-color-literal / no-arbitrary-tw-value / no-raw-color-scale /
|
|
2480
2517
|
* no-large-radius / prefer-gap-over-space / no-manual-dark-classnames /
|
|
@@ -2485,8 +2522,30 @@ var ESLINT_CONFIG_CONTENT = `/**
|
|
|
2485
2522
|
*/
|
|
2486
2523
|
import consumerPreset from '@teamix-evo/eslint-config/presets/consumer';
|
|
2487
2524
|
|
|
2488
|
-
export default [
|
|
2525
|
+
export default [
|
|
2526
|
+
...consumerPreset,${tailwindSettings}
|
|
2527
|
+
];
|
|
2489
2528
|
`;
|
|
2529
|
+
}
|
|
2530
|
+
var TAILWIND_CSS_CANDIDATES = [
|
|
2531
|
+
"src/index.css",
|
|
2532
|
+
"src/globals.css",
|
|
2533
|
+
"src/app/globals.css",
|
|
2534
|
+
"app/globals.css",
|
|
2535
|
+
"styles/globals.css",
|
|
2536
|
+
"src/styles/tailwind.css"
|
|
2537
|
+
];
|
|
2538
|
+
async function detectTailwindCssConfigPath(projectRoot) {
|
|
2539
|
+
for (const candidate of TAILWIND_CSS_CANDIDATES) {
|
|
2540
|
+
const content = await readFileOrNull(path14.join(projectRoot, candidate));
|
|
2541
|
+
if (content && /@(?:import\s+['"]tailwindcss(?:\/[^'"]*)?['"]|theme\b|tailwind\b)/.test(
|
|
2542
|
+
content
|
|
2543
|
+
)) {
|
|
2544
|
+
return `./${candidate}`;
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
return null;
|
|
2548
|
+
}
|
|
2490
2549
|
var STYLELINT_CONFIG_CONTENT = `/** @type {import('stylelint').Config} */
|
|
2491
2550
|
module.exports = {
|
|
2492
2551
|
extends: ['@teamix-evo/stylelint-config/presets/consumer'],
|
|
@@ -2515,8 +2574,8 @@ async function runLintInit(options) {
|
|
|
2515
2574
|
eslintExistingPaths = [],
|
|
2516
2575
|
stylelintExistingPaths = []
|
|
2517
2576
|
} = options;
|
|
2518
|
-
const eslintConfigPath =
|
|
2519
|
-
const stylelintConfigPath =
|
|
2577
|
+
const eslintConfigPath = path14.join(projectRoot, "eslint.config.js");
|
|
2578
|
+
const stylelintConfigPath = path14.join(projectRoot, "stylelint.config.cjs");
|
|
2520
2579
|
const eslintTemplateExists = await fileExists(eslintConfigPath);
|
|
2521
2580
|
const stylelintTemplateExists = await fileExists(stylelintConfigPath);
|
|
2522
2581
|
const eslintSkipRequested = eslintStrategy === "skip" && eslintExistingPaths.length > 0;
|
|
@@ -2540,18 +2599,24 @@ async function runLintInit(options) {
|
|
|
2540
2599
|
}
|
|
2541
2600
|
if (eslintNeedsWrite && eslintExistingPaths.length > 0) {
|
|
2542
2601
|
for (const rel2 of eslintExistingPaths) {
|
|
2543
|
-
await backupFile(
|
|
2602
|
+
await backupFile(path14.join(projectRoot, rel2), projectRoot);
|
|
2544
2603
|
}
|
|
2545
2604
|
}
|
|
2546
2605
|
if (stylelintNeedsWrite && stylelintExistingPaths.length > 0) {
|
|
2547
2606
|
for (const rel2 of stylelintExistingPaths) {
|
|
2548
|
-
await backupFile(
|
|
2607
|
+
await backupFile(path14.join(projectRoot, rel2), projectRoot);
|
|
2549
2608
|
}
|
|
2550
2609
|
}
|
|
2551
2610
|
let wroteEslint = false;
|
|
2552
2611
|
let wroteStylelint = false;
|
|
2553
2612
|
if (eslintNeedsWrite) {
|
|
2554
|
-
await
|
|
2613
|
+
const tailwindCssConfigPath = await detectTailwindCssConfigPath(
|
|
2614
|
+
projectRoot
|
|
2615
|
+
);
|
|
2616
|
+
await writeFileSafe(
|
|
2617
|
+
eslintConfigPath,
|
|
2618
|
+
renderEslintConfig(tailwindCssConfigPath)
|
|
2619
|
+
);
|
|
2555
2620
|
logger.debug(`Wrote eslint.config.js \u2192 ${eslintConfigPath}`);
|
|
2556
2621
|
wroteEslint = true;
|
|
2557
2622
|
}
|
|
@@ -2601,12 +2666,12 @@ async function runLintInit(options) {
|
|
|
2601
2666
|
};
|
|
2602
2667
|
}
|
|
2603
2668
|
function detectPm(projectRoot) {
|
|
2604
|
-
if (fs12.existsSync(
|
|
2605
|
-
if (fs12.existsSync(
|
|
2669
|
+
if (fs12.existsSync(path14.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
|
|
2670
|
+
if (fs12.existsSync(path14.join(projectRoot, "yarn.lock"))) return "yarn";
|
|
2606
2671
|
return "npm";
|
|
2607
2672
|
}
|
|
2608
2673
|
async function patchPackageJsonScripts(projectRoot) {
|
|
2609
|
-
const pkgPath =
|
|
2674
|
+
const pkgPath = path14.join(projectRoot, "package.json");
|
|
2610
2675
|
const raw = await readFileOrNull(pkgPath);
|
|
2611
2676
|
if (!raw) return false;
|
|
2612
2677
|
let pkg;
|
|
@@ -2636,7 +2701,7 @@ async function patchPackageJsonScripts(projectRoot) {
|
|
|
2636
2701
|
|
|
2637
2702
|
// src/core/init-detect.ts
|
|
2638
2703
|
import * as fs13 from "fs/promises";
|
|
2639
|
-
import * as
|
|
2704
|
+
import * as path15 from "path";
|
|
2640
2705
|
var IGNORED_TOP_LEVEL = /* @__PURE__ */ new Set([
|
|
2641
2706
|
".git",
|
|
2642
2707
|
".gitignore",
|
|
@@ -2648,6 +2713,7 @@ var IGNORED_TOP_LEVEL = /* @__PURE__ */ new Set([
|
|
|
2648
2713
|
".vscode",
|
|
2649
2714
|
".qoder",
|
|
2650
2715
|
".claude",
|
|
2716
|
+
".agents",
|
|
2651
2717
|
"README.md",
|
|
2652
2718
|
"README",
|
|
2653
2719
|
"README.txt",
|
|
@@ -2656,7 +2722,7 @@ var IGNORED_TOP_LEVEL = /* @__PURE__ */ new Set([
|
|
|
2656
2722
|
"LICENSE.txt"
|
|
2657
2723
|
]);
|
|
2658
2724
|
async function detectProjectState(cwd) {
|
|
2659
|
-
const absCwd =
|
|
2725
|
+
const absCwd = path15.resolve(cwd);
|
|
2660
2726
|
const teamixDir = getTeamixDir(absCwd);
|
|
2661
2727
|
const hasTeamixDir = await fileExists(teamixDir);
|
|
2662
2728
|
if (hasTeamixDir) {
|
|
@@ -2664,7 +2730,7 @@ async function detectProjectState(cwd) {
|
|
|
2664
2730
|
state: "teamix-evo-installed",
|
|
2665
2731
|
cwd: absCwd,
|
|
2666
2732
|
hasTeamixDir: true,
|
|
2667
|
-
hasPackageJson: await fileExists(
|
|
2733
|
+
hasPackageJson: await fileExists(path15.join(absCwd, "package.json")),
|
|
2668
2734
|
significantEntries: []
|
|
2669
2735
|
};
|
|
2670
2736
|
}
|
|
@@ -2705,7 +2771,7 @@ async function detectProjectState(cwd) {
|
|
|
2705
2771
|
|
|
2706
2772
|
// src/core/project-state.ts
|
|
2707
2773
|
import * as fs14 from "fs/promises";
|
|
2708
|
-
import * as
|
|
2774
|
+
import * as path16 from "path";
|
|
2709
2775
|
var IGNORED_TOP_LEVEL2 = /* @__PURE__ */ new Set([
|
|
2710
2776
|
".git",
|
|
2711
2777
|
".gitignore",
|
|
@@ -2717,6 +2783,7 @@ var IGNORED_TOP_LEVEL2 = /* @__PURE__ */ new Set([
|
|
|
2717
2783
|
".vscode",
|
|
2718
2784
|
".qoder",
|
|
2719
2785
|
".claude",
|
|
2786
|
+
".agents",
|
|
2720
2787
|
"README.md",
|
|
2721
2788
|
"README",
|
|
2722
2789
|
"README.txt",
|
|
@@ -2736,22 +2803,22 @@ async function isShadcnComponentsJson(filePath) {
|
|
|
2736
2803
|
}
|
|
2737
2804
|
}
|
|
2738
2805
|
async function detectProjectState2(cwd) {
|
|
2739
|
-
const absCwd =
|
|
2806
|
+
const absCwd = path16.resolve(cwd);
|
|
2740
2807
|
const teamixDir = getTeamixDir(absCwd);
|
|
2741
2808
|
const hasTeamixDir = await fileExists(teamixDir);
|
|
2742
|
-
const hasTeamixConfig = hasTeamixDir && await fileExists(
|
|
2809
|
+
const hasTeamixConfig = hasTeamixDir && await fileExists(path16.join(teamixDir, "config.json"));
|
|
2743
2810
|
if (hasTeamixDir && hasTeamixConfig) {
|
|
2744
2811
|
return {
|
|
2745
2812
|
state: "teamix-evo",
|
|
2746
2813
|
cwd: absCwd,
|
|
2747
2814
|
hasTeamixDir: true,
|
|
2748
|
-
hasPackageJson: await fileExists(
|
|
2815
|
+
hasPackageJson: await fileExists(path16.join(absCwd, "package.json")),
|
|
2749
2816
|
hasComponentsJson: false,
|
|
2750
2817
|
significantEntries: []
|
|
2751
2818
|
};
|
|
2752
2819
|
}
|
|
2753
|
-
const componentsJsonPath =
|
|
2754
|
-
const hasPackageJson = await fileExists(
|
|
2820
|
+
const componentsJsonPath = path16.join(absCwd, "components.json");
|
|
2821
|
+
const hasPackageJson = await fileExists(path16.join(absCwd, "package.json"));
|
|
2755
2822
|
const hasComponentsJson = await isShadcnComponentsJson(componentsJsonPath);
|
|
2756
2823
|
if (hasPackageJson && hasComponentsJson) {
|
|
2757
2824
|
return {
|
|
@@ -2794,7 +2861,7 @@ async function detectProjectState2(cwd) {
|
|
|
2794
2861
|
let buildTool = "unknown";
|
|
2795
2862
|
let allDeps = {};
|
|
2796
2863
|
if (hasPackageJson) {
|
|
2797
|
-
const pkgRaw = await readFileOrNull(
|
|
2864
|
+
const pkgRaw = await readFileOrNull(path16.join(absCwd, "package.json"));
|
|
2798
2865
|
if (pkgRaw) {
|
|
2799
2866
|
try {
|
|
2800
2867
|
const pkg = JSON.parse(pkgRaw);
|
|
@@ -2810,11 +2877,11 @@ async function detectProjectState2(cwd) {
|
|
|
2810
2877
|
} else if ("element-ui" in allDeps || "element-plus" in allDeps) {
|
|
2811
2878
|
legacyLib = "element";
|
|
2812
2879
|
}
|
|
2813
|
-
if (await fileExists(
|
|
2880
|
+
if (await fileExists(path16.join(absCwd, "build.json"))) {
|
|
2814
2881
|
buildTool = "ice";
|
|
2815
|
-
} else if (await fileExists(
|
|
2882
|
+
} 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
2883
|
buildTool = "vite";
|
|
2817
|
-
} else if (await fileExists(
|
|
2884
|
+
} else if (await fileExists(path16.join(absCwd, "webpack.config.js")) || await fileExists(path16.join(absCwd, "webpack.config.ts"))) {
|
|
2818
2885
|
buildTool = "webpack";
|
|
2819
2886
|
} else if ("umi" in allDeps || "@umijs/max" in allDeps) {
|
|
2820
2887
|
buildTool = "umi";
|
|
@@ -2886,7 +2953,7 @@ function assertCommandPrecondition(command, state, options) {
|
|
|
2886
2953
|
// src/core/init-conflicts.ts
|
|
2887
2954
|
import * as crypto from "crypto";
|
|
2888
2955
|
import * as fs15 from "fs/promises";
|
|
2889
|
-
import * as
|
|
2956
|
+
import * as path17 from "path";
|
|
2890
2957
|
var TAILWIND_CONFIG_CANDIDATES = [
|
|
2891
2958
|
"tailwind.config.ts",
|
|
2892
2959
|
"tailwind.config.js",
|
|
@@ -2950,7 +3017,7 @@ function fingerprint(parts) {
|
|
|
2950
3017
|
return `sha256:${hash.digest("hex").slice(0, 16)}`;
|
|
2951
3018
|
}
|
|
2952
3019
|
async function readPackageJson(cwd) {
|
|
2953
|
-
const raw = await readFileOrNull(
|
|
3020
|
+
const raw = await readFileOrNull(path17.join(cwd, "package.json"));
|
|
2954
3021
|
if (raw === null) return null;
|
|
2955
3022
|
try {
|
|
2956
3023
|
return JSON.parse(raw);
|
|
@@ -2970,7 +3037,7 @@ function detectTailwindMajor(pkg) {
|
|
|
2970
3037
|
return null;
|
|
2971
3038
|
}
|
|
2972
3039
|
async function detectAgentsMd(cwd) {
|
|
2973
|
-
const target =
|
|
3040
|
+
const target = path17.join(cwd, "AGENTS.md");
|
|
2974
3041
|
const content = await readFileOrNull(target);
|
|
2975
3042
|
const exists = content !== null;
|
|
2976
3043
|
return {
|
|
@@ -2983,7 +3050,7 @@ async function detectAgentsMd(cwd) {
|
|
|
2983
3050
|
};
|
|
2984
3051
|
}
|
|
2985
3052
|
async function detectComponentsJson(cwd) {
|
|
2986
|
-
const target =
|
|
3053
|
+
const target = path17.join(cwd, "components.json");
|
|
2987
3054
|
const content = await readFileOrNull(target);
|
|
2988
3055
|
const exists = content !== null;
|
|
2989
3056
|
return {
|
|
@@ -2999,7 +3066,7 @@ async function detectTailwindConfig(cwd) {
|
|
|
2999
3066
|
const matched = [];
|
|
3000
3067
|
const contents = [];
|
|
3001
3068
|
for (const rel2 of TAILWIND_CONFIG_CANDIDATES) {
|
|
3002
|
-
const c = await readFileOrNull(
|
|
3069
|
+
const c = await readFileOrNull(path17.join(cwd, rel2));
|
|
3003
3070
|
if (c !== null) {
|
|
3004
3071
|
matched.push(rel2);
|
|
3005
3072
|
contents.push(c);
|
|
@@ -3022,14 +3089,14 @@ async function detectTokens(cwd) {
|
|
|
3022
3089
|
const matched = [];
|
|
3023
3090
|
const contents = [];
|
|
3024
3091
|
for (const rel2 of TOKENS_FILE_CANDIDATES) {
|
|
3025
|
-
const c = await readFileOrNull(
|
|
3092
|
+
const c = await readFileOrNull(path17.join(cwd, rel2));
|
|
3026
3093
|
if (c !== null) {
|
|
3027
3094
|
matched.push(rel2);
|
|
3028
3095
|
contents.push(c);
|
|
3029
3096
|
}
|
|
3030
3097
|
}
|
|
3031
3098
|
for (const rel2 of TOKENS_DIR_CANDIDATES) {
|
|
3032
|
-
const abs =
|
|
3099
|
+
const abs = path17.join(cwd, rel2);
|
|
3033
3100
|
if (await isDir(abs) && await dirHasContent(abs)) {
|
|
3034
3101
|
matched.push(`${rel2}/`);
|
|
3035
3102
|
}
|
|
@@ -3048,7 +3115,7 @@ async function detectIndexCss(cwd) {
|
|
|
3048
3115
|
const matched = [];
|
|
3049
3116
|
const contents = [];
|
|
3050
3117
|
for (const rel2 of INDEX_CSS_CANDIDATES) {
|
|
3051
|
-
const c = await readFileOrNull(
|
|
3118
|
+
const c = await readFileOrNull(path17.join(cwd, rel2));
|
|
3052
3119
|
if (c !== null) {
|
|
3053
3120
|
matched.push(rel2);
|
|
3054
3121
|
contents.push(c);
|
|
@@ -3067,17 +3134,17 @@ async function detectIndexCss(cwd) {
|
|
|
3067
3134
|
async function detectShadcnSource(cwd) {
|
|
3068
3135
|
const matched = [];
|
|
3069
3136
|
for (const rel2 of SHADCN_FILE_CANDIDATES) {
|
|
3070
|
-
if (await fileExists(
|
|
3137
|
+
if (await fileExists(path17.join(cwd, rel2))) matched.push(rel2);
|
|
3071
3138
|
}
|
|
3072
3139
|
for (const rel2 of SHADCN_DIR_CANDIDATES) {
|
|
3073
|
-
const abs =
|
|
3140
|
+
const abs = path17.join(cwd, rel2);
|
|
3074
3141
|
if (await isDir(abs) && await dirHasContent(abs)) {
|
|
3075
3142
|
matched.push(`${rel2}/`);
|
|
3076
3143
|
}
|
|
3077
3144
|
}
|
|
3078
3145
|
let componentCount = 0;
|
|
3079
3146
|
try {
|
|
3080
|
-
const uiDir =
|
|
3147
|
+
const uiDir = path17.join(cwd, "src/components/ui");
|
|
3081
3148
|
if (await isDir(uiDir)) {
|
|
3082
3149
|
const entries = await fs15.readdir(uiDir);
|
|
3083
3150
|
componentCount = entries.filter(
|
|
@@ -3097,7 +3164,7 @@ async function detectShadcnSource(cwd) {
|
|
|
3097
3164
|
};
|
|
3098
3165
|
}
|
|
3099
3166
|
async function detectConflicts(cwd) {
|
|
3100
|
-
const absCwd =
|
|
3167
|
+
const absCwd = path17.resolve(cwd);
|
|
3101
3168
|
const items = await Promise.all([
|
|
3102
3169
|
detectAgentsMd(absCwd),
|
|
3103
3170
|
detectComponentsJson(absCwd),
|
|
@@ -3118,7 +3185,7 @@ async function detectEslintConfig(cwd) {
|
|
|
3118
3185
|
const matched = [];
|
|
3119
3186
|
const contents = [];
|
|
3120
3187
|
for (const rel2 of ESLINT_CONFIG_CANDIDATES) {
|
|
3121
|
-
const c = await readFileOrNull(
|
|
3188
|
+
const c = await readFileOrNull(path17.join(cwd, rel2));
|
|
3122
3189
|
if (c !== null) {
|
|
3123
3190
|
matched.push(rel2);
|
|
3124
3191
|
contents.push(c);
|
|
@@ -3138,7 +3205,7 @@ async function detectStylelintConfig(cwd) {
|
|
|
3138
3205
|
const matched = [];
|
|
3139
3206
|
const contents = [];
|
|
3140
3207
|
for (const rel2 of STYLELINT_CONFIG_CANDIDATES) {
|
|
3141
|
-
const c = await readFileOrNull(
|
|
3208
|
+
const c = await readFileOrNull(path17.join(cwd, rel2));
|
|
3142
3209
|
if (c !== null) {
|
|
3143
3210
|
matched.push(rel2);
|
|
3144
3211
|
contents.push(c);
|
|
@@ -3156,9 +3223,9 @@ async function detectStylelintConfig(cwd) {
|
|
|
3156
3223
|
}
|
|
3157
3224
|
|
|
3158
3225
|
// src/core/html-theme-patch.ts
|
|
3159
|
-
import * as
|
|
3226
|
+
import * as path18 from "path";
|
|
3160
3227
|
async function patchHtmlDataTheme(projectRoot, variant) {
|
|
3161
|
-
const htmlPath =
|
|
3228
|
+
const htmlPath = path18.join(projectRoot, "index.html");
|
|
3162
3229
|
const content = await readFileOrNull(htmlPath);
|
|
3163
3230
|
if (content === null) {
|
|
3164
3231
|
return { status: "not-found", htmlPath };
|
|
@@ -3178,7 +3245,7 @@ async function patchHtmlDataTheme(projectRoot, variant) {
|
|
|
3178
3245
|
}
|
|
3179
3246
|
|
|
3180
3247
|
// src/core/meta-installer.ts
|
|
3181
|
-
import * as
|
|
3248
|
+
import * as path19 from "path";
|
|
3182
3249
|
import * as fs16 from "fs/promises";
|
|
3183
3250
|
import { createRequire as createRequire5 } from "module";
|
|
3184
3251
|
import {
|
|
@@ -3189,11 +3256,11 @@ var require6 = createRequire5(import.meta.url);
|
|
|
3189
3256
|
var META_DIR = "meta";
|
|
3190
3257
|
function resolvePackageRoot4(packageName) {
|
|
3191
3258
|
const pkgJsonPath = require6.resolve(`${packageName}/package.json`);
|
|
3192
|
-
return
|
|
3259
|
+
return path19.dirname(pkgJsonPath);
|
|
3193
3260
|
}
|
|
3194
3261
|
function getMetaDir(projectRoot, category) {
|
|
3195
|
-
const base =
|
|
3196
|
-
return category ?
|
|
3262
|
+
const base = path19.join(getTeamixDir(projectRoot), META_DIR);
|
|
3263
|
+
return category ? path19.join(base, category) : base;
|
|
3197
3264
|
}
|
|
3198
3265
|
async function landUiMeta(projectRoot) {
|
|
3199
3266
|
const packageRoot = resolvePackageRoot4("@teamix-evo/ui");
|
|
@@ -3207,7 +3274,7 @@ async function landUiMeta(projectRoot) {
|
|
|
3207
3274
|
}
|
|
3208
3275
|
async function landBizUiMeta(projectRoot, variant) {
|
|
3209
3276
|
const packageRoot = resolvePackageRoot4("@teamix-evo/biz-ui");
|
|
3210
|
-
const variantRoot =
|
|
3277
|
+
const variantRoot = path19.join(packageRoot, "variants", variant);
|
|
3211
3278
|
const manifest = await loadVariantUiPackageManifest2(variantRoot);
|
|
3212
3279
|
return landManifestMeta({
|
|
3213
3280
|
projectRoot,
|
|
@@ -3221,8 +3288,8 @@ async function landManifestMeta(opts) {
|
|
|
3221
3288
|
await ensureTeamixDir(projectRoot);
|
|
3222
3289
|
const metaDir = getMetaDir(projectRoot, category);
|
|
3223
3290
|
await ensureDir(metaDir);
|
|
3224
|
-
const manifestDest =
|
|
3225
|
-
const manifestSrc =
|
|
3291
|
+
const manifestDest = path19.join(metaDir, "manifest.json");
|
|
3292
|
+
const manifestSrc = path19.join(packageRoot, "manifest.json");
|
|
3226
3293
|
await fs16.copyFile(manifestSrc, manifestDest);
|
|
3227
3294
|
logger.debug(`meta: copied manifest.json \u2192 ${manifestDest}`);
|
|
3228
3295
|
let written = 0;
|
|
@@ -3230,8 +3297,8 @@ async function landManifestMeta(opts) {
|
|
|
3230
3297
|
for (const entry of manifest.entries) {
|
|
3231
3298
|
if (!entry.meta) continue;
|
|
3232
3299
|
total++;
|
|
3233
|
-
const srcPath =
|
|
3234
|
-
const destPath =
|
|
3300
|
+
const srcPath = path19.join(packageRoot, entry.meta);
|
|
3301
|
+
const destPath = path19.join(metaDir, `${entry.id}.md`);
|
|
3235
3302
|
try {
|
|
3236
3303
|
await fs16.copyFile(srcPath, destPath);
|
|
3237
3304
|
written++;
|
|
@@ -3257,17 +3324,17 @@ async function landManifestMeta(opts) {
|
|
|
3257
3324
|
|
|
3258
3325
|
// src/core/deps-install.ts
|
|
3259
3326
|
import * as fs17 from "fs/promises";
|
|
3260
|
-
import * as
|
|
3327
|
+
import * as path20 from "path";
|
|
3261
3328
|
import { exec } from "child_process";
|
|
3262
3329
|
import { promisify } from "util";
|
|
3263
3330
|
var execAsync = promisify(exec);
|
|
3264
3331
|
async function detectPackageManager(projectRoot) {
|
|
3265
|
-
if (await fileExists(
|
|
3266
|
-
if (await fileExists(
|
|
3332
|
+
if (await fileExists(path20.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
|
|
3333
|
+
if (await fileExists(path20.join(projectRoot, "pnpm-workspace.yaml")))
|
|
3267
3334
|
return "pnpm";
|
|
3268
|
-
if (await fileExists(
|
|
3269
|
-
if (await fileExists(
|
|
3270
|
-
if (await fileExists(
|
|
3335
|
+
if (await fileExists(path20.join(projectRoot, "bun.lockb"))) return "bun";
|
|
3336
|
+
if (await fileExists(path20.join(projectRoot, "bun.lock"))) return "bun";
|
|
3337
|
+
if (await fileExists(path20.join(projectRoot, "yarn.lock"))) return "yarn";
|
|
3271
3338
|
return "npm";
|
|
3272
3339
|
}
|
|
3273
3340
|
function getInstallCommand(pm) {
|
|
@@ -3284,7 +3351,7 @@ function getInstallCommand(pm) {
|
|
|
3284
3351
|
}
|
|
3285
3352
|
async function installProjectDeps(options) {
|
|
3286
3353
|
const { projectRoot, npmDependencies, skipInstall = false } = options;
|
|
3287
|
-
const pkgPath =
|
|
3354
|
+
const pkgPath = path20.join(projectRoot, "package.json");
|
|
3288
3355
|
const raw = await readFileOrNull(pkgPath);
|
|
3289
3356
|
if (!raw) {
|
|
3290
3357
|
throw new Error(
|
|
@@ -3376,18 +3443,18 @@ ${stepLines}
|
|
|
3376
3443
|
|
|
3377
3444
|
// src/core/file-changes.ts
|
|
3378
3445
|
import * as fs18 from "fs/promises";
|
|
3379
|
-
import * as
|
|
3446
|
+
import * as path21 from "path";
|
|
3380
3447
|
function toRelativePosix(p, projectRoot) {
|
|
3381
3448
|
let rel2 = p;
|
|
3382
|
-
if (
|
|
3383
|
-
rel2 =
|
|
3449
|
+
if (path21.isAbsolute(p)) {
|
|
3450
|
+
rel2 = path21.relative(projectRoot, p);
|
|
3384
3451
|
}
|
|
3385
|
-
return rel2.split(
|
|
3452
|
+
return rel2.split(path21.sep).join("/");
|
|
3386
3453
|
}
|
|
3387
3454
|
|
|
3388
3455
|
// src/core/project-init.ts
|
|
3389
3456
|
import * as fsNode from "fs/promises";
|
|
3390
|
-
import * as
|
|
3457
|
+
import * as path22 from "path";
|
|
3391
3458
|
var CRITICAL_STEPS = /* @__PURE__ */ new Set([
|
|
3392
3459
|
"tokens",
|
|
3393
3460
|
"skills",
|
|
@@ -3509,9 +3576,9 @@ async function runProjectInit(options) {
|
|
|
3509
3576
|
name: "skills",
|
|
3510
3577
|
status: "ok",
|
|
3511
3578
|
detail: `${result.skillCount} skills, ${result.fileCount} files (added: ${result.addedSkillIds.join(", ") || "none"})`,
|
|
3512
|
-
changes: result.
|
|
3579
|
+
changes: result.resources.map((resource) => ({
|
|
3513
3580
|
kind: "created",
|
|
3514
|
-
path:
|
|
3581
|
+
path: resource.target,
|
|
3515
3582
|
step: "skills",
|
|
3516
3583
|
detail: "skill installed"
|
|
3517
3584
|
}))
|
|
@@ -3761,7 +3828,7 @@ async function runProjectInit(options) {
|
|
|
3761
3828
|
detail: "projectRoot does not exist"
|
|
3762
3829
|
});
|
|
3763
3830
|
} else {
|
|
3764
|
-
const giPath =
|
|
3831
|
+
const giPath = path22.join(projectRoot, ".gitignore");
|
|
3765
3832
|
let giContent = "";
|
|
3766
3833
|
try {
|
|
3767
3834
|
giContent = await fsNode.readFile(giPath, "utf-8");
|
|
@@ -3821,12 +3888,12 @@ async function runProjectInit(options) {
|
|
|
3821
3888
|
if (!dryRun && hasFailures) {
|
|
3822
3889
|
try {
|
|
3823
3890
|
const checklistContent = renderInitChecklist({ variant, status, steps });
|
|
3824
|
-
const checklistPath =
|
|
3891
|
+
const checklistPath = path22.join(
|
|
3825
3892
|
projectRoot,
|
|
3826
3893
|
".teamix-evo",
|
|
3827
3894
|
"init-checklist.md"
|
|
3828
3895
|
);
|
|
3829
|
-
await fsNode.mkdir(
|
|
3896
|
+
await fsNode.mkdir(path22.dirname(checklistPath), { recursive: true });
|
|
3830
3897
|
await fsNode.writeFile(checklistPath, checklistContent, "utf-8");
|
|
3831
3898
|
logger.info(" wrote .teamix-evo/init-checklist.md");
|
|
3832
3899
|
} catch {
|
|
@@ -3870,7 +3937,7 @@ import { hasManagedRegion as hasManagedRegion3, replaceManagedRegion as replaceM
|
|
|
3870
3937
|
|
|
3871
3938
|
// src/core/snapshot.ts
|
|
3872
3939
|
import * as fs19 from "fs/promises";
|
|
3873
|
-
import * as
|
|
3940
|
+
import * as path23 from "path";
|
|
3874
3941
|
var TEAMIX_DIR2 = ".teamix-evo";
|
|
3875
3942
|
var SNAPSHOTS_DIR = ".snapshots";
|
|
3876
3943
|
var META_FILE = "_meta.json";
|
|
@@ -3886,7 +3953,7 @@ function fsSafeToIso(safe) {
|
|
|
3886
3953
|
);
|
|
3887
3954
|
}
|
|
3888
3955
|
async function createSnapshot(projectRoot, opts = {}) {
|
|
3889
|
-
const teamixDir =
|
|
3956
|
+
const teamixDir = path23.join(projectRoot, TEAMIX_DIR2);
|
|
3890
3957
|
try {
|
|
3891
3958
|
const stat4 = await fs19.stat(teamixDir);
|
|
3892
3959
|
if (!stat4.isDirectory()) return null;
|
|
@@ -3896,14 +3963,14 @@ async function createSnapshot(projectRoot, opts = {}) {
|
|
|
3896
3963
|
}
|
|
3897
3964
|
const isoTs = (/* @__PURE__ */ new Date()).toISOString();
|
|
3898
3965
|
const ts = isoToFsSafe(isoTs);
|
|
3899
|
-
const snapshotRoot =
|
|
3900
|
-
const target =
|
|
3966
|
+
const snapshotRoot = path23.join(teamixDir, SNAPSHOTS_DIR);
|
|
3967
|
+
const target = path23.join(snapshotRoot, ts);
|
|
3901
3968
|
await fs19.mkdir(target, { recursive: true });
|
|
3902
3969
|
const entries = await fs19.readdir(teamixDir, { withFileTypes: true });
|
|
3903
3970
|
for (const entry of entries) {
|
|
3904
3971
|
if (entry.name === SNAPSHOTS_DIR) continue;
|
|
3905
|
-
const src =
|
|
3906
|
-
const dst =
|
|
3972
|
+
const src = path23.join(teamixDir, entry.name);
|
|
3973
|
+
const dst = path23.join(target, entry.name);
|
|
3907
3974
|
await fs19.cp(src, dst, { recursive: true });
|
|
3908
3975
|
}
|
|
3909
3976
|
const meta = {
|
|
@@ -3911,19 +3978,19 @@ async function createSnapshot(projectRoot, opts = {}) {
|
|
|
3911
3978
|
reason: opts.reason ?? "manual"
|
|
3912
3979
|
};
|
|
3913
3980
|
await fs19.writeFile(
|
|
3914
|
-
|
|
3981
|
+
path23.join(target, META_FILE),
|
|
3915
3982
|
JSON.stringify(meta, null, 2) + "\n",
|
|
3916
3983
|
"utf-8"
|
|
3917
3984
|
);
|
|
3918
3985
|
logger.debug(
|
|
3919
|
-
`Snapshot created \u2192 ${
|
|
3986
|
+
`Snapshot created \u2192 ${path23.relative(projectRoot, target)} (${meta.reason})`
|
|
3920
3987
|
);
|
|
3921
3988
|
const keep = opts.keep ?? DEFAULT_KEEP;
|
|
3922
3989
|
await pruneSnapshots(projectRoot, keep, { protectedTs: opts.protectedTs });
|
|
3923
3990
|
return { ts, path: target };
|
|
3924
3991
|
}
|
|
3925
3992
|
async function listSnapshots(projectRoot) {
|
|
3926
|
-
const snapshotRoot =
|
|
3993
|
+
const snapshotRoot = path23.join(projectRoot, TEAMIX_DIR2, SNAPSHOTS_DIR);
|
|
3927
3994
|
let entries;
|
|
3928
3995
|
try {
|
|
3929
3996
|
entries = await fs19.readdir(snapshotRoot, { withFileTypes: true });
|
|
@@ -3934,11 +4001,11 @@ async function listSnapshots(projectRoot) {
|
|
|
3934
4001
|
const result = [];
|
|
3935
4002
|
for (const entry of entries) {
|
|
3936
4003
|
if (!entry.isDirectory()) continue;
|
|
3937
|
-
const dir =
|
|
4004
|
+
const dir = path23.join(snapshotRoot, entry.name);
|
|
3938
4005
|
let isoTs = null;
|
|
3939
4006
|
let reason = null;
|
|
3940
4007
|
try {
|
|
3941
|
-
const raw = await fs19.readFile(
|
|
4008
|
+
const raw = await fs19.readFile(path23.join(dir, META_FILE), "utf-8");
|
|
3942
4009
|
const parsed = JSON.parse(raw);
|
|
3943
4010
|
if (typeof parsed.ts === "string") isoTs = parsed.ts;
|
|
3944
4011
|
if (typeof parsed.reason === "string" && SNAPSHOT_REASONS.includes(
|
|
@@ -3972,7 +4039,7 @@ async function pruneSnapshots(projectRoot, keep = DEFAULT_KEEP, opts = {}) {
|
|
|
3972
4039
|
|
|
3973
4040
|
// src/core/graft-init.ts
|
|
3974
4041
|
import * as fsNode2 from "fs/promises";
|
|
3975
|
-
import * as
|
|
4042
|
+
import * as path24 from "path";
|
|
3976
4043
|
var CRITICAL_STEPS2 = /* @__PURE__ */ new Set([
|
|
3977
4044
|
"ensure-teamix-dir",
|
|
3978
4045
|
"tokens",
|
|
@@ -4011,7 +4078,7 @@ async function runGraftInit(options) {
|
|
|
4011
4078
|
onStep
|
|
4012
4079
|
} = options;
|
|
4013
4080
|
const ide = options.ide ?? "qoder";
|
|
4014
|
-
const ides = options.ides ?? [
|
|
4081
|
+
const ides = options.ides ?? [...ALL_IDE_KINDS];
|
|
4015
4082
|
const scope = options.scope ?? "project";
|
|
4016
4083
|
const steps = [];
|
|
4017
4084
|
let aborted = false;
|
|
@@ -4179,7 +4246,7 @@ async function runGraftInit(options) {
|
|
|
4179
4246
|
}
|
|
4180
4247
|
if (!aborted) {
|
|
4181
4248
|
try {
|
|
4182
|
-
const agentsMdPath =
|
|
4249
|
+
const agentsMdPath = path24.join(projectRoot, "AGENTS.md");
|
|
4183
4250
|
const existing = await readFileOrNull(agentsMdPath) ?? "";
|
|
4184
4251
|
const meta = LEGACY_LIB_META[legacyLib] ?? {
|
|
4185
4252
|
displayName: legacyLib,
|
|
@@ -4240,7 +4307,7 @@ async function runGraftInit(options) {
|
|
|
4240
4307
|
}
|
|
4241
4308
|
if (!aborted) {
|
|
4242
4309
|
try {
|
|
4243
|
-
const giPath =
|
|
4310
|
+
const giPath = path24.join(projectRoot, ".gitignore");
|
|
4244
4311
|
let giContent = "";
|
|
4245
4312
|
try {
|
|
4246
4313
|
giContent = await fsNode2.readFile(giPath, "utf-8");
|
|
@@ -4295,7 +4362,7 @@ ${body}
|
|
|
4295
4362
|
}
|
|
4296
4363
|
|
|
4297
4364
|
// src/core/installer.ts
|
|
4298
|
-
import * as
|
|
4365
|
+
import * as path25 from "path";
|
|
4299
4366
|
import * as fs20 from "fs/promises";
|
|
4300
4367
|
async function installResources(options) {
|
|
4301
4368
|
const { projectRoot, manifest, data, variantDir, packageRoot } = options;
|
|
@@ -4333,7 +4400,7 @@ async function installSingleResource(resource, projectRoot, data, variantDir, pa
|
|
|
4333
4400
|
variantDir,
|
|
4334
4401
|
packageRoot
|
|
4335
4402
|
);
|
|
4336
|
-
const targetPath =
|
|
4403
|
+
const targetPath = path25.join(projectRoot, resource.target);
|
|
4337
4404
|
let content;
|
|
4338
4405
|
if (resource.template) {
|
|
4339
4406
|
const templateContent = await loadTemplateFile(sourcePath);
|
|
@@ -4357,13 +4424,13 @@ async function installRecursiveResource(resource, projectRoot, data, variantDir,
|
|
|
4357
4424
|
variantDir,
|
|
4358
4425
|
packageRoot
|
|
4359
4426
|
);
|
|
4360
|
-
const targetDir =
|
|
4427
|
+
const targetDir = path25.join(projectRoot, resource.target);
|
|
4361
4428
|
const results = [];
|
|
4362
4429
|
await ensureDir(targetDir);
|
|
4363
4430
|
const entries = await walkDir(sourcePath);
|
|
4364
4431
|
for (const entry of entries) {
|
|
4365
|
-
const relPath =
|
|
4366
|
-
let targetFile =
|
|
4432
|
+
const relPath = path25.relative(sourcePath, entry);
|
|
4433
|
+
let targetFile = path25.join(targetDir, relPath);
|
|
4367
4434
|
if (resource.template && targetFile.endsWith(".hbs")) {
|
|
4368
4435
|
targetFile = targetFile.slice(0, -4);
|
|
4369
4436
|
}
|
|
@@ -4376,7 +4443,7 @@ async function installRecursiveResource(resource, projectRoot, data, variantDir,
|
|
|
4376
4443
|
}
|
|
4377
4444
|
await writeFileSafe(targetFile, content);
|
|
4378
4445
|
const hash = computeHash(content);
|
|
4379
|
-
const targetRel =
|
|
4446
|
+
const targetRel = path25.relative(projectRoot, targetFile);
|
|
4380
4447
|
results.push({
|
|
4381
4448
|
id: `${resource.id}:${relPath}`,
|
|
4382
4449
|
target: targetRel,
|
|
@@ -4389,23 +4456,23 @@ async function installRecursiveResource(resource, projectRoot, data, variantDir,
|
|
|
4389
4456
|
}
|
|
4390
4457
|
|
|
4391
4458
|
// src/core/registry-client.ts
|
|
4392
|
-
import * as
|
|
4459
|
+
import * as path26 from "path";
|
|
4393
4460
|
import * as fs21 from "fs/promises";
|
|
4394
4461
|
import { createRequire as createRequire6 } from "module";
|
|
4395
4462
|
import { loadVariantManifest } from "@teamix-evo/registry";
|
|
4396
4463
|
var require7 = createRequire6(import.meta.url);
|
|
4397
4464
|
function resolvePackageRoot5(packageName) {
|
|
4398
4465
|
const pkgJsonPath = require7.resolve(`${packageName}/package.json`);
|
|
4399
|
-
return
|
|
4466
|
+
return path26.dirname(pkgJsonPath);
|
|
4400
4467
|
}
|
|
4401
4468
|
async function loadVariantData(packageName, variant) {
|
|
4402
4469
|
const packageRoot = resolvePackageRoot5(packageName);
|
|
4403
|
-
const variantDir =
|
|
4470
|
+
const variantDir = path26.join(packageRoot, "library", variant);
|
|
4404
4471
|
logger.debug(`Resolved variant dir: ${variantDir}`);
|
|
4405
4472
|
logger.debug(`Package root: ${packageRoot}`);
|
|
4406
4473
|
const manifest = await loadVariantManifest(variantDir);
|
|
4407
4474
|
let data = {};
|
|
4408
|
-
const dataPath =
|
|
4475
|
+
const dataPath = path26.join(variantDir, "_data.json");
|
|
4409
4476
|
try {
|
|
4410
4477
|
const raw = await fs21.readFile(dataPath, "utf-8");
|
|
4411
4478
|
data = JSON.parse(raw);
|