agentpacks 0.3.0 → 0.4.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 (166) hide show
  1. package/README.md +168 -8
  2. package/dist/api.d.ts +2 -0
  3. package/dist/api.js +929 -409
  4. package/dist/cli/export-cmd.js +281 -149
  5. package/dist/cli/generate.js +740 -247
  6. package/dist/cli/import-cmd.js +57 -85
  7. package/dist/cli/info.d.ts +4 -0
  8. package/dist/cli/info.js +232 -0
  9. package/dist/cli/init.js +8 -36
  10. package/dist/cli/install.js +414 -129
  11. package/dist/cli/login.d.ts +9 -0
  12. package/dist/cli/login.js +202 -0
  13. package/dist/cli/models-explain.d.ts +16 -0
  14. package/dist/cli/models-explain.js +1205 -0
  15. package/dist/cli/pack/create.js +4 -32
  16. package/dist/cli/pack/enable.js +1 -29
  17. package/dist/cli/pack/list.js +266 -134
  18. package/dist/cli/pack/validate.js +274 -127
  19. package/dist/cli/publish.d.ts +8 -0
  20. package/dist/cli/publish.js +672 -0
  21. package/dist/cli/search.d.ts +12 -0
  22. package/dist/cli/search.js +210 -0
  23. package/dist/core/config.d.ts +2 -1
  24. package/dist/core/config.js +74 -117
  25. package/dist/core/dependency-resolver.js +4 -28
  26. package/dist/core/feature-merger.d.ts +7 -0
  27. package/dist/core/feature-merger.js +289 -29
  28. package/dist/core/index.js +283 -140
  29. package/dist/core/lockfile.js +0 -28
  30. package/dist/core/metarepo.js +74 -116
  31. package/dist/core/pack-loader.d.ts +2 -0
  32. package/dist/core/pack-loader.js +266 -133
  33. package/dist/core/profile-resolver.d.ts +75 -0
  34. package/dist/core/profile-resolver.js +111 -0
  35. package/dist/exporters/cursor-plugin.js +4 -32
  36. package/dist/exporters/index.js +4 -32
  37. package/dist/features/agents.d.ts +5 -0
  38. package/dist/features/agents.js +2 -30
  39. package/dist/features/commands.js +2 -30
  40. package/dist/features/hooks.js +2 -30
  41. package/dist/features/ignore.js +0 -28
  42. package/dist/features/index.d.ts +1 -0
  43. package/dist/features/index.js +176 -31
  44. package/dist/features/mcp.js +2 -30
  45. package/dist/features/models.d.ts +167 -0
  46. package/dist/features/models.js +293 -0
  47. package/dist/features/plugins.js +2 -30
  48. package/dist/features/rules.js +2 -30
  49. package/dist/features/skills.js +2 -30
  50. package/dist/importers/claude-code.js +10 -38
  51. package/dist/importers/cursor.js +15 -43
  52. package/dist/importers/opencode.js +16 -44
  53. package/dist/importers/rulesync.js +22 -50
  54. package/dist/index.js +1710 -538
  55. package/dist/node/api.js +929 -409
  56. package/dist/node/cli/export-cmd.js +281 -149
  57. package/dist/node/cli/generate.js +740 -247
  58. package/dist/node/cli/import-cmd.js +57 -85
  59. package/dist/node/cli/info.js +232 -0
  60. package/dist/node/cli/init.js +8 -36
  61. package/dist/node/cli/install.js +414 -129
  62. package/dist/node/cli/login.js +202 -0
  63. package/dist/node/cli/models-explain.js +1205 -0
  64. package/dist/node/cli/pack/create.js +4 -32
  65. package/dist/node/cli/pack/enable.js +1 -29
  66. package/dist/node/cli/pack/list.js +266 -134
  67. package/dist/node/cli/pack/validate.js +274 -127
  68. package/dist/node/cli/publish.js +672 -0
  69. package/dist/node/cli/search.js +210 -0
  70. package/dist/node/core/config.js +74 -117
  71. package/dist/node/core/dependency-resolver.js +4 -28
  72. package/dist/node/core/feature-merger.js +289 -29
  73. package/dist/node/core/index.js +283 -140
  74. package/dist/node/core/lockfile.js +0 -28
  75. package/dist/node/core/metarepo.js +74 -116
  76. package/dist/node/core/pack-loader.js +266 -133
  77. package/dist/node/core/profile-resolver.js +111 -0
  78. package/dist/node/exporters/cursor-plugin.js +4 -32
  79. package/dist/node/exporters/index.js +4 -32
  80. package/dist/node/features/agents.js +2 -30
  81. package/dist/node/features/commands.js +2 -30
  82. package/dist/node/features/hooks.js +2 -30
  83. package/dist/node/features/ignore.js +0 -28
  84. package/dist/node/features/index.js +176 -31
  85. package/dist/node/features/mcp.js +2 -30
  86. package/dist/node/features/models.js +293 -0
  87. package/dist/node/features/plugins.js +2 -30
  88. package/dist/node/features/rules.js +2 -30
  89. package/dist/node/features/skills.js +2 -30
  90. package/dist/node/importers/claude-code.js +10 -38
  91. package/dist/node/importers/cursor.js +15 -43
  92. package/dist/node/importers/opencode.js +16 -44
  93. package/dist/node/importers/rulesync.js +22 -50
  94. package/dist/node/index.js +1710 -538
  95. package/dist/node/sources/git-ref.js +7 -30
  96. package/dist/node/sources/git.js +7 -30
  97. package/dist/node/sources/index.js +337 -39
  98. package/dist/node/sources/local.js +0 -28
  99. package/dist/node/sources/npm-ref.js +0 -28
  100. package/dist/node/sources/npm.js +10 -37
  101. package/dist/node/sources/registry-ref.js +37 -0
  102. package/dist/node/sources/registry.js +355 -0
  103. package/dist/node/targets/additional-targets.js +196 -37
  104. package/dist/node/targets/agents-md.js +5 -33
  105. package/dist/node/targets/base-target.js +0 -28
  106. package/dist/node/targets/claude-code.js +211 -41
  107. package/dist/node/targets/codex-cli.js +7 -35
  108. package/dist/node/targets/copilot.js +202 -41
  109. package/dist/node/targets/cursor.js +188 -40
  110. package/dist/node/targets/gemini-cli.js +10 -38
  111. package/dist/node/targets/generic-md-target.js +196 -37
  112. package/dist/node/targets/index.js +414 -106
  113. package/dist/node/targets/opencode.js +171 -51
  114. package/dist/node/targets/registry.js +414 -106
  115. package/dist/node/utils/credentials.js +38 -0
  116. package/dist/node/utils/diff.js +22 -34
  117. package/dist/node/utils/filesystem.js +2 -30
  118. package/dist/node/utils/frontmatter.js +0 -28
  119. package/dist/node/utils/global.js +3 -31
  120. package/dist/node/utils/markdown.js +0 -28
  121. package/dist/node/utils/model-allowlist.js +110 -0
  122. package/dist/node/utils/model-guidance.js +78 -0
  123. package/dist/node/utils/registry-client.js +142 -0
  124. package/dist/node/utils/tarball.js +49 -0
  125. package/dist/sources/git-ref.js +7 -30
  126. package/dist/sources/git.d.ts +2 -2
  127. package/dist/sources/git.js +7 -30
  128. package/dist/sources/index.d.ts +2 -0
  129. package/dist/sources/index.js +337 -39
  130. package/dist/sources/local.js +0 -28
  131. package/dist/sources/npm-ref.js +0 -28
  132. package/dist/sources/npm.js +10 -37
  133. package/dist/sources/registry-ref.d.ts +30 -0
  134. package/dist/sources/registry-ref.js +37 -0
  135. package/dist/sources/registry.d.ts +18 -0
  136. package/dist/sources/registry.js +355 -0
  137. package/dist/targets/additional-targets.js +196 -37
  138. package/dist/targets/agents-md.js +5 -33
  139. package/dist/targets/base-target.d.ts +2 -0
  140. package/dist/targets/base-target.js +0 -28
  141. package/dist/targets/claude-code.js +211 -41
  142. package/dist/targets/codex-cli.js +7 -35
  143. package/dist/targets/copilot.js +202 -41
  144. package/dist/targets/cursor.js +188 -40
  145. package/dist/targets/gemini-cli.js +10 -38
  146. package/dist/targets/generic-md-target.js +196 -37
  147. package/dist/targets/index.js +414 -106
  148. package/dist/targets/opencode.js +171 -51
  149. package/dist/targets/registry.js +414 -106
  150. package/dist/utils/credentials.d.ts +19 -0
  151. package/dist/utils/credentials.js +38 -0
  152. package/dist/utils/diff.js +22 -34
  153. package/dist/utils/filesystem.js +2 -30
  154. package/dist/utils/frontmatter.js +0 -28
  155. package/dist/utils/global.js +3 -31
  156. package/dist/utils/markdown.js +0 -28
  157. package/dist/utils/model-allowlist.d.ts +39 -0
  158. package/dist/utils/model-allowlist.js +110 -0
  159. package/dist/utils/model-guidance.d.ts +6 -0
  160. package/dist/utils/model-guidance.js +78 -0
  161. package/dist/utils/registry-client.d.ts +141 -0
  162. package/dist/utils/registry-client.js +142 -0
  163. package/dist/utils/tarball.d.ts +13 -0
  164. package/dist/utils/tarball.js +49 -0
  165. package/package.json +171 -5
  166. package/templates/pack/models.json +38 -0
@@ -1,32 +1,4 @@
1
1
  // @bun
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __moduleCache = /* @__PURE__ */ new WeakMap;
7
- var __toCommonJS = (from) => {
8
- var entry = __moduleCache.get(from), desc;
9
- if (entry)
10
- return entry;
11
- entry = __defProp({}, "__esModule", { value: true });
12
- if (from && typeof from === "object" || typeof from === "function")
13
- __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
14
- get: () => from[key],
15
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
- }));
17
- __moduleCache.set(from, entry);
18
- return entry;
19
- };
20
- var __export = (target, all) => {
21
- for (var name in all)
22
- __defProp(target, name, {
23
- get: all[name],
24
- enumerable: true,
25
- configurable: true,
26
- set: (newValue) => all[name] = () => newValue
27
- });
28
- };
29
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
30
2
  var __require = import.meta.require;
31
3
 
32
4
  // src/utils/filesystem.ts
@@ -36,10 +8,10 @@ import {
36
8
  readFileSync,
37
9
  writeFileSync,
38
10
  readdirSync,
11
+ rmSync,
39
12
  statSync
40
13
  } from "fs";
41
14
  import { dirname, relative, join } from "path";
42
- import { removeSync } from "fs-extra";
43
15
  var GENERATED_HEADER_MD = "<!-- Generated by agentpacks. DO NOT EDIT. -->";
44
16
  var GENERATED_HEADER_JSON = "// Generated by agentpacks. DO NOT EDIT.";
45
17
  var GENERATED_HEADER_JS = "// Generated by agentpacks. DO NOT EDIT.";
@@ -80,7 +52,7 @@ function ensureDir(dirPath) {
80
52
  }
81
53
  function removeIfExists(targetPath) {
82
54
  if (existsSync(targetPath)) {
83
- removeSync(targetPath);
55
+ rmSync(targetPath, { recursive: true, force: true });
84
56
  }
85
57
  }
86
58
  function listFiles(dirPath, options = {}) {
@@ -317,6 +289,110 @@ function resolveHooksForTarget(hooks, targetId) {
317
289
  return merged;
318
290
  }
319
291
 
292
+ // src/core/profile-resolver.ts
293
+ function resolveModels(merged, modelProfile, targetId) {
294
+ let defaultModel = merged.default;
295
+ let smallModel = merged.small;
296
+ let agents = { ...merged.agents };
297
+ if (modelProfile && merged.profiles?.[modelProfile]) {
298
+ const resolvedProfile = resolveProfileInheritance(modelProfile, merged.profiles);
299
+ if (resolvedProfile.default)
300
+ defaultModel = resolvedProfile.default;
301
+ if (resolvedProfile.small)
302
+ smallModel = resolvedProfile.small;
303
+ if (resolvedProfile.agents) {
304
+ agents = { ...agents, ...resolvedProfile.agents };
305
+ }
306
+ }
307
+ if (targetId) {
308
+ const targetOverride = merged.overrides?.[targetId];
309
+ if (targetOverride) {
310
+ if (targetOverride.default)
311
+ defaultModel = targetOverride.default;
312
+ if (targetOverride.small)
313
+ smallModel = targetOverride.small;
314
+ if (targetOverride.agents) {
315
+ agents = { ...agents, ...targetOverride.agents };
316
+ }
317
+ }
318
+ }
319
+ const providers = {};
320
+ if (merged.providers) {
321
+ for (const [name, config] of Object.entries(merged.providers)) {
322
+ providers[name] = {
323
+ ...config.options ? { options: config.options } : {},
324
+ ...config.models ? { models: config.models } : {}
325
+ };
326
+ }
327
+ }
328
+ const profileNames = Object.keys(merged.profiles ?? {});
329
+ const profiles = {};
330
+ if (merged.profiles) {
331
+ for (const [name, profile] of Object.entries(merged.profiles)) {
332
+ profiles[name] = {
333
+ description: profile.description,
334
+ default: profile.default,
335
+ small: profile.small
336
+ };
337
+ }
338
+ }
339
+ return {
340
+ default: defaultModel,
341
+ small: smallModel,
342
+ agents,
343
+ providers,
344
+ routing: merged.routing ?? [],
345
+ profileNames,
346
+ activeProfile: modelProfile,
347
+ profiles
348
+ };
349
+ }
350
+ function resolveAgentModel(resolved, agentName, frontmatterModel) {
351
+ const fromModels = resolved.agents[agentName];
352
+ if (fromModels) {
353
+ return {
354
+ model: fromModels.model,
355
+ temperature: fromModels.temperature,
356
+ top_p: fromModels.top_p
357
+ };
358
+ }
359
+ if (frontmatterModel) {
360
+ return { model: frontmatterModel };
361
+ }
362
+ return {};
363
+ }
364
+ function resolveProfileInheritance(profileName, profiles) {
365
+ const visited = new Set;
366
+ return resolveProfileChain(profileName, profiles, visited, 0);
367
+ }
368
+ var MAX_INHERITANCE_DEPTH = 10;
369
+ function resolveProfileChain(name, profiles, visited, depth) {
370
+ if (depth > MAX_INHERITANCE_DEPTH) {
371
+ throw new Error(`Profile inheritance too deep (max ${MAX_INHERITANCE_DEPTH}): ${name}`);
372
+ }
373
+ if (visited.has(name)) {
374
+ throw new Error(`Circular profile inheritance detected: ${[...visited, name].join(" \u2192 ")}`);
375
+ }
376
+ const profile = profiles[name];
377
+ if (!profile) {
378
+ throw new Error(`Profile "${name}" not found`);
379
+ }
380
+ visited.add(name);
381
+ if (!profile.extends) {
382
+ return { ...profile };
383
+ }
384
+ const parent = resolveProfileChain(profile.extends, profiles, visited, depth + 1);
385
+ return {
386
+ description: profile.description ?? parent.description,
387
+ default: profile.default ?? parent.default,
388
+ small: profile.small ?? parent.small,
389
+ agents: {
390
+ ...parent.agents,
391
+ ...profile.agents
392
+ }
393
+ };
394
+ }
395
+
320
396
  // src/targets/base-target.ts
321
397
  class BaseTarget {
322
398
  supportsFeature(feature) {
@@ -361,7 +437,7 @@ ${content}`;
361
437
  }
362
438
 
363
439
  // src/targets/opencode.ts
364
- import { resolve as resolve2, join as join4 } from "path";
440
+ import { resolve, join as join4 } from "path";
365
441
  var TARGET_ID = "opencode";
366
442
 
367
443
  class OpenCodeTarget extends BaseTarget {
@@ -375,32 +451,48 @@ class OpenCodeTarget extends BaseTarget {
375
451
  "hooks",
376
452
  "plugins",
377
453
  "mcp",
378
- "ignore"
454
+ "ignore",
455
+ "models"
379
456
  ];
380
457
  generate(options) {
381
458
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
382
- const root = resolve2(projectRoot, baseDir);
459
+ const root = resolve(projectRoot, baseDir);
383
460
  const effective = this.getEffectiveFeatures(enabledFeatures);
384
461
  const filesWritten = [];
385
462
  const filesDeleted = [];
386
463
  const warnings = [];
387
- const opencodeDir = resolve2(root, ".opencode");
464
+ const opencodeDir = resolve(root, ".opencode");
388
465
  if (effective.includes("agents")) {
389
- const agentDir = resolve2(opencodeDir, "agent");
466
+ const agentDir = resolve(opencodeDir, "agent");
390
467
  if (deleteExisting) {
391
468
  removeIfExists(agentDir);
392
469
  filesDeleted.push(agentDir);
393
470
  }
394
471
  ensureDir(agentDir);
472
+ const resolvedModels = features.models ? resolveModels(features.models, options.modelProfile, TARGET_ID) : null;
395
473
  const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID));
396
474
  for (const agent of agents) {
397
475
  const filepath = join4(agentDir, `${agent.name}.md`);
398
- writeGeneratedFile(filepath, agent.content);
476
+ const fm = {};
477
+ const oc = agent.meta.opencode ?? {};
478
+ const modelsAgent = resolvedModels?.agents[agent.name];
479
+ const agentModel = modelsAgent?.model ?? oc.model;
480
+ const agentTemp = modelsAgent?.temperature ?? oc.temperature;
481
+ if (agentModel)
482
+ fm.model = agentModel;
483
+ if (agentTemp !== undefined)
484
+ fm.temperature = agentTemp;
485
+ if (oc.mode)
486
+ fm.mode = oc.mode;
487
+ if (oc.top_p !== undefined)
488
+ fm.top_p = oc.top_p;
489
+ const content = Object.keys(fm).length > 0 ? serializeFrontmatter(fm, agent.content) : agent.content;
490
+ writeGeneratedFile(filepath, content);
399
491
  filesWritten.push(filepath);
400
492
  }
401
493
  }
402
494
  if (effective.includes("skills")) {
403
- const skillDir = resolve2(opencodeDir, "skill");
495
+ const skillDir = resolve(opencodeDir, "skill");
404
496
  if (deleteExisting) {
405
497
  removeIfExists(skillDir);
406
498
  filesDeleted.push(skillDir);
@@ -416,7 +508,7 @@ class OpenCodeTarget extends BaseTarget {
416
508
  }
417
509
  }
418
510
  if (effective.includes("commands")) {
419
- const cmdDir = resolve2(opencodeDir, "command");
511
+ const cmdDir = resolve(opencodeDir, "command");
420
512
  if (deleteExisting) {
421
513
  removeIfExists(cmdDir);
422
514
  filesDeleted.push(cmdDir);
@@ -430,7 +522,7 @@ class OpenCodeTarget extends BaseTarget {
430
522
  }
431
523
  }
432
524
  if (effective.includes("hooks") || effective.includes("plugins")) {
433
- const pluginsDir = resolve2(opencodeDir, "plugins");
525
+ const pluginsDir = resolve(opencodeDir, "plugins");
434
526
  ensureDir(pluginsDir);
435
527
  if (effective.includes("hooks")) {
436
528
  for (const hookSet of features.hooks) {
@@ -453,21 +545,52 @@ class OpenCodeTarget extends BaseTarget {
453
545
  }
454
546
  }
455
547
  }
456
- if (effective.includes("mcp")) {
457
- const mcpEntries = Object.entries(features.mcpServers);
458
- if (mcpEntries.length > 0) {
459
- const opencodeConfig = buildOpenCodeMcp(features.mcpServers);
460
- const filepath = resolve2(root, "opencode.json");
548
+ if (effective.includes("mcp") || effective.includes("models")) {
549
+ const filepath = resolve(root, "opencode.json");
550
+ const opencodeConfig = {
551
+ $schema: "https://opencode.ai/config.json"
552
+ };
553
+ if (effective.includes("mcp")) {
554
+ const mcpEntries = Object.entries(features.mcpServers);
555
+ if (mcpEntries.length > 0) {
556
+ opencodeConfig.mcp = buildOpenCodeMcpServers(features.mcpServers);
557
+ }
558
+ }
559
+ if (effective.includes("models") && features.models) {
560
+ const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID);
561
+ if (resolved.default)
562
+ opencodeConfig.model = resolved.default;
563
+ if (resolved.small)
564
+ opencodeConfig.small_model = resolved.small;
565
+ if (Object.keys(resolved.providers).length > 0) {
566
+ opencodeConfig.provider = resolved.providers;
567
+ }
568
+ const agentEntries = Object.entries(resolved.agents);
569
+ if (agentEntries.length > 0) {
570
+ const agentConfig = {};
571
+ for (const [name, assignment] of agentEntries) {
572
+ const config = { model: assignment.model };
573
+ if (assignment.temperature !== undefined) {
574
+ config.temperature = assignment.temperature;
575
+ }
576
+ if (assignment.top_p !== undefined) {
577
+ config.top_p = assignment.top_p;
578
+ }
579
+ agentConfig[name] = config;
580
+ }
581
+ opencodeConfig.agent = agentConfig;
582
+ }
583
+ }
584
+ if (Object.keys(opencodeConfig).length > 1) {
461
585
  writeGeneratedJson(filepath, opencodeConfig, { header: false });
462
586
  filesWritten.push(filepath);
463
587
  }
464
588
  }
465
589
  if (effective.includes("rules")) {
466
590
  const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID));
467
- const rootRules = getRootRules(rules);
468
591
  const detailRules = getDetailRules(rules);
469
592
  if (detailRules.length > 0) {
470
- const memoriesDir = resolve2(opencodeDir, "memories");
593
+ const memoriesDir = resolve(opencodeDir, "memories");
471
594
  if (deleteExisting) {
472
595
  removeIfExists(memoriesDir);
473
596
  filesDeleted.push(memoriesDir);
@@ -483,7 +606,7 @@ class OpenCodeTarget extends BaseTarget {
483
606
  return this.createResult(filesWritten, filesDeleted, warnings);
484
607
  }
485
608
  }
486
- function buildOpenCodeMcp(servers) {
609
+ function buildOpenCodeMcpServers(servers) {
487
610
  const mcp = {};
488
611
  for (const [name, entry] of Object.entries(servers)) {
489
612
  if (entry.url) {
@@ -503,10 +626,7 @@ function buildOpenCodeMcp(servers) {
503
626
  };
504
627
  }
505
628
  }
506
- return {
507
- $schema: "https://opencode.ai/config.json",
508
- mcp
509
- };
629
+ return mcp;
510
630
  }
511
631
  function generateOpenCodeHookPlugin(packName, events) {
512
632
  const identifier = packNameToIdentifier(packName);
@@ -553,7 +673,7 @@ function mapHookEvents(events) {
553
673
  }
554
674
 
555
675
  // src/targets/cursor.ts
556
- import { resolve as resolve3, join as join5 } from "path";
676
+ import { resolve as resolve2, join as join5 } from "path";
557
677
  var TARGET_ID2 = "cursor";
558
678
 
559
679
  class CursorTarget extends BaseTarget {
@@ -566,18 +686,19 @@ class CursorTarget extends BaseTarget {
566
686
  "skills",
567
687
  "hooks",
568
688
  "mcp",
569
- "ignore"
689
+ "ignore",
690
+ "models"
570
691
  ];
571
692
  generate(options) {
572
693
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
573
- const root = resolve3(projectRoot, baseDir);
694
+ const root = resolve2(projectRoot, baseDir);
574
695
  const effective = this.getEffectiveFeatures(enabledFeatures);
575
696
  const filesWritten = [];
576
697
  const filesDeleted = [];
577
698
  const warnings = [];
578
- const cursorDir = resolve3(root, ".cursor");
699
+ const cursorDir = resolve2(root, ".cursor");
579
700
  if (effective.includes("rules")) {
580
- const rulesDir = resolve3(cursorDir, "rules");
701
+ const rulesDir = resolve2(cursorDir, "rules");
581
702
  if (deleteExisting) {
582
703
  removeIfExists(rulesDir);
583
704
  filesDeleted.push(rulesDir);
@@ -601,18 +722,25 @@ class CursorTarget extends BaseTarget {
601
722
  }
602
723
  }
603
724
  if (effective.includes("agents")) {
604
- const agentsDir = resolve3(cursorDir, "agents");
725
+ const agentsDir = resolve2(cursorDir, "agents");
605
726
  if (deleteExisting) {
606
727
  removeIfExists(agentsDir);
607
728
  filesDeleted.push(agentsDir);
608
729
  }
609
730
  ensureDir(agentsDir);
731
+ const resolvedModels = features.models ? resolveModels(features.models, options.modelProfile, TARGET_ID2) : null;
610
732
  const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID2));
611
733
  for (const agent of agents) {
612
734
  const frontmatter = {
613
735
  name: agent.name,
614
736
  description: agent.meta.description ?? ""
615
737
  };
738
+ const cursorMeta = agent.meta.cursor ?? {};
739
+ const modelsAgent = resolvedModels?.agents[agent.name];
740
+ const model = modelsAgent?.model ?? cursorMeta.model;
741
+ if (model) {
742
+ frontmatter.model = model;
743
+ }
616
744
  const filepath = join5(agentsDir, `${agent.name}.md`);
617
745
  const content = serializeFrontmatter(frontmatter, agent.content);
618
746
  writeGeneratedFile(filepath, content);
@@ -620,7 +748,7 @@ class CursorTarget extends BaseTarget {
620
748
  }
621
749
  }
622
750
  if (effective.includes("skills")) {
623
- const skillsDir = resolve3(cursorDir, "skills");
751
+ const skillsDir = resolve2(cursorDir, "skills");
624
752
  if (deleteExisting) {
625
753
  removeIfExists(skillsDir);
626
754
  filesDeleted.push(skillsDir);
@@ -641,7 +769,7 @@ class CursorTarget extends BaseTarget {
641
769
  }
642
770
  }
643
771
  if (effective.includes("commands")) {
644
- const commandsDir = resolve3(cursorDir, "commands");
772
+ const commandsDir = resolve2(cursorDir, "commands");
645
773
  if (deleteExisting) {
646
774
  removeIfExists(commandsDir);
647
775
  filesDeleted.push(commandsDir);
@@ -658,14 +786,14 @@ class CursorTarget extends BaseTarget {
658
786
  const mcpEntries = Object.entries(features.mcpServers);
659
787
  if (mcpEntries.length > 0) {
660
788
  const mcpConfig = buildCursorMcp(features.mcpServers);
661
- const filepath = resolve3(cursorDir, "mcp.json");
789
+ const filepath = resolve2(cursorDir, "mcp.json");
662
790
  writeGeneratedJson(filepath, mcpConfig, { header: false });
663
791
  filesWritten.push(filepath);
664
792
  }
665
793
  }
666
794
  if (effective.includes("ignore")) {
667
795
  if (features.ignorePatterns.length > 0) {
668
- const filepath = resolve3(root, ".cursorignore");
796
+ const filepath = resolve2(root, ".cursorignore");
669
797
  const content = features.ignorePatterns.join(`
670
798
  `) + `
671
799
  `;
@@ -673,6 +801,17 @@ class CursorTarget extends BaseTarget {
673
801
  filesWritten.push(filepath);
674
802
  }
675
803
  }
804
+ if (effective.includes("models") && features.models) {
805
+ const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID2);
806
+ const guidanceContent = buildCursorModelGuidance(resolved);
807
+ if (guidanceContent) {
808
+ const rulesDir = resolve2(cursorDir, "rules");
809
+ ensureDir(rulesDir);
810
+ const filepath = join5(rulesDir, "model-config.mdc");
811
+ writeGeneratedFile(filepath, guidanceContent, { header: false });
812
+ filesWritten.push(filepath);
813
+ }
814
+ }
676
815
  return this.createResult(filesWritten, filesDeleted, warnings);
677
816
  }
678
817
  }
@@ -691,9 +830,135 @@ function buildCursorMcp(servers) {
691
830
  }
692
831
  return { mcpServers };
693
832
  }
833
+ function buildCursorModelGuidance(resolved) {
834
+ if (!resolved.default && !resolved.small && Object.keys(resolved.agents).length === 0) {
835
+ return null;
836
+ }
837
+ const frontmatter = {
838
+ description: "Model configuration and selection guidelines for this workspace",
839
+ alwaysApply: true
840
+ };
841
+ const lines = [];
842
+ lines.push("# Model Configuration");
843
+ lines.push("");
844
+ lines.push("Use the following model preferences when working in this project.");
845
+ lines.push("");
846
+ if (resolved.default || resolved.small) {
847
+ lines.push("## Default Models");
848
+ lines.push("");
849
+ if (resolved.default) {
850
+ lines.push(`- **Primary model**: ${resolved.default}`);
851
+ }
852
+ if (resolved.small) {
853
+ lines.push(`- **Lightweight tasks** (titles, summaries): ${resolved.small}`);
854
+ }
855
+ lines.push("");
856
+ }
857
+ const agentEntries = Object.entries(resolved.agents);
858
+ if (agentEntries.length > 0) {
859
+ lines.push("## Agent Model Assignments");
860
+ lines.push("");
861
+ lines.push("| Agent | Model | Temperature |");
862
+ lines.push("| --- | --- | --- |");
863
+ for (const [name, assignment] of agentEntries) {
864
+ const temp = assignment.temperature !== undefined ? String(assignment.temperature) : "\u2014";
865
+ lines.push(`| ${name} | ${assignment.model} | ${temp} |`);
866
+ }
867
+ lines.push("");
868
+ }
869
+ if (Object.keys(resolved.profiles).length > 0) {
870
+ lines.push("## Available Profiles");
871
+ lines.push("");
872
+ lines.push("| Profile | Description | Default Model |");
873
+ lines.push("| --- | --- | --- |");
874
+ for (const [name, profile] of Object.entries(resolved.profiles)) {
875
+ lines.push(`| ${name} | ${profile.description ?? "\u2014"} | ${profile.default ?? "\u2014"} |`);
876
+ }
877
+ lines.push("");
878
+ }
879
+ if (resolved.activeProfile) {
880
+ lines.push(`**Active profile**: \`${resolved.activeProfile}\``);
881
+ lines.push("");
882
+ }
883
+ return serializeFrontmatter(frontmatter, lines.join(`
884
+ `));
885
+ }
886
+
887
+ // src/utils/model-guidance.ts
888
+ function generateModelGuidanceMarkdown(resolved) {
889
+ if (!resolved.default && !resolved.small && Object.keys(resolved.agents).length === 0 && Object.keys(resolved.profiles).length === 0) {
890
+ return null;
891
+ }
892
+ const lines = [];
893
+ lines.push("# Model Configuration");
894
+ lines.push("");
895
+ lines.push("Use the following model preferences when working in this project.");
896
+ lines.push("");
897
+ if (resolved.default || resolved.small) {
898
+ lines.push("## Default Models");
899
+ lines.push("");
900
+ if (resolved.default) {
901
+ lines.push(`- **Primary model**: ${resolved.default}`);
902
+ }
903
+ if (resolved.small) {
904
+ lines.push(`- **Lightweight tasks** (titles, summaries): ${resolved.small}`);
905
+ }
906
+ lines.push("");
907
+ }
908
+ const agentEntries = Object.entries(resolved.agents);
909
+ if (agentEntries.length > 0) {
910
+ lines.push("## Agent Model Assignments");
911
+ lines.push("");
912
+ lines.push("| Agent | Model | Temperature |");
913
+ lines.push("| --- | --- | --- |");
914
+ for (const [name, assignment] of agentEntries) {
915
+ const temp = assignment.temperature !== undefined ? String(assignment.temperature) : "\u2014";
916
+ lines.push(`| ${name} | ${assignment.model} | ${temp} |`);
917
+ }
918
+ lines.push("");
919
+ }
920
+ if (Object.keys(resolved.profiles).length > 0) {
921
+ lines.push("## Available Profiles");
922
+ lines.push("");
923
+ lines.push("| Profile | Description | Default Model |");
924
+ lines.push("| --- | --- | --- |");
925
+ for (const [name, profile] of Object.entries(resolved.profiles)) {
926
+ lines.push(`| ${name} | ${profile.description ?? "\u2014"} | ${profile.default ?? "\u2014"} |`);
927
+ }
928
+ lines.push("");
929
+ }
930
+ if (resolved.activeProfile) {
931
+ lines.push(`**Active profile**: \`${resolved.activeProfile}\``);
932
+ lines.push("");
933
+ }
934
+ if (resolved.routing.length > 0) {
935
+ lines.push("## Task-Aware Routing");
936
+ lines.push("");
937
+ lines.push("Select the appropriate profile based on the task context:");
938
+ lines.push("");
939
+ lines.push("| Condition | Profile | Description |");
940
+ lines.push("| --- | --- | --- |");
941
+ for (const rule of resolved.routing) {
942
+ const conditions = Object.entries(rule.when).map(([k, v]) => `${k}=${v}`).join(", ");
943
+ const desc = rule.description ?? "\u2014";
944
+ lines.push(`| ${conditions} | ${rule.use} | ${desc} |`);
945
+ }
946
+ lines.push("");
947
+ lines.push("### Condition Reference");
948
+ lines.push("");
949
+ lines.push("- **complexity**: low | medium | high | critical");
950
+ lines.push("- **urgency**: low | normal | high");
951
+ lines.push("- **budget**: minimal | standard | premium");
952
+ lines.push("- **contextWindowNeed**: small | medium | large | max");
953
+ lines.push("- **toolUseIntensity**: none | light | heavy");
954
+ lines.push("");
955
+ }
956
+ return lines.join(`
957
+ `);
958
+ }
694
959
 
695
960
  // src/targets/claude-code.ts
696
- import { resolve as resolve4, join as join6 } from "path";
961
+ import { resolve as resolve3, join as join6 } from "path";
697
962
  var TARGET_ID3 = "claudecode";
698
963
 
699
964
  class ClaudeCodeTarget extends BaseTarget {
@@ -706,18 +971,19 @@ class ClaudeCodeTarget extends BaseTarget {
706
971
  "skills",
707
972
  "hooks",
708
973
  "mcp",
709
- "ignore"
974
+ "ignore",
975
+ "models"
710
976
  ];
711
977
  generate(options) {
712
978
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
713
- const root = resolve4(projectRoot, baseDir);
979
+ const root = resolve3(projectRoot, baseDir);
714
980
  const effective = this.getEffectiveFeatures(enabledFeatures);
715
981
  const filesWritten = [];
716
982
  const filesDeleted = [];
717
983
  const warnings = [];
718
- const claudeDir = resolve4(root, ".claude");
984
+ const claudeDir = resolve3(root, ".claude");
719
985
  if (effective.includes("rules")) {
720
- const rulesDir = resolve4(claudeDir, "rules");
986
+ const rulesDir = resolve3(claudeDir, "rules");
721
987
  if (deleteExisting) {
722
988
  removeIfExists(rulesDir);
723
989
  filesDeleted.push(rulesDir);
@@ -730,7 +996,7 @@ class ClaudeCodeTarget extends BaseTarget {
730
996
  const claudeMd = rootRules.map((r) => r.content).join(`
731
997
 
732
998
  `);
733
- const filepath = resolve4(claudeDir, "CLAUDE.md");
999
+ const filepath = resolve3(claudeDir, "CLAUDE.md");
734
1000
  writeGeneratedFile(filepath, claudeMd);
735
1001
  filesWritten.push(filepath);
736
1002
  }
@@ -741,21 +1007,30 @@ class ClaudeCodeTarget extends BaseTarget {
741
1007
  }
742
1008
  }
743
1009
  if (effective.includes("agents")) {
744
- const agentsDir = resolve4(claudeDir, "agents");
1010
+ const agentsDir = resolve3(claudeDir, "agents");
745
1011
  if (deleteExisting) {
746
1012
  removeIfExists(agentsDir);
747
1013
  filesDeleted.push(agentsDir);
748
1014
  }
749
1015
  ensureDir(agentsDir);
1016
+ const resolvedModels = features.models ? resolveModels(features.models, options.modelProfile, TARGET_ID3) : null;
750
1017
  const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID3));
751
1018
  for (const agent of agents) {
752
1019
  const filepath = join6(agentsDir, `${agent.name}.md`);
753
- writeGeneratedFile(filepath, agent.content);
1020
+ const cc = agent.meta.claudecode ?? {};
1021
+ const modelsAgent = resolvedModels?.agents[agent.name];
1022
+ const agentModel = modelsAgent?.model ?? cc.model;
1023
+ let content = agent.content;
1024
+ if (agentModel) {
1025
+ content = `<!-- model: ${agentModel} -->
1026
+ ${content}`;
1027
+ }
1028
+ writeGeneratedFile(filepath, content);
754
1029
  filesWritten.push(filepath);
755
1030
  }
756
1031
  }
757
1032
  if (effective.includes("skills")) {
758
- const skillsDir = resolve4(claudeDir, "skills");
1033
+ const skillsDir = resolve3(claudeDir, "skills");
759
1034
  if (deleteExisting) {
760
1035
  removeIfExists(skillsDir);
761
1036
  filesDeleted.push(skillsDir);
@@ -771,7 +1046,7 @@ class ClaudeCodeTarget extends BaseTarget {
771
1046
  }
772
1047
  }
773
1048
  if (effective.includes("commands")) {
774
- const commandsDir = resolve4(claudeDir, "commands");
1049
+ const commandsDir = resolve3(claudeDir, "commands");
775
1050
  if (deleteExisting) {
776
1051
  removeIfExists(commandsDir);
777
1052
  filesDeleted.push(commandsDir);
@@ -784,10 +1059,21 @@ class ClaudeCodeTarget extends BaseTarget {
784
1059
  filesWritten.push(filepath);
785
1060
  }
786
1061
  }
1062
+ if (effective.includes("models") && features.models) {
1063
+ const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID3);
1064
+ const guidance = generateModelGuidanceMarkdown(resolved);
1065
+ if (guidance) {
1066
+ const rulesDir = resolve3(claudeDir, "rules");
1067
+ ensureDir(rulesDir);
1068
+ const filepath = join6(rulesDir, "model-config.md");
1069
+ writeGeneratedFile(filepath, guidance);
1070
+ filesWritten.push(filepath);
1071
+ }
1072
+ }
787
1073
  if (effective.includes("hooks") || effective.includes("mcp") || effective.includes("ignore")) {
788
1074
  const settings = buildClaudeSettings(options, effective);
789
1075
  if (Object.keys(settings).length > 0) {
790
- const filepath = resolve4(claudeDir, "settings.json");
1076
+ const filepath = resolve3(claudeDir, "settings.json");
791
1077
  const existing = readJsonOrNull(filepath) ?? {};
792
1078
  const merged = { ...existing, ...settings };
793
1079
  writeGeneratedJson(filepath, merged, { header: false });
@@ -844,7 +1130,7 @@ function toPascalCase(str) {
844
1130
  }
845
1131
 
846
1132
  // src/targets/codex-cli.ts
847
- import { resolve as resolve5, join as join7 } from "path";
1133
+ import { resolve as resolve4, join as join7 } from "path";
848
1134
  var TARGET_ID4 = "codexcli";
849
1135
 
850
1136
  class CodexCliTarget extends BaseTarget {
@@ -853,14 +1139,14 @@ class CodexCliTarget extends BaseTarget {
853
1139
  supportedFeatures = ["rules", "skills", "mcp", "hooks"];
854
1140
  generate(options) {
855
1141
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
856
- const root = resolve5(projectRoot, baseDir);
1142
+ const root = resolve4(projectRoot, baseDir);
857
1143
  const effective = this.getEffectiveFeatures(enabledFeatures);
858
1144
  const filesWritten = [];
859
1145
  const filesDeleted = [];
860
1146
  const warnings = [];
861
- const codexDir = resolve5(root, ".codex");
1147
+ const codexDir = resolve4(root, ".codex");
862
1148
  if (effective.includes("rules")) {
863
- const memoriesDir = resolve5(codexDir, "memories");
1149
+ const memoriesDir = resolve4(codexDir, "memories");
864
1150
  if (deleteExisting) {
865
1151
  removeIfExists(memoriesDir);
866
1152
  filesDeleted.push(memoriesDir);
@@ -874,7 +1160,7 @@ class CodexCliTarget extends BaseTarget {
874
1160
  }
875
1161
  }
876
1162
  if (effective.includes("skills")) {
877
- const skillsDir = resolve5(codexDir, "skills");
1163
+ const skillsDir = resolve4(codexDir, "skills");
878
1164
  if (deleteExisting) {
879
1165
  removeIfExists(skillsDir);
880
1166
  filesDeleted.push(skillsDir);
@@ -894,7 +1180,7 @@ class CodexCliTarget extends BaseTarget {
894
1180
  }
895
1181
 
896
1182
  // src/targets/gemini-cli.ts
897
- import { resolve as resolve6, join as join8 } from "path";
1183
+ import { resolve as resolve5, join as join8 } from "path";
898
1184
  var TARGET_ID5 = "geminicli";
899
1185
 
900
1186
  class GeminiCliTarget extends BaseTarget {
@@ -910,12 +1196,12 @@ class GeminiCliTarget extends BaseTarget {
910
1196
  ];
911
1197
  generate(options) {
912
1198
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
913
- const root = resolve6(projectRoot, baseDir);
1199
+ const root = resolve5(projectRoot, baseDir);
914
1200
  const effective = this.getEffectiveFeatures(enabledFeatures);
915
1201
  const filesWritten = [];
916
1202
  const filesDeleted = [];
917
1203
  const warnings = [];
918
- const geminiDir = resolve6(root, ".gemini");
1204
+ const geminiDir = resolve5(root, ".gemini");
919
1205
  if (effective.includes("rules")) {
920
1206
  const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID5));
921
1207
  const rootRules = getRootRules(rules);
@@ -924,12 +1210,12 @@ class GeminiCliTarget extends BaseTarget {
924
1210
  const geminiMd = rootRules.map((r) => r.content).join(`
925
1211
 
926
1212
  `);
927
- const filepath = resolve6(root, "GEMINI.md");
1213
+ const filepath = resolve5(root, "GEMINI.md");
928
1214
  writeGeneratedFile(filepath, geminiMd);
929
1215
  filesWritten.push(filepath);
930
1216
  }
931
1217
  if (detailRules.length > 0) {
932
- const memoriesDir = resolve6(geminiDir, "memories");
1218
+ const memoriesDir = resolve5(geminiDir, "memories");
933
1219
  if (deleteExisting) {
934
1220
  removeIfExists(memoriesDir);
935
1221
  filesDeleted.push(memoriesDir);
@@ -943,7 +1229,7 @@ class GeminiCliTarget extends BaseTarget {
943
1229
  }
944
1230
  }
945
1231
  if (effective.includes("commands")) {
946
- const commandsDir = resolve6(geminiDir, "commands");
1232
+ const commandsDir = resolve5(geminiDir, "commands");
947
1233
  if (deleteExisting) {
948
1234
  removeIfExists(commandsDir);
949
1235
  filesDeleted.push(commandsDir);
@@ -961,14 +1247,14 @@ class GeminiCliTarget extends BaseTarget {
961
1247
  const mcpEntries = Object.entries(features.mcpServers);
962
1248
  if (mcpEntries.length > 0) {
963
1249
  const settings = buildGeminiSettings(features.mcpServers);
964
- const filepath = resolve6(geminiDir, "settings.json");
1250
+ const filepath = resolve5(geminiDir, "settings.json");
965
1251
  writeGeneratedJson(filepath, settings, { header: false });
966
1252
  filesWritten.push(filepath);
967
1253
  }
968
1254
  }
969
1255
  if (effective.includes("ignore")) {
970
1256
  if (features.ignorePatterns.length > 0) {
971
- const filepath = resolve6(root, ".geminiignore");
1257
+ const filepath = resolve5(root, ".geminiignore");
972
1258
  const content = features.ignorePatterns.join(`
973
1259
  `) + `
974
1260
  `;
@@ -1007,7 +1293,7 @@ function buildGeminiSettings(servers) {
1007
1293
  }
1008
1294
 
1009
1295
  // src/targets/copilot.ts
1010
- import { resolve as resolve7, join as join9 } from "path";
1296
+ import { resolve as resolve6, join as join9 } from "path";
1011
1297
  var TARGET_ID6 = "copilot";
1012
1298
 
1013
1299
  class CopilotTarget extends BaseTarget {
@@ -1019,16 +1305,17 @@ class CopilotTarget extends BaseTarget {
1019
1305
  "agents",
1020
1306
  "skills",
1021
1307
  "mcp",
1022
- "ignore"
1308
+ "ignore",
1309
+ "models"
1023
1310
  ];
1024
1311
  generate(options) {
1025
1312
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
1026
- const root = resolve7(projectRoot, baseDir);
1313
+ const root = resolve6(projectRoot, baseDir);
1027
1314
  const effective = this.getEffectiveFeatures(enabledFeatures);
1028
1315
  const filesWritten = [];
1029
1316
  const filesDeleted = [];
1030
1317
  const warnings = [];
1031
- const githubDir = resolve7(root, ".github");
1318
+ const githubDir = resolve6(root, ".github");
1032
1319
  if (effective.includes("rules")) {
1033
1320
  const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID6));
1034
1321
  if (rules.length > 0) {
@@ -1037,15 +1324,15 @@ class CopilotTarget extends BaseTarget {
1037
1324
  ---
1038
1325
 
1039
1326
  `);
1040
- const filepath = resolve7(githubDir, "copilot-instructions.md");
1327
+ const filepath = resolve6(githubDir, "copilot-instructions.md");
1041
1328
  ensureDir(githubDir);
1042
1329
  writeGeneratedFile(filepath, combinedContent);
1043
1330
  filesWritten.push(filepath);
1044
1331
  }
1045
1332
  }
1046
1333
  if (effective.includes("agents")) {
1047
- const copilotDir = resolve7(githubDir, "copilot");
1048
- const agentsDir = resolve7(copilotDir, "agents");
1334
+ const copilotDir = resolve6(githubDir, "copilot");
1335
+ const agentsDir = resolve6(copilotDir, "agents");
1049
1336
  if (deleteExisting) {
1050
1337
  removeIfExists(agentsDir);
1051
1338
  filesDeleted.push(agentsDir);
@@ -1059,8 +1346,8 @@ class CopilotTarget extends BaseTarget {
1059
1346
  }
1060
1347
  }
1061
1348
  if (effective.includes("skills")) {
1062
- const copilotDir = resolve7(githubDir, "copilot");
1063
- const skillsDir = resolve7(copilotDir, "skills");
1349
+ const copilotDir = resolve6(githubDir, "copilot");
1350
+ const skillsDir = resolve6(copilotDir, "skills");
1064
1351
  if (deleteExisting) {
1065
1352
  removeIfExists(skillsDir);
1066
1353
  filesDeleted.push(skillsDir);
@@ -1076,8 +1363,8 @@ class CopilotTarget extends BaseTarget {
1076
1363
  }
1077
1364
  }
1078
1365
  if (effective.includes("commands")) {
1079
- const copilotDir = resolve7(githubDir, "copilot");
1080
- const commandsDir = resolve7(copilotDir, "commands");
1366
+ const copilotDir = resolve6(githubDir, "copilot");
1367
+ const commandsDir = resolve6(copilotDir, "commands");
1081
1368
  if (deleteExisting) {
1082
1369
  removeIfExists(commandsDir);
1083
1370
  filesDeleted.push(commandsDir);
@@ -1091,19 +1378,30 @@ class CopilotTarget extends BaseTarget {
1091
1378
  }
1092
1379
  }
1093
1380
  if (effective.includes("ignore")) {}
1381
+ if (effective.includes("models") && features.models) {
1382
+ const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID6);
1383
+ const guidance = generateModelGuidanceMarkdown(resolved);
1384
+ if (guidance) {
1385
+ const copilotDir = resolve6(githubDir, "copilot");
1386
+ ensureDir(copilotDir);
1387
+ const filepath = join9(copilotDir, "model-config.md");
1388
+ writeGeneratedFile(filepath, guidance);
1389
+ filesWritten.push(filepath);
1390
+ }
1391
+ }
1094
1392
  return this.createResult(filesWritten, filesDeleted, warnings);
1095
1393
  }
1096
1394
  }
1097
1395
 
1098
1396
  // src/targets/agents-md.ts
1099
- import { resolve as resolve8 } from "path";
1397
+ import { resolve as resolve7 } from "path";
1100
1398
  class AgentsMdTarget extends BaseTarget {
1101
1399
  id = "agentsmd";
1102
1400
  name = "AGENTS.md";
1103
1401
  supportedFeatures = ["rules"];
1104
1402
  generate(options) {
1105
1403
  const { projectRoot, baseDir, features } = options;
1106
- const root = resolve8(projectRoot, baseDir);
1404
+ const root = resolve7(projectRoot, baseDir);
1107
1405
  const filesWritten = [];
1108
1406
  const warnings = [];
1109
1407
  const rootRules = getRootRules(features.rules);
@@ -1115,7 +1413,7 @@ class AgentsMdTarget extends BaseTarget {
1115
1413
  const content = sections.join(`
1116
1414
 
1117
1415
  `);
1118
- const filepath = resolve8(root, "AGENTS.md");
1416
+ const filepath = resolve7(root, "AGENTS.md");
1119
1417
  writeGeneratedFile(filepath, content);
1120
1418
  filesWritten.push(filepath);
1121
1419
  return this.createResult(filesWritten, [], warnings);
@@ -1123,7 +1421,7 @@ class AgentsMdTarget extends BaseTarget {
1123
1421
  }
1124
1422
 
1125
1423
  // src/targets/generic-md-target.ts
1126
- import { resolve as resolve9, join as join10 } from "path";
1424
+ import { resolve as resolve8, join as join10 } from "path";
1127
1425
  function createGenericMdTarget(config) {
1128
1426
  return new GenericMdTarget(config);
1129
1427
  }
@@ -1142,16 +1440,16 @@ class GenericMdTarget extends BaseTarget {
1142
1440
  }
1143
1441
  generate(options) {
1144
1442
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
1145
- const root = resolve9(projectRoot, baseDir);
1443
+ const root = resolve8(projectRoot, baseDir);
1146
1444
  const effective = this.getEffectiveFeatures(enabledFeatures);
1147
1445
  const filesWritten = [];
1148
1446
  const filesDeleted = [];
1149
1447
  const warnings = [];
1150
- const configDir = resolve9(root, this.config.configDir);
1448
+ const configDir = resolve8(root, this.config.configDir);
1151
1449
  const rulesSubDir = this.config.rulesDir ?? "rules";
1152
1450
  const ext = this.config.ruleExtension ?? ".md";
1153
1451
  if (effective.includes("rules")) {
1154
- const rulesDir = resolve9(configDir, rulesSubDir);
1452
+ const rulesDir = resolve8(configDir, rulesSubDir);
1155
1453
  if (deleteExisting) {
1156
1454
  removeIfExists(rulesDir);
1157
1455
  filesDeleted.push(rulesDir);
@@ -1165,7 +1463,7 @@ class GenericMdTarget extends BaseTarget {
1165
1463
  }
1166
1464
  }
1167
1465
  if (effective.includes("commands")) {
1168
- const commandsDir = resolve9(configDir, "commands");
1466
+ const commandsDir = resolve8(configDir, "commands");
1169
1467
  if (deleteExisting) {
1170
1468
  removeIfExists(commandsDir);
1171
1469
  filesDeleted.push(commandsDir);
@@ -1182,7 +1480,7 @@ class GenericMdTarget extends BaseTarget {
1182
1480
  const mcpEntries = Object.entries(features.mcpServers);
1183
1481
  if (mcpEntries.length > 0) {
1184
1482
  const mcpDir = this.config.mcpInConfigDir ? configDir : root;
1185
- const filepath = resolve9(mcpDir, "mcp.json");
1483
+ const filepath = resolve8(mcpDir, "mcp.json");
1186
1484
  writeGeneratedJson(filepath, { mcpServers: features.mcpServers }, {
1187
1485
  header: false
1188
1486
  });
@@ -1191,13 +1489,23 @@ class GenericMdTarget extends BaseTarget {
1191
1489
  }
1192
1490
  if (effective.includes("ignore") && this.config.ignoreFile) {
1193
1491
  if (features.ignorePatterns.length > 0) {
1194
- const filepath = resolve9(root, this.config.ignoreFile);
1492
+ const filepath = resolve8(root, this.config.ignoreFile);
1195
1493
  writeGeneratedFile(filepath, features.ignorePatterns.join(`
1196
1494
  `) + `
1197
1495
  `);
1198
1496
  filesWritten.push(filepath);
1199
1497
  }
1200
1498
  }
1499
+ if (effective.includes("models") && features.models) {
1500
+ const resolved = resolveModels(features.models, options.modelProfile, this.id);
1501
+ const guidance = generateModelGuidanceMarkdown(resolved);
1502
+ if (guidance) {
1503
+ ensureDir(configDir);
1504
+ const filepath = join10(configDir, "model-config.md");
1505
+ writeGeneratedFile(filepath, guidance);
1506
+ filesWritten.push(filepath);
1507
+ }
1508
+ }
1201
1509
  return this.createResult(filesWritten, filesDeleted, warnings);
1202
1510
  }
1203
1511
  }