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
@@ -219,6 +219,8 @@ function agentMatchesTarget(agent, targetId) {
219
219
  // src/features/skills.ts
220
220
  import { readFileSync as readFileSync5, existsSync as existsSync2 } from "fs";
221
221
  import { basename as basename4, join as join2 } from "path";
222
+ var SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
223
+ var SKILL_NAME_MAX_LENGTH = 64;
222
224
  function parseSkills(skillsDir, packName) {
223
225
  const dirs = listDirs(skillsDir);
224
226
  const skills = [];
@@ -242,6 +244,59 @@ function parseSkillFile(filepath, skillDir, packName) {
242
244
  content
243
245
  };
244
246
  }
247
+ function buildSkillFrontmatter(skill) {
248
+ return {
249
+ ...skill.meta,
250
+ name: skill.name
251
+ };
252
+ }
253
+ function serializeSkill(skill) {
254
+ return serializeFrontmatter(buildSkillFrontmatter(skill), skill.content);
255
+ }
256
+ function normalizeImportedSkillMarkdown(source, skillName) {
257
+ const { data, content } = parseFrontmatter(source);
258
+ const normalized = {
259
+ ...data,
260
+ name: skillName
261
+ };
262
+ let addedDescription = false;
263
+ const description = normalized.description;
264
+ if (typeof description !== "string" || description.trim().length === 0) {
265
+ normalized.description = `Imported skill: ${skillName}`;
266
+ addedDescription = true;
267
+ }
268
+ return {
269
+ content: serializeFrontmatter(normalized, content),
270
+ addedDescription
271
+ };
272
+ }
273
+ function validateAgentSkillsFrontmatter(skill) {
274
+ const errors = [];
275
+ const dirName = basename4(skill.sourceDir);
276
+ const declaredName = skill.meta.name;
277
+ if (typeof declaredName !== "string" || declaredName.trim().length === 0) {
278
+ errors.push('Missing required frontmatter field "name".');
279
+ } else {
280
+ if (declaredName.length > SKILL_NAME_MAX_LENGTH) {
281
+ errors.push(`Invalid "name": must be at most ${SKILL_NAME_MAX_LENGTH} characters.`);
282
+ }
283
+ if (!SKILL_NAME_PATTERN.test(declaredName)) {
284
+ errors.push('Invalid "name": use lowercase letters, numbers, and single hyphens only.');
285
+ }
286
+ if (declaredName !== dirName) {
287
+ errors.push(`Invalid "name": must match containing directory "${dirName}".`);
288
+ }
289
+ }
290
+ const description = skill.meta.description;
291
+ if (typeof description !== "string" || description.trim().length === 0) {
292
+ errors.push('Missing required frontmatter field "description".');
293
+ }
294
+ const allowedTools = skill.meta["allowed-tools"];
295
+ if (allowedTools !== undefined && (!Array.isArray(allowedTools) || allowedTools.some((tool) => typeof tool !== "string" || tool.length === 0))) {
296
+ errors.push('Invalid "allowed-tools": expected an array of non-empty strings.');
297
+ }
298
+ return errors;
299
+ }
245
300
  function skillMatchesTarget(skill, targetId) {
246
301
  const { targets } = skill.meta;
247
302
  if (!targets || targets === "*")
@@ -503,7 +558,7 @@ class OpenCodeTarget extends BaseTarget {
503
558
  const skillSubDir = join4(skillDir, skill.name);
504
559
  ensureDir(skillSubDir);
505
560
  const filepath = join4(skillSubDir, "SKILL.md");
506
- writeGeneratedFile(filepath, skill.content);
561
+ writeGeneratedFile(filepath, serializeSkill(skill));
507
562
  filesWritten.push(filepath);
508
563
  }
509
564
  }
@@ -758,12 +813,8 @@ class CursorTarget extends BaseTarget {
758
813
  for (const skill of skills) {
759
814
  const skillSubDir = join5(skillsDir, skill.name);
760
815
  ensureDir(skillSubDir);
761
- const frontmatter = {
762
- name: skill.name,
763
- description: skill.meta.description ?? ""
764
- };
765
816
  const filepath = join5(skillSubDir, "SKILL.md");
766
- const content = serializeFrontmatter(frontmatter, skill.content);
817
+ const content = serializeSkill(skill);
767
818
  writeGeneratedFile(filepath, content);
768
819
  filesWritten.push(filepath);
769
820
  }
@@ -1063,7 +1114,7 @@ ${content}`;
1063
1114
  const skillSubDir = join6(skillsDir, skill.name);
1064
1115
  ensureDir(skillSubDir);
1065
1116
  const filepath = join6(skillSubDir, "SKILL.md");
1066
- writeGeneratedFile(filepath, skill.content);
1117
+ writeGeneratedFile(filepath, serializeSkill(skill));
1067
1118
  filesWritten.push(filepath);
1068
1119
  }
1069
1120
  }
@@ -1193,7 +1244,7 @@ class CodexCliTarget extends BaseTarget {
1193
1244
  const skillSubDir = join7(skillsDir, skill.name);
1194
1245
  ensureDir(skillSubDir);
1195
1246
  const filepath = join7(skillSubDir, "SKILL.md");
1196
- writeGeneratedFile(filepath, skill.content);
1247
+ writeGeneratedFile(filepath, serializeSkill(skill));
1197
1248
  filesWritten.push(filepath);
1198
1249
  }
1199
1250
  }
@@ -1201,12 +1252,168 @@ class CodexCliTarget extends BaseTarget {
1201
1252
  }
1202
1253
  }
1203
1254
 
1204
- // src/targets/gemini-cli.ts
1255
+ // src/targets/mistral-vibe.ts
1205
1256
  import { resolve as resolve5, join as join8 } from "path";
1206
- var TARGET_ID5 = "geminicli";
1257
+ var TARGET_ID5 = "mistralvibe";
1207
1258
 
1208
- class GeminiCliTarget extends BaseTarget {
1259
+ class MistralVibeTarget extends BaseTarget {
1209
1260
  id = TARGET_ID5;
1261
+ name = "Mistral Vibe";
1262
+ supportedFeatures = [
1263
+ "rules",
1264
+ "commands",
1265
+ "agents",
1266
+ "skills",
1267
+ "mcp",
1268
+ "ignore",
1269
+ "models"
1270
+ ];
1271
+ generate(options) {
1272
+ const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
1273
+ const root = resolve5(projectRoot, baseDir);
1274
+ const effective = this.getEffectiveFeatures(enabledFeatures);
1275
+ const filesWritten = [];
1276
+ const filesDeleted = [];
1277
+ const warnings = [];
1278
+ const vibeDir = resolve5(root, ".vibe");
1279
+ ensureDir(vibeDir);
1280
+ if (effective.includes("rules")) {
1281
+ const rulesDir = resolve5(vibeDir, "rules");
1282
+ if (deleteExisting) {
1283
+ removeIfExists(rulesDir);
1284
+ filesDeleted.push(rulesDir);
1285
+ }
1286
+ ensureDir(rulesDir);
1287
+ const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID5));
1288
+ for (const rule of rules) {
1289
+ const filepath = join8(rulesDir, `${rule.name}.md`);
1290
+ writeGeneratedFile(filepath, rule.content);
1291
+ filesWritten.push(filepath);
1292
+ }
1293
+ }
1294
+ if (effective.includes("agents")) {
1295
+ const agentsDir = resolve5(vibeDir, "agents");
1296
+ if (deleteExisting) {
1297
+ removeIfExists(agentsDir);
1298
+ filesDeleted.push(agentsDir);
1299
+ }
1300
+ ensureDir(agentsDir);
1301
+ const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID5));
1302
+ for (const agent of agents) {
1303
+ const filepath = join8(agentsDir, `${agent.name}.md`);
1304
+ writeGeneratedFile(filepath, agent.content);
1305
+ filesWritten.push(filepath);
1306
+ }
1307
+ }
1308
+ if (effective.includes("skills")) {
1309
+ const skillsDir = resolve5(vibeDir, "skills");
1310
+ if (deleteExisting) {
1311
+ removeIfExists(skillsDir);
1312
+ filesDeleted.push(skillsDir);
1313
+ }
1314
+ ensureDir(skillsDir);
1315
+ const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID5));
1316
+ for (const skill of skills) {
1317
+ const skillSubDir = join8(skillsDir, skill.name);
1318
+ ensureDir(skillSubDir);
1319
+ const filepath = join8(skillSubDir, "SKILL.md");
1320
+ writeGeneratedFile(filepath, serializeSkill(skill));
1321
+ filesWritten.push(filepath);
1322
+ }
1323
+ }
1324
+ if (effective.includes("commands")) {
1325
+ const commandsDir = resolve5(vibeDir, "commands");
1326
+ if (deleteExisting) {
1327
+ removeIfExists(commandsDir);
1328
+ filesDeleted.push(commandsDir);
1329
+ }
1330
+ ensureDir(commandsDir);
1331
+ const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID5));
1332
+ for (const command of commands) {
1333
+ const filepath = join8(commandsDir, `${command.name}.md`);
1334
+ writeGeneratedFile(filepath, command.content);
1335
+ filesWritten.push(filepath);
1336
+ }
1337
+ }
1338
+ let hasMcpConfig = false;
1339
+ if (effective.includes("mcp")) {
1340
+ const mcpEntries = Object.entries(features.mcpServers);
1341
+ if (mcpEntries.length > 0) {
1342
+ const filepath = resolve5(vibeDir, "mcp.json");
1343
+ writeGeneratedJson(filepath, { mcpServers: features.mcpServers }, {
1344
+ header: false
1345
+ });
1346
+ filesWritten.push(filepath);
1347
+ hasMcpConfig = true;
1348
+ }
1349
+ }
1350
+ if (effective.includes("ignore") && features.ignorePatterns.length > 0) {
1351
+ const filepath = resolve5(root, ".vibeignore");
1352
+ writeGeneratedFile(filepath, features.ignorePatterns.join(`
1353
+ `) + `
1354
+ `);
1355
+ filesWritten.push(filepath);
1356
+ }
1357
+ let defaultModel;
1358
+ let smallModel;
1359
+ if (effective.includes("models") && features.models) {
1360
+ const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID5);
1361
+ defaultModel = resolved.default;
1362
+ smallModel = resolved.small;
1363
+ const guidance = generateModelGuidanceMarkdown(resolved);
1364
+ if (guidance) {
1365
+ const filepath = join8(vibeDir, "model-config.md");
1366
+ writeGeneratedFile(filepath, guidance);
1367
+ filesWritten.push(filepath);
1368
+ }
1369
+ }
1370
+ const vibeConfig = buildVibeConfigToml({
1371
+ hasMcpConfig,
1372
+ defaultModel,
1373
+ smallModel,
1374
+ profile: options.modelProfile
1375
+ });
1376
+ if (vibeConfig.length > 0) {
1377
+ const filepath = resolve5(vibeDir, "config.toml");
1378
+ writeGeneratedFile(filepath, vibeConfig);
1379
+ filesWritten.push(filepath);
1380
+ }
1381
+ return this.createResult(filesWritten, filesDeleted, warnings);
1382
+ }
1383
+ }
1384
+ function buildVibeConfigToml(options) {
1385
+ const lines = [];
1386
+ if (options.defaultModel || options.smallModel || options.profile) {
1387
+ lines.push("[models]");
1388
+ if (options.defaultModel) {
1389
+ lines.push(`default = "${escapeTomlString(options.defaultModel)}"`);
1390
+ }
1391
+ if (options.smallModel) {
1392
+ lines.push(`small = "${escapeTomlString(options.smallModel)}"`);
1393
+ }
1394
+ if (options.profile) {
1395
+ lines.push(`profile = "${escapeTomlString(options.profile)}"`);
1396
+ }
1397
+ lines.push("");
1398
+ }
1399
+ if (options.hasMcpConfig) {
1400
+ lines.push("[mcp]");
1401
+ lines.push('config_path = ".vibe/mcp.json"');
1402
+ lines.push("");
1403
+ }
1404
+ return lines.join(`
1405
+ `).trim();
1406
+ }
1407
+ function escapeTomlString(value) {
1408
+ return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
1409
+ }
1410
+
1411
+ // src/targets/gemini-cli.ts
1412
+ import { resolve as resolve6, join as join9 } from "path";
1413
+ var TARGET_ID6 = "geminicli";
1414
+
1415
+ class GeminiCliTarget extends BaseTarget {
1416
+ id = TARGET_ID6;
1210
1417
  name = "Gemini CLI";
1211
1418
  supportedFeatures = [
1212
1419
  "rules",
@@ -1218,49 +1425,49 @@ class GeminiCliTarget extends BaseTarget {
1218
1425
  ];
1219
1426
  generate(options) {
1220
1427
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
1221
- const root = resolve5(projectRoot, baseDir);
1428
+ const root = resolve6(projectRoot, baseDir);
1222
1429
  const effective = this.getEffectiveFeatures(enabledFeatures);
1223
1430
  const filesWritten = [];
1224
1431
  const filesDeleted = [];
1225
1432
  const warnings = [];
1226
- const geminiDir = resolve5(root, ".gemini");
1433
+ const geminiDir = resolve6(root, ".gemini");
1227
1434
  if (effective.includes("rules")) {
1228
- const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID5));
1435
+ const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID6));
1229
1436
  const rootRules = getRootRules(rules);
1230
1437
  const detailRules = getDetailRules(rules);
1231
1438
  if (rootRules.length > 0) {
1232
1439
  const geminiMd = rootRules.map((r) => r.content).join(`
1233
1440
 
1234
1441
  `);
1235
- const filepath = resolve5(root, "GEMINI.md");
1442
+ const filepath = resolve6(root, "GEMINI.md");
1236
1443
  writeGeneratedFile(filepath, geminiMd);
1237
1444
  filesWritten.push(filepath);
1238
1445
  }
1239
1446
  if (detailRules.length > 0) {
1240
- const memoriesDir = resolve5(geminiDir, "memories");
1447
+ const memoriesDir = resolve6(geminiDir, "memories");
1241
1448
  if (deleteExisting) {
1242
1449
  removeIfExists(memoriesDir);
1243
1450
  filesDeleted.push(memoriesDir);
1244
1451
  }
1245
1452
  ensureDir(memoriesDir);
1246
1453
  for (const rule of detailRules) {
1247
- const filepath = join8(memoriesDir, `${rule.name}.md`);
1454
+ const filepath = join9(memoriesDir, `${rule.name}.md`);
1248
1455
  writeGeneratedFile(filepath, rule.content);
1249
1456
  filesWritten.push(filepath);
1250
1457
  }
1251
1458
  }
1252
1459
  }
1253
1460
  if (effective.includes("commands")) {
1254
- const commandsDir = resolve5(geminiDir, "commands");
1461
+ const commandsDir = resolve6(geminiDir, "commands");
1255
1462
  if (deleteExisting) {
1256
1463
  removeIfExists(commandsDir);
1257
1464
  filesDeleted.push(commandsDir);
1258
1465
  }
1259
1466
  ensureDir(commandsDir);
1260
- const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID5));
1467
+ const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID6));
1261
1468
  for (const cmd of commands) {
1262
1469
  const toml = buildGeminiCommand(cmd.name, cmd.meta.description ?? "", cmd.content);
1263
- const filepath = join8(commandsDir, `${cmd.name}.toml`);
1470
+ const filepath = join9(commandsDir, `${cmd.name}.toml`);
1264
1471
  writeGeneratedFile(filepath, toml, { type: "md" });
1265
1472
  filesWritten.push(filepath);
1266
1473
  }
@@ -1269,14 +1476,14 @@ class GeminiCliTarget extends BaseTarget {
1269
1476
  const mcpEntries = Object.entries(features.mcpServers);
1270
1477
  if (mcpEntries.length > 0) {
1271
1478
  const settings = buildGeminiSettings(features.mcpServers);
1272
- const filepath = resolve5(geminiDir, "settings.json");
1479
+ const filepath = resolve6(geminiDir, "settings.json");
1273
1480
  writeGeneratedJson(filepath, settings, { header: false });
1274
1481
  filesWritten.push(filepath);
1275
1482
  }
1276
1483
  }
1277
1484
  if (effective.includes("ignore")) {
1278
1485
  if (features.ignorePatterns.length > 0) {
1279
- const filepath = resolve5(root, ".geminiignore");
1486
+ const filepath = resolve6(root, ".geminiignore");
1280
1487
  const content = features.ignorePatterns.join(`
1281
1488
  `) + `
1282
1489
  `;
@@ -1315,11 +1522,11 @@ function buildGeminiSettings(servers) {
1315
1522
  }
1316
1523
 
1317
1524
  // src/targets/copilot.ts
1318
- import { resolve as resolve6, join as join9 } from "path";
1319
- var TARGET_ID6 = "copilot";
1525
+ import { resolve as resolve7, join as join10 } from "path";
1526
+ var TARGET_ID7 = "copilot";
1320
1527
 
1321
1528
  class CopilotTarget extends BaseTarget {
1322
- id = TARGET_ID6;
1529
+ id = TARGET_ID7;
1323
1530
  name = "GitHub Copilot";
1324
1531
  supportedFeatures = [
1325
1532
  "rules",
@@ -1332,81 +1539,81 @@ class CopilotTarget extends BaseTarget {
1332
1539
  ];
1333
1540
  generate(options) {
1334
1541
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
1335
- const root = resolve6(projectRoot, baseDir);
1542
+ const root = resolve7(projectRoot, baseDir);
1336
1543
  const effective = this.getEffectiveFeatures(enabledFeatures);
1337
1544
  const filesWritten = [];
1338
1545
  const filesDeleted = [];
1339
1546
  const warnings = [];
1340
- const githubDir = resolve6(root, ".github");
1547
+ const githubDir = resolve7(root, ".github");
1341
1548
  if (effective.includes("rules")) {
1342
- const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID6));
1549
+ const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID7));
1343
1550
  if (rules.length > 0) {
1344
1551
  const combinedContent = rules.map((r) => r.content).join(`
1345
1552
 
1346
1553
  ---
1347
1554
 
1348
1555
  `);
1349
- const filepath = resolve6(githubDir, "copilot-instructions.md");
1556
+ const filepath = resolve7(githubDir, "copilot-instructions.md");
1350
1557
  ensureDir(githubDir);
1351
1558
  writeGeneratedFile(filepath, combinedContent);
1352
1559
  filesWritten.push(filepath);
1353
1560
  }
1354
1561
  }
1355
1562
  if (effective.includes("agents")) {
1356
- const copilotDir = resolve6(githubDir, "copilot");
1357
- const agentsDir = resolve6(copilotDir, "agents");
1563
+ const copilotDir = resolve7(githubDir, "copilot");
1564
+ const agentsDir = resolve7(copilotDir, "agents");
1358
1565
  if (deleteExisting) {
1359
1566
  removeIfExists(agentsDir);
1360
1567
  filesDeleted.push(agentsDir);
1361
1568
  }
1362
1569
  ensureDir(agentsDir);
1363
- const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID6));
1570
+ const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID7));
1364
1571
  for (const agent of agents) {
1365
- const filepath = join9(agentsDir, `${agent.name}.md`);
1572
+ const filepath = join10(agentsDir, `${agent.name}.md`);
1366
1573
  writeGeneratedFile(filepath, agent.content);
1367
1574
  filesWritten.push(filepath);
1368
1575
  }
1369
1576
  }
1370
1577
  if (effective.includes("skills")) {
1371
- const copilotDir = resolve6(githubDir, "copilot");
1372
- const skillsDir = resolve6(copilotDir, "skills");
1578
+ const copilotDir = resolve7(githubDir, "copilot");
1579
+ const skillsDir = resolve7(copilotDir, "skills");
1373
1580
  if (deleteExisting) {
1374
1581
  removeIfExists(skillsDir);
1375
1582
  filesDeleted.push(skillsDir);
1376
1583
  }
1377
1584
  ensureDir(skillsDir);
1378
- const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID6));
1585
+ const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID7));
1379
1586
  for (const skill of skills) {
1380
- const skillSubDir = join9(skillsDir, skill.name);
1587
+ const skillSubDir = join10(skillsDir, skill.name);
1381
1588
  ensureDir(skillSubDir);
1382
- const filepath = join9(skillSubDir, "SKILL.md");
1383
- writeGeneratedFile(filepath, skill.content);
1589
+ const filepath = join10(skillSubDir, "SKILL.md");
1590
+ writeGeneratedFile(filepath, serializeSkill(skill));
1384
1591
  filesWritten.push(filepath);
1385
1592
  }
1386
1593
  }
1387
1594
  if (effective.includes("commands")) {
1388
- const copilotDir = resolve6(githubDir, "copilot");
1389
- const commandsDir = resolve6(copilotDir, "commands");
1595
+ const copilotDir = resolve7(githubDir, "copilot");
1596
+ const commandsDir = resolve7(copilotDir, "commands");
1390
1597
  if (deleteExisting) {
1391
1598
  removeIfExists(commandsDir);
1392
1599
  filesDeleted.push(commandsDir);
1393
1600
  }
1394
1601
  ensureDir(commandsDir);
1395
- const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID6));
1602
+ const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID7));
1396
1603
  for (const cmd of commands) {
1397
- const filepath = join9(commandsDir, `${cmd.name}.md`);
1604
+ const filepath = join10(commandsDir, `${cmd.name}.md`);
1398
1605
  writeGeneratedFile(filepath, cmd.content);
1399
1606
  filesWritten.push(filepath);
1400
1607
  }
1401
1608
  }
1402
1609
  if (effective.includes("ignore")) {}
1403
1610
  if (effective.includes("models") && features.models) {
1404
- const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID6);
1611
+ const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID7);
1405
1612
  const guidance = generateModelGuidanceMarkdown(resolved);
1406
1613
  if (guidance) {
1407
- const copilotDir = resolve6(githubDir, "copilot");
1614
+ const copilotDir = resolve7(githubDir, "copilot");
1408
1615
  ensureDir(copilotDir);
1409
- const filepath = join9(copilotDir, "model-config.md");
1616
+ const filepath = join10(copilotDir, "model-config.md");
1410
1617
  writeGeneratedFile(filepath, guidance);
1411
1618
  filesWritten.push(filepath);
1412
1619
  }
@@ -1416,14 +1623,14 @@ class CopilotTarget extends BaseTarget {
1416
1623
  }
1417
1624
 
1418
1625
  // src/targets/agents-md.ts
1419
- import { resolve as resolve7 } from "path";
1626
+ import { resolve as resolve8 } from "path";
1420
1627
  class AgentsMdTarget extends BaseTarget {
1421
1628
  id = "agentsmd";
1422
1629
  name = "AGENTS.md";
1423
1630
  supportedFeatures = ["rules"];
1424
1631
  generate(options) {
1425
1632
  const { projectRoot, baseDir, features } = options;
1426
- const root = resolve7(projectRoot, baseDir);
1633
+ const root = resolve8(projectRoot, baseDir);
1427
1634
  const filesWritten = [];
1428
1635
  const warnings = [];
1429
1636
  const rootRules = getRootRules(features.rules);
@@ -1435,7 +1642,7 @@ class AgentsMdTarget extends BaseTarget {
1435
1642
  const content = sections.join(`
1436
1643
 
1437
1644
  `);
1438
- const filepath = resolve7(root, "AGENTS.md");
1645
+ const filepath = resolve8(root, "AGENTS.md");
1439
1646
  writeGeneratedFile(filepath, content);
1440
1647
  filesWritten.push(filepath);
1441
1648
  return this.createResult(filesWritten, [], warnings);
@@ -1443,7 +1650,7 @@ class AgentsMdTarget extends BaseTarget {
1443
1650
  }
1444
1651
 
1445
1652
  // src/targets/generic-md-target.ts
1446
- import { resolve as resolve8, join as join10 } from "path";
1653
+ import { resolve as resolve9, join as join11 } from "path";
1447
1654
  function createGenericMdTarget(config) {
1448
1655
  return new GenericMdTarget(config);
1449
1656
  }
@@ -1462,16 +1669,16 @@ class GenericMdTarget extends BaseTarget {
1462
1669
  }
1463
1670
  generate(options) {
1464
1671
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
1465
- const root = resolve8(projectRoot, baseDir);
1672
+ const root = resolve9(projectRoot, baseDir);
1466
1673
  const effective = this.getEffectiveFeatures(enabledFeatures);
1467
1674
  const filesWritten = [];
1468
1675
  const filesDeleted = [];
1469
1676
  const warnings = [];
1470
- const configDir = resolve8(root, this.config.configDir);
1677
+ const configDir = resolve9(root, this.config.configDir);
1471
1678
  const rulesSubDir = this.config.rulesDir ?? "rules";
1472
1679
  const ext = this.config.ruleExtension ?? ".md";
1473
1680
  if (effective.includes("rules")) {
1474
- const rulesDir = resolve8(configDir, rulesSubDir);
1681
+ const rulesDir = resolve9(configDir, rulesSubDir);
1475
1682
  if (deleteExisting) {
1476
1683
  removeIfExists(rulesDir);
1477
1684
  filesDeleted.push(rulesDir);
@@ -1479,13 +1686,13 @@ class GenericMdTarget extends BaseTarget {
1479
1686
  ensureDir(rulesDir);
1480
1687
  const rules = features.rules.filter((r) => ruleMatchesTarget(r, this.id));
1481
1688
  for (const rule of rules) {
1482
- const filepath = join10(rulesDir, `${rule.name}${ext}`);
1689
+ const filepath = join11(rulesDir, `${rule.name}${ext}`);
1483
1690
  writeGeneratedFile(filepath, rule.content);
1484
1691
  filesWritten.push(filepath);
1485
1692
  }
1486
1693
  }
1487
1694
  if (effective.includes("commands")) {
1488
- const commandsDir = resolve8(configDir, "commands");
1695
+ const commandsDir = resolve9(configDir, "commands");
1489
1696
  if (deleteExisting) {
1490
1697
  removeIfExists(commandsDir);
1491
1698
  filesDeleted.push(commandsDir);
@@ -1493,7 +1700,7 @@ class GenericMdTarget extends BaseTarget {
1493
1700
  ensureDir(commandsDir);
1494
1701
  const commands = features.commands.filter((c) => commandMatchesTarget(c, this.id));
1495
1702
  for (const cmd of commands) {
1496
- const filepath = join10(commandsDir, `${cmd.name}.md`);
1703
+ const filepath = join11(commandsDir, `${cmd.name}.md`);
1497
1704
  writeGeneratedFile(filepath, cmd.content);
1498
1705
  filesWritten.push(filepath);
1499
1706
  }
@@ -1502,7 +1709,7 @@ class GenericMdTarget extends BaseTarget {
1502
1709
  const mcpEntries = Object.entries(features.mcpServers);
1503
1710
  if (mcpEntries.length > 0) {
1504
1711
  const mcpDir = this.config.mcpInConfigDir ? configDir : root;
1505
- const filepath = resolve8(mcpDir, "mcp.json");
1712
+ const filepath = resolve9(mcpDir, "mcp.json");
1506
1713
  writeGeneratedJson(filepath, { mcpServers: features.mcpServers }, {
1507
1714
  header: false
1508
1715
  });
@@ -1511,7 +1718,7 @@ class GenericMdTarget extends BaseTarget {
1511
1718
  }
1512
1719
  if (effective.includes("ignore") && this.config.ignoreFile) {
1513
1720
  if (features.ignorePatterns.length > 0) {
1514
- const filepath = resolve8(root, this.config.ignoreFile);
1721
+ const filepath = resolve9(root, this.config.ignoreFile);
1515
1722
  writeGeneratedFile(filepath, features.ignorePatterns.join(`
1516
1723
  `) + `
1517
1724
  `);
@@ -1523,7 +1730,7 @@ class GenericMdTarget extends BaseTarget {
1523
1730
  const guidance = generateModelGuidanceMarkdown(resolved);
1524
1731
  if (guidance) {
1525
1732
  ensureDir(configDir);
1526
- const filepath = join10(configDir, "model-config.md");
1733
+ const filepath = join11(configDir, "model-config.md");
1527
1734
  writeGeneratedFile(filepath, guidance);
1528
1735
  filesWritten.push(filepath);
1529
1736
  }
@@ -1635,6 +1842,7 @@ var TARGETS = [
1635
1842
  new CursorTarget,
1636
1843
  new ClaudeCodeTarget,
1637
1844
  new CodexCliTarget,
1845
+ new MistralVibeTarget,
1638
1846
  new GeminiCliTarget,
1639
1847
  new CopilotTarget,
1640
1848
  new AgentsMdTarget,
@@ -1671,6 +1879,7 @@ export {
1671
1879
  getTarget,
1672
1880
  getAllTargets,
1673
1881
  OpenCodeTarget,
1882
+ MistralVibeTarget,
1674
1883
  GeminiCliTarget,
1675
1884
  CursorTarget,
1676
1885
  CopilotTarget,