teamix-evo 0.14.1 → 0.14.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/dist/index.js CHANGED
@@ -3911,18 +3911,24 @@ init_state();
3911
3911
  var AGENTS_MD_MANAGED_ID = "teamix-evo-skills";
3912
3912
  async function runGenerateAgentsMd(options) {
3913
3913
  const { projectRoot, variant, skillIds } = options;
3914
+ const globalSkillIds = options.globalSkillIds ?? [];
3914
3915
  const mode = options.mode ?? "overwrite";
3915
3916
  const config = await readProjectConfig(projectRoot);
3916
3917
  const lock = await readSkillsLock(projectRoot);
3917
3918
  const ides = config?.packages?.skills?.ides ?? ["qoder", "claude"];
3918
3919
  const scope = config?.packages?.skills?.scope ?? lock?.skills[skillIds[0] ?? ""]?.scope ?? "project";
3919
- const ordered = [...skillIds].sort(
3920
+ const skillScopeMap = /* @__PURE__ */ new Map();
3921
+ for (const id of skillIds) skillScopeMap.set(id, scope);
3922
+ for (const id of globalSkillIds) skillScopeMap.set(id, "global");
3923
+ const allSkillIds = [...skillIds, ...globalSkillIds];
3924
+ const ordered = allSkillIds.sort(
3920
3925
  (a, b) => bucketRank(a) - bucketRank(b) || a.localeCompare(b)
3921
3926
  );
3922
3927
  const sections = [];
3923
3928
  const missingSkillIds = [];
3924
3929
  for (const id of ordered) {
3925
- const { section, missing } = await renderSkillSection(projectRoot, id, ides, scope);
3930
+ const skillScope = skillScopeMap.get(id) ?? scope;
3931
+ const { section, missing } = await renderSkillSection(projectRoot, id, ides, skillScope);
3926
3932
  sections.push(section);
3927
3933
  if (missing) missingSkillIds.push(id);
3928
3934
  }
@@ -4006,6 +4012,12 @@ async function renderSkillSection(projectRoot, skillId, ides, scope) {
4006
4012
  if (parts?.coordinates) {
4007
4013
  lines.push(`- **Coordinates with**: ${parts.coordinates}`);
4008
4014
  }
4015
+ if (scope === "global") {
4016
+ lines.push("");
4017
+ lines.push(
4018
+ "> **\u5168\u5C40\u6280\u80FD** \u2014 \u5B89\u88C5\u5728\u5168\u5C40\u800C\u975E\u9879\u76EE\u5185\uFF0C\u4E0D\u968F\u4EE3\u7801\u4ED3\u5E93\u5206\u53D1\u3002AI \u89E6\u53D1\u65F6\u5E94\u5148\u786E\u8BA4\u672C\u6280\u80FD\u53EF\u7528\uFF1B\u82E5\u4E0D\u53EF\u7528\uFF0C\u5F15\u5BFC\u7528\u6237\u6267\u884C\u5168\u5C40\u5B89\u88C5\u3002"
4019
+ );
4020
+ }
4009
4021
  return { section: lines.join("\n"), missing };
4010
4022
  }
4011
4023
  function renderAgentsMd(args) {
@@ -4322,10 +4334,12 @@ async function runSkillsUpdate(options) {
4322
4334
  const variant = await readTokensVariant(projectRoot);
4323
4335
  if (variant) {
4324
4336
  const projectSkillIds = Object.entries(lock.skills).filter(([, v]) => v.scope === "project").map(([id]) => id);
4337
+ const globalSkillIds = Object.entries(lock.skills).filter(([, v]) => v.scope === "global").map(([id]) => id);
4325
4338
  await runGenerateAgentsMd({
4326
4339
  projectRoot,
4327
4340
  variant,
4328
4341
  skillIds: projectSkillIds,
4342
+ globalSkillIds,
4329
4343
  mode: "merge-managed"
4330
4344
  });
4331
4345
  }
@@ -5231,6 +5245,10 @@ async function loadUiData(packageName) {
5231
5245
  const packageRoot = resolvePackageRoot2(packageName);
5232
5246
  logger.debug(`Resolved ui package root: ${packageRoot}`);
5233
5247
  const manifest = await loadUiPackageManifest(packageRoot);
5248
+ const pkgJson = JSON.parse(
5249
+ await fs18.readFile(path23.join(packageRoot, "package.json"), "utf-8")
5250
+ );
5251
+ manifest.version = pkgJson.version;
5234
5252
  let data = {};
5235
5253
  const dataPath = path23.join(packageRoot, "_data.json");
5236
5254
  try {
@@ -6010,6 +6028,7 @@ import { Command as Command24 } from "commander";
6010
6028
  // src/core/ui-upgrade.ts
6011
6029
  init_state();
6012
6030
  import * as path29 from "path";
6031
+ import * as fs23 from "fs/promises";
6013
6032
  import { createRequire as createRequire7 } from "module";
6014
6033
  import {
6015
6034
  loadUiPackageManifest as loadUiPackageManifest3,
@@ -6717,6 +6736,7 @@ async function buildStaging(args) {
6717
6736
  if (category === "blocks") {
6718
6737
  const root = args.blocksPackageRoot ?? resolvePackageRoot4("@teamix-evo/blocks");
6719
6738
  const manifest = await loadUiPackageManifest3(root);
6739
+ manifest.version = await readPkgVersion(root);
6720
6740
  return buildUiUpgradeStaging({
6721
6741
  projectRoot,
6722
6742
  category,
@@ -6731,6 +6751,7 @@ async function buildStaging(args) {
6731
6751
  if (category === "ui") {
6732
6752
  const root = args.uiPackageRoot ?? resolvePackageRoot4("@teamix-evo/ui");
6733
6753
  const manifest = await loadUiPackageManifest3(root);
6754
+ manifest.version = await readPkgVersion(root);
6734
6755
  return buildUiUpgradeStaging({
6735
6756
  projectRoot,
6736
6757
  category,
@@ -6762,7 +6783,7 @@ async function buildStaging(args) {
6762
6783
  const synthetic = {
6763
6784
  schemaVersion: 1,
6764
6785
  package: "ui",
6765
- version: variantManifest.version,
6786
+ version: await readPkgVersion(bizRoot),
6766
6787
  engines: variantManifest.engines,
6767
6788
  entries: merged
6768
6789
  };
@@ -6778,6 +6799,13 @@ async function buildStaging(args) {
6778
6799
  onlyIds
6779
6800
  });
6780
6801
  }
6802
+ async function readPkgVersion(packageRoot) {
6803
+ const raw = await fs23.readFile(
6804
+ path29.join(packageRoot, "package.json"),
6805
+ "utf-8"
6806
+ );
6807
+ return JSON.parse(raw).version;
6808
+ }
6781
6809
 
6782
6810
  // src/commands/_upgrade-command-factory.ts
6783
6811
  init_logger();
@@ -6901,7 +6929,7 @@ import { Command as Command25 } from "commander";
6901
6929
 
6902
6930
  // src/core/ui-promote.ts
6903
6931
  init_fs();
6904
- import * as fs24 from "fs/promises";
6932
+ import * as fs25 from "fs/promises";
6905
6933
  import * as path31 from "path";
6906
6934
  init_logger();
6907
6935
  init_error();
@@ -6909,7 +6937,7 @@ init_state();
6909
6937
 
6910
6938
  // src/core/ui-promote-imports.ts
6911
6939
  init_fs();
6912
- import * as fs23 from "fs/promises";
6940
+ import * as fs24 from "fs/promises";
6913
6941
  import * as path30 from "path";
6914
6942
  var SOURCE_FILE_EXT = /\.(tsx?|jsx?|mts|cts)$/;
6915
6943
  var STATIC_IMPORT_FROM = /^(\s*(?:import|export)\s[\s\S]*?from\s+['"])([^'"\n]+)(['"])/;
@@ -7016,7 +7044,7 @@ async function collectTsFiles(root) {
7016
7044
  async function walk(dir) {
7017
7045
  let entries;
7018
7046
  try {
7019
- entries = await fs23.readdir(dir, { withFileTypes: true });
7047
+ entries = await fs24.readdir(dir, { withFileTypes: true });
7020
7048
  } catch (err) {
7021
7049
  if (err.code === "ENOENT") return;
7022
7050
  throw err;
@@ -7421,7 +7449,7 @@ async function findLatestUiStagingDir(projectRoot) {
7421
7449
  const base = path31.join(projectRoot, TEAMIX_DIR5, STAGING_DIR2);
7422
7450
  let entries;
7423
7451
  try {
7424
- entries = await fs24.readdir(base, { withFileTypes: true });
7452
+ entries = await fs25.readdir(base, { withFileTypes: true });
7425
7453
  } catch (err) {
7426
7454
  if (err.code === "ENOENT") return null;
7427
7455
  throw err;
@@ -7518,7 +7546,7 @@ function posix2(p2) {
7518
7546
  }
7519
7547
 
7520
7548
  // src/core/file-changes.ts
7521
- import * as fs25 from "fs/promises";
7549
+ import * as fs26 from "fs/promises";
7522
7550
  import * as path32 from "path";
7523
7551
  function toRelativePosix(p2, projectRoot) {
7524
7552
  let rel2 = p2;
@@ -7710,6 +7738,7 @@ import { Command as Command27 } from "commander";
7710
7738
 
7711
7739
  // src/core/variant-ui-add.ts
7712
7740
  import * as path33 from "path";
7741
+ import * as fs27 from "fs/promises";
7713
7742
  import { createRequire as createRequire8 } from "module";
7714
7743
  import {
7715
7744
  loadUiPackageManifest as loadUiPackageManifest4,
@@ -7745,6 +7774,10 @@ async function runVariantUiAdd(packageName, options) {
7745
7774
  }
7746
7775
  const variantDir = path33.join(packageRoot, "variants", variant);
7747
7776
  const variantManifest = await loadVariantUiPackageManifest3(variantDir);
7777
+ const pkgJson = JSON.parse(
7778
+ await fs27.readFile(path33.join(packageRoot, "package.json"), "utf-8")
7779
+ );
7780
+ const packageVersion = pkgJson.version;
7748
7781
  const knownIds = new Set(variantManifest.entries.map((e) => e.id));
7749
7782
  const unknown = ids.filter((id) => !knownIds.has(id));
7750
7783
  if (unknown.length > 0) {
@@ -7768,7 +7801,7 @@ async function runVariantUiAdd(packageName, options) {
7768
7801
  const adaptedManifest = {
7769
7802
  schemaVersion: 1,
7770
7803
  package: "ui",
7771
- version: variantManifest.version,
7804
+ version: packageVersion,
7772
7805
  engines: variantManifest.engines,
7773
7806
  entries: mergedEntries
7774
7807
  };
@@ -7796,7 +7829,7 @@ async function runVariantUiAdd(packageName, options) {
7796
7829
  const entry = {
7797
7830
  package: fullPackageName,
7798
7831
  variant,
7799
- version: variantManifest.version,
7832
+ version: packageVersion,
7800
7833
  installedAt: (/* @__PURE__ */ new Date()).toISOString(),
7801
7834
  resources: mergedResources
7802
7835
  };
@@ -8199,7 +8232,7 @@ import * as prompts6 from "@clack/prompts";
8199
8232
  init_fs();
8200
8233
  init_logger();
8201
8234
  import * as path34 from "path";
8202
- import * as fs26 from "fs";
8235
+ import * as fs28 from "fs";
8203
8236
  import { execa } from "execa";
8204
8237
  var ESLINT_CONFIG_CONTENT = `/**
8205
8238
  * teamix-evo consumer ESLint preset \u2014 9 token-discipline rules.
@@ -8291,7 +8324,7 @@ async function runLintInit(options) {
8291
8324
  let stylelintIgnoreFilesWarning = false;
8292
8325
  if (!stylelintNeedsWrite && stylelintTemplateExists) {
8293
8326
  try {
8294
- const existingContent = fs26.readFileSync(stylelintConfigPath, "utf-8");
8327
+ const existingContent = fs28.readFileSync(stylelintConfigPath, "utf-8");
8295
8328
  const usesTeamixPreset = existingContent.includes("@teamix-evo/stylelint-config/presets/") || existingContent.includes("@teamix-evo/stylelint-config/preset/");
8296
8329
  const hasTokenIgnore = existingContent.includes("tokens.theme.css") && existingContent.includes("tokens.overrides.css");
8297
8330
  if (!usesTeamixPreset && !hasTokenIgnore) {
@@ -8328,8 +8361,8 @@ async function runLintInit(options) {
8328
8361
  };
8329
8362
  }
8330
8363
  function detectPm(projectRoot) {
8331
- if (fs26.existsSync(path34.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
8332
- if (fs26.existsSync(path34.join(projectRoot, "yarn.lock"))) return "yarn";
8364
+ if (fs28.existsSync(path34.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
8365
+ if (fs28.existsSync(path34.join(projectRoot, "yarn.lock"))) return "yarn";
8333
8366
  return "npm";
8334
8367
  }
8335
8368
  async function patchPackageJsonScripts(projectRoot) {
@@ -8425,7 +8458,7 @@ import { execa as execa2 } from "execa";
8425
8458
  // src/core/project-state.ts
8426
8459
  init_fs();
8427
8460
  init_state();
8428
- import * as fs27 from "fs/promises";
8461
+ import * as fs29 from "fs/promises";
8429
8462
  import * as path35 from "path";
8430
8463
  var IGNORED_TOP_LEVEL = /* @__PURE__ */ new Set([
8431
8464
  ".git",
@@ -8485,7 +8518,7 @@ async function detectProjectState(cwd) {
8485
8518
  }
8486
8519
  let entries;
8487
8520
  try {
8488
- entries = await fs27.readdir(absCwd);
8521
+ entries = await fs29.readdir(absCwd);
8489
8522
  } catch (err) {
8490
8523
  if (err.code === "ENOENT") {
8491
8524
  return {
@@ -8570,7 +8603,7 @@ function assertCommandPrecondition(command, state) {
8570
8603
  // src/core/deps-install.ts
8571
8604
  init_fs();
8572
8605
  init_logger();
8573
- import * as fs28 from "fs/promises";
8606
+ import * as fs30 from "fs/promises";
8574
8607
  import * as path36 from "path";
8575
8608
  import { exec as exec4 } from "child_process";
8576
8609
  import { promisify as promisify4 } from "util";
@@ -8627,7 +8660,7 @@ async function installProjectDeps(options) {
8627
8660
  pkg.dependencies = Object.fromEntries(
8628
8661
  Object.entries(pkg.dependencies).sort(([a], [b]) => a.localeCompare(b))
8629
8662
  );
8630
- await fs28.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
8663
+ await fs30.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
8631
8664
  logger.info(
8632
8665
  ` patched package.json: +${Object.keys(added).length} dependencies`
8633
8666
  );
@@ -8809,6 +8842,7 @@ async function runProjectInit(options) {
8809
8842
  `teamix-evo-design-${variant}`,
8810
8843
  `teamix-evo-code-${variant}`
8811
8844
  ],
8845
+ globalSkillIds: ["teamix-evo-manage"],
8812
8846
  mode: "merge-managed"
8813
8847
  });
8814
8848
  record({
@@ -9595,7 +9629,7 @@ import * as prompts7 from "@clack/prompts";
9595
9629
 
9596
9630
  // src/core/snapshot.ts
9597
9631
  init_logger();
9598
- import * as fs29 from "fs/promises";
9632
+ import * as fs31 from "fs/promises";
9599
9633
  import * as path42 from "path";
9600
9634
  var TEAMIX_DIR6 = ".teamix-evo";
9601
9635
  var SNAPSHOTS_DIR = ".snapshots";
@@ -9613,7 +9647,7 @@ function fsSafeToIso(safe) {
9613
9647
  async function createSnapshot(projectRoot, opts = {}) {
9614
9648
  const teamixDir = path42.join(projectRoot, TEAMIX_DIR6);
9615
9649
  try {
9616
- const stat5 = await fs29.stat(teamixDir);
9650
+ const stat5 = await fs31.stat(teamixDir);
9617
9651
  if (!stat5.isDirectory()) return null;
9618
9652
  } catch (err) {
9619
9653
  if (err.code === "ENOENT") return null;
@@ -9623,19 +9657,19 @@ async function createSnapshot(projectRoot, opts = {}) {
9623
9657
  const ts = isoToFsSafe3(isoTs);
9624
9658
  const snapshotRoot = path42.join(teamixDir, SNAPSHOTS_DIR);
9625
9659
  const target = path42.join(snapshotRoot, ts);
9626
- await fs29.mkdir(target, { recursive: true });
9627
- const entries = await fs29.readdir(teamixDir, { withFileTypes: true });
9660
+ await fs31.mkdir(target, { recursive: true });
9661
+ const entries = await fs31.readdir(teamixDir, { withFileTypes: true });
9628
9662
  for (const entry of entries) {
9629
9663
  if (entry.name === SNAPSHOTS_DIR) continue;
9630
9664
  const src = path42.join(teamixDir, entry.name);
9631
9665
  const dst = path42.join(target, entry.name);
9632
- await fs29.cp(src, dst, { recursive: true });
9666
+ await fs31.cp(src, dst, { recursive: true });
9633
9667
  }
9634
9668
  const meta = {
9635
9669
  ts: isoTs,
9636
9670
  reason: opts.reason ?? "manual"
9637
9671
  };
9638
- await fs29.writeFile(
9672
+ await fs31.writeFile(
9639
9673
  path42.join(target, META_FILE),
9640
9674
  JSON.stringify(meta, null, 2) + "\n",
9641
9675
  "utf-8"
@@ -9651,7 +9685,7 @@ async function listSnapshots(projectRoot) {
9651
9685
  const snapshotRoot = path42.join(projectRoot, TEAMIX_DIR6, SNAPSHOTS_DIR);
9652
9686
  let entries;
9653
9687
  try {
9654
- entries = await fs29.readdir(snapshotRoot, { withFileTypes: true });
9688
+ entries = await fs31.readdir(snapshotRoot, { withFileTypes: true });
9655
9689
  } catch (err) {
9656
9690
  if (err.code === "ENOENT") return [];
9657
9691
  throw err;
@@ -9663,7 +9697,7 @@ async function listSnapshots(projectRoot) {
9663
9697
  let isoTs = null;
9664
9698
  let reason = null;
9665
9699
  try {
9666
- const raw = await fs29.readFile(path42.join(dir, META_FILE), "utf-8");
9700
+ const raw = await fs31.readFile(path42.join(dir, META_FILE), "utf-8");
9667
9701
  const parsed = JSON.parse(raw);
9668
9702
  if (typeof parsed.ts === "string") isoTs = parsed.ts;
9669
9703
  if (typeof parsed.reason === "string" && ["init", "update", "switch", "restore", "manual"].includes(
@@ -9688,7 +9722,7 @@ async function pruneSnapshots(projectRoot, keep = DEFAULT_KEEP, opts = {}) {
9688
9722
  const toRemove = opts.protectedTs ? tail.filter((s) => s.ts !== opts.protectedTs) : tail;
9689
9723
  const removed = [];
9690
9724
  for (const snap of toRemove) {
9691
- await fs29.rm(snap.path, { recursive: true, force: true });
9725
+ await fs31.rm(snap.path, { recursive: true, force: true });
9692
9726
  removed.push(snap.ts);
9693
9727
  logger.debug(`Pruned snapshot ${snap.ts}`);
9694
9728
  }
@@ -9698,7 +9732,7 @@ async function restoreSnapshot(projectRoot, ts) {
9698
9732
  const snapshotRoot = path42.join(projectRoot, TEAMIX_DIR6, SNAPSHOTS_DIR);
9699
9733
  const target = path42.join(snapshotRoot, ts);
9700
9734
  try {
9701
- const stat5 = await fs29.stat(target);
9735
+ const stat5 = await fs31.stat(target);
9702
9736
  if (!stat5.isDirectory()) {
9703
9737
  throw new Error(`Snapshot path is not a directory: ${target}`);
9704
9738
  }
@@ -9712,20 +9746,20 @@ async function restoreSnapshot(projectRoot, ts) {
9712
9746
  }
9713
9747
  await createSnapshot(projectRoot, { reason: "restore", protectedTs: ts });
9714
9748
  const teamixDir = path42.join(projectRoot, TEAMIX_DIR6);
9715
- const live = await fs29.readdir(teamixDir, { withFileTypes: true });
9749
+ const live = await fs31.readdir(teamixDir, { withFileTypes: true });
9716
9750
  for (const entry of live) {
9717
9751
  if (entry.name === SNAPSHOTS_DIR) continue;
9718
- await fs29.rm(path42.join(teamixDir, entry.name), {
9752
+ await fs31.rm(path42.join(teamixDir, entry.name), {
9719
9753
  recursive: true,
9720
9754
  force: true
9721
9755
  });
9722
9756
  }
9723
- const snapshotEntries = await fs29.readdir(target, { withFileTypes: true });
9757
+ const snapshotEntries = await fs31.readdir(target, { withFileTypes: true });
9724
9758
  for (const entry of snapshotEntries) {
9725
9759
  if (entry.name === META_FILE) continue;
9726
9760
  const src = path42.join(target, entry.name);
9727
9761
  const dst = path42.join(teamixDir, entry.name);
9728
- await fs29.cp(src, dst, { recursive: true });
9762
+ await fs31.cp(src, dst, { recursive: true });
9729
9763
  }
9730
9764
  logger.debug(`Restored .teamix-evo/ from snapshot ${ts}`);
9731
9765
  }
@@ -9840,7 +9874,7 @@ import * as prompts8 from "@clack/prompts";
9840
9874
  // src/core/variant-switch.ts
9841
9875
  init_fs();
9842
9876
  import * as path44 from "path";
9843
- import * as fs30 from "fs/promises";
9877
+ import * as fs32 from "fs/promises";
9844
9878
  import {
9845
9879
  loadTokensPackageManifest as loadTokensPackageManifest3,
9846
9880
  getVariantEntry as getVariantEntry3
@@ -9913,7 +9947,7 @@ async function runVariantSwitch(options) {
9913
9947
  });
9914
9948
  continue;
9915
9949
  }
9916
- const upstreamContent = await fs30.readFile(upstreamAbs, "utf-8");
9950
+ const upstreamContent = await fs32.readFile(upstreamAbs, "utf-8");
9917
9951
  if (resource.strategy === "regenerable") {
9918
9952
  const newHash = computeHash(upstreamContent);
9919
9953
  if (newHash === resource.hash) {
@@ -9971,7 +10005,7 @@ async function runVariantSwitch(options) {
9971
10005
  const upstreamBasename = lookupUpstreamBasename2(consumerBasename);
9972
10006
  const upstreamAbs = upstreamBasename ? upstreamByBasename.get(upstreamBasename) : void 0;
9973
10007
  if (resource.strategy === "regenerable" && upstreamAbs) {
9974
- const upstreamContent = await fs30.readFile(upstreamAbs, "utf-8");
10008
+ const upstreamContent = await fs32.readFile(upstreamAbs, "utf-8");
9975
10009
  await writeFileSafe(consumerAbs, upstreamContent);
9976
10010
  logger.debug(`[variant-switch] rewrite regenerable: ${resource.target}`);
9977
10011
  refreshedResources.push({
@@ -9981,8 +10015,8 @@ async function runVariantSwitch(options) {
9981
10015
  continue;
9982
10016
  }
9983
10017
  if (resource.strategy === "managed" && upstreamAbs && await fileExists(consumerAbs)) {
9984
- const upstreamContent = await fs30.readFile(upstreamAbs, "utf-8");
9985
- const consumerContent = await fs30.readFile(consumerAbs, "utf-8");
10018
+ const upstreamContent = await fs32.readFile(upstreamAbs, "utf-8");
10019
+ const consumerContent = await fs32.readFile(consumerAbs, "utf-8");
9986
10020
  const merged = mergeManagedRegions(upstreamContent, consumerContent);
9987
10021
  if (merged !== consumerContent) {
9988
10022
  await writeFileSafe(consumerAbs, merged);
@@ -10079,10 +10113,12 @@ async function runVariantSwitch(options) {
10079
10113
  const lock2 = await readSkillsLock(projectRoot);
10080
10114
  if (lock2) {
10081
10115
  const projectSkillIds = Object.entries(lock2.skills).filter(([, v]) => v.scope === "project").map(([id]) => id);
10116
+ const globalSkillIds = Object.entries(lock2.skills).filter(([, v]) => v.scope === "global").map(([id]) => id);
10082
10117
  await runGenerateAgentsMd({
10083
10118
  projectRoot,
10084
10119
  variant: newVariant,
10085
10120
  skillIds: projectSkillIds,
10121
+ globalSkillIds,
10086
10122
  mode: "merge-managed"
10087
10123
  });
10088
10124
  }