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
  import { createRequire } from "node:module";
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 = /* @__PURE__ */ createRequire(import.meta.url);
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 = {}) {
@@ -279,6 +251,110 @@ function skillMatchesTarget(skill, targetId) {
279
251
  return Array.isArray(targets) && targets.includes(targetId);
280
252
  }
281
253
 
254
+ // src/core/profile-resolver.ts
255
+ function resolveModels(merged, modelProfile, targetId) {
256
+ let defaultModel = merged.default;
257
+ let smallModel = merged.small;
258
+ let agents = { ...merged.agents };
259
+ if (modelProfile && merged.profiles?.[modelProfile]) {
260
+ const resolvedProfile = resolveProfileInheritance(modelProfile, merged.profiles);
261
+ if (resolvedProfile.default)
262
+ defaultModel = resolvedProfile.default;
263
+ if (resolvedProfile.small)
264
+ smallModel = resolvedProfile.small;
265
+ if (resolvedProfile.agents) {
266
+ agents = { ...agents, ...resolvedProfile.agents };
267
+ }
268
+ }
269
+ if (targetId) {
270
+ const targetOverride = merged.overrides?.[targetId];
271
+ if (targetOverride) {
272
+ if (targetOverride.default)
273
+ defaultModel = targetOverride.default;
274
+ if (targetOverride.small)
275
+ smallModel = targetOverride.small;
276
+ if (targetOverride.agents) {
277
+ agents = { ...agents, ...targetOverride.agents };
278
+ }
279
+ }
280
+ }
281
+ const providers = {};
282
+ if (merged.providers) {
283
+ for (const [name, config] of Object.entries(merged.providers)) {
284
+ providers[name] = {
285
+ ...config.options ? { options: config.options } : {},
286
+ ...config.models ? { models: config.models } : {}
287
+ };
288
+ }
289
+ }
290
+ const profileNames = Object.keys(merged.profiles ?? {});
291
+ const profiles = {};
292
+ if (merged.profiles) {
293
+ for (const [name, profile] of Object.entries(merged.profiles)) {
294
+ profiles[name] = {
295
+ description: profile.description,
296
+ default: profile.default,
297
+ small: profile.small
298
+ };
299
+ }
300
+ }
301
+ return {
302
+ default: defaultModel,
303
+ small: smallModel,
304
+ agents,
305
+ providers,
306
+ routing: merged.routing ?? [],
307
+ profileNames,
308
+ activeProfile: modelProfile,
309
+ profiles
310
+ };
311
+ }
312
+ function resolveAgentModel(resolved, agentName, frontmatterModel) {
313
+ const fromModels = resolved.agents[agentName];
314
+ if (fromModels) {
315
+ return {
316
+ model: fromModels.model,
317
+ temperature: fromModels.temperature,
318
+ top_p: fromModels.top_p
319
+ };
320
+ }
321
+ if (frontmatterModel) {
322
+ return { model: frontmatterModel };
323
+ }
324
+ return {};
325
+ }
326
+ function resolveProfileInheritance(profileName, profiles) {
327
+ const visited = new Set;
328
+ return resolveProfileChain(profileName, profiles, visited, 0);
329
+ }
330
+ var MAX_INHERITANCE_DEPTH = 10;
331
+ function resolveProfileChain(name, profiles, visited, depth) {
332
+ if (depth > MAX_INHERITANCE_DEPTH) {
333
+ throw new Error(`Profile inheritance too deep (max ${MAX_INHERITANCE_DEPTH}): ${name}`);
334
+ }
335
+ if (visited.has(name)) {
336
+ throw new Error(`Circular profile inheritance detected: ${[...visited, name].join(" → ")}`);
337
+ }
338
+ const profile = profiles[name];
339
+ if (!profile) {
340
+ throw new Error(`Profile "${name}" not found`);
341
+ }
342
+ visited.add(name);
343
+ if (!profile.extends) {
344
+ return { ...profile };
345
+ }
346
+ const parent = resolveProfileChain(profile.extends, profiles, visited, depth + 1);
347
+ return {
348
+ description: profile.description ?? parent.description,
349
+ default: profile.default ?? parent.default,
350
+ small: profile.small ?? parent.small,
351
+ agents: {
352
+ ...parent.agents,
353
+ ...profile.agents
354
+ }
355
+ };
356
+ }
357
+
282
358
  // src/targets/base-target.ts
283
359
  class BaseTarget {
284
360
  supportsFeature(feature) {
@@ -297,8 +373,81 @@ class BaseTarget {
297
373
  }
298
374
  }
299
375
 
376
+ // src/utils/model-guidance.ts
377
+ function generateModelGuidanceMarkdown(resolved) {
378
+ if (!resolved.default && !resolved.small && Object.keys(resolved.agents).length === 0 && Object.keys(resolved.profiles).length === 0) {
379
+ return null;
380
+ }
381
+ const lines = [];
382
+ lines.push("# Model Configuration");
383
+ lines.push("");
384
+ lines.push("Use the following model preferences when working in this project.");
385
+ lines.push("");
386
+ if (resolved.default || resolved.small) {
387
+ lines.push("## Default Models");
388
+ lines.push("");
389
+ if (resolved.default) {
390
+ lines.push(`- **Primary model**: ${resolved.default}`);
391
+ }
392
+ if (resolved.small) {
393
+ lines.push(`- **Lightweight tasks** (titles, summaries): ${resolved.small}`);
394
+ }
395
+ lines.push("");
396
+ }
397
+ const agentEntries = Object.entries(resolved.agents);
398
+ if (agentEntries.length > 0) {
399
+ lines.push("## Agent Model Assignments");
400
+ lines.push("");
401
+ lines.push("| Agent | Model | Temperature |");
402
+ lines.push("| --- | --- | --- |");
403
+ for (const [name, assignment] of agentEntries) {
404
+ const temp = assignment.temperature !== undefined ? String(assignment.temperature) : "—";
405
+ lines.push(`| ${name} | ${assignment.model} | ${temp} |`);
406
+ }
407
+ lines.push("");
408
+ }
409
+ if (Object.keys(resolved.profiles).length > 0) {
410
+ lines.push("## Available Profiles");
411
+ lines.push("");
412
+ lines.push("| Profile | Description | Default Model |");
413
+ lines.push("| --- | --- | --- |");
414
+ for (const [name, profile] of Object.entries(resolved.profiles)) {
415
+ lines.push(`| ${name} | ${profile.description ?? "—"} | ${profile.default ?? "—"} |`);
416
+ }
417
+ lines.push("");
418
+ }
419
+ if (resolved.activeProfile) {
420
+ lines.push(`**Active profile**: \`${resolved.activeProfile}\``);
421
+ lines.push("");
422
+ }
423
+ if (resolved.routing.length > 0) {
424
+ lines.push("## Task-Aware Routing");
425
+ lines.push("");
426
+ lines.push("Select the appropriate profile based on the task context:");
427
+ lines.push("");
428
+ lines.push("| Condition | Profile | Description |");
429
+ lines.push("| --- | --- | --- |");
430
+ for (const rule of resolved.routing) {
431
+ const conditions = Object.entries(rule.when).map(([k, v]) => `${k}=${v}`).join(", ");
432
+ const desc = rule.description ?? "—";
433
+ lines.push(`| ${conditions} | ${rule.use} | ${desc} |`);
434
+ }
435
+ lines.push("");
436
+ lines.push("### Condition Reference");
437
+ lines.push("");
438
+ lines.push("- **complexity**: low | medium | high | critical");
439
+ lines.push("- **urgency**: low | normal | high");
440
+ lines.push("- **budget**: minimal | standard | premium");
441
+ lines.push("- **contextWindowNeed**: small | medium | large | max");
442
+ lines.push("- **toolUseIntensity**: none | light | heavy");
443
+ lines.push("");
444
+ }
445
+ return lines.join(`
446
+ `);
447
+ }
448
+
300
449
  // src/targets/copilot.ts
301
- import { resolve as resolve2, join as join3 } from "path";
450
+ import { resolve, join as join3 } from "path";
302
451
  var TARGET_ID = "copilot";
303
452
 
304
453
  class CopilotTarget extends BaseTarget {
@@ -310,16 +459,17 @@ class CopilotTarget extends BaseTarget {
310
459
  "agents",
311
460
  "skills",
312
461
  "mcp",
313
- "ignore"
462
+ "ignore",
463
+ "models"
314
464
  ];
315
465
  generate(options) {
316
466
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
317
- const root = resolve2(projectRoot, baseDir);
467
+ const root = resolve(projectRoot, baseDir);
318
468
  const effective = this.getEffectiveFeatures(enabledFeatures);
319
469
  const filesWritten = [];
320
470
  const filesDeleted = [];
321
471
  const warnings = [];
322
- const githubDir = resolve2(root, ".github");
472
+ const githubDir = resolve(root, ".github");
323
473
  if (effective.includes("rules")) {
324
474
  const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID));
325
475
  if (rules.length > 0) {
@@ -328,15 +478,15 @@ class CopilotTarget extends BaseTarget {
328
478
  ---
329
479
 
330
480
  `);
331
- const filepath = resolve2(githubDir, "copilot-instructions.md");
481
+ const filepath = resolve(githubDir, "copilot-instructions.md");
332
482
  ensureDir(githubDir);
333
483
  writeGeneratedFile(filepath, combinedContent);
334
484
  filesWritten.push(filepath);
335
485
  }
336
486
  }
337
487
  if (effective.includes("agents")) {
338
- const copilotDir = resolve2(githubDir, "copilot");
339
- const agentsDir = resolve2(copilotDir, "agents");
488
+ const copilotDir = resolve(githubDir, "copilot");
489
+ const agentsDir = resolve(copilotDir, "agents");
340
490
  if (deleteExisting) {
341
491
  removeIfExists(agentsDir);
342
492
  filesDeleted.push(agentsDir);
@@ -350,8 +500,8 @@ class CopilotTarget extends BaseTarget {
350
500
  }
351
501
  }
352
502
  if (effective.includes("skills")) {
353
- const copilotDir = resolve2(githubDir, "copilot");
354
- const skillsDir = resolve2(copilotDir, "skills");
503
+ const copilotDir = resolve(githubDir, "copilot");
504
+ const skillsDir = resolve(copilotDir, "skills");
355
505
  if (deleteExisting) {
356
506
  removeIfExists(skillsDir);
357
507
  filesDeleted.push(skillsDir);
@@ -367,8 +517,8 @@ class CopilotTarget extends BaseTarget {
367
517
  }
368
518
  }
369
519
  if (effective.includes("commands")) {
370
- const copilotDir = resolve2(githubDir, "copilot");
371
- const commandsDir = resolve2(copilotDir, "commands");
520
+ const copilotDir = resolve(githubDir, "copilot");
521
+ const commandsDir = resolve(copilotDir, "commands");
372
522
  if (deleteExisting) {
373
523
  removeIfExists(commandsDir);
374
524
  filesDeleted.push(commandsDir);
@@ -382,6 +532,17 @@ class CopilotTarget extends BaseTarget {
382
532
  }
383
533
  }
384
534
  if (effective.includes("ignore")) {}
535
+ if (effective.includes("models") && features.models) {
536
+ const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID);
537
+ const guidance = generateModelGuidanceMarkdown(resolved);
538
+ if (guidance) {
539
+ const copilotDir = resolve(githubDir, "copilot");
540
+ ensureDir(copilotDir);
541
+ const filepath = join3(copilotDir, "model-config.md");
542
+ writeGeneratedFile(filepath, guidance);
543
+ filesWritten.push(filepath);
544
+ }
545
+ }
385
546
  return this.createResult(filesWritten, filesDeleted, warnings);
386
547
  }
387
548
  }
@@ -1,32 +1,4 @@
1
1
  import { createRequire } from "node:module";
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 = /* @__PURE__ */ createRequire(import.meta.url);
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 = {}) {
@@ -279,6 +251,110 @@ function skillMatchesTarget(skill, targetId) {
279
251
  return Array.isArray(targets) && targets.includes(targetId);
280
252
  }
281
253
 
254
+ // src/core/profile-resolver.ts
255
+ function resolveModels(merged, modelProfile, targetId) {
256
+ let defaultModel = merged.default;
257
+ let smallModel = merged.small;
258
+ let agents = { ...merged.agents };
259
+ if (modelProfile && merged.profiles?.[modelProfile]) {
260
+ const resolvedProfile = resolveProfileInheritance(modelProfile, merged.profiles);
261
+ if (resolvedProfile.default)
262
+ defaultModel = resolvedProfile.default;
263
+ if (resolvedProfile.small)
264
+ smallModel = resolvedProfile.small;
265
+ if (resolvedProfile.agents) {
266
+ agents = { ...agents, ...resolvedProfile.agents };
267
+ }
268
+ }
269
+ if (targetId) {
270
+ const targetOverride = merged.overrides?.[targetId];
271
+ if (targetOverride) {
272
+ if (targetOverride.default)
273
+ defaultModel = targetOverride.default;
274
+ if (targetOverride.small)
275
+ smallModel = targetOverride.small;
276
+ if (targetOverride.agents) {
277
+ agents = { ...agents, ...targetOverride.agents };
278
+ }
279
+ }
280
+ }
281
+ const providers = {};
282
+ if (merged.providers) {
283
+ for (const [name, config] of Object.entries(merged.providers)) {
284
+ providers[name] = {
285
+ ...config.options ? { options: config.options } : {},
286
+ ...config.models ? { models: config.models } : {}
287
+ };
288
+ }
289
+ }
290
+ const profileNames = Object.keys(merged.profiles ?? {});
291
+ const profiles = {};
292
+ if (merged.profiles) {
293
+ for (const [name, profile] of Object.entries(merged.profiles)) {
294
+ profiles[name] = {
295
+ description: profile.description,
296
+ default: profile.default,
297
+ small: profile.small
298
+ };
299
+ }
300
+ }
301
+ return {
302
+ default: defaultModel,
303
+ small: smallModel,
304
+ agents,
305
+ providers,
306
+ routing: merged.routing ?? [],
307
+ profileNames,
308
+ activeProfile: modelProfile,
309
+ profiles
310
+ };
311
+ }
312
+ function resolveAgentModel(resolved, agentName, frontmatterModel) {
313
+ const fromModels = resolved.agents[agentName];
314
+ if (fromModels) {
315
+ return {
316
+ model: fromModels.model,
317
+ temperature: fromModels.temperature,
318
+ top_p: fromModels.top_p
319
+ };
320
+ }
321
+ if (frontmatterModel) {
322
+ return { model: frontmatterModel };
323
+ }
324
+ return {};
325
+ }
326
+ function resolveProfileInheritance(profileName, profiles) {
327
+ const visited = new Set;
328
+ return resolveProfileChain(profileName, profiles, visited, 0);
329
+ }
330
+ var MAX_INHERITANCE_DEPTH = 10;
331
+ function resolveProfileChain(name, profiles, visited, depth) {
332
+ if (depth > MAX_INHERITANCE_DEPTH) {
333
+ throw new Error(`Profile inheritance too deep (max ${MAX_INHERITANCE_DEPTH}): ${name}`);
334
+ }
335
+ if (visited.has(name)) {
336
+ throw new Error(`Circular profile inheritance detected: ${[...visited, name].join(" → ")}`);
337
+ }
338
+ const profile = profiles[name];
339
+ if (!profile) {
340
+ throw new Error(`Profile "${name}" not found`);
341
+ }
342
+ visited.add(name);
343
+ if (!profile.extends) {
344
+ return { ...profile };
345
+ }
346
+ const parent = resolveProfileChain(profile.extends, profiles, visited, depth + 1);
347
+ return {
348
+ description: profile.description ?? parent.description,
349
+ default: profile.default ?? parent.default,
350
+ small: profile.small ?? parent.small,
351
+ agents: {
352
+ ...parent.agents,
353
+ ...profile.agents
354
+ }
355
+ };
356
+ }
357
+
282
358
  // src/targets/base-target.ts
283
359
  class BaseTarget {
284
360
  supportsFeature(feature) {
@@ -298,7 +374,7 @@ class BaseTarget {
298
374
  }
299
375
 
300
376
  // src/targets/cursor.ts
301
- import { resolve as resolve2, join as join3 } from "path";
377
+ import { resolve, join as join3 } from "path";
302
378
  var TARGET_ID = "cursor";
303
379
 
304
380
  class CursorTarget extends BaseTarget {
@@ -311,18 +387,19 @@ class CursorTarget extends BaseTarget {
311
387
  "skills",
312
388
  "hooks",
313
389
  "mcp",
314
- "ignore"
390
+ "ignore",
391
+ "models"
315
392
  ];
316
393
  generate(options) {
317
394
  const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
318
- const root = resolve2(projectRoot, baseDir);
395
+ const root = resolve(projectRoot, baseDir);
319
396
  const effective = this.getEffectiveFeatures(enabledFeatures);
320
397
  const filesWritten = [];
321
398
  const filesDeleted = [];
322
399
  const warnings = [];
323
- const cursorDir = resolve2(root, ".cursor");
400
+ const cursorDir = resolve(root, ".cursor");
324
401
  if (effective.includes("rules")) {
325
- const rulesDir = resolve2(cursorDir, "rules");
402
+ const rulesDir = resolve(cursorDir, "rules");
326
403
  if (deleteExisting) {
327
404
  removeIfExists(rulesDir);
328
405
  filesDeleted.push(rulesDir);
@@ -346,18 +423,25 @@ class CursorTarget extends BaseTarget {
346
423
  }
347
424
  }
348
425
  if (effective.includes("agents")) {
349
- const agentsDir = resolve2(cursorDir, "agents");
426
+ const agentsDir = resolve(cursorDir, "agents");
350
427
  if (deleteExisting) {
351
428
  removeIfExists(agentsDir);
352
429
  filesDeleted.push(agentsDir);
353
430
  }
354
431
  ensureDir(agentsDir);
432
+ const resolvedModels = features.models ? resolveModels(features.models, options.modelProfile, TARGET_ID) : null;
355
433
  const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID));
356
434
  for (const agent of agents) {
357
435
  const frontmatter = {
358
436
  name: agent.name,
359
437
  description: agent.meta.description ?? ""
360
438
  };
439
+ const cursorMeta = agent.meta.cursor ?? {};
440
+ const modelsAgent = resolvedModels?.agents[agent.name];
441
+ const model = modelsAgent?.model ?? cursorMeta.model;
442
+ if (model) {
443
+ frontmatter.model = model;
444
+ }
361
445
  const filepath = join3(agentsDir, `${agent.name}.md`);
362
446
  const content = serializeFrontmatter(frontmatter, agent.content);
363
447
  writeGeneratedFile(filepath, content);
@@ -365,7 +449,7 @@ class CursorTarget extends BaseTarget {
365
449
  }
366
450
  }
367
451
  if (effective.includes("skills")) {
368
- const skillsDir = resolve2(cursorDir, "skills");
452
+ const skillsDir = resolve(cursorDir, "skills");
369
453
  if (deleteExisting) {
370
454
  removeIfExists(skillsDir);
371
455
  filesDeleted.push(skillsDir);
@@ -386,7 +470,7 @@ class CursorTarget extends BaseTarget {
386
470
  }
387
471
  }
388
472
  if (effective.includes("commands")) {
389
- const commandsDir = resolve2(cursorDir, "commands");
473
+ const commandsDir = resolve(cursorDir, "commands");
390
474
  if (deleteExisting) {
391
475
  removeIfExists(commandsDir);
392
476
  filesDeleted.push(commandsDir);
@@ -403,14 +487,14 @@ class CursorTarget extends BaseTarget {
403
487
  const mcpEntries = Object.entries(features.mcpServers);
404
488
  if (mcpEntries.length > 0) {
405
489
  const mcpConfig = buildCursorMcp(features.mcpServers);
406
- const filepath = resolve2(cursorDir, "mcp.json");
490
+ const filepath = resolve(cursorDir, "mcp.json");
407
491
  writeGeneratedJson(filepath, mcpConfig, { header: false });
408
492
  filesWritten.push(filepath);
409
493
  }
410
494
  }
411
495
  if (effective.includes("ignore")) {
412
496
  if (features.ignorePatterns.length > 0) {
413
- const filepath = resolve2(root, ".cursorignore");
497
+ const filepath = resolve(root, ".cursorignore");
414
498
  const content = features.ignorePatterns.join(`
415
499
  `) + `
416
500
  `;
@@ -418,6 +502,17 @@ class CursorTarget extends BaseTarget {
418
502
  filesWritten.push(filepath);
419
503
  }
420
504
  }
505
+ if (effective.includes("models") && features.models) {
506
+ const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID);
507
+ const guidanceContent = buildCursorModelGuidance(resolved);
508
+ if (guidanceContent) {
509
+ const rulesDir = resolve(cursorDir, "rules");
510
+ ensureDir(rulesDir);
511
+ const filepath = join3(rulesDir, "model-config.mdc");
512
+ writeGeneratedFile(filepath, guidanceContent, { header: false });
513
+ filesWritten.push(filepath);
514
+ }
515
+ }
421
516
  return this.createResult(filesWritten, filesDeleted, warnings);
422
517
  }
423
518
  }
@@ -436,6 +531,59 @@ function buildCursorMcp(servers) {
436
531
  }
437
532
  return { mcpServers };
438
533
  }
534
+ function buildCursorModelGuidance(resolved) {
535
+ if (!resolved.default && !resolved.small && Object.keys(resolved.agents).length === 0) {
536
+ return null;
537
+ }
538
+ const frontmatter = {
539
+ description: "Model configuration and selection guidelines for this workspace",
540
+ alwaysApply: true
541
+ };
542
+ const lines = [];
543
+ lines.push("# Model Configuration");
544
+ lines.push("");
545
+ lines.push("Use the following model preferences when working in this project.");
546
+ lines.push("");
547
+ if (resolved.default || resolved.small) {
548
+ lines.push("## Default Models");
549
+ lines.push("");
550
+ if (resolved.default) {
551
+ lines.push(`- **Primary model**: ${resolved.default}`);
552
+ }
553
+ if (resolved.small) {
554
+ lines.push(`- **Lightweight tasks** (titles, summaries): ${resolved.small}`);
555
+ }
556
+ lines.push("");
557
+ }
558
+ const agentEntries = Object.entries(resolved.agents);
559
+ if (agentEntries.length > 0) {
560
+ lines.push("## Agent Model Assignments");
561
+ lines.push("");
562
+ lines.push("| Agent | Model | Temperature |");
563
+ lines.push("| --- | --- | --- |");
564
+ for (const [name, assignment] of agentEntries) {
565
+ const temp = assignment.temperature !== undefined ? String(assignment.temperature) : "—";
566
+ lines.push(`| ${name} | ${assignment.model} | ${temp} |`);
567
+ }
568
+ lines.push("");
569
+ }
570
+ if (Object.keys(resolved.profiles).length > 0) {
571
+ lines.push("## Available Profiles");
572
+ lines.push("");
573
+ lines.push("| Profile | Description | Default Model |");
574
+ lines.push("| --- | --- | --- |");
575
+ for (const [name, profile] of Object.entries(resolved.profiles)) {
576
+ lines.push(`| ${name} | ${profile.description ?? "—"} | ${profile.default ?? "—"} |`);
577
+ }
578
+ lines.push("");
579
+ }
580
+ if (resolved.activeProfile) {
581
+ lines.push(`**Active profile**: \`${resolved.activeProfile}\``);
582
+ lines.push("");
583
+ }
584
+ return serializeFrontmatter(frontmatter, lines.join(`
585
+ `));
586
+ }
439
587
  export {
440
588
  CursorTarget
441
589
  };