agentpacks 0.9.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +41 -14
  2. package/dist/api.js +403 -179
  3. package/dist/cli/export-cmd.js +58 -5
  4. package/dist/cli/generate.js +268 -59
  5. package/dist/cli/import-cmd.js +203 -95
  6. package/dist/cli/install.js +1 -0
  7. package/dist/cli/models-explain.js +56 -0
  8. package/dist/cli/pack/list.js +56 -0
  9. package/dist/cli/pack/validate.js +143 -18
  10. package/dist/cli/publish.js +1 -0
  11. package/dist/core/config.d.ts +1 -1
  12. package/dist/core/config.js +1 -0
  13. package/dist/core/index.js +56 -0
  14. package/dist/core/metarepo.js +1 -0
  15. package/dist/core/pack-loader.js +56 -0
  16. package/dist/exporters/cursor-plugin.js +109 -22
  17. package/dist/exporters/index.js +109 -22
  18. package/dist/features/index.d.ts +1 -1
  19. package/dist/features/index.js +59 -0
  20. package/dist/features/skills.d.ts +22 -0
  21. package/dist/features/skills.js +60 -1
  22. package/dist/importers/cursor.js +122 -26
  23. package/dist/importers/opencode.js +138 -24
  24. package/dist/importers/rulesync.js +147 -33
  25. package/dist/index.js +484 -244
  26. package/dist/node/api.js +403 -179
  27. package/dist/node/cli/export-cmd.js +58 -5
  28. package/dist/node/cli/generate.js +268 -59
  29. package/dist/node/cli/import-cmd.js +203 -95
  30. package/dist/node/cli/install.js +1 -0
  31. package/dist/node/cli/models-explain.js +56 -0
  32. package/dist/node/cli/pack/list.js +56 -0
  33. package/dist/node/cli/pack/validate.js +143 -18
  34. package/dist/node/cli/publish.js +1 -0
  35. package/dist/node/core/config.js +1 -0
  36. package/dist/node/core/index.js +56 -0
  37. package/dist/node/core/metarepo.js +1 -0
  38. package/dist/node/core/pack-loader.js +56 -0
  39. package/dist/node/exporters/cursor-plugin.js +109 -22
  40. package/dist/node/exporters/index.js +109 -22
  41. package/dist/node/features/index.js +59 -0
  42. package/dist/node/features/skills.js +60 -1
  43. package/dist/node/importers/cursor.js +122 -26
  44. package/dist/node/importers/opencode.js +138 -24
  45. package/dist/node/importers/rulesync.js +147 -33
  46. package/dist/node/index.js +484 -244
  47. package/dist/node/targets/claude-code.js +56 -1
  48. package/dist/node/targets/codex-cli.js +56 -1
  49. package/dist/node/targets/copilot.js +56 -1
  50. package/dist/node/targets/cursor.js +56 -5
  51. package/dist/node/targets/index.js +268 -59
  52. package/dist/node/targets/mistral-vibe.js +661 -0
  53. package/dist/node/targets/opencode.js +56 -1
  54. package/dist/node/targets/registry.js +267 -59
  55. package/dist/node/utils/model-allowlist.js +6 -2
  56. package/dist/targets/claude-code.js +56 -1
  57. package/dist/targets/codex-cli.js +56 -1
  58. package/dist/targets/copilot.js +56 -1
  59. package/dist/targets/cursor.js +56 -5
  60. package/dist/targets/index.d.ts +1 -0
  61. package/dist/targets/index.js +268 -59
  62. package/dist/targets/mistral-vibe.d.ts +13 -0
  63. package/dist/targets/mistral-vibe.js +661 -0
  64. package/dist/targets/opencode.js +56 -1
  65. package/dist/targets/registry.js +267 -59
  66. package/dist/utils/model-allowlist.js +6 -2
  67. package/package.json +15 -3
@@ -11,6 +11,7 @@ var TARGET_IDS = [
11
11
  "cursor",
12
12
  "claudecode",
13
13
  "codexcli",
14
+ "mistralvibe",
14
15
  "geminicli",
15
16
  "copilot",
16
17
  "agentsmd",
@@ -351,6 +352,8 @@ function agentMatchesTarget(agent, targetId) {
351
352
  // src/features/skills.ts
352
353
  import { readFileSync as readFileSync6, existsSync as existsSync3 } from "fs";
353
354
  import { basename as basename4, join as join2 } from "path";
355
+ var SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
356
+ var SKILL_NAME_MAX_LENGTH = 64;
354
357
  function parseSkills(skillsDir, packName) {
355
358
  const dirs = listDirs(skillsDir);
356
359
  const skills = [];
@@ -374,6 +377,59 @@ function parseSkillFile(filepath, skillDir, packName) {
374
377
  content
375
378
  };
376
379
  }
380
+ function buildSkillFrontmatter(skill) {
381
+ return {
382
+ ...skill.meta,
383
+ name: skill.name
384
+ };
385
+ }
386
+ function serializeSkill(skill) {
387
+ return serializeFrontmatter(buildSkillFrontmatter(skill), skill.content);
388
+ }
389
+ function normalizeImportedSkillMarkdown(source, skillName) {
390
+ const { data, content } = parseFrontmatter(source);
391
+ const normalized = {
392
+ ...data,
393
+ name: skillName
394
+ };
395
+ let addedDescription = false;
396
+ const description = normalized.description;
397
+ if (typeof description !== "string" || description.trim().length === 0) {
398
+ normalized.description = `Imported skill: ${skillName}`;
399
+ addedDescription = true;
400
+ }
401
+ return {
402
+ content: serializeFrontmatter(normalized, content),
403
+ addedDescription
404
+ };
405
+ }
406
+ function validateAgentSkillsFrontmatter(skill) {
407
+ const errors = [];
408
+ const dirName = basename4(skill.sourceDir);
409
+ const declaredName = skill.meta.name;
410
+ if (typeof declaredName !== "string" || declaredName.trim().length === 0) {
411
+ errors.push('Missing required frontmatter field "name".');
412
+ } else {
413
+ if (declaredName.length > SKILL_NAME_MAX_LENGTH) {
414
+ errors.push(`Invalid "name": must be at most ${SKILL_NAME_MAX_LENGTH} characters.`);
415
+ }
416
+ if (!SKILL_NAME_PATTERN.test(declaredName)) {
417
+ errors.push('Invalid "name": use lowercase letters, numbers, and single hyphens only.');
418
+ }
419
+ if (declaredName !== dirName) {
420
+ errors.push(`Invalid "name": must match containing directory "${dirName}".`);
421
+ }
422
+ }
423
+ const description = skill.meta.description;
424
+ if (typeof description !== "string" || description.trim().length === 0) {
425
+ errors.push('Missing required frontmatter field "description".');
426
+ }
427
+ const allowedTools = skill.meta["allowed-tools"];
428
+ if (allowedTools !== undefined && (!Array.isArray(allowedTools) || allowedTools.some((tool) => typeof tool !== "string" || tool.length === 0))) {
429
+ errors.push('Invalid "allowed-tools": expected an array of non-empty strings.');
430
+ }
431
+ return errors;
432
+ }
377
433
  function skillMatchesTarget(skill, targetId) {
378
434
  const { targets } = skill.meta;
379
435
  if (!targets || targets === "*")
@@ -859,12 +915,9 @@ function exportCursorPlugin(pack, outputDir) {
859
915
  for (const skill of pack.skills) {
860
916
  const skillSubDir = join8(skillsDir, skill.name);
861
917
  ensureDir(skillSubDir);
862
- const fm = {
863
- name: skill.name,
864
- description: skill.meta.description ?? ""
865
- };
866
918
  const filepath = join8(skillSubDir, "SKILL.md");
867
- writeFileSync2(filepath, serializeFrontmatter(fm, skill.content));
919
+ const content = serializeFrontmatter(buildSkillFrontmatter(skill), skill.content);
920
+ writeFileSync2(filepath, content);
868
921
  filesWritten.push(filepath);
869
922
  }
870
923
  }
@@ -11,6 +11,7 @@ var TARGET_IDS = [
11
11
  "cursor",
12
12
  "claudecode",
13
13
  "codexcli",
14
+ "mistralvibe",
14
15
  "geminicli",
15
16
  "copilot",
16
17
  "agentsmd",
@@ -351,6 +352,8 @@ function agentMatchesTarget(agent, targetId) {
351
352
  // src/features/skills.ts
352
353
  import { readFileSync as readFileSync6, existsSync as existsSync3 } from "fs";
353
354
  import { basename as basename4, join as join2 } from "path";
355
+ var SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
356
+ var SKILL_NAME_MAX_LENGTH = 64;
354
357
  function parseSkills(skillsDir, packName) {
355
358
  const dirs = listDirs(skillsDir);
356
359
  const skills = [];
@@ -374,6 +377,59 @@ function parseSkillFile(filepath, skillDir, packName) {
374
377
  content
375
378
  };
376
379
  }
380
+ function buildSkillFrontmatter(skill) {
381
+ return {
382
+ ...skill.meta,
383
+ name: skill.name
384
+ };
385
+ }
386
+ function serializeSkill(skill) {
387
+ return serializeFrontmatter(buildSkillFrontmatter(skill), skill.content);
388
+ }
389
+ function normalizeImportedSkillMarkdown(source, skillName) {
390
+ const { data, content } = parseFrontmatter(source);
391
+ const normalized = {
392
+ ...data,
393
+ name: skillName
394
+ };
395
+ let addedDescription = false;
396
+ const description = normalized.description;
397
+ if (typeof description !== "string" || description.trim().length === 0) {
398
+ normalized.description = `Imported skill: ${skillName}`;
399
+ addedDescription = true;
400
+ }
401
+ return {
402
+ content: serializeFrontmatter(normalized, content),
403
+ addedDescription
404
+ };
405
+ }
406
+ function validateAgentSkillsFrontmatter(skill) {
407
+ const errors = [];
408
+ const dirName = basename4(skill.sourceDir);
409
+ const declaredName = skill.meta.name;
410
+ if (typeof declaredName !== "string" || declaredName.trim().length === 0) {
411
+ errors.push('Missing required frontmatter field "name".');
412
+ } else {
413
+ if (declaredName.length > SKILL_NAME_MAX_LENGTH) {
414
+ errors.push(`Invalid "name": must be at most ${SKILL_NAME_MAX_LENGTH} characters.`);
415
+ }
416
+ if (!SKILL_NAME_PATTERN.test(declaredName)) {
417
+ errors.push('Invalid "name": use lowercase letters, numbers, and single hyphens only.');
418
+ }
419
+ if (declaredName !== dirName) {
420
+ errors.push(`Invalid "name": must match containing directory "${dirName}".`);
421
+ }
422
+ }
423
+ const description = skill.meta.description;
424
+ if (typeof description !== "string" || description.trim().length === 0) {
425
+ errors.push('Missing required frontmatter field "description".');
426
+ }
427
+ const allowedTools = skill.meta["allowed-tools"];
428
+ if (allowedTools !== undefined && (!Array.isArray(allowedTools) || allowedTools.some((tool) => typeof tool !== "string" || tool.length === 0))) {
429
+ errors.push('Invalid "allowed-tools": expected an array of non-empty strings.');
430
+ }
431
+ return errors;
432
+ }
377
433
  function skillMatchesTarget(skill, targetId) {
378
434
  const { targets } = skill.meta;
379
435
  if (!targets || targets === "*")
@@ -1111,7 +1167,7 @@ class OpenCodeTarget extends BaseTarget {
1111
1167
  const skillSubDir = join8(skillDir, skill.name);
1112
1168
  ensureDir(skillSubDir);
1113
1169
  const filepath = join8(skillSubDir, "SKILL.md");
1114
- writeGeneratedFile(filepath, skill.content);
1170
+ writeGeneratedFile(filepath, serializeSkill(skill));
1115
1171
  filesWritten.push(filepath);
1116
1172
  }
1117
1173
  }
@@ -1366,12 +1422,8 @@ class CursorTarget extends BaseTarget {
1366
1422
  for (const skill of skills) {
1367
1423
  const skillSubDir = join9(skillsDir, skill.name);
1368
1424
  ensureDir(skillSubDir);
1369
- const frontmatter = {
1370
- name: skill.name,
1371
- description: skill.meta.description ?? ""
1372
- };
1373
1425
  const filepath = join9(skillSubDir, "SKILL.md");
1374
- const content = serializeFrontmatter(frontmatter, skill.content);
1426
+ const content = serializeSkill(skill);
1375
1427
  writeGeneratedFile(filepath, content);
1376
1428
  filesWritten.push(filepath);
1377
1429
  }
@@ -1671,7 +1723,7 @@ ${content}`;
1671
1723
  const skillSubDir = join10(skillsDir, skill.name);
1672
1724
  ensureDir(skillSubDir);
1673
1725
  const filepath = join10(skillSubDir, "SKILL.md");
1674
- writeGeneratedFile(filepath, skill.content);
1726
+ writeGeneratedFile(filepath, serializeSkill(skill));
1675
1727
  filesWritten.push(filepath);
1676
1728
  }
1677
1729
  }
@@ -1801,7 +1853,7 @@ class CodexCliTarget extends BaseTarget {
1801
1853
  const skillSubDir = join11(skillsDir, skill.name);
1802
1854
  ensureDir(skillSubDir);
1803
1855
  const filepath = join11(skillSubDir, "SKILL.md");
1804
- writeGeneratedFile(filepath, skill.content);
1856
+ writeGeneratedFile(filepath, serializeSkill(skill));
1805
1857
  filesWritten.push(filepath);
1806
1858
  }
1807
1859
  }
@@ -1809,12 +1861,168 @@ class CodexCliTarget extends BaseTarget {
1809
1861
  }
1810
1862
  }
1811
1863
 
1812
- // src/targets/gemini-cli.ts
1864
+ // src/targets/mistral-vibe.ts
1813
1865
  import { resolve as resolve7, join as join12 } from "path";
1814
- var TARGET_ID5 = "geminicli";
1866
+ var TARGET_ID5 = "mistralvibe";
1815
1867
 
1816
- class GeminiCliTarget extends BaseTarget {
1868
+ class MistralVibeTarget extends BaseTarget {
1817
1869
  id = TARGET_ID5;
1870
+ name = "Mistral Vibe";
1871
+ supportedFeatures = [
1872
+ "rules",
1873
+ "commands",
1874
+ "agents",
1875
+ "skills",
1876
+ "mcp",
1877
+ "ignore",
1878
+ "models"
1879
+ ];
1880
+ generate(options) {
1881
+ const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
1882
+ const root = resolve7(projectRoot, baseDir);
1883
+ const effective = this.getEffectiveFeatures(enabledFeatures);
1884
+ const filesWritten = [];
1885
+ const filesDeleted = [];
1886
+ const warnings = [];
1887
+ const vibeDir = resolve7(root, ".vibe");
1888
+ ensureDir(vibeDir);
1889
+ if (effective.includes("rules")) {
1890
+ const rulesDir = resolve7(vibeDir, "rules");
1891
+ if (deleteExisting) {
1892
+ removeIfExists(rulesDir);
1893
+ filesDeleted.push(rulesDir);
1894
+ }
1895
+ ensureDir(rulesDir);
1896
+ const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID5));
1897
+ for (const rule of rules) {
1898
+ const filepath = join12(rulesDir, `${rule.name}.md`);
1899
+ writeGeneratedFile(filepath, rule.content);
1900
+ filesWritten.push(filepath);
1901
+ }
1902
+ }
1903
+ if (effective.includes("agents")) {
1904
+ const agentsDir = resolve7(vibeDir, "agents");
1905
+ if (deleteExisting) {
1906
+ removeIfExists(agentsDir);
1907
+ filesDeleted.push(agentsDir);
1908
+ }
1909
+ ensureDir(agentsDir);
1910
+ const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID5));
1911
+ for (const agent of agents) {
1912
+ const filepath = join12(agentsDir, `${agent.name}.md`);
1913
+ writeGeneratedFile(filepath, agent.content);
1914
+ filesWritten.push(filepath);
1915
+ }
1916
+ }
1917
+ if (effective.includes("skills")) {
1918
+ const skillsDir = resolve7(vibeDir, "skills");
1919
+ if (deleteExisting) {
1920
+ removeIfExists(skillsDir);
1921
+ filesDeleted.push(skillsDir);
1922
+ }
1923
+ ensureDir(skillsDir);
1924
+ const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID5));
1925
+ for (const skill of skills) {
1926
+ const skillSubDir = join12(skillsDir, skill.name);
1927
+ ensureDir(skillSubDir);
1928
+ const filepath = join12(skillSubDir, "SKILL.md");
1929
+ writeGeneratedFile(filepath, serializeSkill(skill));
1930
+ filesWritten.push(filepath);
1931
+ }
1932
+ }
1933
+ if (effective.includes("commands")) {
1934
+ const commandsDir = resolve7(vibeDir, "commands");
1935
+ if (deleteExisting) {
1936
+ removeIfExists(commandsDir);
1937
+ filesDeleted.push(commandsDir);
1938
+ }
1939
+ ensureDir(commandsDir);
1940
+ const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID5));
1941
+ for (const command of commands) {
1942
+ const filepath = join12(commandsDir, `${command.name}.md`);
1943
+ writeGeneratedFile(filepath, command.content);
1944
+ filesWritten.push(filepath);
1945
+ }
1946
+ }
1947
+ let hasMcpConfig = false;
1948
+ if (effective.includes("mcp")) {
1949
+ const mcpEntries = Object.entries(features.mcpServers);
1950
+ if (mcpEntries.length > 0) {
1951
+ const filepath = resolve7(vibeDir, "mcp.json");
1952
+ writeGeneratedJson(filepath, { mcpServers: features.mcpServers }, {
1953
+ header: false
1954
+ });
1955
+ filesWritten.push(filepath);
1956
+ hasMcpConfig = true;
1957
+ }
1958
+ }
1959
+ if (effective.includes("ignore") && features.ignorePatterns.length > 0) {
1960
+ const filepath = resolve7(root, ".vibeignore");
1961
+ writeGeneratedFile(filepath, features.ignorePatterns.join(`
1962
+ `) + `
1963
+ `);
1964
+ filesWritten.push(filepath);
1965
+ }
1966
+ let defaultModel;
1967
+ let smallModel;
1968
+ if (effective.includes("models") && features.models) {
1969
+ const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID5);
1970
+ defaultModel = resolved.default;
1971
+ smallModel = resolved.small;
1972
+ const guidance = generateModelGuidanceMarkdown(resolved);
1973
+ if (guidance) {
1974
+ const filepath = join12(vibeDir, "model-config.md");
1975
+ writeGeneratedFile(filepath, guidance);
1976
+ filesWritten.push(filepath);
1977
+ }
1978
+ }
1979
+ const vibeConfig = buildVibeConfigToml({
1980
+ hasMcpConfig,
1981
+ defaultModel,
1982
+ smallModel,
1983
+ profile: options.modelProfile
1984
+ });
1985
+ if (vibeConfig.length > 0) {
1986
+ const filepath = resolve7(vibeDir, "config.toml");
1987
+ writeGeneratedFile(filepath, vibeConfig);
1988
+ filesWritten.push(filepath);
1989
+ }
1990
+ return this.createResult(filesWritten, filesDeleted, warnings);
1991
+ }
1992
+ }
1993
+ function buildVibeConfigToml(options) {
1994
+ const lines = [];
1995
+ if (options.defaultModel || options.smallModel || options.profile) {
1996
+ lines.push("[models]");
1997
+ if (options.defaultModel) {
1998
+ lines.push(`default = "${escapeTomlString(options.defaultModel)}"`);
1999
+ }
2000
+ if (options.smallModel) {
2001
+ lines.push(`small = "${escapeTomlString(options.smallModel)}"`);
2002
+ }
2003
+ if (options.profile) {
2004
+ lines.push(`profile = "${escapeTomlString(options.profile)}"`);
2005
+ }
2006
+ lines.push("");
2007
+ }
2008
+ if (options.hasMcpConfig) {
2009
+ lines.push("[mcp]");
2010
+ lines.push('config_path = ".vibe/mcp.json"');
2011
+ lines.push("");
2012
+ }
2013
+ return lines.join(`
2014
+ `).trim();
2015
+ }
2016
+ function escapeTomlString(value) {
2017
+ return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
2018
+ }
2019
+
2020
+ // src/targets/gemini-cli.ts
2021
+ import { resolve as resolve8, join as join13 } from "path";
2022
+ var TARGET_ID6 = "geminicli";
2023
+
2024
+ class GeminiCliTarget extends BaseTarget {
2025
+ id = TARGET_ID6;
1818
2026
  name = "Gemini CLI";
1819
2027
  supportedFeatures = [
1820
2028
  "rules",
@@ -1826,49 +2034,49 @@ class GeminiCliTarget extends BaseTarget {
1826
2034
  ];
1827
2035
  generate(options) {
1828
2036
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
1829
- const root = resolve7(projectRoot, baseDir);
2037
+ const root = resolve8(projectRoot, baseDir);
1830
2038
  const effective = this.getEffectiveFeatures(enabledFeatures);
1831
2039
  const filesWritten = [];
1832
2040
  const filesDeleted = [];
1833
2041
  const warnings = [];
1834
- const geminiDir = resolve7(root, ".gemini");
2042
+ const geminiDir = resolve8(root, ".gemini");
1835
2043
  if (effective.includes("rules")) {
1836
- const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID5));
2044
+ const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID6));
1837
2045
  const rootRules = getRootRules(rules);
1838
2046
  const detailRules = getDetailRules(rules);
1839
2047
  if (rootRules.length > 0) {
1840
2048
  const geminiMd = rootRules.map((r) => r.content).join(`
1841
2049
 
1842
2050
  `);
1843
- const filepath = resolve7(root, "GEMINI.md");
2051
+ const filepath = resolve8(root, "GEMINI.md");
1844
2052
  writeGeneratedFile(filepath, geminiMd);
1845
2053
  filesWritten.push(filepath);
1846
2054
  }
1847
2055
  if (detailRules.length > 0) {
1848
- const memoriesDir = resolve7(geminiDir, "memories");
2056
+ const memoriesDir = resolve8(geminiDir, "memories");
1849
2057
  if (deleteExisting) {
1850
2058
  removeIfExists(memoriesDir);
1851
2059
  filesDeleted.push(memoriesDir);
1852
2060
  }
1853
2061
  ensureDir(memoriesDir);
1854
2062
  for (const rule of detailRules) {
1855
- const filepath = join12(memoriesDir, `${rule.name}.md`);
2063
+ const filepath = join13(memoriesDir, `${rule.name}.md`);
1856
2064
  writeGeneratedFile(filepath, rule.content);
1857
2065
  filesWritten.push(filepath);
1858
2066
  }
1859
2067
  }
1860
2068
  }
1861
2069
  if (effective.includes("commands")) {
1862
- const commandsDir = resolve7(geminiDir, "commands");
2070
+ const commandsDir = resolve8(geminiDir, "commands");
1863
2071
  if (deleteExisting) {
1864
2072
  removeIfExists(commandsDir);
1865
2073
  filesDeleted.push(commandsDir);
1866
2074
  }
1867
2075
  ensureDir(commandsDir);
1868
- const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID5));
2076
+ const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID6));
1869
2077
  for (const cmd of commands) {
1870
2078
  const toml = buildGeminiCommand(cmd.name, cmd.meta.description ?? "", cmd.content);
1871
- const filepath = join12(commandsDir, `${cmd.name}.toml`);
2079
+ const filepath = join13(commandsDir, `${cmd.name}.toml`);
1872
2080
  writeGeneratedFile(filepath, toml, { type: "md" });
1873
2081
  filesWritten.push(filepath);
1874
2082
  }
@@ -1877,14 +2085,14 @@ class GeminiCliTarget extends BaseTarget {
1877
2085
  const mcpEntries = Object.entries(features.mcpServers);
1878
2086
  if (mcpEntries.length > 0) {
1879
2087
  const settings = buildGeminiSettings(features.mcpServers);
1880
- const filepath = resolve7(geminiDir, "settings.json");
2088
+ const filepath = resolve8(geminiDir, "settings.json");
1881
2089
  writeGeneratedJson(filepath, settings, { header: false });
1882
2090
  filesWritten.push(filepath);
1883
2091
  }
1884
2092
  }
1885
2093
  if (effective.includes("ignore")) {
1886
2094
  if (features.ignorePatterns.length > 0) {
1887
- const filepath = resolve7(root, ".geminiignore");
2095
+ const filepath = resolve8(root, ".geminiignore");
1888
2096
  const content = features.ignorePatterns.join(`
1889
2097
  `) + `
1890
2098
  `;
@@ -1923,11 +2131,11 @@ function buildGeminiSettings(servers) {
1923
2131
  }
1924
2132
 
1925
2133
  // src/targets/copilot.ts
1926
- import { resolve as resolve8, join as join13 } from "path";
1927
- var TARGET_ID6 = "copilot";
2134
+ import { resolve as resolve9, join as join14 } from "path";
2135
+ var TARGET_ID7 = "copilot";
1928
2136
 
1929
2137
  class CopilotTarget extends BaseTarget {
1930
- id = TARGET_ID6;
2138
+ id = TARGET_ID7;
1931
2139
  name = "GitHub Copilot";
1932
2140
  supportedFeatures = [
1933
2141
  "rules",
@@ -1940,81 +2148,81 @@ class CopilotTarget extends BaseTarget {
1940
2148
  ];
1941
2149
  generate(options) {
1942
2150
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
1943
- const root = resolve8(projectRoot, baseDir);
2151
+ const root = resolve9(projectRoot, baseDir);
1944
2152
  const effective = this.getEffectiveFeatures(enabledFeatures);
1945
2153
  const filesWritten = [];
1946
2154
  const filesDeleted = [];
1947
2155
  const warnings = [];
1948
- const githubDir = resolve8(root, ".github");
2156
+ const githubDir = resolve9(root, ".github");
1949
2157
  if (effective.includes("rules")) {
1950
- const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID6));
2158
+ const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID7));
1951
2159
  if (rules.length > 0) {
1952
2160
  const combinedContent = rules.map((r) => r.content).join(`
1953
2161
 
1954
2162
  ---
1955
2163
 
1956
2164
  `);
1957
- const filepath = resolve8(githubDir, "copilot-instructions.md");
2165
+ const filepath = resolve9(githubDir, "copilot-instructions.md");
1958
2166
  ensureDir(githubDir);
1959
2167
  writeGeneratedFile(filepath, combinedContent);
1960
2168
  filesWritten.push(filepath);
1961
2169
  }
1962
2170
  }
1963
2171
  if (effective.includes("agents")) {
1964
- const copilotDir = resolve8(githubDir, "copilot");
1965
- const agentsDir = resolve8(copilotDir, "agents");
2172
+ const copilotDir = resolve9(githubDir, "copilot");
2173
+ const agentsDir = resolve9(copilotDir, "agents");
1966
2174
  if (deleteExisting) {
1967
2175
  removeIfExists(agentsDir);
1968
2176
  filesDeleted.push(agentsDir);
1969
2177
  }
1970
2178
  ensureDir(agentsDir);
1971
- const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID6));
2179
+ const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID7));
1972
2180
  for (const agent of agents) {
1973
- const filepath = join13(agentsDir, `${agent.name}.md`);
2181
+ const filepath = join14(agentsDir, `${agent.name}.md`);
1974
2182
  writeGeneratedFile(filepath, agent.content);
1975
2183
  filesWritten.push(filepath);
1976
2184
  }
1977
2185
  }
1978
2186
  if (effective.includes("skills")) {
1979
- const copilotDir = resolve8(githubDir, "copilot");
1980
- const skillsDir = resolve8(copilotDir, "skills");
2187
+ const copilotDir = resolve9(githubDir, "copilot");
2188
+ const skillsDir = resolve9(copilotDir, "skills");
1981
2189
  if (deleteExisting) {
1982
2190
  removeIfExists(skillsDir);
1983
2191
  filesDeleted.push(skillsDir);
1984
2192
  }
1985
2193
  ensureDir(skillsDir);
1986
- const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID6));
2194
+ const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID7));
1987
2195
  for (const skill of skills) {
1988
- const skillSubDir = join13(skillsDir, skill.name);
2196
+ const skillSubDir = join14(skillsDir, skill.name);
1989
2197
  ensureDir(skillSubDir);
1990
- const filepath = join13(skillSubDir, "SKILL.md");
1991
- writeGeneratedFile(filepath, skill.content);
2198
+ const filepath = join14(skillSubDir, "SKILL.md");
2199
+ writeGeneratedFile(filepath, serializeSkill(skill));
1992
2200
  filesWritten.push(filepath);
1993
2201
  }
1994
2202
  }
1995
2203
  if (effective.includes("commands")) {
1996
- const copilotDir = resolve8(githubDir, "copilot");
1997
- const commandsDir = resolve8(copilotDir, "commands");
2204
+ const copilotDir = resolve9(githubDir, "copilot");
2205
+ const commandsDir = resolve9(copilotDir, "commands");
1998
2206
  if (deleteExisting) {
1999
2207
  removeIfExists(commandsDir);
2000
2208
  filesDeleted.push(commandsDir);
2001
2209
  }
2002
2210
  ensureDir(commandsDir);
2003
- const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID6));
2211
+ const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID7));
2004
2212
  for (const cmd of commands) {
2005
- const filepath = join13(commandsDir, `${cmd.name}.md`);
2213
+ const filepath = join14(commandsDir, `${cmd.name}.md`);
2006
2214
  writeGeneratedFile(filepath, cmd.content);
2007
2215
  filesWritten.push(filepath);
2008
2216
  }
2009
2217
  }
2010
2218
  if (effective.includes("ignore")) {}
2011
2219
  if (effective.includes("models") && features.models) {
2012
- const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID6);
2220
+ const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID7);
2013
2221
  const guidance = generateModelGuidanceMarkdown(resolved);
2014
2222
  if (guidance) {
2015
- const copilotDir = resolve8(githubDir, "copilot");
2223
+ const copilotDir = resolve9(githubDir, "copilot");
2016
2224
  ensureDir(copilotDir);
2017
- const filepath = join13(copilotDir, "model-config.md");
2225
+ const filepath = join14(copilotDir, "model-config.md");
2018
2226
  writeGeneratedFile(filepath, guidance);
2019
2227
  filesWritten.push(filepath);
2020
2228
  }
@@ -2024,14 +2232,14 @@ class CopilotTarget extends BaseTarget {
2024
2232
  }
2025
2233
 
2026
2234
  // src/targets/agents-md.ts
2027
- import { resolve as resolve9 } from "path";
2235
+ import { resolve as resolve10 } from "path";
2028
2236
  class AgentsMdTarget extends BaseTarget {
2029
2237
  id = "agentsmd";
2030
2238
  name = "AGENTS.md";
2031
2239
  supportedFeatures = ["rules"];
2032
2240
  generate(options) {
2033
2241
  const { projectRoot, baseDir, features } = options;
2034
- const root = resolve9(projectRoot, baseDir);
2242
+ const root = resolve10(projectRoot, baseDir);
2035
2243
  const filesWritten = [];
2036
2244
  const warnings = [];
2037
2245
  const rootRules = getRootRules(features.rules);
@@ -2043,7 +2251,7 @@ class AgentsMdTarget extends BaseTarget {
2043
2251
  const content = sections.join(`
2044
2252
 
2045
2253
  `);
2046
- const filepath = resolve9(root, "AGENTS.md");
2254
+ const filepath = resolve10(root, "AGENTS.md");
2047
2255
  writeGeneratedFile(filepath, content);
2048
2256
  filesWritten.push(filepath);
2049
2257
  return this.createResult(filesWritten, [], warnings);
@@ -2051,7 +2259,7 @@ class AgentsMdTarget extends BaseTarget {
2051
2259
  }
2052
2260
 
2053
2261
  // src/targets/generic-md-target.ts
2054
- import { resolve as resolve10, join as join14 } from "path";
2262
+ import { resolve as resolve11, join as join15 } from "path";
2055
2263
  function createGenericMdTarget(config) {
2056
2264
  return new GenericMdTarget(config);
2057
2265
  }
@@ -2070,16 +2278,16 @@ class GenericMdTarget extends BaseTarget {
2070
2278
  }
2071
2279
  generate(options) {
2072
2280
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
2073
- const root = resolve10(projectRoot, baseDir);
2281
+ const root = resolve11(projectRoot, baseDir);
2074
2282
  const effective = this.getEffectiveFeatures(enabledFeatures);
2075
2283
  const filesWritten = [];
2076
2284
  const filesDeleted = [];
2077
2285
  const warnings = [];
2078
- const configDir = resolve10(root, this.config.configDir);
2286
+ const configDir = resolve11(root, this.config.configDir);
2079
2287
  const rulesSubDir = this.config.rulesDir ?? "rules";
2080
2288
  const ext = this.config.ruleExtension ?? ".md";
2081
2289
  if (effective.includes("rules")) {
2082
- const rulesDir = resolve10(configDir, rulesSubDir);
2290
+ const rulesDir = resolve11(configDir, rulesSubDir);
2083
2291
  if (deleteExisting) {
2084
2292
  removeIfExists(rulesDir);
2085
2293
  filesDeleted.push(rulesDir);
@@ -2087,13 +2295,13 @@ class GenericMdTarget extends BaseTarget {
2087
2295
  ensureDir(rulesDir);
2088
2296
  const rules = features.rules.filter((r) => ruleMatchesTarget(r, this.id));
2089
2297
  for (const rule of rules) {
2090
- const filepath = join14(rulesDir, `${rule.name}${ext}`);
2298
+ const filepath = join15(rulesDir, `${rule.name}${ext}`);
2091
2299
  writeGeneratedFile(filepath, rule.content);
2092
2300
  filesWritten.push(filepath);
2093
2301
  }
2094
2302
  }
2095
2303
  if (effective.includes("commands")) {
2096
- const commandsDir = resolve10(configDir, "commands");
2304
+ const commandsDir = resolve11(configDir, "commands");
2097
2305
  if (deleteExisting) {
2098
2306
  removeIfExists(commandsDir);
2099
2307
  filesDeleted.push(commandsDir);
@@ -2101,7 +2309,7 @@ class GenericMdTarget extends BaseTarget {
2101
2309
  ensureDir(commandsDir);
2102
2310
  const commands = features.commands.filter((c) => commandMatchesTarget(c, this.id));
2103
2311
  for (const cmd of commands) {
2104
- const filepath = join14(commandsDir, `${cmd.name}.md`);
2312
+ const filepath = join15(commandsDir, `${cmd.name}.md`);
2105
2313
  writeGeneratedFile(filepath, cmd.content);
2106
2314
  filesWritten.push(filepath);
2107
2315
  }
@@ -2110,7 +2318,7 @@ class GenericMdTarget extends BaseTarget {
2110
2318
  const mcpEntries = Object.entries(features.mcpServers);
2111
2319
  if (mcpEntries.length > 0) {
2112
2320
  const mcpDir = this.config.mcpInConfigDir ? configDir : root;
2113
- const filepath = resolve10(mcpDir, "mcp.json");
2321
+ const filepath = resolve11(mcpDir, "mcp.json");
2114
2322
  writeGeneratedJson(filepath, { mcpServers: features.mcpServers }, {
2115
2323
  header: false
2116
2324
  });
@@ -2119,7 +2327,7 @@ class GenericMdTarget extends BaseTarget {
2119
2327
  }
2120
2328
  if (effective.includes("ignore") && this.config.ignoreFile) {
2121
2329
  if (features.ignorePatterns.length > 0) {
2122
- const filepath = resolve10(root, this.config.ignoreFile);
2330
+ const filepath = resolve11(root, this.config.ignoreFile);
2123
2331
  writeGeneratedFile(filepath, features.ignorePatterns.join(`
2124
2332
  `) + `
2125
2333
  `);
@@ -2131,7 +2339,7 @@ class GenericMdTarget extends BaseTarget {
2131
2339
  const guidance = generateModelGuidanceMarkdown(resolved);
2132
2340
  if (guidance) {
2133
2341
  ensureDir(configDir);
2134
- const filepath = join14(configDir, "model-config.md");
2342
+ const filepath = join15(configDir, "model-config.md");
2135
2343
  writeGeneratedFile(filepath, guidance);
2136
2344
  filesWritten.push(filepath);
2137
2345
  }
@@ -2243,6 +2451,7 @@ var TARGETS = [
2243
2451
  new CursorTarget,
2244
2452
  new ClaudeCodeTarget,
2245
2453
  new CodexCliTarget,
2454
+ new MistralVibeTarget,
2246
2455
  new GeminiCliTarget,
2247
2456
  new CopilotTarget,
2248
2457
  new AgentsMdTarget,