agentpacks 1.7.12 → 1.8.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 (147) hide show
  1. package/dist/api.js +48 -3658
  2. package/dist/cli/export-cmd.js +7 -1027
  3. package/dist/cli/generate.js +39 -2731
  4. package/dist/cli/import-cmd.js +19 -770
  5. package/dist/cli/info.js +4 -231
  6. package/dist/cli/init.js +9 -185
  7. package/dist/cli/install.js +4 -902
  8. package/dist/cli/login.js +6 -201
  9. package/dist/cli/models-explain.js +14 -1266
  10. package/dist/cli/pack/create.js +4 -146
  11. package/dist/cli/pack/enable.js +2 -65
  12. package/dist/cli/pack/list.js +5 -893
  13. package/dist/cli/pack/validate.js +4 -642
  14. package/dist/cli/publish.js +8 -679
  15. package/dist/cli/search.js +4 -209
  16. package/dist/core/config.d.ts +1 -1
  17. package/dist/core/config.js +1 -145
  18. package/dist/core/dependency-resolver.js +1 -126
  19. package/dist/core/feature-merger.js +3 -398
  20. package/dist/core/index.js +5 -1129
  21. package/dist/core/lockfile.js +2 -43
  22. package/dist/core/metarepo.js +1 -183
  23. package/dist/core/pack-loader.js +4 -841
  24. package/dist/core/profile-resolver.js +1 -110
  25. package/dist/exporters/cursor-plugin.js +6 -404
  26. package/dist/exporters/index.js +6 -404
  27. package/dist/features/agents.js +3 -161
  28. package/dist/features/commands.js +3 -161
  29. package/dist/features/hooks.js +3 -153
  30. package/dist/features/ignore.js +2 -43
  31. package/dist/features/index.js +4 -629
  32. package/dist/features/mcp.js +3 -143
  33. package/dist/features/models.js +3 -292
  34. package/dist/features/plugins.js +3 -139
  35. package/dist/features/rules.d.ts +0 -1
  36. package/dist/features/rules.js +3 -169
  37. package/dist/features/skills.js +3 -228
  38. package/dist/importers/claude-code.js +6 -195
  39. package/dist/importers/cursor.js +5 -355
  40. package/dist/importers/opencode.js +6 -346
  41. package/dist/importers/rulesync.js +5 -365
  42. package/dist/index.js +89 -4934
  43. package/dist/node/api.js +48 -3659
  44. package/dist/node/cli/export-cmd.js +7 -1028
  45. package/dist/node/cli/generate.js +39 -2732
  46. package/dist/node/cli/import-cmd.js +19 -771
  47. package/dist/node/cli/info.js +4 -232
  48. package/dist/node/cli/init.js +9 -186
  49. package/dist/node/cli/install.js +4 -903
  50. package/dist/node/cli/login.js +6 -202
  51. package/dist/node/cli/models-explain.js +14 -1267
  52. package/dist/node/cli/pack/create.js +4 -147
  53. package/dist/node/cli/pack/enable.js +2 -66
  54. package/dist/node/cli/pack/list.js +5 -894
  55. package/dist/node/cli/pack/validate.js +4 -643
  56. package/dist/node/cli/publish.js +8 -680
  57. package/dist/node/cli/search.js +4 -210
  58. package/dist/node/core/config.js +1 -146
  59. package/dist/node/core/dependency-resolver.js +1 -127
  60. package/dist/node/core/feature-merger.js +3 -399
  61. package/dist/node/core/index.js +5 -1130
  62. package/dist/node/core/lockfile.js +2 -44
  63. package/dist/node/core/metarepo.js +1 -184
  64. package/dist/node/core/pack-loader.js +4 -842
  65. package/dist/node/core/profile-resolver.js +1 -111
  66. package/dist/node/exporters/cursor-plugin.js +6 -405
  67. package/dist/node/exporters/index.js +6 -405
  68. package/dist/node/features/agents.js +3 -162
  69. package/dist/node/features/commands.js +3 -162
  70. package/dist/node/features/hooks.js +3 -154
  71. package/dist/node/features/ignore.js +2 -44
  72. package/dist/node/features/index.js +4 -630
  73. package/dist/node/features/mcp.js +3 -144
  74. package/dist/node/features/models.js +3 -293
  75. package/dist/node/features/plugins.js +3 -140
  76. package/dist/node/features/rules.js +3 -170
  77. package/dist/node/features/skills.js +3 -229
  78. package/dist/node/importers/claude-code.js +6 -196
  79. package/dist/node/importers/cursor.js +5 -356
  80. package/dist/node/importers/opencode.js +6 -347
  81. package/dist/node/importers/rulesync.js +5 -366
  82. package/dist/node/index.js +89 -4935
  83. package/dist/node/sources/git-ref.js +1 -56
  84. package/dist/node/sources/git.js +2 -222
  85. package/dist/node/sources/index.js +4 -714
  86. package/dist/node/sources/local.js +1 -24
  87. package/dist/node/sources/npm-ref.js +1 -56
  88. package/dist/node/sources/npm.js +2 -184
  89. package/dist/node/sources/registry-ref.js +1 -37
  90. package/dist/node/sources/registry.js +4 -355
  91. package/dist/node/targets/additional-targets.js +6 -587
  92. package/dist/node/targets/base-target.js +1 -23
  93. package/dist/node/targets/claude-code.js +6 -714
  94. package/dist/node/targets/codex-cli.js +3 -324
  95. package/dist/node/targets/copilot.js +5 -603
  96. package/dist/node/targets/cursor.js +6 -700
  97. package/dist/node/targets/gemini-cli.js +10 -319
  98. package/dist/node/targets/generic-md-target.js +6 -478
  99. package/dist/node/targets/index.js +32 -1873
  100. package/dist/node/targets/mistral-vibe.js +7 -661
  101. package/dist/node/targets/opencode.js +13 -723
  102. package/dist/node/targets/registry.js +32 -1864
  103. package/dist/node/utils/credentials.js +3 -38
  104. package/dist/node/utils/diff.js +5 -132
  105. package/dist/node/utils/filesystem.js +3 -124
  106. package/dist/node/utils/frontmatter.js +1 -24
  107. package/dist/node/utils/global.js +1 -53
  108. package/dist/node/utils/markdown.js +3 -30
  109. package/dist/node/utils/model-allowlist.js +1 -126
  110. package/dist/node/utils/model-guidance.js +2 -78
  111. package/dist/node/utils/registry-client.js +1 -142
  112. package/dist/node/utils/tarball.js +1 -49
  113. package/dist/sources/git-ref.js +1 -55
  114. package/dist/sources/git.js +2 -221
  115. package/dist/sources/index.js +4 -713
  116. package/dist/sources/local.js +1 -23
  117. package/dist/sources/npm-ref.js +1 -55
  118. package/dist/sources/npm.js +2 -183
  119. package/dist/sources/registry-ref.js +1 -36
  120. package/dist/sources/registry.js +4 -354
  121. package/dist/targets/additional-targets.js +6 -586
  122. package/dist/targets/base-target.js +1 -22
  123. package/dist/targets/claude-code.js +6 -713
  124. package/dist/targets/codex-cli.js +3 -323
  125. package/dist/targets/copilot.js +5 -602
  126. package/dist/targets/cursor.js +6 -699
  127. package/dist/targets/gemini-cli.js +10 -318
  128. package/dist/targets/generic-md-target.js +6 -477
  129. package/dist/targets/index.d.ts +0 -1
  130. package/dist/targets/index.js +32 -1872
  131. package/dist/targets/mistral-vibe.js +7 -660
  132. package/dist/targets/opencode.js +13 -722
  133. package/dist/targets/registry.js +32 -1863
  134. package/dist/utils/credentials.js +3 -37
  135. package/dist/utils/diff.js +5 -131
  136. package/dist/utils/filesystem.js +3 -123
  137. package/dist/utils/frontmatter.js +1 -23
  138. package/dist/utils/global.js +1 -52
  139. package/dist/utils/markdown.js +3 -29
  140. package/dist/utils/model-allowlist.js +1 -125
  141. package/dist/utils/model-guidance.js +2 -77
  142. package/dist/utils/registry-client.js +1 -141
  143. package/dist/utils/tarball.js +1 -48
  144. package/package.json +5 -17
  145. package/dist/node/targets/agents-md.js +0 -211
  146. package/dist/targets/agents-md.d.ts +0 -13
  147. package/dist/targets/agents-md.js +0 -211
package/dist/api.js CHANGED
@@ -1,3675 +1,65 @@
1
1
  // @bun
2
- var __require = import.meta.require;
3
-
4
- // src/core/config.ts
5
- import { existsSync, readFileSync } from "fs";
6
- import { parse as parseJsonc } from "jsonc-parser";
7
- import { resolve } from "path";
8
- import { z } from "zod";
9
- var TARGET_IDS = [
10
- "opencode",
11
- "cursor",
12
- "claudecode",
13
- "codexcli",
14
- "mistralvibe",
15
- "geminicli",
16
- "copilot",
17
- "agentsmd",
18
- "cline",
19
- "kilo",
20
- "roo",
21
- "qwencode",
22
- "kiro",
23
- "factorydroid",
24
- "antigravity",
25
- "junie",
26
- "augmentcode",
27
- "windsurf",
28
- "warp",
29
- "replit",
30
- "zed"
31
- ];
32
- var FEATURE_IDS = [
33
- "rules",
34
- "commands",
35
- "agents",
36
- "skills",
37
- "hooks",
38
- "plugins",
39
- "mcp",
40
- "ignore",
41
- "models"
42
- ];
43
- var REPO_MODES = ["repo", "monorepo", "metarepo"];
44
- var PackManifestSchema = z.object({
45
- name: z.string().min(1),
46
- version: z.string().default("1.0.0"),
47
- description: z.string().default(""),
48
- author: z.union([
49
- z.string(),
50
- z.object({ name: z.string(), email: z.string().optional() })
51
- ]).optional(),
52
- homepage: z.string().optional(),
53
- repository: z.union([
54
- z.string(),
55
- z.object({ url: z.string(), type: z.string().optional() })
56
- ]).optional(),
57
- license: z.string().optional(),
58
- logo: z.string().optional(),
59
- tags: z.array(z.string()).default([]),
60
- dependencies: z.array(z.string()).default([]),
61
- conflicts: z.array(z.string()).default([]),
62
- targets: z.union([z.literal("*"), z.array(z.string())]).default("*"),
63
- features: z.union([z.literal("*"), z.array(z.string())]).default("*")
64
- });
65
- var FeaturesSchema = z.union([
66
- z.literal("*"),
67
- z.array(z.string()),
68
- z.record(z.string(), z.union([z.literal("*"), z.array(z.string())]))
69
- ]);
70
- var WorkspaceConfigSchema = z.object({
71
- $schema: z.string().optional(),
72
- packs: z.array(z.string()).default(["./packs/default"]),
73
- disabled: z.array(z.string()).default([]),
74
- targets: z.union([z.literal("*"), z.array(z.string())]).default("*"),
75
- features: FeaturesSchema.default("*"),
76
- mode: z.enum(REPO_MODES).default("repo"),
77
- baseDirs: z.array(z.string()).default(["."]),
78
- global: z.boolean().default(false),
79
- delete: z.boolean().default(true),
80
- verbose: z.boolean().default(false),
81
- silent: z.boolean().default(false),
82
- overrides: z.record(z.string(), z.record(z.string(), z.string())).default({}),
83
- sources: z.array(z.object({
84
- source: z.string(),
85
- packs: z.array(z.string()).optional(),
86
- skills: z.array(z.string()).optional()
87
- })).default([]),
88
- modelProfile: z.string().optional()
89
- });
90
- var CONFIG_FILES = ["agentpacks.local.jsonc", "agentpacks.jsonc"];
91
- function loadWorkspaceConfig(projectRoot) {
92
- for (const filename of CONFIG_FILES) {
93
- const filepath = resolve(projectRoot, filename);
94
- if (existsSync(filepath)) {
95
- const raw = readFileSync(filepath, "utf-8");
96
- const parsed = parseJsonc(raw);
97
- return WorkspaceConfigSchema.parse(parsed);
98
- }
99
- }
100
- return WorkspaceConfigSchema.parse({});
101
- }
102
- function loadPackManifest(packDir) {
103
- const filepath = resolve(packDir, "pack.json");
104
- if (!existsSync(filepath)) {
105
- const dirName = packDir.split("/").pop() ?? "unknown";
106
- return PackManifestSchema.parse({ name: dirName });
107
- }
108
- const raw = readFileSync(filepath, "utf-8");
109
- const parsed = JSON.parse(raw);
110
- return PackManifestSchema.parse(parsed);
111
- }
112
- function resolveFeatures(config, targetId) {
113
- const { features } = config;
114
- if (features === "*") {
115
- return [...FEATURE_IDS];
116
- }
117
- if (Array.isArray(features)) {
118
- if (features.includes("*"))
119
- return [...FEATURE_IDS];
120
- return features.filter((f) => FEATURE_IDS.includes(f));
121
- }
122
- const targetFeatures = features[targetId];
123
- if (!targetFeatures)
124
- return [];
125
- if (targetFeatures === "*")
126
- return [...FEATURE_IDS];
127
- if (Array.isArray(targetFeatures) && targetFeatures.includes("*"))
128
- return [...FEATURE_IDS];
129
- return targetFeatures.filter((f) => FEATURE_IDS.includes(f));
130
- }
131
- function resolveTargets(config) {
132
- if (config.targets === "*")
133
- return [...TARGET_IDS];
134
- return config.targets;
135
- }
136
-
137
- // src/core/dependency-resolver.ts
138
- function buildDependencyGraph(manifests) {
139
- const graph = new Map;
140
- for (const m of manifests) {
141
- graph.set(m.name, {
142
- name: m.name,
143
- manifest: m,
144
- dependencies: m.dependencies,
145
- conflicts: m.conflicts
146
- });
147
- }
148
- return graph;
149
- }
150
- function resolveDependencies(manifests) {
151
- const graph = buildDependencyGraph(manifests);
152
- const allNames = new Set(graph.keys());
153
- const missingDeps = [];
154
- for (const [name, node] of graph) {
155
- for (const dep of node.dependencies) {
156
- if (!allNames.has(dep)) {
157
- missingDeps.push([name, dep]);
158
- }
159
- }
160
- }
161
- const { sorted, cycles } = topologicalSort(graph);
162
- const conflictPairs = detectConflicts(graph);
163
- const ok = cycles.length === 0 && conflictPairs.length === 0 && missingDeps.length === 0;
164
- return { sorted, cycles, conflictPairs, missingDeps, ok };
165
- }
166
- function topologicalSort(graph) {
167
- const inDegree = new Map;
168
- for (const name of graph.keys()) {
169
- inDegree.set(name, 0);
170
- }
171
- for (const [, node] of graph) {
172
- for (const dep of node.dependencies) {
173
- if (graph.has(dep)) {
174
- inDegree.set(dep, (inDegree.get(dep) ?? 0) + 1);
175
- }
176
- }
177
- }
178
- const queue = [];
179
- for (const [name, degree] of inDegree) {
180
- if (degree === 0)
181
- queue.push(name);
182
- }
183
- const sorted = [];
184
- while (queue.length > 0) {
185
- const current = queue.shift();
186
- if (!current)
187
- continue;
188
- sorted.push(current);
189
- const node = graph.get(current);
190
- if (!node)
191
- continue;
192
- for (const dep of node.dependencies) {
193
- if (!graph.has(dep))
194
- continue;
195
- const newDegree = (inDegree.get(dep) ?? 1) - 1;
196
- inDegree.set(dep, newDegree);
197
- if (newDegree === 0) {
198
- queue.push(dep);
199
- }
200
- }
201
- }
202
- const cycles = [];
203
- if (sorted.length < graph.size) {
204
- const remaining = new Set;
205
- for (const name of graph.keys()) {
206
- if (!sorted.includes(name))
207
- remaining.add(name);
208
- }
209
- const visited = new Set;
210
- for (const start of remaining) {
211
- if (visited.has(start))
212
- continue;
213
- const cycle = traceCycle(start, graph, remaining);
214
- if (cycle.length > 0) {
215
- cycles.push(cycle);
216
- for (const n of cycle)
217
- visited.add(n);
218
- }
219
- }
220
- }
221
- return { sorted: sorted.reverse(), cycles };
222
- }
223
- function traceCycle(start, graph, remaining) {
224
- const path = [];
225
- const pathSet = new Set;
226
- let current = start;
227
- while (current && !pathSet.has(current)) {
228
- path.push(current);
229
- pathSet.add(current);
230
- const node = graph.get(current);
231
- if (!node)
232
- break;
233
- current = node.dependencies.find((d) => remaining.has(d) && graph.has(d));
234
- }
235
- if (current && pathSet.has(current)) {
236
- const cycleStart = path.indexOf(current);
237
- return path.slice(cycleStart);
238
- }
239
- return path;
240
- }
241
- function detectConflicts(graph) {
242
- const conflicts = [];
243
- const seen = new Set;
244
- for (const [name, node] of graph) {
245
- for (const conflict of node.conflicts) {
246
- if (graph.has(conflict)) {
247
- const key = [name, conflict].sort().join(":");
248
- if (!seen.has(key)) {
249
- seen.add(key);
250
- conflicts.push([name, conflict]);
251
- }
252
- }
253
- }
254
- }
255
- return conflicts;
256
- }
257
-
258
- // src/utils/filesystem.ts
259
- import {
260
- existsSync as existsSync2,
261
- mkdirSync,
262
- readdirSync,
263
- readFileSync as readFileSync2,
264
- rmSync,
265
- statSync,
266
- writeFileSync
267
- } from "fs";
268
- import { dirname, join, relative } from "path";
269
- var GENERATED_HEADER_MD = "<!-- Generated by agentpacks. DO NOT EDIT. -->";
270
- var GENERATED_HEADER_JSON = "// Generated by agentpacks. DO NOT EDIT.";
271
- var GENERATED_HEADER_JS = "// Generated by agentpacks. DO NOT EDIT.";
272
- function writeGeneratedFile(filepath, content, options = {}) {
273
- const { header = true, type } = options;
274
- const ext = type ?? inferFileType(filepath);
275
- ensureDir(dirname(filepath));
276
- let output = content;
277
- if (header) {
278
- const headerComment = getHeader(ext);
279
- if (headerComment) {
280
- output = `${headerComment}
281
- ${content}`;
282
- }
283
- }
284
- writeFileSync(filepath, output, "utf-8");
285
- }
286
- function writeGeneratedJson(filepath, data, options = {}) {
287
- const json = JSON.stringify(data, null, 2);
288
- writeGeneratedFile(filepath, json + `
289
- `, { ...options, type: "json" });
290
- }
291
- function readFileOrNull(filepath) {
292
- if (!existsSync2(filepath))
293
- return null;
294
- return readFileSync2(filepath, "utf-8");
295
- }
296
- function readJsonOrNull(filepath) {
297
- const content = readFileOrNull(filepath);
298
- if (content === null)
299
- return null;
300
- return JSON.parse(content);
301
- }
302
- function ensureDir(dirPath) {
303
- if (!existsSync2(dirPath)) {
304
- mkdirSync(dirPath, { recursive: true });
305
- }
306
- }
307
- function removeIfExists(targetPath) {
308
- if (existsSync2(targetPath)) {
309
- rmSync(targetPath, { recursive: true, force: true });
310
- }
311
- }
312
- function listFiles(dirPath, options = {}) {
313
- const { extension, recursive = false } = options;
314
- if (!existsSync2(dirPath))
315
- return [];
316
- const results = [];
317
- const entries = readdirSync(dirPath);
318
- for (const entry of entries) {
319
- const fullPath = join(dirPath, entry);
320
- const stat = statSync(fullPath);
321
- if (stat.isDirectory() && recursive) {
322
- results.push(...listFiles(fullPath, options));
323
- } else if (stat.isFile()) {
324
- if (!extension || entry.endsWith(extension)) {
325
- results.push(fullPath);
326
- }
327
- }
328
- }
329
- return results;
330
- }
331
- function listDirs(dirPath) {
332
- if (!existsSync2(dirPath))
333
- return [];
334
- return readdirSync(dirPath).map((entry) => join(dirPath, entry)).filter((fullPath) => statSync(fullPath).isDirectory());
335
- }
336
- function relPath(projectRoot, filepath) {
337
- return relative(projectRoot, filepath);
338
- }
339
- function isGeneratedFile(filepath) {
340
- const content = readFileOrNull(filepath);
341
- if (!content)
342
- return false;
343
- return content.startsWith(GENERATED_HEADER_MD) || content.startsWith(GENERATED_HEADER_JSON) || content.startsWith(GENERATED_HEADER_JS);
344
- }
345
- function inferFileType(filepath) {
346
- if (filepath.endsWith(".json") || filepath.endsWith(".jsonc"))
347
- return "json";
348
- if (filepath.endsWith(".ts") || filepath.endsWith(".mts"))
349
- return "ts";
350
- if (filepath.endsWith(".js") || filepath.endsWith(".mjs"))
351
- return "js";
352
- return "md";
353
- }
354
- function getHeader(type) {
355
- switch (type) {
356
- case "md":
357
- return GENERATED_HEADER_MD;
358
- case "json":
359
- return GENERATED_HEADER_JSON;
360
- case "js":
361
- case "ts":
362
- return GENERATED_HEADER_JS;
363
- default:
364
- return null;
365
- }
366
- }
367
-
368
- // src/features/models.ts
369
- import { join as join2 } from "path";
370
- import { z as z2 } from "zod";
371
- var SECRET_PATTERNS = [
372
- /["']api[_-]?key["']\s*:/i,
373
- /["']apiKey["']\s*:/i,
374
- /["']secret["']\s*:/i,
375
- /["']password["']\s*:/i,
376
- /["'](?:auth_token|access_token|bearer_token)["']\s*:/i,
377
- /["']private[_-]?key["']\s*:/i,
378
- /-----BEGIN\s+(RSA|EC|DSA|OPENSSH|PGP)\s+PRIVATE\s+KEY-----/,
379
- /sk-[a-zA-Z0-9]{20,}/,
380
- /Bearer\s+[a-zA-Z0-9._-]{20,}/
381
- ];
382
- var AgentModelSchema = z2.object({
383
- model: z2.string(),
384
- temperature: z2.number().min(0).max(2).optional(),
385
- top_p: z2.number().min(0).max(1).optional()
386
- });
387
- var ModelProfileSchema = z2.object({
388
- extends: z2.string().optional(),
389
- description: z2.string().optional(),
390
- default: z2.string().optional(),
391
- small: z2.string().optional(),
392
- agents: z2.record(z2.string(), AgentModelSchema).optional()
393
- });
394
- var RoutingConditionSchema = z2.object({
395
- complexity: z2.enum(["low", "medium", "high", "critical"]).optional().describe("Task complexity level"),
396
- urgency: z2.enum(["low", "normal", "high"]).optional().describe("Time sensitivity"),
397
- budget: z2.enum(["minimal", "standard", "premium"]).optional().describe("Cost/token budget tier"),
398
- contextWindowNeed: z2.enum(["small", "medium", "large", "max"]).optional().describe("Required context window size"),
399
- toolUseIntensity: z2.enum(["none", "light", "heavy"]).optional().describe("Expected tool/function calling intensity")
400
- });
401
- var RoutingRuleSchema = z2.object({
402
- when: z2.record(z2.string(), z2.string()),
403
- use: z2.string(),
404
- description: z2.string().optional(),
405
- priority: z2.number().optional()
406
- });
407
- var ProviderModelSchema = z2.object({
408
- options: z2.record(z2.string(), z2.unknown()).optional(),
409
- variants: z2.record(z2.string(), z2.record(z2.string(), z2.unknown())).optional()
410
- });
411
- var ProviderConfigSchema = z2.object({
412
- options: z2.record(z2.string(), z2.unknown()).optional(),
413
- models: z2.record(z2.string(), ProviderModelSchema).optional()
414
- });
415
- var ModelsSchema = z2.object({
416
- default: z2.string().optional(),
417
- small: z2.string().optional(),
418
- agents: z2.record(z2.string(), AgentModelSchema).optional(),
419
- profiles: z2.record(z2.string(), ModelProfileSchema).optional(),
420
- providers: z2.record(z2.string(), ProviderConfigSchema).optional(),
421
- routing: z2.array(RoutingRuleSchema).optional(),
422
- overrides: z2.record(z2.string(), z2.object({
423
- default: z2.string().optional(),
424
- small: z2.string().optional(),
425
- agents: z2.record(z2.string(), AgentModelSchema).optional()
426
- })).optional()
427
- });
428
- function parseModels(packDir, packName) {
429
- const modelsPath = join2(packDir, "models.json");
430
- const raw = readJsonOrNull(modelsPath);
431
- if (!raw)
432
- return null;
433
- const parsed = ModelsSchema.parse(raw);
434
- return {
435
- packName,
436
- sourcePath: modelsPath,
437
- config: parsed
438
- };
439
- }
440
- function mergeModelsConfigs(configs) {
441
- const warnings = [];
442
- const result = {};
443
- for (const entry of configs) {
444
- const { config, packName } = entry;
445
- if (config.default !== undefined && result.default === undefined) {
446
- result.default = config.default;
447
- } else if (config.default !== undefined && result.default !== undefined) {
448
- warnings.push(`Models "default" from pack "${packName}" skipped (already defined).`);
449
- }
450
- if (config.small !== undefined && result.small === undefined) {
451
- result.small = config.small;
452
- } else if (config.small !== undefined && result.small !== undefined) {
453
- warnings.push(`Models "small" from pack "${packName}" skipped (already defined).`);
454
- }
455
- if (config.agents) {
456
- if (!result.agents)
457
- result.agents = {};
458
- for (const [name, assignment] of Object.entries(config.agents)) {
459
- if (name in result.agents) {
460
- warnings.push(`Models agent "${name}" from pack "${packName}" skipped (already defined).`);
461
- continue;
462
- }
463
- result.agents[name] = assignment;
464
- }
465
- }
466
- if (config.profiles) {
467
- if (!result.profiles)
468
- result.profiles = {};
469
- for (const [name, profile] of Object.entries(config.profiles)) {
470
- if (name in result.profiles) {
471
- warnings.push(`Models profile "${name}" from pack "${packName}" skipped (already defined).`);
472
- continue;
473
- }
474
- result.profiles[name] = profile;
475
- }
476
- }
477
- if (config.providers) {
478
- if (!result.providers)
479
- result.providers = {};
480
- for (const [providerName, providerConfig] of Object.entries(config.providers)) {
481
- if (!(providerName in result.providers)) {
482
- result.providers[providerName] = providerConfig;
483
- } else {
484
- const existing = result.providers[providerName];
485
- if (!existing) {
486
- result.providers[providerName] = providerConfig;
487
- continue;
488
- }
489
- if (providerConfig.options) {
490
- existing.options = {
491
- ...providerConfig.options,
492
- ...existing.options
493
- };
494
- }
495
- if (providerConfig.models) {
496
- if (!existing.models)
497
- existing.models = {};
498
- for (const [modelName, modelConfig] of Object.entries(providerConfig.models)) {
499
- if (!(modelName in existing.models)) {
500
- existing.models[modelName] = modelConfig;
501
- }
502
- }
503
- }
504
- }
505
- }
506
- }
507
- if (config.routing) {
508
- if (!result.routing)
509
- result.routing = [];
510
- result.routing.push(...config.routing);
511
- }
512
- if (config.overrides) {
513
- if (!result.overrides)
514
- result.overrides = {};
515
- for (const [targetId, override] of Object.entries(config.overrides)) {
516
- if (targetId in result.overrides) {
517
- warnings.push(`Models override for target "${targetId}" from pack "${packName}" skipped (already defined).`);
518
- continue;
519
- }
520
- result.overrides[targetId] = override;
521
- }
522
- }
523
- }
524
- return { config: result, warnings };
525
- }
526
- function scanModelsForSecrets(config) {
527
- const warnings = [];
528
- const json = JSON.stringify(config);
529
- for (const pattern of SECRET_PATTERNS) {
530
- if (pattern.test(json)) {
531
- warnings.push(`Potential secret detected in models.json matching pattern: ${pattern.source}`);
532
- }
533
- }
534
- return warnings;
535
- }
536
-
537
- // src/core/feature-merger.ts
538
- class FeatureMerger {
539
- packs;
540
- warnings = [];
541
- constructor(packs) {
542
- this.packs = packs;
543
- }
544
- merge() {
545
- this.warnings = [];
546
- const features = {
547
- rules: this.mergeRules(),
548
- commands: this.mergeByName("commands"),
549
- agents: this.mergeByName("agents"),
550
- skills: this.mergeByName("skills"),
551
- hooks: this.mergeHooks(),
552
- plugins: this.mergePlugins(),
553
- mcpServers: this.mergeMcp(),
554
- ignorePatterns: this.mergeIgnore(),
555
- models: this.mergeModels()
556
- };
557
- return { features, warnings: this.warnings };
558
- }
559
- mergeRules() {
560
- const seen = new Map;
561
- const result = [];
562
- for (const pack of this.packs) {
563
- for (const rule of pack.rules) {
564
- const existing = seen.get(rule.name);
565
- if (existing) {
566
- this.warnings.push(`Rule "${rule.name}" from pack "${rule.packName}" skipped (already defined by "${existing}").`);
567
- continue;
568
- }
569
- seen.set(rule.name, rule.packName);
570
- result.push(rule);
571
- }
572
- }
573
- return result;
574
- }
575
- mergeByName(featureKey) {
576
- const seen = new Map;
577
- const result = [];
578
- for (const pack of this.packs) {
579
- const items = pack[featureKey];
580
- for (const item of items) {
581
- const existing = seen.get(item.name);
582
- if (existing) {
583
- this.warnings.push(`${featureKey.slice(0, -1)} "${item.name}" from pack "${item.packName}" skipped (already defined by "${existing}").`);
584
- continue;
585
- }
586
- seen.set(item.name, item.packName);
587
- result.push(item);
588
- }
589
- }
590
- return result;
591
- }
592
- mergeHooks() {
593
- return this.packs.map((p) => p.hooks).filter((h) => h !== null);
594
- }
595
- mergePlugins() {
596
- const seen = new Map;
597
- const result = [];
598
- for (const pack of this.packs) {
599
- for (const plugin of pack.plugins) {
600
- const key = `${plugin.name}.${plugin.extension}`;
601
- const existing = seen.get(key);
602
- if (existing) {
603
- this.warnings.push(`Plugin "${key}" from pack "${plugin.packName}" skipped (already defined by "${existing}").`);
604
- continue;
605
- }
606
- seen.set(key, plugin.packName);
607
- result.push(plugin);
608
- }
609
- }
610
- return result;
611
- }
612
- mergeMcp() {
613
- const servers = {};
614
- for (const pack of this.packs) {
615
- if (!pack.mcp)
616
- continue;
617
- for (const [name, entry] of Object.entries(pack.mcp.servers)) {
618
- if (name in servers) {
619
- this.warnings.push(`MCP server "${name}" from pack "${pack.manifest.name}" skipped (already defined).`);
620
- continue;
621
- }
622
- servers[name] = entry;
623
- }
624
- }
625
- return servers;
626
- }
627
- mergeIgnore() {
628
- const seen = new Set;
629
- const result = [];
630
- for (const pack of this.packs) {
631
- if (!pack.ignore)
632
- continue;
633
- for (const pattern of pack.ignore.patterns) {
634
- if (!seen.has(pattern)) {
635
- seen.add(pattern);
636
- result.push(pattern);
637
- }
638
- }
639
- }
640
- return result;
641
- }
642
- mergeModels() {
643
- const configs = this.packs.map((p) => p.models).filter((m) => m != null);
644
- if (configs.length === 0)
645
- return null;
646
- const { config, warnings } = mergeModelsConfigs(configs);
647
- this.warnings.push(...warnings);
648
- return config;
649
- }
650
- }
651
-
652
- // src/core/lockfile.ts
653
- import { createHash } from "crypto";
654
- import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
655
- import { resolve as resolve2 } from "path";
656
- var LOCKFILE_VERSION = 1;
657
- var LOCKFILE_NAME = "agentpacks.lock";
658
- function loadLockfile(projectRoot) {
659
- const filepath = resolve2(projectRoot, LOCKFILE_NAME);
660
- if (!existsSync3(filepath)) {
661
- return { lockfileVersion: LOCKFILE_VERSION, sources: {} };
662
- }
663
- const raw = readFileSync3(filepath, "utf-8");
664
- return JSON.parse(raw);
665
- }
666
- function saveLockfile(projectRoot, lockfile) {
667
- const filepath = resolve2(projectRoot, LOCKFILE_NAME);
668
- writeFileSync2(filepath, JSON.stringify(lockfile, null, 2) + `
669
- `);
670
- }
671
- function getLockedSource(lockfile, sourceKey) {
672
- return lockfile.sources[sourceKey];
673
- }
674
- function setLockedSource(lockfile, sourceKey, entry) {
675
- lockfile.sources[sourceKey] = entry;
676
- }
677
- function computeIntegrity(content) {
678
- const hash = createHash("sha256").update(content).digest("hex");
679
- return `sha256-${hash}`;
680
- }
681
- function isLockfileFrozenValid(lockfile, sourceKeys) {
682
- const missing = sourceKeys.filter((key) => !(key in lockfile.sources));
683
- return { valid: missing.length === 0, missing };
684
- }
685
-
686
- // src/utils/frontmatter.ts
687
- import matter from "gray-matter";
688
- function parseFrontmatter(source) {
689
- const { data, content } = matter(source);
690
- return {
691
- data,
692
- content: content.trim(),
693
- raw: source
694
- };
695
- }
696
- function serializeFrontmatter(data, content) {
697
- const filtered = Object.fromEntries(Object.entries(data).filter(([, v]) => v !== undefined));
698
- if (Object.keys(filtered).length === 0) {
699
- return content;
700
- }
701
- return matter.stringify(content, filtered);
702
- }
703
-
704
- // src/features/agents.ts
705
- import { readFileSync as readFileSync4 } from "fs";
706
- import { basename } from "path";
707
- function parseAgents(agentsDir, packName) {
708
- const files = listFiles(agentsDir, { extension: ".md" });
709
- return files.map((filepath) => parseAgentFile(filepath, packName));
710
- }
711
- function parseAgentFile(filepath, packName) {
712
- const raw = readFileSync4(filepath, "utf-8");
713
- const { data, content } = parseFrontmatter(raw);
714
- return {
715
- name: data.name ?? basename(filepath, ".md"),
716
- sourcePath: filepath,
717
- packName,
718
- meta: data,
719
- content
720
- };
721
- }
722
- function agentMatchesTarget(agent, targetId) {
723
- const { targets } = agent.meta;
724
- if (!targets || targets === "*")
725
- return true;
726
- if (Array.isArray(targets) && targets.includes("*"))
727
- return true;
728
- return Array.isArray(targets) && targets.includes(targetId);
729
- }
730
-
731
- // src/features/commands.ts
732
- import { readFileSync as readFileSync5 } from "fs";
733
- import { basename as basename2 } from "path";
734
- function parseCommands(commandsDir, packName) {
735
- const files = listFiles(commandsDir, { extension: ".md" });
736
- return files.map((filepath) => parseCommandFile(filepath, packName));
737
- }
738
- function parseCommandFile(filepath, packName) {
739
- const raw = readFileSync5(filepath, "utf-8");
740
- const { data, content } = parseFrontmatter(raw);
741
- return {
742
- name: basename2(filepath, ".md"),
743
- sourcePath: filepath,
744
- packName,
745
- meta: data,
746
- content
747
- };
748
- }
749
- function commandMatchesTarget(cmd, targetId) {
750
- const { targets } = cmd.meta;
751
- if (!targets || targets === "*")
752
- return true;
753
- if (Array.isArray(targets) && targets.includes("*"))
754
- return true;
755
- return Array.isArray(targets) && targets.includes(targetId);
756
- }
757
-
758
- // src/features/hooks.ts
759
- import { join as join3 } from "path";
760
- var TARGET_OVERRIDE_KEYS = ["cursor", "claudecode", "opencode"];
761
- function parseHooks(packDir, packName) {
762
- const hooksPath = join3(packDir, "hooks", "hooks.json");
763
- const raw = readJsonOrNull(hooksPath);
764
- if (!raw)
765
- return null;
766
- const shared = raw.hooks ?? {};
767
- const targetOverrides = {};
768
- for (const key of TARGET_OVERRIDE_KEYS) {
769
- const override = raw[key];
770
- if (override && typeof override === "object" && "hooks" in override && override.hooks) {
771
- targetOverrides[key] = override.hooks;
772
- }
773
- }
774
- return {
775
- packName,
776
- sourcePath: hooksPath,
777
- version: raw.version,
778
- shared,
779
- targetOverrides
780
- };
781
- }
782
- function resolveHooksForTarget(hooks, targetId) {
783
- const merged = {};
784
- for (const [event, entries] of Object.entries(hooks.shared)) {
785
- merged[event] = [...entries];
786
- }
787
- const overrides = hooks.targetOverrides[targetId];
788
- if (overrides) {
789
- for (const [event, entries] of Object.entries(overrides)) {
790
- merged[event] = [...merged[event] ?? [], ...entries];
791
- }
792
- }
793
- return merged;
794
- }
795
-
796
- // src/features/ignore.ts
797
- import { existsSync as existsSync4, readFileSync as readFileSync6 } from "fs";
798
- import { join as join4 } from "path";
799
- var IGNORE_FILES = ["ignore", ".aiignore"];
800
- function parseIgnore(packDir, packName) {
801
- for (const filename of IGNORE_FILES) {
802
- const filepath = join4(packDir, filename);
803
- if (existsSync4(filepath)) {
804
- const raw = readFileSync6(filepath, "utf-8");
805
- const patterns = parseIgnoreContent(raw);
806
- return {
807
- packName,
808
- sourcePath: filepath,
809
- patterns
810
- };
811
- }
812
- }
813
- return null;
814
- }
815
- function parseIgnoreContent(content) {
816
- return content.split(`
817
- `).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
818
- }
819
- function mergeIgnorePatterns(configs) {
820
- const seen = new Set;
821
- const result = [];
822
- for (const config of configs) {
823
- for (const pattern of config.patterns) {
824
- if (!seen.has(pattern)) {
825
- seen.add(pattern);
826
- result.push(pattern);
827
- }
828
- }
829
- }
830
- return result;
831
- }
832
-
833
- // src/features/mcp.ts
834
- import { join as join5 } from "path";
835
- function parseMcp(packDir, packName) {
836
- const mcpPath = join5(packDir, "mcp.json");
837
- const raw = readJsonOrNull(mcpPath);
838
- if (!raw?.mcpServers)
839
- return null;
840
- return {
841
- packName,
842
- sourcePath: mcpPath,
843
- servers: raw.mcpServers
844
- };
845
- }
846
- function mergeMcpConfigs(configs) {
847
- const servers = {};
848
- const warnings = [];
849
- for (const config of configs) {
850
- for (const [name, entry] of Object.entries(config.servers)) {
851
- if (name in servers) {
852
- warnings.push(`MCP server "${name}" from pack "${config.packName}" skipped (already defined).`);
853
- continue;
854
- }
855
- servers[name] = entry;
856
- }
857
- }
858
- return { servers, warnings };
859
- }
860
-
861
- // src/features/plugins.ts
862
- import { existsSync as existsSync5, readFileSync as readFileSync7 } from "fs";
863
- import { basename as basename3, join as join6 } from "path";
864
- function parsePlugins(packDir, packName) {
865
- const pluginsDir = join6(packDir, "plugins");
866
- if (!existsSync5(pluginsDir))
867
- return [];
868
- const tsFiles = listFiles(pluginsDir, { extension: ".ts" });
869
- const jsFiles = listFiles(pluginsDir, { extension: ".js" });
870
- const allFiles = [...tsFiles, ...jsFiles];
871
- return allFiles.map((filepath) => parsePluginFile(filepath, packName));
872
- }
873
- function parsePluginFile(filepath, packName) {
874
- const content = readFileSync7(filepath, "utf-8");
875
- const ext = filepath.endsWith(".ts") ? "ts" : "js";
876
- return {
877
- name: basename3(filepath, `.${ext}`),
878
- sourcePath: filepath,
879
- packName,
880
- content,
881
- extension: ext
882
- };
883
- }
884
-
885
- // src/features/rules.ts
886
- import { readFileSync as readFileSync8 } from "fs";
887
- import { basename as basename4 } from "path";
888
- function parseRules(rulesDir, packName) {
889
- const files = listFiles(rulesDir, { extension: ".md" });
890
- return files.map((filepath) => parseRuleFile(filepath, packName));
891
- }
892
- function parseRuleFile(filepath, packName) {
893
- const raw = readFileSync8(filepath, "utf-8");
894
- const { data, content } = parseFrontmatter(raw);
895
- return {
896
- name: basename4(filepath, ".md"),
897
- sourcePath: filepath,
898
- packName,
899
- meta: data,
900
- content
901
- };
902
- }
903
- function ruleMatchesTarget(rule, targetId) {
904
- const { targets } = rule.meta;
905
- if (!targets || targets === "*")
906
- return true;
907
- if (Array.isArray(targets) && targets.includes("*"))
908
- return true;
909
- return Array.isArray(targets) && targets.includes(targetId);
910
- }
911
- function getRootRules(rules) {
912
- return rules.filter((r) => r.meta.root === true);
913
- }
914
- function getDetailRules(rules) {
915
- return rules.filter((r) => r.meta.root !== true);
916
- }
917
-
918
- // src/features/skills.ts
919
- import { existsSync as existsSync6, readFileSync as readFileSync9 } from "fs";
920
- import { basename as basename5, join as join7 } from "path";
921
- var SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
922
- var SKILL_NAME_MAX_LENGTH = 64;
923
- function parseSkills(skillsDir, packName) {
924
- const dirs = listDirs(skillsDir);
925
- const skills = [];
926
- for (const dir of dirs) {
927
- const skillMd = join7(dir, "SKILL.md");
928
- if (existsSync6(skillMd)) {
929
- skills.push(parseSkillFile(skillMd, dir, packName));
930
- }
931
- }
932
- return skills;
933
- }
934
- function parseSkillFile(filepath, skillDir, packName) {
935
- const raw = readFileSync9(filepath, "utf-8");
936
- const { data, content } = parseFrontmatter(raw);
937
- return {
938
- name: data.name ?? basename5(skillDir),
939
- sourcePath: filepath,
940
- sourceDir: skillDir,
941
- packName,
942
- meta: data,
943
- content
944
- };
945
- }
946
- function buildSkillFrontmatter(skill) {
947
- return {
948
- ...skill.meta,
949
- name: skill.name
950
- };
951
- }
952
- function serializeSkill(skill) {
953
- return serializeFrontmatter(buildSkillFrontmatter(skill), skill.content);
954
- }
955
- function normalizeImportedSkillMarkdown(source, skillName) {
956
- const { data, content } = parseFrontmatter(source);
957
- const normalized = {
958
- ...data,
959
- name: skillName
960
- };
961
- let addedDescription = false;
962
- const description = normalized.description;
963
- if (typeof description !== "string" || description.trim().length === 0) {
964
- normalized.description = `Imported skill: ${skillName}`;
965
- addedDescription = true;
966
- }
967
- return {
968
- content: serializeFrontmatter(normalized, content),
969
- addedDescription
970
- };
971
- }
972
- function validateAgentSkillsFrontmatter(skill) {
973
- const errors = [];
974
- const dirName = basename5(skill.sourceDir);
975
- const declaredName = skill.meta.name;
976
- if (typeof declaredName !== "string" || declaredName.trim().length === 0) {
977
- errors.push('Missing required frontmatter field "name".');
978
- } else {
979
- if (declaredName.length > SKILL_NAME_MAX_LENGTH) {
980
- errors.push(`Invalid "name": must be at most ${SKILL_NAME_MAX_LENGTH} characters.`);
981
- }
982
- if (!SKILL_NAME_PATTERN.test(declaredName)) {
983
- errors.push('Invalid "name": use lowercase letters, numbers, and single hyphens only.');
984
- }
985
- if (declaredName !== dirName) {
986
- errors.push(`Invalid "name": must match containing directory "${dirName}".`);
987
- }
988
- }
989
- const description = skill.meta.description;
990
- if (typeof description !== "string" || description.trim().length === 0) {
991
- errors.push('Missing required frontmatter field "description".');
992
- }
993
- const allowedTools = skill.meta["allowed-tools"];
994
- if (allowedTools !== undefined && (!Array.isArray(allowedTools) || allowedTools.some((tool) => typeof tool !== "string" || tool.length === 0))) {
995
- errors.push('Invalid "allowed-tools": expected an array of non-empty strings.');
996
- }
997
- return errors;
998
- }
999
- function skillMatchesTarget(skill, targetId) {
1000
- const { targets } = skill.meta;
1001
- if (!targets || targets === "*")
1002
- return true;
1003
- if (Array.isArray(targets) && targets.includes("*"))
1004
- return true;
1005
- return Array.isArray(targets) && targets.includes(targetId);
1006
- }
1007
-
1008
- // src/core/pack-loader.ts
1009
- import { existsSync as existsSync7 } from "fs";
1010
- import { isAbsolute, resolve as resolve3 } from "path";
1011
- class PackLoader {
1012
- projectRoot;
1013
- config;
1014
- constructor(projectRoot, config) {
1015
- this.projectRoot = projectRoot;
1016
- this.config = config;
1017
- }
1018
- loadAll() {
1019
- const warnings = [];
1020
- const packs = [];
1021
- const disabledSet = new Set(this.config.disabled);
1022
- for (const packRef of this.config.packs) {
1023
- const packDir = this.resolvePackPath(packRef);
1024
- if (!packDir) {
1025
- warnings.push(`Pack "${packRef}" could not be resolved. Skipping.`);
1026
- continue;
1027
- }
1028
- if (!existsSync7(packDir)) {
1029
- warnings.push(`Pack directory "${packDir}" does not exist. Skipping.`);
1030
- continue;
1031
- }
1032
- const manifest = loadPackManifest(packDir);
1033
- if (disabledSet.has(manifest.name) || disabledSet.has(packRef)) {
1034
- continue;
1035
- }
1036
- const loaded = this.loadPack(packDir, manifest);
1037
- packs.push(loaded);
1038
- }
1039
- return { packs, warnings };
1040
- }
1041
- loadPack(packDir, manifest) {
1042
- const name = manifest.name;
1043
- const rulesDir = resolve3(packDir, "rules");
1044
- const commandsDir = resolve3(packDir, "commands");
1045
- const agentsDir = resolve3(packDir, "agents");
1046
- const skillsDir = resolve3(packDir, "skills");
1047
- return {
1048
- manifest,
1049
- directory: packDir,
1050
- rules: existsSync7(rulesDir) ? parseRules(rulesDir, name) : [],
1051
- commands: existsSync7(commandsDir) ? parseCommands(commandsDir, name) : [],
1052
- agents: existsSync7(agentsDir) ? parseAgents(agentsDir, name) : [],
1053
- skills: existsSync7(skillsDir) ? parseSkills(skillsDir, name) : [],
1054
- hooks: parseHooks(packDir, name),
1055
- plugins: parsePlugins(packDir, name),
1056
- mcp: parseMcp(packDir, name),
1057
- ignore: parseIgnore(packDir, name),
1058
- models: parseModels(packDir, name)
1059
- };
1060
- }
1061
- loadForBaseDir(baseDir) {
1062
- const baseDirRoot = resolve3(this.projectRoot, baseDir);
1063
- const localConfigPath = resolve3(baseDirRoot, "agentpacks.jsonc");
1064
- if (!existsSync7(localConfigPath)) {
1065
- return { packs: [], warnings: [] };
1066
- }
1067
- const localConfig = loadWorkspaceConfig(baseDirRoot);
1068
- const loader = new PackLoader(baseDirRoot, localConfig);
1069
- return loader.loadAll();
1070
- }
1071
- resolveCuratedPack(packRef) {
1072
- const curatedDir = resolve3(this.projectRoot, ".agentpacks", ".curated");
1073
- let packName = packRef;
1074
- if (packName.startsWith("registry:"))
1075
- packName = packName.slice(9);
1076
- if (packName.startsWith("npm:"))
1077
- packName = packName.slice(4);
1078
- if (packName.startsWith("github:"))
1079
- packName = packName.slice(7);
1080
- if (packName.startsWith("@"))
1081
- packName = packName.slice(1);
1082
- if (packName.includes("/")) {
1083
- const parts = packName.split("/");
1084
- packName = packName.includes("@") ? parts.join("-") : parts[parts.length - 1] ?? packName;
1085
- }
1086
- const withoutVersion = packName.split("@")[0] ?? packName;
1087
- packName = withoutVersion.split(":")[0] ?? withoutVersion;
1088
- const resolved = resolve3(curatedDir, packName);
1089
- return existsSync7(resolved) ? resolved : null;
1090
- }
1091
- resolvePackPath(packRef) {
1092
- if (packRef.startsWith("./") || packRef.startsWith("../")) {
1093
- return resolve3(this.projectRoot, packRef);
1094
- }
1095
- if (isAbsolute(packRef)) {
1096
- return packRef;
1097
- }
1098
- if (packRef.startsWith("registry:")) {
1099
- return this.resolveCuratedPack(packRef);
1100
- }
1101
- if (packRef.startsWith("@") || packRef.startsWith("npm:") || !packRef.includes("/")) {
1102
- return this.resolveCuratedPack(packRef);
1103
- }
1104
- if (packRef.startsWith("github:") || packRef.includes("/")) {
1105
- return this.resolveCuratedPack(packRef);
1106
- }
1107
- return resolve3(this.projectRoot, packRef);
1108
- }
1109
- }
1110
-
1111
- // src/core/profile-resolver.ts
1112
- function resolveModels(merged, modelProfile, targetId) {
1113
- let defaultModel = merged.default;
1114
- let smallModel = merged.small;
1115
- let agents = { ...merged.agents };
1116
- if (modelProfile && merged.profiles?.[modelProfile]) {
1117
- const resolvedProfile = resolveProfileInheritance(modelProfile, merged.profiles);
1118
- if (resolvedProfile.default)
1119
- defaultModel = resolvedProfile.default;
1120
- if (resolvedProfile.small)
1121
- smallModel = resolvedProfile.small;
1122
- if (resolvedProfile.agents) {
1123
- agents = { ...agents, ...resolvedProfile.agents };
1124
- }
1125
- }
1126
- if (targetId) {
1127
- const targetOverride = merged.overrides?.[targetId];
1128
- if (targetOverride) {
1129
- if (targetOverride.default)
1130
- defaultModel = targetOverride.default;
1131
- if (targetOverride.small)
1132
- smallModel = targetOverride.small;
1133
- if (targetOverride.agents) {
1134
- agents = { ...agents, ...targetOverride.agents };
1135
- }
1136
- }
1137
- }
1138
- const providers = {};
1139
- if (merged.providers) {
1140
- for (const [name, config] of Object.entries(merged.providers)) {
1141
- providers[name] = {
1142
- ...config.options ? { options: config.options } : {},
1143
- ...config.models ? { models: config.models } : {}
1144
- };
1145
- }
1146
- }
1147
- const profileNames = Object.keys(merged.profiles ?? {});
1148
- const profiles = {};
1149
- if (merged.profiles) {
1150
- for (const [name, profile] of Object.entries(merged.profiles)) {
1151
- profiles[name] = {
1152
- description: profile.description,
1153
- default: profile.default,
1154
- small: profile.small
1155
- };
1156
- }
1157
- }
1158
- return {
1159
- default: defaultModel,
1160
- small: smallModel,
1161
- agents,
1162
- providers,
1163
- routing: merged.routing ?? [],
1164
- profileNames,
1165
- activeProfile: modelProfile,
1166
- profiles
1167
- };
1168
- }
1169
- function resolveAgentModel(resolved, agentName, frontmatterModel) {
1170
- const fromModels = resolved.agents[agentName];
1171
- if (fromModels) {
1172
- return {
1173
- model: fromModels.model,
1174
- temperature: fromModels.temperature,
1175
- top_p: fromModels.top_p
1176
- };
1177
- }
1178
- if (frontmatterModel) {
1179
- return { model: frontmatterModel };
1180
- }
1181
- return {};
1182
- }
1183
- function resolveProfileInheritance(profileName, profiles) {
1184
- const visited = new Set;
1185
- return resolveProfileChain(profileName, profiles, visited, 0);
1186
- }
1187
- var MAX_INHERITANCE_DEPTH = 10;
1188
- function resolveProfileChain(name, profiles, visited, depth) {
1189
- if (depth > MAX_INHERITANCE_DEPTH) {
1190
- throw new Error(`Profile inheritance too deep (max ${MAX_INHERITANCE_DEPTH}): ${name}`);
1191
- }
1192
- if (visited.has(name)) {
1193
- throw new Error(`Circular profile inheritance detected: ${[...visited, name].join(" \u2192 ")}`);
1194
- }
1195
- const profile = profiles[name];
1196
- if (!profile) {
1197
- throw new Error(`Profile "${name}" not found`);
1198
- }
1199
- visited.add(name);
1200
- if (!profile.extends) {
1201
- return { ...profile };
1202
- }
1203
- const parent = resolveProfileChain(profile.extends, profiles, visited, depth + 1);
1204
- return {
1205
- description: profile.description ?? parent.description,
1206
- default: profile.default ?? parent.default,
1207
- small: profile.small ?? parent.small,
1208
- agents: {
1209
- ...parent.agents,
1210
- ...profile.agents
1211
- }
1212
- };
1213
- }
1214
-
1215
- // src/exporters/cursor-plugin.ts
1216
- import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "fs";
1217
- import { join as join8, resolve as resolve4 } from "path";
1218
- function exportCursorPlugin(pack, outputDir) {
1219
- const filesWritten = [];
1220
- const pluginName = normalizeCursorPluginName(pack.manifest.name);
1221
- const pluginDir = resolve4(outputDir, pluginName);
1222
- mkdirSync2(pluginDir, { recursive: true });
1223
- const manifest = {
1224
- name: pluginName
1225
- };
1226
- if (pack.manifest.version) {
1227
- manifest.version = pack.manifest.version;
1228
- }
1229
- if (pack.manifest.description) {
1230
- manifest.description = pack.manifest.description;
1231
- }
1232
- const author = toCursorPluginAuthor(pack.manifest.author);
1233
- if (author) {
1234
- manifest.author = author;
1235
- }
1236
- if (pack.manifest.homepage) {
1237
- manifest.homepage = pack.manifest.homepage;
1238
- }
1239
- if (pack.manifest.repository) {
1240
- manifest.repository = typeof pack.manifest.repository === "string" ? pack.manifest.repository : pack.manifest.repository.url;
1241
- }
1242
- if (pack.manifest.license) {
1243
- manifest.license = pack.manifest.license;
1244
- }
1245
- if (pack.manifest.logo) {
1246
- manifest.logo = pack.manifest.logo;
1247
- }
1248
- if (pack.manifest.tags.length > 0) {
1249
- manifest.keywords = pack.manifest.tags;
1250
- }
1251
- if (pack.rules.length > 0) {
1252
- const rulesDir = join8(pluginDir, "rules");
1253
- ensureDir(rulesDir);
1254
- manifest.rules = "rules";
1255
- for (const rule of pack.rules) {
1256
- const cursorMeta = rule.meta.cursor ?? {};
1257
- const fm = {
1258
- description: cursorMeta.description ?? rule.meta.description ?? "",
1259
- alwaysApply: cursorMeta.alwaysApply ?? rule.meta.root ?? false
1260
- };
1261
- const globs = cursorMeta.globs ?? rule.meta.globs;
1262
- if (globs)
1263
- fm.globs = globs;
1264
- const filename = `${rule.name}.mdc`;
1265
- const filepath = join8(rulesDir, filename);
1266
- writeFileSync3(filepath, serializeFrontmatter(fm, rule.content));
1267
- filesWritten.push(filepath);
1268
- }
1269
- }
1270
- if (pack.agents.length > 0) {
1271
- const agentsDir = join8(pluginDir, "agents");
1272
- ensureDir(agentsDir);
1273
- manifest.agents = "agents";
1274
- for (const agent of pack.agents) {
1275
- const fm = {
1276
- name: agent.name,
1277
- description: agent.meta.description ?? ""
1278
- };
1279
- const filename = `${agent.name}.md`;
1280
- const filepath = join8(agentsDir, filename);
1281
- writeFileSync3(filepath, serializeFrontmatter(fm, agent.content));
1282
- filesWritten.push(filepath);
1283
- }
1284
- }
1285
- if (pack.skills.length > 0) {
1286
- const skillsDir = join8(pluginDir, "skills");
1287
- ensureDir(skillsDir);
1288
- manifest.skills = "skills";
1289
- for (const skill of pack.skills) {
1290
- const skillSubDir = join8(skillsDir, skill.name);
1291
- ensureDir(skillSubDir);
1292
- const filepath = join8(skillSubDir, "SKILL.md");
1293
- const content = serializeFrontmatter(buildSkillFrontmatter(skill), skill.content);
1294
- writeFileSync3(filepath, content);
1295
- filesWritten.push(filepath);
1296
- }
1297
- }
1298
- if (pack.commands.length > 0) {
1299
- const commandsDir = join8(pluginDir, "commands");
1300
- ensureDir(commandsDir);
1301
- manifest.commands = "commands";
1302
- for (const cmd of pack.commands) {
1303
- const fm = {
1304
- name: cmd.name
1305
- };
1306
- if (cmd.meta.description) {
1307
- fm.description = cmd.meta.description;
1308
- }
1309
- const filename = `${cmd.name}.md`;
1310
- const filepath = join8(commandsDir, filename);
1311
- writeFileSync3(filepath, serializeFrontmatter(fm, cmd.content));
1312
- filesWritten.push(filepath);
1313
- }
1314
- }
1315
- if (pack.hooks) {
1316
- const events = resolveHooksForTarget(pack.hooks, "cursor");
1317
- if (Object.keys(events).length > 0) {
1318
- const hooksDir = join8(pluginDir, "hooks");
1319
- ensureDir(hooksDir);
1320
- const filepath = join8(hooksDir, "hooks.json");
1321
- writeFileSync3(filepath, JSON.stringify({ version: pack.hooks.version ?? 1, hooks: events }, null, 2) + `
1322
- `);
1323
- filesWritten.push(filepath);
1324
- manifest.hooks = "hooks/hooks.json";
1325
- }
1326
- }
1327
- if (pack.mcp && Object.keys(pack.mcp.servers).length > 0) {
1328
- manifest.mcpServers = ".mcp.json";
1329
- const filepath = join8(pluginDir, ".mcp.json");
1330
- writeFileSync3(filepath, JSON.stringify({ mcpServers: pack.mcp.servers }, null, 2) + `
1331
- `);
1332
- filesWritten.push(filepath);
1333
- }
1334
- const manifestDir = join8(pluginDir, ".cursor-plugin");
1335
- ensureDir(manifestDir);
1336
- const manifestPath = join8(manifestDir, "plugin.json");
1337
- writeFileSync3(manifestPath, JSON.stringify(manifest, null, 2) + `
1338
- `);
1339
- filesWritten.push(manifestPath);
1340
- return { outputDir: pluginDir, filesWritten, manifest };
1341
- }
1342
- function normalizeCursorPluginName(name) {
1343
- const normalized = name.toLowerCase().replace(/[^a-z0-9.-]+/g, "-").replace(/-+/g, "-").replace(/^[^a-z0-9]+/, "").replace(/[^a-z0-9]+$/, "");
1344
- return normalized.length > 0 ? normalized : "agentpacks-plugin";
1345
- }
1346
- function toCursorPluginAuthor(author) {
1347
- if (!author) {
1348
- return null;
1349
- }
1350
- if (typeof author === "string") {
1351
- return { name: author };
1352
- }
1353
- return {
1354
- name: author.name,
1355
- ...author.email ? { email: author.email } : {}
1356
- };
1357
- }
1358
-
1359
- // src/importers/claude-code.ts
1360
- import { copyFileSync, existsSync as existsSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync4 } from "fs";
1361
- import { basename as basename6, join as join9, resolve as resolve5 } from "path";
1362
- function importFromClaudeCode(projectRoot, outputPackDir) {
1363
- const warnings = [];
1364
- const filesImported = [];
1365
- const claudeDir = resolve5(projectRoot, ".claude");
1366
- const hasClaudeMd = existsSync8(resolve5(projectRoot, "CLAUDE.md"));
1367
- const hasClaudeDir = existsSync8(claudeDir);
1368
- if (!hasClaudeMd && !hasClaudeDir) {
1369
- return {
1370
- packDir: "",
1371
- filesImported: [],
1372
- warnings: ["No CLAUDE.md or .claude/ directory found."],
1373
- configGenerated: false
1374
- };
1375
- }
1376
- const packDir = outputPackDir ?? resolve5(projectRoot, "packs", "claude-import");
1377
- ensureDir(packDir);
1378
- const rulesDir = resolve5(packDir, "rules");
1379
- ensureDir(rulesDir);
1380
- if (hasClaudeMd) {
1381
- const raw = readFileSync10(resolve5(projectRoot, "CLAUDE.md"), "utf-8");
1382
- const ruleContent = [
1383
- "---",
1384
- "root: true",
1385
- 'description: "Root Claude Code rules"',
1386
- "---",
1387
- "",
1388
- raw
1389
- ].join(`
1390
- `);
1391
- const dest = join9(rulesDir, "claude-root.md");
1392
- writeFileSync4(dest, ruleContent);
1393
- filesImported.push(dest);
1394
- }
1395
- if (hasClaudeDir) {
1396
- const claudeRulesDir = resolve5(claudeDir, "rules");
1397
- if (existsSync8(claudeRulesDir)) {
1398
- const files = listFiles(claudeRulesDir, { extension: ".md" });
1399
- for (const file of files) {
1400
- const dest = join9(rulesDir, basename6(file));
1401
- copyFileSync(file, dest);
1402
- filesImported.push(dest);
1403
- }
1404
- }
1405
- const settingsPath = resolve5(claudeDir, "settings.json");
1406
- if (existsSync8(settingsPath)) {
1407
- try {
1408
- const raw = readFileSync10(settingsPath, "utf-8");
1409
- const settings = JSON.parse(raw);
1410
- const mcpServers = settings.mcpServers ?? settings.mcp_servers;
1411
- if (mcpServers && typeof mcpServers === "object") {
1412
- const mcpConfig = { servers: mcpServers };
1413
- const dest = join9(packDir, "mcp.json");
1414
- writeFileSync4(dest, JSON.stringify(mcpConfig, null, 2) + `
1415
- `);
1416
- filesImported.push(dest);
1417
- }
1418
- } catch {
1419
- warnings.push("Failed to parse .claude/settings.json");
1420
- }
1421
- }
1422
- }
1423
- const packJson = {
1424
- name: "claude-import",
1425
- version: "1.0.0",
1426
- description: "Imported from Claude Code",
1427
- tags: ["imported", "claude-code"],
1428
- dependencies: [],
1429
- conflicts: [],
1430
- targets: "*",
1431
- features: "*"
1432
- };
1433
- const packJsonPath = join9(packDir, "pack.json");
1434
- writeFileSync4(packJsonPath, JSON.stringify(packJson, null, 2) + `
1435
- `);
1436
- filesImported.push(packJsonPath);
1437
- return { packDir, filesImported, warnings, configGenerated: false };
1438
- }
1439
-
1440
- // src/importers/cursor.ts
1441
- import { copyFileSync as copyFileSync2, existsSync as existsSync9, readFileSync as readFileSync11, writeFileSync as writeFileSync5 } from "fs";
1442
- import { basename as basename7, join as join10, resolve as resolve6 } from "path";
1443
- function importFromCursor(projectRoot, outputPackDir) {
1444
- const cursorDir = resolve6(projectRoot, ".cursor");
1445
- const warnings = [];
1446
- const filesImported = [];
1447
- if (!existsSync9(cursorDir)) {
1448
- return {
1449
- packDir: "",
1450
- filesImported: [],
1451
- warnings: ["No .cursor/ directory found."],
1452
- configGenerated: false
1453
- };
1454
- }
1455
- const packDir = outputPackDir ?? resolve6(projectRoot, "packs", "cursor-import");
1456
- ensureDir(packDir);
1457
- const rulesDir = resolve6(cursorDir, "rules");
1458
- if (existsSync9(rulesDir)) {
1459
- const outRulesDir = resolve6(packDir, "rules");
1460
- ensureDir(outRulesDir);
1461
- const files = listFiles(rulesDir, { extension: ".mdc" });
1462
- for (const file of files) {
1463
- const raw = readFileSync11(file, "utf-8");
1464
- const { data, content } = parseFrontmatter(raw);
1465
- const meta = {};
1466
- if (data.description)
1467
- meta.description = data.description;
1468
- if (data.alwaysApply)
1469
- meta.root = true;
1470
- if (data.globs)
1471
- meta.globs = data.globs;
1472
- meta.cursor = { ...data };
1473
- const mdContent = buildAgentpacksRule(meta, content);
1474
- const name = basename7(file, ".mdc");
1475
- const dest = join10(outRulesDir, `${name}.md`);
1476
- writeFileSync5(dest, mdContent);
1477
- filesImported.push(dest);
1478
- }
1479
- const mdFiles = listFiles(rulesDir, { extension: ".md" });
1480
- for (const file of mdFiles) {
1481
- const dest = join10(outRulesDir, basename7(file));
1482
- copyFileSync2(file, dest);
1483
- filesImported.push(dest);
1484
- }
1485
- }
1486
- const agentsDir = resolve6(cursorDir, "agents");
1487
- if (existsSync9(agentsDir)) {
1488
- const outDir = resolve6(packDir, "agents");
1489
- ensureDir(outDir);
1490
- const files = listFiles(agentsDir, { extension: ".md" });
1491
- for (const file of files) {
1492
- const dest = join10(outDir, basename7(file));
1493
- copyFileSync2(file, dest);
1494
- filesImported.push(dest);
1495
- }
1496
- }
1497
- const skillsDir = resolve6(cursorDir, "skills");
1498
- if (existsSync9(skillsDir)) {
1499
- const outDir = resolve6(packDir, "skills");
1500
- ensureDir(outDir);
1501
- const dirs = listDirs(skillsDir);
1502
- for (const dir of dirs) {
1503
- const name = basename7(dir);
1504
- const skillMd = join10(dir, "SKILL.md");
1505
- if (existsSync9(skillMd)) {
1506
- const outSkillDir = join10(outDir, name);
1507
- ensureDir(outSkillDir);
1508
- const rawSkill = readFileSync11(skillMd, "utf-8");
1509
- const normalized = normalizeImportedSkillMarkdown(rawSkill, name);
1510
- const dest = join10(outSkillDir, "SKILL.md");
1511
- writeFileSync5(dest, normalized.content);
1512
- filesImported.push(dest);
1513
- if (normalized.addedDescription) {
1514
- warnings.push(`skills/${name}/SKILL.md missing description; added import placeholder.`);
1515
- }
1516
- }
1517
- }
1518
- }
1519
- const commandsDir = resolve6(cursorDir, "commands");
1520
- if (existsSync9(commandsDir)) {
1521
- const outDir = resolve6(packDir, "commands");
1522
- ensureDir(outDir);
1523
- const files = listFiles(commandsDir, { extension: ".md" });
1524
- for (const file of files) {
1525
- const dest = join10(outDir, basename7(file));
1526
- copyFileSync2(file, dest);
1527
- filesImported.push(dest);
1528
- }
1529
- }
1530
- const mcpJson = resolve6(cursorDir, "mcp.json");
1531
- if (existsSync9(mcpJson)) {
1532
- copyFileSync2(mcpJson, join10(packDir, "mcp.json"));
1533
- filesImported.push(join10(packDir, "mcp.json"));
1534
- }
1535
- const cursorIgnore = resolve6(projectRoot, ".cursorignore");
1536
- if (existsSync9(cursorIgnore)) {
1537
- copyFileSync2(cursorIgnore, join10(packDir, "ignore"));
1538
- filesImported.push(join10(packDir, "ignore"));
1539
- }
1540
- writePackJson(packDir, "cursor-import", filesImported);
1541
- return { packDir, filesImported, warnings, configGenerated: false };
1542
- }
1543
- function buildAgentpacksRule(meta, content) {
1544
- const lines = ["---"];
1545
- for (const [k, v] of Object.entries(meta)) {
1546
- if (typeof v === "object") {
1547
- lines.push(`${k}: ${JSON.stringify(v)}`);
1548
- } else {
1549
- lines.push(`${k}: ${v}`);
1550
- }
1551
- }
1552
- lines.push("---", "", content);
1553
- return lines.join(`
1554
- `);
1555
- }
1556
- function writePackJson(packDir, name, filesImported) {
1557
- const packJson = {
1558
- name,
1559
- version: "1.0.0",
1560
- description: `Imported from Cursor`,
1561
- tags: ["imported", "cursor"],
1562
- dependencies: [],
1563
- conflicts: [],
1564
- targets: "*",
1565
- features: "*"
1566
- };
1567
- const dest = join10(packDir, "pack.json");
1568
- writeFileSync5(dest, JSON.stringify(packJson, null, 2) + `
1569
- `);
1570
- filesImported.push(dest);
1571
- }
1572
-
1573
- // src/importers/opencode.ts
1574
- import { copyFileSync as copyFileSync3, existsSync as existsSync10, readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "fs";
1575
- import { basename as basename8, join as join11, resolve as resolve7 } from "path";
1576
- function importFromOpenCode(projectRoot, outputPackDir) {
1577
- const warnings = [];
1578
- const filesImported = [];
1579
- const ocDir = resolve7(projectRoot, ".opencode");
1580
- if (!existsSync10(ocDir)) {
1581
- return {
1582
- packDir: "",
1583
- filesImported: [],
1584
- warnings: ["No .opencode/ directory found."],
1585
- configGenerated: false
1586
- };
1587
- }
1588
- const packDir = outputPackDir ?? resolve7(projectRoot, "packs", "opencode-import");
1589
- ensureDir(packDir);
1590
- importDirMd(resolve7(ocDir, "rules"), resolve7(packDir, "rules"), filesImported);
1591
- importDirMd(resolve7(ocDir, "commands"), resolve7(packDir, "commands"), filesImported);
1592
- importDirMd(resolve7(ocDir, "agents"), resolve7(packDir, "agents"), filesImported);
1593
- const skillDir = resolve7(ocDir, "skill");
1594
- if (existsSync10(skillDir)) {
1595
- const outSkillDir = resolve7(packDir, "skills");
1596
- ensureDir(outSkillDir);
1597
- const dirs = listDirs(skillDir);
1598
- for (const dir of dirs) {
1599
- const name = basename8(dir);
1600
- if (name.startsWith("."))
1601
- continue;
1602
- const skillMd = join11(dir, "SKILL.md");
1603
- if (existsSync10(skillMd)) {
1604
- const outDir = join11(outSkillDir, name);
1605
- ensureDir(outDir);
1606
- const rawSkill = readFileSync12(skillMd, "utf-8");
1607
- const normalized = normalizeImportedSkillMarkdown(rawSkill, name);
1608
- const dest2 = join11(outDir, "SKILL.md");
1609
- writeFileSync6(dest2, normalized.content);
1610
- filesImported.push(dest2);
1611
- if (normalized.addedDescription) {
1612
- warnings.push(`skills/${name}/SKILL.md missing description; added import placeholder.`);
1613
- }
1614
- }
1615
- }
1616
- }
1617
- const pluginsDir = resolve7(ocDir, "plugins");
1618
- if (existsSync10(pluginsDir)) {
1619
- const outPluginsDir = resolve7(packDir, "plugins");
1620
- ensureDir(outPluginsDir);
1621
- const files = listFiles(pluginsDir);
1622
- for (const file of files) {
1623
- if (file.endsWith(".ts") || file.endsWith(".js")) {
1624
- const dest2 = join11(outPluginsDir, basename8(file));
1625
- copyFileSync3(file, dest2);
1626
- filesImported.push(dest2);
1627
- }
1628
- }
1629
- }
1630
- const agentsMd = resolve7(projectRoot, "AGENTS.md");
1631
- if (existsSync10(agentsMd)) {
1632
- const outRulesDir = resolve7(packDir, "rules");
1633
- ensureDir(outRulesDir);
1634
- const raw = readFileSync12(agentsMd, "utf-8");
1635
- const ruleContent = [
1636
- "---",
1637
- "root: true",
1638
- 'description: "AGENTS.md root rules"',
1639
- "---",
1640
- "",
1641
- raw
1642
- ].join(`
1643
- `);
1644
- const dest2 = join11(outRulesDir, "agents-md-root.md");
1645
- writeFileSync6(dest2, ruleContent);
1646
- filesImported.push(dest2);
1647
- }
1648
- const ocJson = resolve7(projectRoot, "opencode.json");
1649
- if (existsSync10(ocJson)) {
1650
- try {
1651
- const raw = readFileSync12(ocJson, "utf-8");
1652
- const config = JSON.parse(raw);
1653
- const mcpObj = config.mcp;
1654
- if (mcpObj) {
1655
- const dest2 = join11(packDir, "mcp.json");
1656
- writeFileSync6(dest2, JSON.stringify({ servers: mcpObj }, null, 2) + `
1657
- `);
1658
- filesImported.push(dest2);
1659
- }
1660
- } catch {
1661
- warnings.push("Failed to parse opencode.json");
1662
- }
1663
- }
1664
- const ocIgnore = resolve7(projectRoot, ".opencodeignore");
1665
- if (existsSync10(ocIgnore)) {
1666
- copyFileSync3(ocIgnore, join11(packDir, "ignore"));
1667
- filesImported.push(join11(packDir, "ignore"));
1668
- }
1669
- const packJson = {
1670
- name: "opencode-import",
1671
- version: "1.0.0",
1672
- description: "Imported from OpenCode",
1673
- tags: ["imported", "opencode"],
1674
- dependencies: [],
1675
- conflicts: [],
1676
- targets: "*",
1677
- features: "*"
1678
- };
1679
- const dest = join11(packDir, "pack.json");
1680
- writeFileSync6(dest, JSON.stringify(packJson, null, 2) + `
1681
- `);
1682
- filesImported.push(dest);
1683
- return { packDir, filesImported, warnings, configGenerated: false };
1684
- }
1685
- function importDirMd(srcDir, outDir, filesImported) {
1686
- if (!existsSync10(srcDir))
1687
- return;
1688
- ensureDir(outDir);
1689
- const files = listFiles(srcDir, { extension: ".md" });
1690
- for (const file of files) {
1691
- const dest = join11(outDir, basename8(file));
1692
- copyFileSync3(file, dest);
1693
- filesImported.push(dest);
1694
- }
1695
- }
1696
-
1697
- // src/importers/rulesync.ts
1698
- import { copyFileSync as copyFileSync4, existsSync as existsSync11, readFileSync as readFileSync13, writeFileSync as writeFileSync7 } from "fs";
1699
- import { parse as parseJsonc2 } from "jsonc-parser";
1700
- import { basename as basename9, join as join12, resolve as resolve8 } from "path";
1701
- function importFromRulesync(projectRoot, outputPackDir) {
1702
- const rulesyncDir = resolve8(projectRoot, ".rulesync");
1703
- const warnings = [];
1704
- const filesImported = [];
1705
- if (!existsSync11(rulesyncDir)) {
1706
- return {
1707
- packDir: "",
1708
- filesImported: [],
1709
- warnings: ["No .rulesync/ directory found."],
1710
- configGenerated: false
1711
- };
1712
- }
1713
- const packDir = outputPackDir ?? resolve8(projectRoot, "packs", "default");
1714
- ensureDir(packDir);
1715
- const rulesDir = resolve8(rulesyncDir, "rules");
1716
- if (existsSync11(rulesDir)) {
1717
- const outRulesDir = resolve8(packDir, "rules");
1718
- ensureDir(outRulesDir);
1719
- const files = listFiles(rulesDir, { extension: ".md" });
1720
- for (const file of files) {
1721
- const dest = join12(outRulesDir, basename9(file));
1722
- copyFileSync4(file, dest);
1723
- filesImported.push(dest);
1724
- }
1725
- }
1726
- const commandsDir = resolve8(rulesyncDir, "commands");
1727
- if (existsSync11(commandsDir)) {
1728
- const outCommandsDir = resolve8(packDir, "commands");
1729
- ensureDir(outCommandsDir);
1730
- const files = listFiles(commandsDir, { extension: ".md" });
1731
- for (const file of files) {
1732
- const dest = join12(outCommandsDir, basename9(file));
1733
- copyFileSync4(file, dest);
1734
- filesImported.push(dest);
1735
- }
1736
- }
1737
- const subagentsDir = resolve8(rulesyncDir, "subagents");
1738
- if (existsSync11(subagentsDir)) {
1739
- const outAgentsDir = resolve8(packDir, "agents");
1740
- ensureDir(outAgentsDir);
1741
- const files = listFiles(subagentsDir, { extension: ".md" });
1742
- for (const file of files) {
1743
- const dest = join12(outAgentsDir, basename9(file));
1744
- copyFileSync4(file, dest);
1745
- filesImported.push(dest);
1746
- }
1747
- }
1748
- const skillsDir = resolve8(rulesyncDir, "skills");
1749
- if (existsSync11(skillsDir)) {
1750
- const outSkillsDir = resolve8(packDir, "skills");
1751
- ensureDir(outSkillsDir);
1752
- const skillDirs = listDirs(skillsDir);
1753
- for (const skillDir of skillDirs) {
1754
- const skillName = basename9(skillDir);
1755
- if (skillName.startsWith("."))
1756
- continue;
1757
- const skillMd = join12(skillDir, "SKILL.md");
1758
- if (existsSync11(skillMd)) {
1759
- const outSkillDir = join12(outSkillsDir, skillName);
1760
- ensureDir(outSkillDir);
1761
- const rawSkill = readFileSync13(skillMd, "utf-8");
1762
- const normalized = normalizeImportedSkillMarkdown(rawSkill, skillName);
1763
- const dest = join12(outSkillDir, "SKILL.md");
1764
- writeFileSync7(dest, normalized.content);
1765
- filesImported.push(dest);
1766
- if (normalized.addedDescription) {
1767
- warnings.push(`skills/${skillName}/SKILL.md missing description; added import placeholder.`);
1768
- }
1769
- }
1770
- }
1771
- }
1772
- const hooksJson = resolve8(rulesyncDir, "hooks.json");
1773
- if (existsSync11(hooksJson)) {
1774
- const outHooksDir = resolve8(packDir, "hooks");
1775
- ensureDir(outHooksDir);
1776
- copyFileSync4(hooksJson, join12(outHooksDir, "hooks.json"));
1777
- filesImported.push(join12(outHooksDir, "hooks.json"));
1778
- }
1779
- const mcpJson = resolve8(rulesyncDir, "mcp.json");
1780
- if (existsSync11(mcpJson)) {
1781
- copyFileSync4(mcpJson, join12(packDir, "mcp.json"));
1782
- filesImported.push(join12(packDir, "mcp.json"));
1783
- }
1784
- const aiIgnore = resolve8(rulesyncDir, ".aiignore");
1785
- const rulesyncIgnore = resolve8(projectRoot, ".rulesyncignore");
1786
- if (existsSync11(aiIgnore)) {
1787
- copyFileSync4(aiIgnore, join12(packDir, "ignore"));
1788
- filesImported.push(join12(packDir, "ignore"));
1789
- } else if (existsSync11(rulesyncIgnore)) {
1790
- copyFileSync4(rulesyncIgnore, join12(packDir, "ignore"));
1791
- filesImported.push(join12(packDir, "ignore"));
1792
- }
1793
- const packJson = {
1794
- name: "default",
1795
- version: "1.0.0",
1796
- description: "Imported from rulesync",
1797
- tags: ["imported", "rulesync"],
1798
- dependencies: [],
1799
- conflicts: [],
1800
- targets: "*",
1801
- features: "*"
1802
- };
1803
- writeFileSync7(join12(packDir, "pack.json"), JSON.stringify(packJson, null, 2) + `
1804
- `);
1805
- filesImported.push(join12(packDir, "pack.json"));
1806
- let configGenerated = false;
1807
- const rulesyncConfig = resolve8(projectRoot, "rulesync.jsonc");
1808
- if (existsSync11(rulesyncConfig)) {
1809
- const agentpacksConfig = convertRulesyncConfig(rulesyncConfig, packDir);
1810
- const configPath = resolve8(projectRoot, "agentpacks.jsonc");
1811
- writeFileSync7(configPath, agentpacksConfig);
1812
- configGenerated = true;
1813
- }
1814
- return { packDir, filesImported, warnings, configGenerated };
1815
- }
1816
- function convertRulesyncConfig(rulesyncPath, _packDir) {
1817
- const raw = readFileSync13(rulesyncPath, "utf-8");
1818
- const parsed = parseJsonc2(raw);
1819
- const targets = parsed.targets ?? ["opencode", "cursor", "claudecode"];
1820
- const features = parsed.features ?? ["*"];
1821
- const baseDirs = parsed.baseDirs ?? ["."];
1822
- const global = parsed.global ?? false;
1823
- const deleteVal = parsed.delete ?? true;
1824
- const relPackDir = "./" + join12("packs", "default");
1825
- const config = {
1826
- $schema: "https://unpkg.com/agentpacks/schema.json",
1827
- packs: [relPackDir],
1828
- disabled: [],
1829
- targets,
1830
- features,
1831
- mode: baseDirs.length > 1 ? "monorepo" : "repo",
1832
- baseDirs,
1833
- global,
1834
- delete: deleteVal
1835
- };
1836
- return JSON.stringify(config, null, 2) + `
1837
- `;
1838
- }
1839
-
1840
- // src/sources/git-ref.ts
1841
- function parseGitSourceRef(source) {
1842
- let s = source;
1843
- if (s.startsWith("github:")) {
1844
- s = s.slice(7);
1845
- }
1846
- let path = "";
1847
- const atIdx = s.indexOf("@");
1848
- const colonIdx = s.indexOf(":", atIdx > -1 ? atIdx : 0);
1849
- if (colonIdx > -1) {
1850
- path = s.slice(colonIdx + 1);
1851
- s = s.slice(0, colonIdx);
1852
- }
1853
- let ref = "main";
1854
- if (atIdx > -1) {
1855
- ref = s.slice(atIdx + 1);
1856
- s = s.slice(0, atIdx);
1857
- }
1858
- const parts = s.split("/");
1859
- if (parts.length < 2) {
1860
- throw new Error(`Invalid git source reference: "${source}". Expected owner/repo format.`);
1861
- }
1862
- const owner = parts[0];
1863
- const repo = parts[1];
1864
- if (!owner || !repo) {
1865
- throw new Error(`Invalid git source reference: "${source}". Expected owner/repo format.`);
1866
- }
1867
- return {
1868
- owner,
1869
- repo,
1870
- ref,
1871
- path: path || ""
1872
- };
1873
- }
1874
- function isGitPackRef(packRef) {
1875
- if (packRef.startsWith("github:"))
1876
- return true;
1877
- if (packRef.startsWith("./") || packRef.startsWith("../") || packRef.startsWith("/")) {
1878
- return false;
1879
- }
1880
- if (packRef.startsWith("@") || packRef.startsWith("npm:"))
1881
- return false;
1882
- const parts = packRef.split("/");
1883
- return parts.length === 2 && !packRef.includes("node_modules");
1884
- }
1885
- function gitSourceKey(parsed) {
1886
- return `${parsed.owner}/${parsed.repo}`;
1887
- }
1888
-
1889
- // src/sources/git.ts
1890
- import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync8 } from "fs";
1891
- import { join as join13, resolve as resolve9 } from "path";
1892
- var GITHUB_API = "https://api.github.com";
1893
- function githubHeaders(token) {
1894
- const h = {
1895
- Accept: "application/vnd.github.v3+json",
1896
- "User-Agent": "agentpacks"
1897
- };
1898
- if (token)
1899
- h.Authorization = `token ${token}`;
1900
- return h;
1901
- }
1902
- async function resolveGitRef(parsed, token) {
1903
- const base = `${GITHUB_API}/repos/${parsed.owner}/${parsed.repo}/git/ref`;
1904
- const res = await fetch(`${base}/heads/${parsed.ref}`, {
1905
- headers: githubHeaders(token)
1906
- });
1907
- if (!res.ok) {
1908
- const tagRes = await fetch(`${base}/tags/${parsed.ref}`, {
1909
- headers: githubHeaders(token)
1910
- });
1911
- if (!tagRes.ok) {
1912
- throw new Error(`Could not resolve ref "${parsed.ref}" for ${parsed.owner}/${parsed.repo}: ${res.status}`);
1913
- }
1914
- const tagData = await tagRes.json();
1915
- return tagData.object.sha;
1916
- }
1917
- const data = await res.json();
1918
- return data.object.sha;
1919
- }
1920
- async function fetchGitDirectory(parsed, sha, subpath, token) {
1921
- const path = parsed.path ? `${parsed.path}/${subpath}` : subpath;
1922
- const url = `${GITHUB_API}/repos/${parsed.owner}/${parsed.repo}/contents/${path}?ref=${sha}`;
1923
- const res = await fetch(url, { headers: githubHeaders(token) });
1924
- if (!res.ok)
1925
- return [];
1926
- return await res.json();
1927
- }
1928
- async function fetchGitFile(downloadUrl, token) {
1929
- const headers = { "User-Agent": "agentpacks" };
1930
- if (token)
1931
- headers.Authorization = `token ${token}`;
1932
- const res = await fetch(downloadUrl, { headers });
1933
- if (!res.ok) {
1934
- throw new Error(`Failed to fetch ${downloadUrl}: ${res.status}`);
1935
- }
1936
- return res.text();
1937
- }
1938
- async function fetchAndWriteSubdir(parsed, sha, remotePath, localDir, installed, token) {
1939
- mkdirSync3(localDir, { recursive: true });
1940
- const entries = await fetchGitDirectory(parsed, sha, remotePath, token);
1941
- for (const entry of entries) {
1942
- if (entry.type === "file" && entry.download_url) {
1943
- const content = await fetchGitFile(entry.download_url, token);
1944
- const filepath = join13(localDir, entry.name);
1945
- writeFileSync8(filepath, content);
1946
- installed.push(filepath);
1947
- } else if (entry.type === "dir") {
1948
- await fetchAndWriteSubdir(parsed, sha, `${remotePath}/${entry.name}`, join13(localDir, entry.name), installed, token);
1949
- }
1950
- }
1951
- }
1952
- async function installGitSource(projectRoot, source, lockfile, options = {}) {
1953
- const parsed = parseGitSourceRef(source);
1954
- const sourceKey = gitSourceKey(parsed);
1955
- const installed = [];
1956
- const warnings = [];
1957
- let resolvedSha;
1958
- const locked = getLockedSource(lockfile, sourceKey);
1959
- if (options.frozen && !locked) {
1960
- throw new Error(`Frozen mode: no lockfile entry for source "${sourceKey}".`);
1961
- }
1962
- if (locked && !options.update) {
1963
- resolvedSha = locked.resolvedRef;
1964
- } else {
1965
- resolvedSha = await resolveGitRef(parsed, options.token);
1966
- }
1967
- const basePath = parsed.path || "packs";
1968
- const entries = await fetchGitDirectory(parsed, resolvedSha, basePath, options.token);
1969
- const curatedDir = resolve9(projectRoot, ".agentpacks", ".curated");
1970
- mkdirSync3(curatedDir, { recursive: true });
1971
- const newLockEntry = {
1972
- requestedRef: parsed.ref,
1973
- resolvedRef: resolvedSha,
1974
- resolvedAt: new Date().toISOString(),
1975
- skills: {},
1976
- packs: {}
1977
- };
1978
- const packDirs = entries.filter((e) => e.type === "dir");
1979
- for (const packEntry of packDirs) {
1980
- const packName = packEntry.name;
1981
- const packOutDir = resolve9(curatedDir, packName);
1982
- const packFiles = await fetchGitDirectory(parsed, resolvedSha, `${basePath}/${packName}`, options.token);
1983
- mkdirSync3(packOutDir, { recursive: true });
1984
- for (const file of packFiles) {
1985
- if (file.type === "file" && file.download_url) {
1986
- const content = await fetchGitFile(file.download_url, options.token);
1987
- writeFileSync8(join13(packOutDir, file.name), content);
1988
- installed.push(join13(packOutDir, file.name));
1989
- if (newLockEntry.packs) {
1990
- newLockEntry.packs[packName] = {
1991
- integrity: computeIntegrity(content)
1992
- };
1993
- }
1994
- } else if (file.type === "dir") {
1995
- await fetchAndWriteSubdir(parsed, resolvedSha, `${basePath}/${packName}/${file.name}`, join13(packOutDir, file.name), installed, options.token);
1996
- }
1997
- }
1998
- }
1999
- if (packDirs.length === 0) {
2000
- const fileEntries = entries.filter((e) => e.type === "file");
2001
- if (fileEntries.length > 0) {
2002
- const packName = parsed.path.split("/").pop() ?? parsed.repo;
2003
- const packOutDir = resolve9(curatedDir, packName);
2004
- mkdirSync3(packOutDir, { recursive: true });
2005
- for (const file of entries) {
2006
- if (file.type === "file" && file.download_url) {
2007
- const content = await fetchGitFile(file.download_url, options.token);
2008
- writeFileSync8(join13(packOutDir, file.name), content);
2009
- installed.push(join13(packOutDir, file.name));
2010
- } else if (file.type === "dir") {
2011
- await fetchAndWriteSubdir(parsed, resolvedSha, `${basePath}/${file.name}`, join13(packOutDir, file.name), installed, options.token);
2012
- }
2013
- }
2014
- }
2015
- }
2016
- setLockedSource(lockfile, sourceKey, newLockEntry);
2017
- return { installed, warnings };
2018
- }
2019
-
2020
- // src/sources/local.ts
2021
- import { existsSync as existsSync12 } from "fs";
2022
- import { isAbsolute as isAbsolute2, resolve as resolve10 } from "path";
2023
- function resolveLocalPack(packRef, projectRoot) {
2024
- let resolved;
2025
- if (isAbsolute2(packRef)) {
2026
- resolved = packRef;
2027
- } else {
2028
- resolved = resolve10(projectRoot, packRef);
2029
- }
2030
- if (!existsSync12(resolved))
2031
- return null;
2032
- return resolved;
2033
- }
2034
- function isLocalPackRef(packRef) {
2035
- return packRef.startsWith("./") || packRef.startsWith("../") || isAbsolute2(packRef);
2036
- }
2037
-
2038
- // src/sources/npm-ref.ts
2039
- function parseNpmSourceRef(source) {
2040
- let s = source;
2041
- if (s.startsWith("npm:")) {
2042
- s = s.slice(4);
2043
- }
2044
- let path = "";
2045
- const pathColonIdx = findPathColon(s);
2046
- if (pathColonIdx > -1) {
2047
- path = s.slice(pathColonIdx + 1);
2048
- s = s.slice(0, pathColonIdx);
2049
- }
2050
- let version = "latest";
2051
- const versionAtIdx = findVersionAt(s);
2052
- if (versionAtIdx > -1) {
2053
- version = s.slice(versionAtIdx + 1);
2054
- s = s.slice(0, versionAtIdx);
2055
- }
2056
- if (!s) {
2057
- throw new Error(`Invalid npm source reference: "${source}". Expected package name.`);
2058
- }
2059
- return { packageName: s, version, path };
2060
- }
2061
- function findPathColon(s) {
2062
- const startAfter = s.startsWith("@") ? s.indexOf("/") + 1 : 0;
2063
- const vAt = findVersionAt(s);
2064
- const searchFrom = vAt > -1 ? vAt : startAfter;
2065
- return s.indexOf(":", searchFrom);
2066
- }
2067
- function findVersionAt(s) {
2068
- if (s.startsWith("@")) {
2069
- const slashIdx = s.indexOf("/");
2070
- if (slashIdx === -1)
2071
- return -1;
2072
- return s.indexOf("@", slashIdx + 1);
2073
- }
2074
- return s.indexOf("@");
2075
- }
2076
- function isNpmPackRef(packRef) {
2077
- if (packRef.startsWith("npm:"))
2078
- return true;
2079
- if (packRef.startsWith("@") && packRef.includes("/"))
2080
- return true;
2081
- return false;
2082
- }
2083
- function npmSourceKey(parsed) {
2084
- return `npm:${parsed.packageName}`;
2085
- }
2086
-
2087
- // src/sources/npm.ts
2088
- import { execSync } from "child_process";
2089
- import { existsSync as existsSync13, mkdirSync as mkdirSync4, readdirSync as readdirSync2 } from "fs";
2090
- import { join as join14, resolve as resolve11 } from "path";
2091
- var NPM_REGISTRY = "https://registry.npmjs.org";
2092
- async function resolveNpmVersion(parsed) {
2093
- const url = `${NPM_REGISTRY}/${encodeURIComponent(parsed.packageName)}/${parsed.version}`;
2094
- const res = await fetch(url, {
2095
- headers: { Accept: "application/json" }
2096
- });
2097
- if (!res.ok) {
2098
- throw new Error(`Could not resolve npm package "${parsed.packageName}@${parsed.version}": ${res.status}`);
2099
- }
2100
- const data = await res.json();
2101
- return { version: data.version, tarball: data.dist.tarball };
2102
- }
2103
- async function installNpmSource(projectRoot, source, lockfile, options = {}) {
2104
- const parsed = parseNpmSourceRef(source);
2105
- const sourceKey = npmSourceKey(parsed);
2106
- const installed = [];
2107
- const warnings = [];
2108
- const locked = getLockedSource(lockfile, sourceKey);
2109
- if (options.frozen && !locked) {
2110
- throw new Error(`Frozen mode: no lockfile entry for source "${sourceKey}".`);
2111
- }
2112
- let resolvedVersion;
2113
- if (locked && !options.update) {
2114
- resolvedVersion = locked.resolvedRef;
2115
- } else {
2116
- const resolved = await resolveNpmVersion(parsed);
2117
- resolvedVersion = resolved.version;
2118
- }
2119
- const curatedDir = resolve11(projectRoot, ".agentpacks", ".curated");
2120
- mkdirSync4(curatedDir, { recursive: true });
2121
- extractNpmPack(parsed, resolvedVersion, curatedDir, installed, warnings);
2122
- const newEntry = {
2123
- requestedRef: parsed.version,
2124
- resolvedRef: resolvedVersion,
2125
- resolvedAt: new Date().toISOString(),
2126
- skills: {},
2127
- packs: {}
2128
- };
2129
- setLockedSource(lockfile, sourceKey, newEntry);
2130
- return { installed, warnings };
2131
- }
2132
- function extractNpmPack(parsed, version, curatedDir, installed, warnings) {
2133
- const pkgSpec = `${parsed.packageName}@${version}`;
2134
- const packName = parsed.packageName.replace(/^@/, "").replace(/\//g, "-");
2135
- const packOutDir = resolve11(curatedDir, packName);
2136
- try {
2137
- const tmpDir = resolve11(curatedDir, ".tmp-npm");
2138
- mkdirSync4(tmpDir, { recursive: true });
2139
- execSync(`npm pack ${pkgSpec} --pack-destination "${tmpDir}"`, {
2140
- stdio: "pipe",
2141
- timeout: 30000
2142
- });
2143
- const tgzFiles = readdirSync2(tmpDir).filter((f) => f.endsWith(".tgz"));
2144
- if (tgzFiles.length === 0) {
2145
- warnings.push(`No tarball found for ${pkgSpec}`);
2146
- return packOutDir;
2147
- }
2148
- const firstTgz = tgzFiles[0];
2149
- if (!firstTgz) {
2150
- warnings.push(`No tarball found for ${pkgSpec}`);
2151
- return packOutDir;
2152
- }
2153
- const tgzPath = join14(tmpDir, firstTgz);
2154
- mkdirSync4(packOutDir, { recursive: true });
2155
- execSync(`tar xzf "${tgzPath}" -C "${packOutDir}" --strip-components=1`, {
2156
- stdio: "pipe",
2157
- timeout: 15000
2158
- });
2159
- execSync(`rm -rf "${tmpDir}"`, { stdio: "pipe" });
2160
- const subpath = parsed.path || "";
2161
- const targetDir = subpath ? join14(packOutDir, subpath) : packOutDir;
2162
- if (existsSync13(targetDir)) {
2163
- collectFiles(targetDir, installed);
2164
- }
2165
- } catch (err) {
2166
- warnings.push(`Failed to extract npm pack ${pkgSpec}: ${err instanceof Error ? err.message : String(err)}`);
2167
- }
2168
- return packOutDir;
2169
- }
2170
- function collectFiles(dir, out) {
2171
- const entries = readdirSync2(dir, { withFileTypes: true });
2172
- for (const entry of entries) {
2173
- const full = join14(dir, entry.name);
2174
- if (entry.isDirectory()) {
2175
- collectFiles(full, out);
2176
- } else {
2177
- out.push(full);
2178
- }
2179
- }
2180
- }
2181
-
2182
- // src/sources/registry-ref.ts
2183
- function parseRegistrySourceRef(source) {
2184
- let s = source;
2185
- if (s.startsWith("registry:")) {
2186
- s = s.slice(9);
2187
- }
2188
- if (!s) {
2189
- throw new Error(`Invalid registry source reference: "${source}". Expected pack name.`);
2190
- }
2191
- let version = "latest";
2192
- const atIdx = s.indexOf("@");
2193
- if (atIdx > 0) {
2194
- version = s.slice(atIdx + 1);
2195
- s = s.slice(0, atIdx);
2196
- }
2197
- if (!s) {
2198
- throw new Error(`Invalid registry source reference: "${source}". Pack name is empty.`);
2199
- }
2200
- if (!/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(s)) {
2201
- throw new Error(`Invalid registry pack name: "${s}". Must be lowercase alphanumeric with hyphens.`);
2202
- }
2203
- return { packName: s, version };
2204
- }
2205
- function isRegistryPackRef(packRef) {
2206
- return packRef.startsWith("registry:");
2207
- }
2208
- function registrySourceKey(parsed) {
2209
- return `registry:${parsed.packName}`;
2210
- }
2211
-
2212
- // src/utils/model-guidance.ts
2213
- function generateModelGuidanceMarkdown(resolved) {
2214
- if (!resolved.default && !resolved.small && Object.keys(resolved.agents).length === 0 && Object.keys(resolved.profiles).length === 0) {
2215
- return null;
2216
- }
2217
- const lines = [];
2218
- lines.push("# Model Configuration");
2219
- lines.push("");
2220
- lines.push("Use the following model preferences when working in this project.");
2221
- lines.push("");
2222
- if (resolved.default || resolved.small) {
2223
- lines.push("## Default Models");
2224
- lines.push("");
2225
- if (resolved.default) {
2226
- lines.push(`- **Primary model**: ${resolved.default}`);
2227
- }
2228
- if (resolved.small) {
2229
- lines.push(`- **Lightweight tasks** (titles, summaries): ${resolved.small}`);
2230
- }
2231
- lines.push("");
2232
- }
2233
- const agentEntries = Object.entries(resolved.agents);
2234
- if (agentEntries.length > 0) {
2235
- lines.push("## Agent Model Assignments");
2236
- lines.push("");
2237
- lines.push("| Agent | Model | Temperature |");
2238
- lines.push("| --- | --- | --- |");
2239
- for (const [name, assignment] of agentEntries) {
2240
- const temp = assignment.temperature !== undefined ? String(assignment.temperature) : "\u2014";
2241
- lines.push(`| ${name} | ${assignment.model} | ${temp} |`);
2242
- }
2243
- lines.push("");
2244
- }
2245
- if (Object.keys(resolved.profiles).length > 0) {
2246
- lines.push("## Available Profiles");
2247
- lines.push("");
2248
- lines.push("| Profile | Description | Default Model |");
2249
- lines.push("| --- | --- | --- |");
2250
- for (const [name, profile] of Object.entries(resolved.profiles)) {
2251
- lines.push(`| ${name} | ${profile.description ?? "\u2014"} | ${profile.default ?? "\u2014"} |`);
2252
- }
2253
- lines.push("");
2254
- }
2255
- if (resolved.activeProfile) {
2256
- lines.push(`**Active profile**: \`${resolved.activeProfile}\``);
2257
- lines.push("");
2258
- }
2259
- if (resolved.routing.length > 0) {
2260
- lines.push("## Task-Aware Routing");
2261
- lines.push("");
2262
- lines.push("Select the appropriate profile based on the task context:");
2263
- lines.push("");
2264
- lines.push("| Condition | Profile | Description |");
2265
- lines.push("| --- | --- | --- |");
2266
- for (const rule of resolved.routing) {
2267
- const conditions = Object.entries(rule.when).map(([k, v]) => `${k}=${v}`).join(", ");
2268
- const desc = rule.description ?? "\u2014";
2269
- lines.push(`| ${conditions} | ${rule.use} | ${desc} |`);
2270
- }
2271
- lines.push("");
2272
- lines.push("### Condition Reference");
2273
- lines.push("");
2274
- lines.push("- **complexity**: low | medium | high | critical");
2275
- lines.push("- **urgency**: low | normal | high");
2276
- lines.push("- **budget**: minimal | standard | premium");
2277
- lines.push("- **contextWindowNeed**: small | medium | large | max");
2278
- lines.push("- **toolUseIntensity**: none | light | heavy");
2279
- lines.push("");
2280
- }
2281
- return lines.join(`
2282
- `);
2283
- }
2284
-
2285
- // src/targets/base-target.ts
2286
- class BaseTarget {
2287
- supportsFeature(feature) {
2288
- return this.supportedFeatures.includes(feature);
2289
- }
2290
- getEffectiveFeatures(enabledFeatures) {
2291
- return enabledFeatures.filter((f) => this.supportsFeature(f));
2292
- }
2293
- createResult(filesWritten = [], filesDeleted = [], warnings = []) {
2294
- return {
2295
- targetId: this.id,
2296
- filesWritten,
2297
- filesDeleted,
2298
- warnings
2299
- };
2300
- }
2301
- }
2302
-
2303
- // src/targets/generic-md-target.ts
2304
- import { join as join15, resolve as resolve12 } from "path";
2305
- function createGenericMdTarget(config) {
2306
- return new GenericMdTarget(config);
2307
- }
2308
-
2309
- class GenericMdTarget extends BaseTarget {
2310
- id;
2311
- name;
2312
- supportedFeatures;
2313
- config;
2314
- constructor(config) {
2315
- super();
2316
- this.id = config.id;
2317
- this.name = config.name;
2318
- this.supportedFeatures = config.supportedFeatures;
2319
- this.config = config;
2320
- }
2321
- generate(options) {
2322
- const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
2323
- const root = resolve12(projectRoot, baseDir);
2324
- const effective = this.getEffectiveFeatures(enabledFeatures);
2325
- const filesWritten = [];
2326
- const filesDeleted = [];
2327
- const warnings = [];
2328
- const configDir = resolve12(root, this.config.configDir);
2329
- const rulesSubDir = this.config.rulesDir ?? "rules";
2330
- const ext = this.config.ruleExtension ?? ".md";
2331
- if (effective.includes("rules")) {
2332
- const rulesDir = resolve12(configDir, rulesSubDir);
2333
- if (deleteExisting) {
2334
- removeIfExists(rulesDir);
2335
- filesDeleted.push(rulesDir);
2336
- }
2337
- ensureDir(rulesDir);
2338
- const rules = features.rules.filter((r) => ruleMatchesTarget(r, this.id));
2339
- for (const rule of rules) {
2340
- const filepath = join15(rulesDir, `${rule.name}${ext}`);
2341
- writeGeneratedFile(filepath, rule.content);
2342
- filesWritten.push(filepath);
2343
- }
2344
- }
2345
- if (effective.includes("commands")) {
2346
- const commandsDir = resolve12(configDir, "commands");
2347
- if (deleteExisting) {
2348
- removeIfExists(commandsDir);
2349
- filesDeleted.push(commandsDir);
2350
- }
2351
- ensureDir(commandsDir);
2352
- const commands = features.commands.filter((c) => commandMatchesTarget(c, this.id));
2353
- for (const cmd of commands) {
2354
- const filepath = join15(commandsDir, `${cmd.name}.md`);
2355
- writeGeneratedFile(filepath, cmd.content);
2356
- filesWritten.push(filepath);
2357
- }
2358
- }
2359
- if (effective.includes("mcp")) {
2360
- const mcpEntries = Object.entries(features.mcpServers);
2361
- if (mcpEntries.length > 0) {
2362
- const mcpDir = this.config.mcpInConfigDir ? configDir : root;
2363
- const filepath = resolve12(mcpDir, "mcp.json");
2364
- writeGeneratedJson(filepath, { mcpServers: features.mcpServers }, {
2365
- header: false
2366
- });
2367
- filesWritten.push(filepath);
2368
- }
2369
- }
2370
- if (effective.includes("ignore") && this.config.ignoreFile) {
2371
- if (features.ignorePatterns.length > 0) {
2372
- const filepath = resolve12(root, this.config.ignoreFile);
2373
- writeGeneratedFile(filepath, features.ignorePatterns.join(`
2374
- `) + `
2375
- `);
2376
- filesWritten.push(filepath);
2377
- }
2378
- }
2379
- if (effective.includes("models") && features.models) {
2380
- const resolved = resolveModels(features.models, options.modelProfile, this.id);
2381
- const guidance = generateModelGuidanceMarkdown(resolved);
2382
- if (guidance) {
2383
- ensureDir(configDir);
2384
- const filepath = join15(configDir, "model-config.md");
2385
- writeGeneratedFile(filepath, guidance);
2386
- filesWritten.push(filepath);
2387
- }
2388
- }
2389
- return this.createResult(filesWritten, filesDeleted, warnings);
2390
- }
2391
- }
2392
-
2393
- // src/targets/additional-targets.ts
2394
- var ClineTarget = createGenericMdTarget({
2395
- id: "cline",
2396
- name: "Cline",
2397
- configDir: ".cline",
2398
- supportedFeatures: ["rules", "commands", "mcp", "ignore"],
2399
- ignoreFile: ".clineignore",
2400
- mcpInConfigDir: true
2401
- });
2402
- var KiloTarget = createGenericMdTarget({
2403
- id: "kilo",
2404
- name: "Kilo Code",
2405
- configDir: ".kilo",
2406
- supportedFeatures: ["rules", "commands", "mcp", "ignore"],
2407
- ignoreFile: ".kiloignore",
2408
- mcpInConfigDir: true
2409
- });
2410
- var RooTarget = createGenericMdTarget({
2411
- id: "roo",
2412
- name: "Roo Code",
2413
- configDir: ".roo",
2414
- supportedFeatures: ["rules", "commands", "mcp", "ignore"],
2415
- ignoreFile: ".rooignore",
2416
- mcpInConfigDir: true
2417
- });
2418
- var QwenCodeTarget = createGenericMdTarget({
2419
- id: "qwencode",
2420
- name: "Qwen Code",
2421
- configDir: ".qwencode",
2422
- supportedFeatures: ["rules", "mcp", "ignore"],
2423
- ignoreFile: ".qwencodeignore",
2424
- mcpInConfigDir: true
2425
- });
2426
- var KiroTarget = createGenericMdTarget({
2427
- id: "kiro",
2428
- name: "Kiro",
2429
- configDir: ".kiro",
2430
- supportedFeatures: ["rules", "mcp"],
2431
- mcpInConfigDir: true
2432
- });
2433
- var FactoryDroidTarget = createGenericMdTarget({
2434
- id: "factorydroid",
2435
- name: "Factory Droid",
2436
- configDir: ".factorydroid",
2437
- supportedFeatures: ["rules", "mcp"],
2438
- mcpInConfigDir: true
2439
- });
2440
- var AntiGravityTarget = createGenericMdTarget({
2441
- id: "antigravity",
2442
- name: "AntiGravity",
2443
- configDir: ".antigravity",
2444
- supportedFeatures: ["rules", "mcp"],
2445
- mcpInConfigDir: true
2446
- });
2447
- var JunieTarget = createGenericMdTarget({
2448
- id: "junie",
2449
- name: "Junie",
2450
- configDir: ".junie",
2451
- supportedFeatures: ["rules", "mcp"],
2452
- mcpInConfigDir: true
2453
- });
2454
- var AugmentCodeTarget = createGenericMdTarget({
2455
- id: "augmentcode",
2456
- name: "Augment Code",
2457
- configDir: ".augmentcode",
2458
- supportedFeatures: ["rules", "mcp"],
2459
- mcpInConfigDir: true
2460
- });
2461
- var WindsurfTarget = createGenericMdTarget({
2462
- id: "windsurf",
2463
- name: "Windsurf",
2464
- configDir: ".windsurf",
2465
- supportedFeatures: ["rules", "mcp", "ignore"],
2466
- ignoreFile: ".windsurfignore",
2467
- mcpInConfigDir: true
2468
- });
2469
- var WarpTarget = createGenericMdTarget({
2470
- id: "warp",
2471
- name: "Warp",
2472
- configDir: ".warp",
2473
- supportedFeatures: ["rules"]
2474
- });
2475
- var ReplitTarget = createGenericMdTarget({
2476
- id: "replit",
2477
- name: "Replit Agent",
2478
- configDir: ".replit",
2479
- supportedFeatures: ["rules", "mcp"],
2480
- mcpInConfigDir: true
2481
- });
2482
- var ZedTarget = createGenericMdTarget({
2483
- id: "zed",
2484
- name: "Zed",
2485
- configDir: ".zed",
2486
- supportedFeatures: ["rules", "mcp"],
2487
- mcpInConfigDir: true
2488
- });
2489
-
2490
- // src/targets/agents-md.ts
2491
- import { resolve as resolve13 } from "path";
2492
- class AgentsMdTarget extends BaseTarget {
2493
- id = "agentsmd";
2494
- name = "AGENTS.md";
2495
- supportedFeatures = ["rules"];
2496
- generate(options) {
2497
- const { projectRoot, baseDir, features } = options;
2498
- const root = resolve13(projectRoot, baseDir);
2499
- const filesWritten = [];
2500
- const warnings = [];
2501
- const rootRules = getRootRules(features.rules);
2502
- if (rootRules.length === 0) {
2503
- warnings.push("No root rules found. AGENTS.md will not be generated.");
2504
- return this.createResult(filesWritten, [], warnings);
2505
- }
2506
- const sections = rootRules.map((r) => r.content);
2507
- const content = sections.join(`
2508
-
2509
- `);
2510
- const filepath = resolve13(root, "AGENTS.md");
2511
- writeGeneratedFile(filepath, content);
2512
- filesWritten.push(filepath);
2513
- return this.createResult(filesWritten, [], warnings);
2514
- }
2515
- }
2516
-
2517
- // src/targets/claude-code.ts
2518
- import { join as join16, resolve as resolve14 } from "path";
2519
- var TARGET_ID = "claudecode";
2520
-
2521
- class ClaudeCodeTarget extends BaseTarget {
2522
- id = TARGET_ID;
2523
- name = "Claude Code";
2524
- supportedFeatures = [
2525
- "rules",
2526
- "commands",
2527
- "agents",
2528
- "skills",
2529
- "hooks",
2530
- "mcp",
2531
- "ignore",
2532
- "models"
2533
- ];
2534
- generate(options) {
2535
- const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
2536
- const root = resolve14(projectRoot, baseDir);
2537
- const effective = this.getEffectiveFeatures(enabledFeatures);
2538
- const filesWritten = [];
2539
- const filesDeleted = [];
2540
- const warnings = [];
2541
- const claudeDir = resolve14(root, ".claude");
2542
- if (effective.includes("rules")) {
2543
- const rulesDir = resolve14(claudeDir, "rules");
2544
- if (deleteExisting) {
2545
- removeIfExists(rulesDir);
2546
- filesDeleted.push(rulesDir);
2547
- }
2548
- ensureDir(rulesDir);
2549
- const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID));
2550
- const rootRules = getRootRules(rules);
2551
- const detailRules = getDetailRules(rules);
2552
- if (rootRules.length > 0) {
2553
- const claudeMd = rootRules.map((r) => r.content).join(`
2554
-
2555
- `);
2556
- const filepath = resolve14(claudeDir, "CLAUDE.md");
2557
- writeGeneratedFile(filepath, claudeMd);
2558
- filesWritten.push(filepath);
2559
- }
2560
- for (const rule of detailRules) {
2561
- const filepath = join16(rulesDir, `${rule.name}.md`);
2562
- writeGeneratedFile(filepath, rule.content);
2563
- filesWritten.push(filepath);
2564
- }
2565
- }
2566
- if (effective.includes("agents")) {
2567
- const agentsDir = resolve14(claudeDir, "agents");
2568
- if (deleteExisting) {
2569
- removeIfExists(agentsDir);
2570
- filesDeleted.push(agentsDir);
2571
- }
2572
- ensureDir(agentsDir);
2573
- const resolvedModels = features.models ? resolveModels(features.models, options.modelProfile, TARGET_ID) : null;
2574
- const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID));
2575
- for (const agent of agents) {
2576
- const filepath = join16(agentsDir, `${agent.name}.md`);
2577
- const cc = agent.meta.claudecode ?? {};
2578
- const modelsAgent = resolvedModels?.agents[agent.name];
2579
- const agentModel = modelsAgent?.model ?? cc.model;
2580
- let content = agent.content;
2581
- if (agentModel) {
2582
- content = `<!-- model: ${agentModel} -->
2583
- ${content}`;
2584
- }
2585
- writeGeneratedFile(filepath, content);
2586
- filesWritten.push(filepath);
2587
- }
2588
- }
2589
- if (effective.includes("skills")) {
2590
- const skillsDir = resolve14(claudeDir, "skills");
2591
- if (deleteExisting) {
2592
- removeIfExists(skillsDir);
2593
- filesDeleted.push(skillsDir);
2594
- }
2595
- ensureDir(skillsDir);
2596
- const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID));
2597
- for (const skill of skills) {
2598
- const skillSubDir = join16(skillsDir, skill.name);
2599
- ensureDir(skillSubDir);
2600
- const filepath = join16(skillSubDir, "SKILL.md");
2601
- writeGeneratedFile(filepath, serializeSkill(skill));
2602
- filesWritten.push(filepath);
2603
- }
2604
- }
2605
- if (effective.includes("commands")) {
2606
- const commandsDir = resolve14(claudeDir, "commands");
2607
- if (deleteExisting) {
2608
- removeIfExists(commandsDir);
2609
- filesDeleted.push(commandsDir);
2610
- }
2611
- ensureDir(commandsDir);
2612
- const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID));
2613
- for (const cmd of commands) {
2614
- const filepath = join16(commandsDir, `${cmd.name}.md`);
2615
- writeGeneratedFile(filepath, cmd.content);
2616
- filesWritten.push(filepath);
2617
- }
2618
- }
2619
- if (effective.includes("models") && features.models) {
2620
- const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID);
2621
- const guidance = generateModelGuidanceMarkdown(resolved);
2622
- if (guidance) {
2623
- const rulesDir = resolve14(claudeDir, "rules");
2624
- ensureDir(rulesDir);
2625
- const filepath = join16(rulesDir, "model-config.md");
2626
- writeGeneratedFile(filepath, guidance);
2627
- filesWritten.push(filepath);
2628
- }
2629
- }
2630
- if (effective.includes("hooks") || effective.includes("mcp") || effective.includes("ignore")) {
2631
- const settings = buildClaudeSettings(options, effective);
2632
- if (Object.keys(settings).length > 0) {
2633
- const filepath = resolve14(claudeDir, "settings.json");
2634
- const existing = readJsonOrNull(filepath) ?? {};
2635
- const merged = { ...existing, ...settings };
2636
- writeGeneratedJson(filepath, merged, { header: false });
2637
- filesWritten.push(filepath);
2638
- }
2639
- }
2640
- return this.createResult(filesWritten, filesDeleted, warnings);
2641
- }
2642
- }
2643
- function buildClaudeSettings(options, effective) {
2644
- const settings = {};
2645
- if (effective.includes("hooks")) {
2646
- const allHookEntries = {};
2647
- for (const hookSet of options.features.hooks) {
2648
- const events = resolveHooksForTarget(hookSet, TARGET_ID);
2649
- for (const [event, entries] of Object.entries(events)) {
2650
- const pascalEvent = toPascalCase(event);
2651
- if (!allHookEntries[pascalEvent]) {
2652
- allHookEntries[pascalEvent] = [];
2653
- }
2654
- allHookEntries[pascalEvent].push(...entries.map((e) => ({
2655
- type: e.type ?? "command",
2656
- ...e.matcher ? { matcher: e.matcher } : {},
2657
- command: e.command
2658
- })));
2659
- }
2660
- }
2661
- if (Object.keys(allHookEntries).length > 0) {
2662
- settings.hooks = allHookEntries;
2663
- }
2664
- }
2665
- if (effective.includes("mcp")) {
2666
- const mcpEntries = Object.entries(options.features.mcpServers);
2667
- if (mcpEntries.length > 0) {
2668
- const mcpServers = {};
2669
- for (const [name, entry] of mcpEntries) {
2670
- if (entry.url) {
2671
- mcpServers[name] = { url: entry.url };
2672
- } else if (entry.command) {
2673
- mcpServers[name] = {
2674
- command: entry.command,
2675
- ...entry.args ? { args: entry.args } : {},
2676
- ...entry.env ? { env: entry.env } : {}
2677
- };
2678
- }
2679
- }
2680
- settings.mcpServers = mcpServers;
2681
- }
2682
- }
2683
- return settings;
2684
- }
2685
- function toPascalCase(str) {
2686
- return str.charAt(0).toUpperCase() + str.slice(1);
2687
- }
2688
-
2689
- // src/targets/codex-cli.ts
2690
- import { join as join17, resolve as resolve15 } from "path";
2691
- var TARGET_ID2 = "codexcli";
2692
-
2693
- class CodexCliTarget extends BaseTarget {
2694
- id = TARGET_ID2;
2695
- name = "Codex CLI";
2696
- supportedFeatures = ["rules", "skills", "mcp", "hooks"];
2697
- generate(options) {
2698
- const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
2699
- const root = resolve15(projectRoot, baseDir);
2700
- const effective = this.getEffectiveFeatures(enabledFeatures);
2701
- const filesWritten = [];
2702
- const filesDeleted = [];
2703
- const warnings = [];
2704
- const codexDir = resolve15(root, ".codex");
2705
- if (effective.includes("rules")) {
2706
- const memoriesDir = resolve15(codexDir, "memories");
2707
- if (deleteExisting) {
2708
- removeIfExists(memoriesDir);
2709
- filesDeleted.push(memoriesDir);
2710
- }
2711
- ensureDir(memoriesDir);
2712
- const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID2));
2713
- for (const rule of rules) {
2714
- const filepath = join17(memoriesDir, `${rule.name}.md`);
2715
- writeGeneratedFile(filepath, rule.content);
2716
- filesWritten.push(filepath);
2717
- }
2718
- }
2719
- if (effective.includes("skills")) {
2720
- const skillsDir = resolve15(codexDir, "skills");
2721
- if (deleteExisting) {
2722
- removeIfExists(skillsDir);
2723
- filesDeleted.push(skillsDir);
2724
- }
2725
- ensureDir(skillsDir);
2726
- const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID2));
2727
- for (const skill of skills) {
2728
- const skillSubDir = join17(skillsDir, skill.name);
2729
- ensureDir(skillSubDir);
2730
- const filepath = join17(skillSubDir, "SKILL.md");
2731
- writeGeneratedFile(filepath, serializeSkill(skill));
2732
- filesWritten.push(filepath);
2733
- }
2734
- }
2735
- return this.createResult(filesWritten, filesDeleted, warnings);
2736
- }
2737
- }
2738
-
2739
- // src/targets/copilot.ts
2740
- import { join as join18, resolve as resolve16 } from "path";
2741
- var TARGET_ID3 = "copilot";
2742
-
2743
- class CopilotTarget extends BaseTarget {
2744
- id = TARGET_ID3;
2745
- name = "GitHub Copilot";
2746
- supportedFeatures = [
2747
- "rules",
2748
- "commands",
2749
- "agents",
2750
- "skills",
2751
- "mcp",
2752
- "ignore",
2753
- "models"
2754
- ];
2755
- generate(options) {
2756
- const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
2757
- const root = resolve16(projectRoot, baseDir);
2758
- const effective = this.getEffectiveFeatures(enabledFeatures);
2759
- const filesWritten = [];
2760
- const filesDeleted = [];
2761
- const warnings = [];
2762
- const githubDir = resolve16(root, ".github");
2763
- if (effective.includes("rules")) {
2764
- const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID3));
2765
- if (rules.length > 0) {
2766
- const combinedContent = rules.map((r) => r.content).join(`
2
+ var k1=import.meta.require;import{existsSync as I$,readFileSync as E$}from"fs";import{parse as j2}from"jsonc-parser";import{resolve as T$}from"path";import{z as N}from"zod";var R$=["opencode","cursor","claudecode","codexcli","mistralvibe","geminicli","copilot","cline","kilo","roo","qwencode","kiro","factorydroid","antigravity","junie","augmentcode","windsurf","warp","replit","zed"],K0=["rules","commands","agents","skills","hooks","plugins","mcp","ignore","models"],S$=["repo","monorepo","metarepo"],D0=N.object({name:N.string().min(1),version:N.string().default("1.0.0"),description:N.string().default(""),author:N.union([N.string(),N.object({name:N.string(),email:N.string().optional()})]).optional(),homepage:N.string().optional(),repository:N.union([N.string(),N.object({url:N.string(),type:N.string().optional()})]).optional(),license:N.string().optional(),logo:N.string().optional(),tags:N.array(N.string()).default([]),dependencies:N.array(N.string()).default([]),conflicts:N.array(N.string()).default([]),targets:N.union([N.literal("*"),N.array(N.string())]).default("*"),features:N.union([N.literal("*"),N.array(N.string())]).default("*")}),h2=N.union([N.literal("*"),N.array(N.string()),N.record(N.string(),N.union([N.literal("*"),N.array(N.string())]))]),u0=N.object({$schema:N.string().optional(),packs:N.array(N.string()).default(["./packs/default"]),disabled:N.array(N.string()).default([]),targets:N.union([N.literal("*"),N.array(N.string())]).default("*"),features:h2.default("*"),mode:N.enum(S$).default("repo"),baseDirs:N.array(N.string()).default(["."]),global:N.boolean().default(!1),delete:N.boolean().default(!0),verbose:N.boolean().default(!1),silent:N.boolean().default(!1),overrides:N.record(N.string(),N.record(N.string(),N.string())).default({}),sources:N.array(N.object({source:N.string(),packs:N.array(N.string()).optional(),skills:N.array(N.string()).optional()})).default([]),modelProfile:N.string().optional()}),v2=["agentpacks.local.jsonc","agentpacks.jsonc"];function f0($){for(let Q of v2){let Y=T$($,Q);if(I$(Y)){let Z=E$(Y,"utf-8"),q=j2(Z);return u0.parse(q)}}return u0.parse({})}function p0($){let Q=T$($,"pack.json");if(!I$(Q)){let q=$.split("/").pop()??"unknown";return D0.parse({name:q})}let Y=E$(Q,"utf-8"),Z=JSON.parse(Y);return D0.parse(Z)}function k2($,Q){let{features:Y}=$;if(Y==="*")return[...K0];if(Array.isArray(Y)){if(Y.includes("*"))return[...K0];return Y.filter((q)=>K0.includes(q))}let Z=Y[Q];if(!Z)return[];if(Z==="*")return[...K0];if(Array.isArray(Z)&&Z.includes("*"))return[...K0];return Z.filter((q)=>K0.includes(q))}function g2($){if($.targets==="*")return[...R$];return $.targets}function m2($){let Q=new Map;for(let Y of $)Q.set(Y.name,{name:Y.name,manifest:Y,dependencies:Y.dependencies,conflicts:Y.conflicts});return Q}function D2($){let Q=m2($),Y=new Set(Q.keys()),Z=[];for(let[H,W]of Q)for(let _ of W.dependencies)if(!Y.has(_))Z.push([H,_]);let{sorted:q,cycles:X}=u2(Q),J=p2(Q),K=X.length===0&&J.length===0&&Z.length===0;return{sorted:q,cycles:X,conflictPairs:J,missingDeps:Z,ok:K}}function u2($){let Q=new Map;for(let X of $.keys())Q.set(X,0);for(let[,X]of $)for(let J of X.dependencies)if($.has(J))Q.set(J,(Q.get(J)??0)+1);let Y=[];for(let[X,J]of Q)if(J===0)Y.push(X);let Z=[];while(Y.length>0){let X=Y.shift();if(!X)continue;Z.push(X);let J=$.get(X);if(!J)continue;for(let K of J.dependencies){if(!$.has(K))continue;let H=(Q.get(K)??1)-1;if(Q.set(K,H),H===0)Y.push(K)}}let q=[];if(Z.length<$.size){let X=new Set;for(let K of $.keys())if(!Z.includes(K))X.add(K);let J=new Set;for(let K of X){if(J.has(K))continue;let H=f2(K,$,X);if(H.length>0){q.push(H);for(let W of H)J.add(W)}}}return{sorted:Z.reverse(),cycles:q}}function f2($,Q,Y){let Z=[],q=new Set,X=$;while(X&&!q.has(X)){Z.push(X),q.add(X);let J=Q.get(X);if(!J)break;X=J.dependencies.find((K)=>Y.has(K)&&Q.has(K))}if(X&&q.has(X)){let J=Z.indexOf(X);return Z.slice(J)}return Z}function p2($){let Q=[],Y=new Set;for(let[Z,q]of $)for(let X of q.conflicts)if($.has(X)){let J=[Z,X].sort().join(":");if(!Y.has(J))Y.add(J),Q.push([Z,X])}return Q}import{existsSync as F0,mkdirSync as d2,readdirSync as y$,readFileSync as c2,rmSync as n2,statSync as j$,writeFileSync as o2}from"fs";import{dirname as l2,join as h$,relative as a2}from"path";var v$="<!-- Generated by agentpacks. DO NOT EDIT. -->",k$="// Generated by agentpacks. DO NOT EDIT.",g$="// Generated by agentpacks. DO NOT EDIT.";function G($,Q,Y={}){let{header:Z=!0,type:q}=Y,X=q??t2($);A(l2($));let J=Q;if(Z){let K=s2(X);if(K)J=`${K}
3
+ ${Q}`}o2($,J,"utf-8")}function S($,Q,Y={}){let Z=JSON.stringify(Q,null,2);G($,Z+`
4
+ `,{...Y,type:"json"})}function m$($){if(!F0($))return null;return c2($,"utf-8")}function e($){let Q=m$($);if(Q===null)return null;return JSON.parse(Q)}function A($){if(!F0($))d2($,{recursive:!0})}function w($){if(F0($))n2($,{recursive:!0,force:!0})}function F($,Q={}){let{extension:Y,recursive:Z=!1}=Q;if(!F0($))return[];let q=[],X=y$($);for(let J of X){let K=h$($,J),H=j$(K);if(H.isDirectory()&&Z)q.push(...F(K,Q));else if(H.isFile()){if(!Y||J.endsWith(Y))q.push(K)}}return q}function $0($){if(!F0($))return[];return y$($).map((Q)=>h$($,Q)).filter((Q)=>j$(Q).isDirectory())}function o1($,Q){return a2($,Q)}function l1($){let Q=m$($);if(!Q)return!1;return Q.startsWith(v$)||Q.startsWith(k$)||Q.startsWith(g$)}function t2($){if($.endsWith(".json")||$.endsWith(".jsonc"))return"json";if($.endsWith(".ts")||$.endsWith(".mts"))return"ts";if($.endsWith(".js")||$.endsWith(".mjs"))return"js";return"md"}function s2($){switch($){case"md":return v$;case"json":return k$;case"js":case"ts":return g$;default:return null}}import{join as i2}from"path";import{z as M}from"zod";var r2=[/["']api[_-]?key["']\s*:/i,/["']apiKey["']\s*:/i,/["']secret["']\s*:/i,/["']password["']\s*:/i,/["'](?:auth_token|access_token|bearer_token)["']\s*:/i,/["']private[_-]?key["']\s*:/i,/-----BEGIN\s+(RSA|EC|DSA|OPENSSH|PGP)\s+PRIVATE\s+KEY-----/,/sk-[a-zA-Z0-9]{20,}/,/Bearer\s+[a-zA-Z0-9._-]{20,}/],d0=M.object({model:M.string(),temperature:M.number().min(0).max(2).optional(),top_p:M.number().min(0).max(1).optional()}),e2=M.object({extends:M.string().optional(),description:M.string().optional(),default:M.string().optional(),small:M.string().optional(),agents:M.record(M.string(),d0).optional()}),r1=M.object({complexity:M.enum(["low","medium","high","critical"]).optional().describe("Task complexity level"),urgency:M.enum(["low","normal","high"]).optional().describe("Time sensitivity"),budget:M.enum(["minimal","standard","premium"]).optional().describe("Cost/token budget tier"),contextWindowNeed:M.enum(["small","medium","large","max"]).optional().describe("Required context window size"),toolUseIntensity:M.enum(["none","light","heavy"]).optional().describe("Expected tool/function calling intensity")}),$9=M.object({when:M.record(M.string(),M.string()),use:M.string(),description:M.string().optional(),priority:M.number().optional()}),Q9=M.object({options:M.record(M.string(),M.unknown()).optional(),variants:M.record(M.string(),M.record(M.string(),M.unknown())).optional()}),Y9=M.object({options:M.record(M.string(),M.unknown()).optional(),models:M.record(M.string(),Q9).optional()}),Z9=M.object({default:M.string().optional(),small:M.string().optional(),agents:M.record(M.string(),d0).optional(),profiles:M.record(M.string(),e2).optional(),providers:M.record(M.string(),Y9).optional(),routing:M.array($9).optional(),overrides:M.record(M.string(),M.object({default:M.string().optional(),small:M.string().optional(),agents:M.record(M.string(),d0).optional()})).optional()});function D$($,Q){let Y=i2($,"models.json"),Z=e(Y);if(!Z)return null;let q=Z9.parse(Z);return{packName:Q,sourcePath:Y,config:q}}function u$($){let Q=[],Y={};for(let Z of $){let{config:q,packName:X}=Z;if(q.default!==void 0&&Y.default===void 0)Y.default=q.default;else if(q.default!==void 0&&Y.default!==void 0)Q.push(`Models "default" from pack "${X}" skipped (already defined).`);if(q.small!==void 0&&Y.small===void 0)Y.small=q.small;else if(q.small!==void 0&&Y.small!==void 0)Q.push(`Models "small" from pack "${X}" skipped (already defined).`);if(q.agents){if(!Y.agents)Y.agents={};for(let[J,K]of Object.entries(q.agents)){if(J in Y.agents){Q.push(`Models agent "${J}" from pack "${X}" skipped (already defined).`);continue}Y.agents[J]=K}}if(q.profiles){if(!Y.profiles)Y.profiles={};for(let[J,K]of Object.entries(q.profiles)){if(J in Y.profiles){Q.push(`Models profile "${J}" from pack "${X}" skipped (already defined).`);continue}Y.profiles[J]=K}}if(q.providers){if(!Y.providers)Y.providers={};for(let[J,K]of Object.entries(q.providers))if(!(J in Y.providers))Y.providers[J]=K;else{let H=Y.providers[J];if(!H){Y.providers[J]=K;continue}if(K.options)H.options={...K.options,...H.options};if(K.models){if(!H.models)H.models={};for(let[W,_]of Object.entries(K.models))if(!(W in H.models))H.models[W]=_}}}if(q.routing){if(!Y.routing)Y.routing=[];Y.routing.push(...q.routing)}if(q.overrides){if(!Y.overrides)Y.overrides={};for(let[J,K]of Object.entries(q.overrides)){if(J in Y.overrides){Q.push(`Models override for target "${J}" from pack "${X}" skipped (already defined).`);continue}Y.overrides[J]=K}}}return{config:Y,warnings:Q}}function e1($){let Q=[],Y=JSON.stringify($);for(let Z of r2)if(Z.test(Y))Q.push(`Potential secret detected in models.json matching pattern: ${Z.source}`);return Q}class f${packs;warnings=[];constructor($){this.packs=$}merge(){return this.warnings=[],{features:{rules:this.mergeRules(),commands:this.mergeByName("commands"),agents:this.mergeByName("agents"),skills:this.mergeByName("skills"),hooks:this.mergeHooks(),plugins:this.mergePlugins(),mcpServers:this.mergeMcp(),ignorePatterns:this.mergeIgnore(),models:this.mergeModels()},warnings:this.warnings}}mergeRules(){let $=new Map,Q=[];for(let Y of this.packs)for(let Z of Y.rules){let q=$.get(Z.name);if(q){this.warnings.push(`Rule "${Z.name}" from pack "${Z.packName}" skipped (already defined by "${q}").`);continue}$.set(Z.name,Z.packName),Q.push(Z)}return Q}mergeByName($){let Q=new Map,Y=[];for(let Z of this.packs){let q=Z[$];for(let X of q){let J=Q.get(X.name);if(J){this.warnings.push(`${$.slice(0,-1)} "${X.name}" from pack "${X.packName}" skipped (already defined by "${J}").`);continue}Q.set(X.name,X.packName),Y.push(X)}}return Y}mergeHooks(){return this.packs.map(($)=>$.hooks).filter(($)=>$!==null)}mergePlugins(){let $=new Map,Q=[];for(let Y of this.packs)for(let Z of Y.plugins){let q=`${Z.name}.${Z.extension}`,X=$.get(q);if(X){this.warnings.push(`Plugin "${q}" from pack "${Z.packName}" skipped (already defined by "${X}").`);continue}$.set(q,Z.packName),Q.push(Z)}return Q}mergeMcp(){let $={};for(let Q of this.packs){if(!Q.mcp)continue;for(let[Y,Z]of Object.entries(Q.mcp.servers)){if(Y in $){this.warnings.push(`MCP server "${Y}" from pack "${Q.manifest.name}" skipped (already defined).`);continue}$[Y]=Z}}return $}mergeIgnore(){let $=new Set,Q=[];for(let Y of this.packs){if(!Y.ignore)continue;for(let Z of Y.ignore.patterns)if(!$.has(Z))$.add(Z),Q.push(Z)}return Q}mergeModels(){let $=this.packs.map((Z)=>Z.models).filter((Z)=>Z!=null);if($.length===0)return null;let{config:Q,warnings:Y}=u$($);return this.warnings.push(...Y),Q}}import{createHash as q9}from"crypto";import{existsSync as X9,readFileSync as L9,writeFileSync as U9}from"fs";import{resolve as p$}from"path";var B9=1,d$="agentpacks.lock";function V9($){let Q=p$($,d$);if(!X9(Q))return{lockfileVersion:B9,sources:{}};let Y=L9(Q,"utf-8");return JSON.parse(Y)}function K9($,Q){let Y=p$($,d$);U9(Y,JSON.stringify(Q,null,2)+`
5
+ `)}function R0($,Q){return $.sources[Q]}function S0($,Q,Y){$.sources[Q]=Y}function c0($){return`sha256-${q9("sha256").update($).digest("hex")}`}function L3($,Q){let Y=Q.filter((Z)=>!(Z in $.sources));return{valid:Y.length===0,missing:Y}}import c$ from"gray-matter";function d($){let{data:Q,content:Y}=c$($);return{data:Q,content:Y.trim(),raw:$}}function v($,Q){let Y=Object.fromEntries(Object.entries($).filter(([,Z])=>Z!==void 0));if(Object.keys(Y).length===0)return Q;return c$.stringify(Q,Y)}import{readFileSync as J9}from"fs";import{basename as O9}from"path";function n$($,Q){return F($,{extension:".md"}).map((Z)=>H9(Z,Q))}function H9($,Q){let Y=J9($,"utf-8"),{data:Z,content:q}=d(Y);return{name:Z.name??O9($,".md"),sourcePath:$,packName:Q,meta:Z,content:q}}function n($,Q){let{targets:Y}=$.meta;if(!Y||Y==="*")return!0;if(Array.isArray(Y)&&Y.includes("*"))return!0;return Array.isArray(Y)&&Y.includes(Q)}import{readFileSync as W9}from"fs";import{basename as P9}from"path";function o$($,Q){return F($,{extension:".md"}).map((Z)=>C9(Z,Q))}function C9($,Q){let Y=W9($,"utf-8"),{data:Z,content:q}=d(Y);return{name:P9($,".md"),sourcePath:$,packName:Q,meta:Z,content:q}}function k($,Q){let{targets:Y}=$.meta;if(!Y||Y==="*")return!0;if(Array.isArray(Y)&&Y.includes("*"))return!0;return Array.isArray(Y)&&Y.includes(Q)}import{join as _9}from"path";var A9=["cursor","claudecode","codexcli","opencode"];function l$($,Q){let Y=_9($,"hooks","hooks.json"),Z=e(Y);if(!Z)return null;let q=Z.hooks??{},X={};for(let J of A9){let K=Z[J];if(K&&typeof K==="object"&&"hooks"in K&&K.hooks)X[J]=K.hooks}return{packName:Q,sourcePath:Y,version:Z.version,shared:q,targetOverrides:X}}function o($,Q){let Y={};for(let[q,X]of Object.entries($.shared))Y[q]=[...X];let Z=$.targetOverrides[Q];if(Z)for(let[q,X]of Object.entries(Z))Y[q]=[...Y[q]??[],...X];return Y}import{existsSync as N9,readFileSync as x9}from"fs";import{join as b9}from"path";var M9=["ignore",".aiignore"];function a$($,Q){for(let Y of M9){let Z=b9($,Y);if(N9(Z)){let q=x9(Z,"utf-8"),X=G9(q);return{packName:Q,sourcePath:Z,patterns:X}}}return null}function G9($){return $.split(`
6
+ `).map((Q)=>Q.trim()).filter((Q)=>Q.length>0&&!Q.startsWith("#"))}function w3($){let Q=new Set,Y=[];for(let Z of $)for(let q of Z.patterns)if(!Q.has(q))Q.add(q),Y.push(q);return Y}import{join as z9}from"path";function t$($,Q){let Y=z9($,"mcp.json"),Z=e(Y);if(!Z?.mcpServers)return null;return{packName:Q,sourcePath:Y,servers:Z.mcpServers}}function T3($){let Q={},Y=[];for(let Z of $)for(let[q,X]of Object.entries(Z.servers)){if(q in Q){Y.push(`MCP server "${q}" from pack "${Z.packName}" skipped (already defined).`);continue}Q[q]=X}return{servers:Q,warnings:Y}}import{existsSync as w9,readFileSync as F9}from"fs";import{basename as I9,join as E9}from"path";function s$($,Q){let Y=E9($,"plugins");if(!w9(Y))return[];let Z=F(Y,{extension:".ts"}),q=F(Y,{extension:".js"});return[...Z,...q].map((J)=>T9(J,Q))}function T9($,Q){let Y=F9($,"utf-8"),Z=$.endsWith(".ts")?"ts":"js";return{name:I9($,`.${Z}`),sourcePath:$,packName:Q,content:Y,extension:Z}}import{readFileSync as R9}from"fs";import{basename as S9}from"path";function i$($,Q){return F($,{extension:".md"}).map((Z)=>y9(Z,Q))}function y9($,Q){let Y=R9($,"utf-8"),{data:Z,content:q}=d(Y);return{name:S9($,".md"),sourcePath:$,packName:Q,meta:Z,content:q}}function y($,Q){let{targets:Y}=$.meta;if(!Y||Y==="*")return!0;if(Array.isArray(Y)&&Y.includes("*"))return!0;return Array.isArray(Y)&&Y.includes(Q)}function y0($){return $.filter((Q)=>Q.meta.root===!0)}function _0($){return $.filter((Q)=>Q.meta.root!==!0)}import{existsSync as j9,readFileSync as h9}from"fs";import{basename as e$,join as v9}from"path";var k9=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,r$=64;function $2($,Q){let Y=$0($),Z=[];for(let q of Y){let X=v9(q,"SKILL.md");if(j9(X))Z.push(g9(X,q,Q))}return Z}function g9($,Q,Y){let Z=h9($,"utf-8"),{data:q,content:X}=d(Z);return{name:q.name??e$(Q),sourcePath:$,sourceDir:Q,packName:Y,meta:q,content:X}}function n0($){return{...$.meta,name:$.name}}function D($){return v(n0($),$.content)}function A0($,Q){let{data:Y,content:Z}=d($),q={...Y,name:Q},X=!1,J=q.description;if(typeof J!=="string"||J.trim().length===0)q.description=`Imported skill: ${Q}`,X=!0;return{content:v(q,Z),addedDescription:X}}function c3($){let Q=[],Y=e$($.sourceDir),Z=$.meta.name;if(typeof Z!=="string"||Z.trim().length===0)Q.push('Missing required frontmatter field "name".');else{if(Z.length>r$)Q.push(`Invalid "name": must be at most ${r$} characters.`);if(!k9.test(Z))Q.push('Invalid "name": use lowercase letters, numbers, and single hyphens only.');if(Z!==Y)Q.push(`Invalid "name": must match containing directory "${Y}".`)}let q=$.meta.description;if(typeof q!=="string"||q.trim().length===0)Q.push('Missing required frontmatter field "description".');let X=$.meta["allowed-tools"];if(X!==void 0&&(!Array.isArray(X)||X.some((J)=>typeof J!=="string"||J.length===0)))Q.push('Invalid "allowed-tools": expected an array of non-empty strings.');return Q}function u($,Q){let{targets:Y}=$.meta;if(!Y||Y==="*")return!0;if(Array.isArray(Y)&&Y.includes("*"))return!0;return Array.isArray(Y)&&Y.includes(Q)}import{existsSync as J0}from"fs";import{isAbsolute as m9,resolve as l}from"path";class o0{projectRoot;config;constructor($,Q){this.projectRoot=$,this.config=Q}loadAll(){let $=[],Q=[],Y=new Set(this.config.disabled);for(let Z of this.config.packs){let q=this.resolvePackPath(Z);if(!q){$.push(`Pack "${Z}" could not be resolved. Skipping.`);continue}if(!J0(q)){$.push(`Pack directory "${q}" does not exist. Skipping.`);continue}let X=p0(q);if(Y.has(X.name)||Y.has(Z))continue;let J=this.loadPack(q,X);Q.push(J)}return{packs:Q,warnings:$}}loadPack($,Q){let Y=Q.name,Z=l($,"rules"),q=l($,"commands"),X=l($,"agents"),J=l($,"skills");return{manifest:Q,directory:$,rules:J0(Z)?i$(Z,Y):[],commands:J0(q)?o$(q,Y):[],agents:J0(X)?n$(X,Y):[],skills:J0(J)?$2(J,Y):[],hooks:l$($,Y),plugins:s$($,Y),mcp:t$($,Y),ignore:a$($,Y),models:D$($,Y)}}loadForBaseDir($){let Q=l(this.projectRoot,$),Y=l(Q,"agentpacks.jsonc");if(!J0(Y))return{packs:[],warnings:[]};let Z=f0(Q);return new o0(Q,Z).loadAll()}resolveCuratedPack($){let Q=l(this.projectRoot,".agentpacks",".curated"),Y=$;if(Y.startsWith("registry:"))Y=Y.slice(9);if(Y.startsWith("npm:"))Y=Y.slice(4);if(Y.startsWith("github:"))Y=Y.slice(7);if(Y.startsWith("@"))Y=Y.slice(1);if(Y.includes("/")){let X=Y.split("/");Y=Y.includes("@")?X.join("-"):X[X.length-1]??Y}let Z=Y.split("@")[0]??Y;Y=Z.split(":")[0]??Z;let q=l(Q,Y);return J0(q)?q:null}resolvePackPath($){if($.startsWith("./")||$.startsWith("../"))return l(this.projectRoot,$);if(m9($))return $;if($.startsWith("registry:"))return this.resolveCuratedPack($);if($.startsWith("@")||$.startsWith("npm:")||!$.includes("/"))return this.resolveCuratedPack($);if($.startsWith("github:")||$.includes("/"))return this.resolveCuratedPack($);return l(this.projectRoot,$)}}function j($,Q,Y){let{default:Z,small:q}=$,X={...$.agents};if(Q&&$.profiles?.[Q]){let W=u9(Q,$.profiles);if(W.default)Z=W.default;if(W.small)q=W.small;if(W.agents)X={...X,...W.agents}}if(Y){let W=$.overrides?.[Y];if(W){if(W.default)Z=W.default;if(W.small)q=W.small;if(W.agents)X={...X,...W.agents}}}let J={};if($.providers)for(let[W,_]of Object.entries($.providers))J[W]={..._.options?{options:_.options}:{},..._.models?{models:_.models}:{}};let K=Object.keys($.profiles??{}),H={};if($.profiles)for(let[W,_]of Object.entries($.profiles))H[W]={description:_.description,default:_.default,small:_.small};return{default:Z,small:q,agents:X,providers:J,routing:$.routing??[],profileNames:K,activeProfile:Q,profiles:H}}function D9($,Q,Y){let Z=$.agents[Q];if(Z)return{model:Z.model,temperature:Z.temperature,top_p:Z.top_p};if(Y)return{model:Y};return{}}function u9($,Q){return Y2($,Q,new Set,0)}var Q2=10;function Y2($,Q,Y,Z){if(Z>Q2)throw Error(`Profile inheritance too deep (max ${Q2}): ${$}`);if(Y.has($))throw Error(`Circular profile inheritance detected: ${[...Y,$].join(" \u2192 ")}`);let q=Q[$];if(!q)throw Error(`Profile "${$}" not found`);if(Y.add($),!q.extends)return{...q};let X=Y2(q.extends,Q,Y,Z+1);return{description:q.description??X.description,default:q.default??X.default,small:q.small??X.small,agents:{...X.agents,...q.agents}}}import{copyFileSync as Z2,existsSync as q2,mkdirSync as f9,writeFileSync as O0}from"fs";import{dirname as p9,join as I,resolve as d9}from"path";function c9($,Q){let Y=[],Z=n9($.manifest.name),q=d9(Q,Z);f9(q,{recursive:!0});let X={name:Z};if($.manifest.version)X.version=$.manifest.version;if($.manifest.description)X.description=$.manifest.description;let J=o9($.manifest.author);if(J)X.author=J;if($.manifest.homepage)X.homepage=$.manifest.homepage;if($.manifest.repository)X.repository=typeof $.manifest.repository==="string"?$.manifest.repository:$.manifest.repository.url;if($.manifest.license)X.license=$.manifest.license;if($.manifest.logo)X.logo=$.manifest.logo;if($.manifest.tags.length>0)X.keywords=$.manifest.tags;if($.rules.length>0){let W=I(q,"rules");A(W),X.rules="rules";for(let _ of $.rules){let C=_.meta.cursor??{},B={description:C.description??_.meta.description??"",alwaysApply:C.alwaysApply??_.meta.root??!1},V=C.globs??_.meta.globs;if(V)B.globs=V;let L=`${_.name}.mdc`,U=I(W,L);O0(U,v(B,_.content)),Y.push(U)}}if($.agents.length>0){let W=I(q,"agents");A(W),X.agents="agents";for(let _ of $.agents){let C={name:_.name,description:_.meta.description??""},B=`${_.name}.md`,V=I(W,B);O0(V,v(C,_.content)),Y.push(V)}}if($.skills.length>0){let W=I(q,"skills");A(W),X.skills="skills";for(let _ of $.skills){let C=I(W,_.name);A(C);let B=I(C,"SKILL.md"),V=v(n0(_),_.content);O0(B,V),Y.push(B)}}if($.commands.length>0){let W=I(q,"commands");A(W),X.commands="commands";for(let _ of $.commands){let C={name:_.name};if(_.meta.description)C.description=_.meta.description;let B=`${_.name}.md`,V=I(W,B);O0(V,v(C,_.content)),Y.push(V)}}if($.hooks){let W=o($.hooks,"cursor");if(Object.keys(W).length>0){let _=I(q,"hooks");A(_);let C=I(_,"hooks.json");O0(C,JSON.stringify({version:$.hooks.version??1,hooks:W},null,2)+`
7
+ `),Y.push(C),X.hooks="hooks/hooks.json"}}if($.mcp&&Object.keys($.mcp.servers).length>0){X.mcpServers=".mcp.json";let W=I(q,".mcp.json");O0(W,JSON.stringify({mcpServers:$.mcp.servers},null,2)+`
8
+ `),Y.push(W)}l9($,q,Y),a9($,q,Y);let K=I(q,".cursor-plugin");A(K);let H=I(K,"plugin.json");return O0(H,JSON.stringify(X,null,2)+`
9
+ `),Y.push(H),{outputDir:q,filesWritten:Y,manifest:X}}function n9($){let Q=$.toLowerCase().replace(/[^a-z0-9.-]+/g,"-").replace(/-+/g,"-").replace(/^[^a-z0-9]+/,"").replace(/[^a-z0-9]+$/,"");return Q.length>0?Q:"agentpacks-plugin"}function o9($){if(!$)return null;if(typeof $==="string")return{name:$};return{name:$.name,...$.email?{email:$.email}:{}}}function l9($,Q,Y){let Z=I($.directory,"README.md");if(!q2(Z))return;let q=I(Q,"README.md");Z2(Z,q),Y.push(q)}function a9($,Q,Y){if(!$.manifest.logo)return;let Z=I($.directory,$.manifest.logo);if(!q2(Z))return;let q=I(Q,$.manifest.logo);A(p9(q)),Z2(Z,q),Y.push(q)}import{copyFileSync as t9,existsSync as j0,readFileSync as X2,writeFileSync as l0}from"fs";import{basename as s9,join as h0,resolve as H0}from"path";function i9($,Q){let Y=[],Z=[],q=H0($,".claude"),X=j0(H0($,"CLAUDE.md")),J=j0(q);if(!X&&!J)return{packDir:"",filesImported:[],warnings:["No CLAUDE.md or .claude/ directory found."],configGenerated:!1};let K=Q??H0($,"packs","claude-import");A(K);let H=H0(K,"rules");if(A(H),X){let B=["---","root: true",'description: "Root Claude Code rules"',"---","",X2(H0($,"CLAUDE.md"),"utf-8")].join(`
10
+ `),V=h0(H,"claude-root.md");l0(V,B),Z.push(V)}if(J){let C=H0(q,"rules");if(j0(C)){let V=F(C,{extension:".md"});for(let L of V){let U=h0(H,s9(L));t9(L,U),Z.push(U)}}let B=H0(q,"settings.json");if(j0(B))try{let V=X2(B,"utf-8"),L=JSON.parse(V),U=L.mcpServers??L.mcp_servers;if(U&&typeof U==="object"){let O={servers:U},P=h0(K,"mcp.json");l0(P,JSON.stringify(O,null,2)+`
11
+ `),Z.push(P)}}catch{Y.push("Failed to parse .claude/settings.json")}}let W={name:"claude-import",version:"1.0.0",description:"Imported from Claude Code",tags:["imported","claude-code"],dependencies:[],conflicts:[],targets:"*",features:"*"},_=h0(K,"pack.json");return l0(_,JSON.stringify(W,null,2)+`
12
+ `),Z.push(_),{packDir:K,filesImported:Z,warnings:Y,configGenerated:!1}}import{copyFileSync as I0,existsSync as Q0,readFileSync as L2,writeFileSync as a0}from"fs";import{basename as E0,join as p,resolve as f}from"path";function r9($,Q){let Y=f($,".cursor"),Z=[],q=[];if(!Q0(Y))return{packDir:"",filesImported:[],warnings:["No .cursor/ directory found."],configGenerated:!1};let X=Q??f($,"packs","cursor-import");A(X);let J=f(Y,"rules");if(Q0(J)){let B=f(X,"rules");A(B);let V=F(J,{extension:".mdc"});for(let U of V){let O=L2(U,"utf-8"),{data:P,content:x}=d(O),b={};if(P.description)b.description=P.description;if(P.alwaysApply)b.root=!0;if(P.globs)b.globs=P.globs;b.cursor={...P};let z=e9(b,x),m=E0(U,".mdc"),V0=p(B,`${m}.md`);a0(V0,z),q.push(V0)}let L=F(J,{extension:".md"});for(let U of L){let O=p(B,E0(U));I0(U,O),q.push(O)}}let K=f(Y,"agents");if(Q0(K)){let B=f(X,"agents");A(B);let V=F(K,{extension:".md"});for(let L of V){let U=p(B,E0(L));I0(L,U),q.push(U)}}let H=f(Y,"skills");if(Q0(H)){let B=f(X,"skills");A(B);let V=$0(H);for(let L of V){let U=E0(L),O=p(L,"SKILL.md");if(Q0(O)){let P=p(B,U);A(P);let x=L2(O,"utf-8"),b=A0(x,U),z=p(P,"SKILL.md");if(a0(z,b.content),q.push(z),b.addedDescription)Z.push(`skills/${U}/SKILL.md missing description; added import placeholder.`)}}}let W=f(Y,"commands");if(Q0(W)){let B=f(X,"commands");A(B);let V=F(W,{extension:".md"});for(let L of V){let U=p(B,E0(L));I0(L,U),q.push(U)}}let _=f(Y,"mcp.json");if(Q0(_))I0(_,p(X,"mcp.json")),q.push(p(X,"mcp.json"));let C=f($,".cursorignore");if(Q0(C))I0(C,p(X,"ignore")),q.push(p(X,"ignore"));return $1(X,"cursor-import",q),{packDir:X,filesImported:q,warnings:Z,configGenerated:!1}}function e9($,Q){let Y=["---"];for(let[Z,q]of Object.entries($))if(typeof q==="object")Y.push(`${Z}: ${JSON.stringify(q)}`);else Y.push(`${Z}: ${q}`);return Y.push("---","",Q),Y.join(`
13
+ `)}function $1($,Q,Y){let Z={name:Q,version:"1.0.0",description:"Imported from Cursor",tags:["imported","cursor"],dependencies:[],conflicts:[],targets:"*",features:"*"},q=p($,"pack.json");a0(q,JSON.stringify(Z,null,2)+`
14
+ `),Y.push(q)}import{copyFileSync as i0,existsSync as Y0,readFileSync as t0,writeFileSync as v0}from"fs";import{basename as r0,join as a,resolve as h}from"path";function Q1($,Q){let Y=[],Z=[],q=h($,".opencode");if(!Y0(q))return{packDir:"",filesImported:[],warnings:["No .opencode/ directory found."],configGenerated:!1};let X=Q??h($,"packs","opencode-import");A(X),s0(h(q,"rules"),h(X,"rules"),Z),s0(h(q,"commands"),h(X,"commands"),Z),s0(h(q,"agents"),h(X,"agents"),Z);let J=h(q,"skill");if(Y0(J)){let V=h(X,"skills");A(V);let L=$0(J);for(let U of L){let O=r0(U);if(O.startsWith("."))continue;let P=a(U,"SKILL.md");if(Y0(P)){let x=a(V,O);A(x);let b=t0(P,"utf-8"),z=A0(b,O),m=a(x,"SKILL.md");if(v0(m,z.content),Z.push(m),z.addedDescription)Y.push(`skills/${O}/SKILL.md missing description; added import placeholder.`)}}}let K=h(q,"plugins");if(Y0(K)){let V=h(X,"plugins");A(V);let L=F(K);for(let U of L)if(U.endsWith(".ts")||U.endsWith(".js")){let O=a(V,r0(U));i0(U,O),Z.push(O)}}let H=h($,"AGENTS.md");if(Y0(H)){let V=h(X,"rules");A(V);let U=["---","root: true",'description: "AGENTS.md root rules"',"---","",t0(H,"utf-8")].join(`
15
+ `),O=a(V,"agents-md-root.md");v0(O,U),Z.push(O)}let W=h($,"opencode.json");if(Y0(W))try{let V=t0(W,"utf-8"),U=JSON.parse(V).mcp;if(U){let O=a(X,"mcp.json");v0(O,JSON.stringify({servers:U},null,2)+`
16
+ `),Z.push(O)}}catch{Y.push("Failed to parse opencode.json")}let _=h($,".opencodeignore");if(Y0(_))i0(_,a(X,"ignore")),Z.push(a(X,"ignore"));let C={name:"opencode-import",version:"1.0.0",description:"Imported from OpenCode",tags:["imported","opencode"],dependencies:[],conflicts:[],targets:"*",features:"*"},B=a(X,"pack.json");return v0(B,JSON.stringify(C,null,2)+`
17
+ `),Z.push(B),{packDir:X,filesImported:Z,warnings:Y,configGenerated:!1}}function s0($,Q,Y){if(!Y0($))return;A(Q);let Z=F($,{extension:".md"});for(let q of Z){let X=a(Q,r0(q));i0(q,X),Y.push(X)}}import{copyFileSync as W0,existsSync as c,readFileSync as U2,writeFileSync as e0}from"fs";import{parse as Y1}from"jsonc-parser";import{basename as k0,join as T,resolve as E}from"path";function Z1($,Q){let Y=E($,".rulesync"),Z=[],q=[];if(!c(Y))return{packDir:"",filesImported:[],warnings:["No .rulesync/ directory found."],configGenerated:!1};let X=Q??E($,"packs","default");A(X);let J=E(Y,"rules");if(c(J)){let P=E(X,"rules");A(P);let x=F(J,{extension:".md"});for(let b of x){let z=T(P,k0(b));W0(b,z),q.push(z)}}let K=E(Y,"commands");if(c(K)){let P=E(X,"commands");A(P);let x=F(K,{extension:".md"});for(let b of x){let z=T(P,k0(b));W0(b,z),q.push(z)}}let H=E(Y,"subagents");if(c(H)){let P=E(X,"agents");A(P);let x=F(H,{extension:".md"});for(let b of x){let z=T(P,k0(b));W0(b,z),q.push(z)}}let W=E(Y,"skills");if(c(W)){let P=E(X,"skills");A(P);let x=$0(W);for(let b of x){let z=k0(b);if(z.startsWith("."))continue;let m=T(b,"SKILL.md");if(c(m)){let V0=T(P,z);A(V0);let y2=U2(m,"utf-8"),w$=A0(y2,z),F$=T(V0,"SKILL.md");if(e0(F$,w$.content),q.push(F$),w$.addedDescription)Z.push(`skills/${z}/SKILL.md missing description; added import placeholder.`)}}}let _=E(Y,"hooks.json");if(c(_)){let P=E(X,"hooks");A(P),W0(_,T(P,"hooks.json")),q.push(T(P,"hooks.json"))}let C=E(Y,"mcp.json");if(c(C))W0(C,T(X,"mcp.json")),q.push(T(X,"mcp.json"));let B=E(Y,".aiignore"),V=E($,".rulesyncignore");if(c(B))W0(B,T(X,"ignore")),q.push(T(X,"ignore"));else if(c(V))W0(V,T(X,"ignore")),q.push(T(X,"ignore"));let L={name:"default",version:"1.0.0",description:"Imported from rulesync",tags:["imported","rulesync"],dependencies:[],conflicts:[],targets:"*",features:"*"};e0(T(X,"pack.json"),JSON.stringify(L,null,2)+`
18
+ `),q.push(T(X,"pack.json"));let U=!1,O=E($,"rulesync.jsonc");if(c(O)){let P=q1(O,X),x=E($,"agentpacks.jsonc");e0(x,P),U=!0}return{packDir:X,filesImported:q,warnings:Z,configGenerated:U}}function q1($,Q){let Y=U2($,"utf-8"),Z=Y1(Y),q=Z.targets??["opencode","cursor","claudecode"],X=Z.features??["*"],J=Z.baseDirs??["."],K=Z.global??!1,H=Z.delete??!0,_={$schema:"https://unpkg.com/agentpacks/schema.json",packs:["./"+T("packs","default")],disabled:[],targets:q,features:X,mode:J.length>1?"monorepo":"repo",baseDirs:J,global:K,delete:H};return JSON.stringify(_,null,2)+`
19
+ `}function $$($){let Q=$;if(Q.startsWith("github:"))Q=Q.slice(7);let Y="",Z=Q.indexOf("@"),q=Q.indexOf(":",Z>-1?Z:0);if(q>-1)Y=Q.slice(q+1),Q=Q.slice(0,q);let X="main";if(Z>-1)X=Q.slice(Z+1),Q=Q.slice(0,Z);let J=Q.split("/");if(J.length<2)throw Error(`Invalid git source reference: "${$}". Expected owner/repo format.`);let K=J[0],H=J[1];if(!K||!H)throw Error(`Invalid git source reference: "${$}". Expected owner/repo format.`);return{owner:K,repo:H,ref:X,path:Y||""}}function X1($){if($.startsWith("github:"))return!0;if($.startsWith("./")||$.startsWith("../")||$.startsWith("/"))return!1;if($.startsWith("@")||$.startsWith("npm:"))return!1;return $.split("/").length===2&&!$.includes("node_modules")}function B2($){return`${$.owner}/${$.repo}`}import{mkdirSync as g0,writeFileSync as Y$}from"fs";import{join as Z0,resolve as Q$}from"path";var V2="https://api.github.com";function Z$($){let Q={Accept:"application/vnd.github.v3+json","User-Agent":"agentpacks"};if($)Q.Authorization=`token ${$}`;return Q}async function L1($,Q){let Y=`${V2}/repos/${$.owner}/${$.repo}/git/ref`,Z=await fetch(`${Y}/heads/${$.ref}`,{headers:Z$(Q)});if(!Z.ok){let X=await fetch(`${Y}/tags/${$.ref}`,{headers:Z$(Q)});if(!X.ok)throw Error(`Could not resolve ref "${$.ref}" for ${$.owner}/${$.repo}: ${Z.status}`);return(await X.json()).object.sha}return(await Z.json()).object.sha}async function q$($,Q,Y,Z){let q=$.path?`${$.path}/${Y}`:Y,X=`${V2}/repos/${$.owner}/${$.repo}/contents/${q}?ref=${Q}`,J=await fetch(X,{headers:Z$(Z)});if(!J.ok)return[];return await J.json()}async function X$($,Q){let Y={"User-Agent":"agentpacks"};if(Q)Y.Authorization=`token ${Q}`;let Z=await fetch($,{headers:Y});if(!Z.ok)throw Error(`Failed to fetch ${$}: ${Z.status}`);return Z.text()}async function L$($,Q,Y,Z,q,X){g0(Z,{recursive:!0});let J=await q$($,Q,Y,X);for(let K of J)if(K.type==="file"&&K.download_url){let H=await X$(K.download_url,X),W=Z0(Z,K.name);Y$(W,H),q.push(W)}else if(K.type==="dir")await L$($,Q,`${Y}/${K.name}`,Z0(Z,K.name),q,X)}async function U1($,Q,Y,Z={}){let q=$$(Q),X=B2(q),J=[],K=[],H,W=R0(Y,X);if(Z.frozen&&!W)throw Error(`Frozen mode: no lockfile entry for source "${X}".`);if(W&&!Z.update)H=W.resolvedRef;else H=await L1(q,Z.token);let _=q.path||"packs",C=await q$(q,H,_,Z.token),B=Q$($,".agentpacks",".curated");g0(B,{recursive:!0});let V={requestedRef:q.ref,resolvedRef:H,resolvedAt:new Date().toISOString(),skills:{},packs:{}},L=C.filter((U)=>U.type==="dir");for(let U of L){let O=U.name,P=Q$(B,O),x=await q$(q,H,`${_}/${O}`,Z.token);g0(P,{recursive:!0});for(let b of x)if(b.type==="file"&&b.download_url){let z=await X$(b.download_url,Z.token);if(Y$(Z0(P,b.name),z),J.push(Z0(P,b.name)),V.packs)V.packs[O]={integrity:c0(z)}}else if(b.type==="dir")await L$(q,H,`${_}/${O}/${b.name}`,Z0(P,b.name),J,Z.token)}if(L.length===0){if(C.filter((O)=>O.type==="file").length>0){let O=q.path.split("/").pop()??q.repo,P=Q$(B,O);g0(P,{recursive:!0});for(let x of C)if(x.type==="file"&&x.download_url){let b=await X$(x.download_url,Z.token);Y$(Z0(P,x.name),b),J.push(Z0(P,x.name))}else if(x.type==="dir")await L$(q,H,`${_}/${x.name}`,Z0(P,x.name),J,Z.token)}}return S0(Y,X,V),{installed:J,warnings:K}}import{existsSync as B1}from"fs";import{isAbsolute as K2,resolve as V1}from"path";function K1($,Q){let Y;if(K2($))Y=$;else Y=V1(Q,$);if(!B1(Y))return null;return Y}function J1($){return $.startsWith("./")||$.startsWith("../")||K2($)}function U$($){let Q=$;if(Q.startsWith("npm:"))Q=Q.slice(4);let Y="",Z=O1(Q);if(Z>-1)Y=Q.slice(Z+1),Q=Q.slice(0,Z);let q="latest",X=J2(Q);if(X>-1)q=Q.slice(X+1),Q=Q.slice(0,X);if(!Q)throw Error(`Invalid npm source reference: "${$}". Expected package name.`);return{packageName:Q,version:q,path:Y}}function O1($){let Q=$.startsWith("@")?$.indexOf("/")+1:0,Y=J2($),Z=Y>-1?Y:Q;return $.indexOf(":",Z)}function J2($){if($.startsWith("@")){let Q=$.indexOf("/");if(Q===-1)return-1;return $.indexOf("@",Q+1)}return $.indexOf("@")}function H1($){if($.startsWith("npm:"))return!0;if($.startsWith("@")&&$.includes("/"))return!0;return!1}function O2($){return`npm:${$.packageName}`}import{execSync as B$}from"child_process";import{existsSync as W1,mkdirSync as V$,readdirSync as H2}from"fs";import{join as K$,resolve as J$}from"path";var P1="https://registry.npmjs.org";async function C1($){let Q=`${P1}/${encodeURIComponent($.packageName)}/${$.version}`,Y=await fetch(Q,{headers:{Accept:"application/json"}});if(!Y.ok)throw Error(`Could not resolve npm package "${$.packageName}@${$.version}": ${Y.status}`);let Z=await Y.json();return{version:Z.version,tarball:Z.dist.tarball}}async function _1($,Q,Y,Z={}){let q=U$(Q),X=O2(q),J=[],K=[],H=R0(Y,X);if(Z.frozen&&!H)throw Error(`Frozen mode: no lockfile entry for source "${X}".`);let W;if(H&&!Z.update)W=H.resolvedRef;else W=(await C1(q)).version;let _=J$($,".agentpacks",".curated");V$(_,{recursive:!0}),A1(q,W,_,J,K);let C={requestedRef:q.version,resolvedRef:W,resolvedAt:new Date().toISOString(),skills:{},packs:{}};return S0(Y,X,C),{installed:J,warnings:K}}function A1($,Q,Y,Z,q){let X=`${$.packageName}@${Q}`,J=$.packageName.replace(/^@/,"").replace(/\//g,"-"),K=J$(Y,J);try{let H=J$(Y,".tmp-npm");V$(H,{recursive:!0}),B$(`npm pack ${X} --pack-destination "${H}"`,{stdio:"pipe",timeout:30000});let W=H2(H).filter((L)=>L.endsWith(".tgz"));if(W.length===0)return q.push(`No tarball found for ${X}`),K;let _=W[0];if(!_)return q.push(`No tarball found for ${X}`),K;let C=K$(H,_);V$(K,{recursive:!0}),B$(`tar xzf "${C}" -C "${K}" --strip-components=1`,{stdio:"pipe",timeout:15000}),B$(`rm -rf "${H}"`,{stdio:"pipe"});let B=$.path||"",V=B?K$(K,B):K;if(W1(V))W2(V,Z)}catch(H){q.push(`Failed to extract npm pack ${X}: ${H instanceof Error?H.message:String(H)}`)}return K}function W2($,Q){let Y=H2($,{withFileTypes:!0});for(let Z of Y){let q=K$($,Z.name);if(Z.isDirectory())W2(q,Q);else Q.push(q)}}function N1($){let Q=$;if(Q.startsWith("registry:"))Q=Q.slice(9);if(!Q)throw Error(`Invalid registry source reference: "${$}". Expected pack name.`);let Y="latest",Z=Q.indexOf("@");if(Z>0)Y=Q.slice(Z+1),Q=Q.slice(0,Z);if(!Q)throw Error(`Invalid registry source reference: "${$}". Pack name is empty.`);if(!/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(Q))throw Error(`Invalid registry pack name: "${Q}". Must be lowercase alphanumeric with hyphens.`);return{packName:Q,version:Y}}function x1($){return $.startsWith("registry:")}function b1($){return`registry:${$.packName}`}function q0($){if(!$.default&&!$.small&&Object.keys($.agents).length===0&&Object.keys($.profiles).length===0)return null;let Q=[];if(Q.push("# Model Configuration"),Q.push(""),Q.push("Use the following model preferences when working in this project."),Q.push(""),$.default||$.small){if(Q.push("## Default Models"),Q.push(""),$.default)Q.push(`- **Primary model**: ${$.default}`);if($.small)Q.push(`- **Lightweight tasks** (titles, summaries): ${$.small}`);Q.push("")}let Y=Object.entries($.agents);if(Y.length>0){Q.push("## Agent Model Assignments"),Q.push(""),Q.push("| Agent | Model | Temperature |"),Q.push("| --- | --- | --- |");for(let[Z,q]of Y){let X=q.temperature!==void 0?String(q.temperature):"\u2014";Q.push(`| ${Z} | ${q.model} | ${X} |`)}Q.push("")}if(Object.keys($.profiles).length>0){Q.push("## Available Profiles"),Q.push(""),Q.push("| Profile | Description | Default Model |"),Q.push("| --- | --- | --- |");for(let[Z,q]of Object.entries($.profiles))Q.push(`| ${Z} | ${q.description??"\u2014"} | ${q.default??"\u2014"} |`);Q.push("")}if($.activeProfile)Q.push(`**Active profile**: \`${$.activeProfile}\``),Q.push("");if($.routing.length>0){Q.push("## Task-Aware Routing"),Q.push(""),Q.push("Select the appropriate profile based on the task context:"),Q.push(""),Q.push("| Condition | Profile | Description |"),Q.push("| --- | --- | --- |");for(let Z of $.routing){let q=Object.entries(Z.when).map(([J,K])=>`${J}=${K}`).join(", "),X=Z.description??"\u2014";Q.push(`| ${q} | ${Z.use} | ${X} |`)}Q.push(""),Q.push("### Condition Reference"),Q.push(""),Q.push("- **complexity**: low | medium | high | critical"),Q.push("- **urgency**: low | normal | high"),Q.push("- **budget**: minimal | standard | premium"),Q.push("- **contextWindowNeed**: small | medium | large | max"),Q.push("- **toolUseIntensity**: none | light | heavy"),Q.push("")}return Q.join(`
20
+ `)}class R{supportsFeature($){return this.supportedFeatures.includes($)}getEffectiveFeatures($){return $.filter((Q)=>this.supportsFeature(Q))}createResult($=[],Q=[],Y=[]){return{targetId:this.id,filesWritten:$,filesDeleted:Q,warnings:Y}}}import{join as O$,resolve as N0}from"path";function g($){return new P2($)}class P2 extends R{id;name;supportedFeatures;config;constructor($){super();this.id=$.id,this.name=$.name,this.supportedFeatures=$.supportedFeatures,this.config=$}generate($){let{projectRoot:Q,baseDir:Y,features:Z,enabledFeatures:q,deleteExisting:X}=$,J=N0(Q,Y),K=this.getEffectiveFeatures(q),H=[],W=[],_=[],C=N0(J,this.config.configDir),B=this.config.rulesDir??"rules",V=this.config.ruleExtension??".md";if(K.includes("rules")){let L=N0(C,B);if(X)w(L),W.push(L);A(L);let U=Z.rules.filter((O)=>y(O,this.id));for(let O of U){let P=O$(L,`${O.name}${V}`);G(P,O.content),H.push(P)}}if(K.includes("commands")){let L=N0(C,"commands");if(X)w(L),W.push(L);A(L);let U=Z.commands.filter((O)=>k(O,this.id));for(let O of U){let P=O$(L,`${O.name}.md`);G(P,O.content),H.push(P)}}if(K.includes("mcp")){if(Object.entries(Z.mcpServers).length>0){let U=this.config.mcpInConfigDir?C:J,O=N0(U,"mcp.json");S(O,{mcpServers:Z.mcpServers},{header:!1}),H.push(O)}}if(K.includes("ignore")&&this.config.ignoreFile){if(Z.ignorePatterns.length>0){let L=N0(J,this.config.ignoreFile);G(L,Z.ignorePatterns.join(`
21
+ `)+`
22
+ `),H.push(L)}}if(K.includes("models")&&Z.models){let L=j(Z.models,$.modelProfile,this.id),U=q0(L);if(U){A(C);let O=O$(C,"model-config.md");G(O,U),H.push(O)}}return this.createResult(H,W,_)}}var C2=g({id:"cline",name:"Cline",configDir:".cline",supportedFeatures:["rules","commands","mcp","ignore"],ignoreFile:".clineignore",mcpInConfigDir:!0}),_2=g({id:"kilo",name:"Kilo Code",configDir:".kilo",supportedFeatures:["rules","commands","mcp","ignore"],ignoreFile:".kiloignore",mcpInConfigDir:!0}),A2=g({id:"roo",name:"Roo Code",configDir:".roo",supportedFeatures:["rules","commands","mcp","ignore"],ignoreFile:".rooignore",mcpInConfigDir:!0}),N2=g({id:"qwencode",name:"Qwen Code",configDir:".qwencode",supportedFeatures:["rules","mcp","ignore"],ignoreFile:".qwencodeignore",mcpInConfigDir:!0}),x2=g({id:"kiro",name:"Kiro",configDir:".kiro",supportedFeatures:["rules","mcp"],mcpInConfigDir:!0}),b2=g({id:"factorydroid",name:"Factory Droid",configDir:".factorydroid",supportedFeatures:["rules","mcp"],mcpInConfigDir:!0}),M2=g({id:"antigravity",name:"AntiGravity",configDir:".antigravity",supportedFeatures:["rules","mcp"],mcpInConfigDir:!0}),G2=g({id:"junie",name:"Junie",configDir:".junie",supportedFeatures:["rules","mcp"],mcpInConfigDir:!0}),z2=g({id:"augmentcode",name:"Augment Code",configDir:".augmentcode",supportedFeatures:["rules","mcp"],mcpInConfigDir:!0}),w2=g({id:"windsurf",name:"Windsurf",configDir:".windsurf",supportedFeatures:["rules","mcp","ignore"],ignoreFile:".windsurfignore",mcpInConfigDir:!0}),F2=g({id:"warp",name:"Warp",configDir:".warp",supportedFeatures:["rules"]}),I2=g({id:"replit",name:"Replit Agent",configDir:".replit",supportedFeatures:["rules","mcp"],mcpInConfigDir:!0}),E2=g({id:"zed",name:"Zed",configDir:".zed",supportedFeatures:["rules","mcp"],mcpInConfigDir:!0});import{join as x0,resolve as i}from"path";var X0="claudecode";class H$ extends R{id=X0;name="Claude Code";supportedFeatures=["rules","commands","agents","skills","hooks","mcp","ignore","models"];generate($){let{projectRoot:Q,baseDir:Y,features:Z,enabledFeatures:q,deleteExisting:X}=$,J=i(Q,Y),K=this.getEffectiveFeatures(q),H=[],W=[],_=[],C=i(J,".claude");if(K.includes("rules")){let B=i(C,"rules");if(X)w(B),W.push(B);A(B);let V=Z.rules.filter((O)=>y(O,X0)),L=y0(V),U=_0(V);if(L.length>0){let O=L.map((x)=>x.content).join(`
23
+
24
+ `),P=i(C,"CLAUDE.md");G(P,O),H.push(P)}for(let O of U){let P=x0(B,`${O.name}.md`);G(P,O.content),H.push(P)}}if(K.includes("agents")){let B=i(C,"agents");if(X)w(B),W.push(B);A(B);let V=Z.models?j(Z.models,$.modelProfile,X0):null,L=Z.agents.filter((U)=>n(U,X0));for(let U of L){let O=x0(B,`${U.name}.md`),P=U.meta.claudecode??{},b=V?.agents[U.name]?.model??P.model,z=U.content;if(b)z=`<!-- model: ${b} -->
25
+ ${z}`;G(O,z),H.push(O)}}if(K.includes("skills")){let B=i(C,"skills");if(X)w(B),W.push(B);A(B);let V=Z.skills.filter((L)=>u(L,X0));for(let L of V){let U=x0(B,L.name);A(U);let O=x0(U,"SKILL.md");G(O,D(L)),H.push(O)}}if(K.includes("commands")){let B=i(C,"commands");if(X)w(B),W.push(B);A(B);let V=Z.commands.filter((L)=>k(L,X0));for(let L of V){let U=x0(B,`${L.name}.md`);G(U,L.content),H.push(U)}}if(K.includes("models")&&Z.models){let B=j(Z.models,$.modelProfile,X0),V=q0(B);if(V){let L=i(C,"rules");A(L);let U=x0(L,"model-config.md");G(U,V),H.push(U)}}if(K.includes("hooks")||K.includes("mcp")||K.includes("ignore")){let B=M1($,K);if(Object.keys(B).length>0){let V=i(C,"settings.json"),U={...e(V)??{},...B};S(V,U,{header:!1}),H.push(V)}}return this.createResult(H,W,_)}}function M1($,Q){let Y={};if(Q.includes("hooks")){let Z={};for(let q of $.features.hooks){let X=o(q,X0);for(let[J,K]of Object.entries(X)){let H=G1(J);if(!Z[H])Z[H]=[];Z[H].push(...K.map((W)=>({type:W.type??"command",...W.matcher?{matcher:W.matcher}:{},command:W.command})))}}if(Object.keys(Z).length>0)Y.hooks=Z}if(Q.includes("mcp")){let Z=Object.entries($.features.mcpServers);if(Z.length>0){let q={};for(let[X,J]of Z)if(J.url)q[X]={url:J.url};else if(J.command)q[X]={command:J.command,...J.args?{args:J.args}:{},...J.env?{env:J.env}:{}};Y.mcpServers=q}}return Y}function G1($){return $.charAt(0).toUpperCase()+$.slice(1)}import{join as W$,resolve as b0}from"path";var m0="codexcli";class C$ extends R{id=m0;name="Codex CLI";supportedFeatures=["rules","skills","mcp","hooks"];generate($){let{projectRoot:Q,baseDir:Y,features:Z,enabledFeatures:q,deleteExisting:X}=$,J=b0(Q,Y),K=this.getEffectiveFeatures(q),H=[],W=[],_=[],C=b0(J,".codex");if(K.includes("rules")){let B=b0(C,"memories");if(X)P$(B,W,_);A(B);let V=Z.rules.filter((L)=>y(L,m0));for(let L of V){let U=W$(B,`${L.name}.md`);G(U,L.content),H.push(U)}}if(K.includes("skills")){let B=b0(C,"skills");if(X)P$(B,W,_);A(B);let V=Z.skills.filter((L)=>u(L,m0));for(let L of V){let U=W$(B,L.name);A(U);let O=W$(U,"SKILL.md");G(O,D(L)),H.push(O)}}if(K.includes("hooks")){let B=b0(C,"hooks.json");if(X)P$(B,W,_);let V={};for(let L of Z.hooks){let U=o(L,m0);for(let[O,P]of Object.entries(U)){if(!V[O])V[O]=[];V[O].push(...P)}}if(Object.keys(V).length>0){let L=Z.hooks.find((U)=>U.version!==void 0)?.version??1;S(B,{version:L,hooks:V},{header:!1}),H.push(B)}}if(K.includes("mcp")){let B=Object.entries(Z.mcpServers);if(B.length>0){let V={};for(let[L,U]of B)if(U.url)V[L]={url:U.url};else if(U.command)V[L]={command:U.command,...U.args?{args:U.args}:{},...U.env?{env:U.env}:{}};if(Object.keys(V).length>0){let L=b0(C,"mcp.json");S(L,{mcpServers:V},{header:!1}),H.push(L)}}}return this.createResult(H,W,_)}}function P$($,Q,Y){try{w($),Q.push($)}catch(Z){Y.push(`Could not remove ${$}: ${Z instanceof Error?Z.message:String(Z)}`)}}import{join as T0,resolve as t}from"path";var M0="copilot";class _$ extends R{id=M0;name="GitHub Copilot";supportedFeatures=["rules","commands","agents","skills","mcp","ignore","models"];generate($){let{projectRoot:Q,baseDir:Y,features:Z,enabledFeatures:q,deleteExisting:X}=$,J=t(Q,Y),K=this.getEffectiveFeatures(q),H=[],W=[],_=[],C=t(J,".github");if(K.includes("rules")){let B=Z.rules.filter((V)=>y(V,M0));if(B.length>0){let V=B.map((U)=>U.content).join(`
2767
26
 
2768
27
  ---
2769
28
 
2770
- `);
2771
- const filepath = resolve16(githubDir, "copilot-instructions.md");
2772
- ensureDir(githubDir);
2773
- writeGeneratedFile(filepath, combinedContent);
2774
- filesWritten.push(filepath);
2775
- }
2776
- }
2777
- if (effective.includes("agents")) {
2778
- const copilotDir = resolve16(githubDir, "copilot");
2779
- const agentsDir = resolve16(copilotDir, "agents");
2780
- if (deleteExisting) {
2781
- removeIfExists(agentsDir);
2782
- filesDeleted.push(agentsDir);
2783
- }
2784
- ensureDir(agentsDir);
2785
- const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID3));
2786
- for (const agent of agents) {
2787
- const filepath = join18(agentsDir, `${agent.name}.md`);
2788
- writeGeneratedFile(filepath, agent.content);
2789
- filesWritten.push(filepath);
2790
- }
2791
- }
2792
- if (effective.includes("skills")) {
2793
- const copilotDir = resolve16(githubDir, "copilot");
2794
- const skillsDir = resolve16(copilotDir, "skills");
2795
- if (deleteExisting) {
2796
- removeIfExists(skillsDir);
2797
- filesDeleted.push(skillsDir);
2798
- }
2799
- ensureDir(skillsDir);
2800
- const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID3));
2801
- for (const skill of skills) {
2802
- const skillSubDir = join18(skillsDir, skill.name);
2803
- ensureDir(skillSubDir);
2804
- const filepath = join18(skillSubDir, "SKILL.md");
2805
- writeGeneratedFile(filepath, serializeSkill(skill));
2806
- filesWritten.push(filepath);
2807
- }
2808
- }
2809
- if (effective.includes("commands")) {
2810
- const copilotDir = resolve16(githubDir, "copilot");
2811
- const commandsDir = resolve16(copilotDir, "commands");
2812
- if (deleteExisting) {
2813
- removeIfExists(commandsDir);
2814
- filesDeleted.push(commandsDir);
2815
- }
2816
- ensureDir(commandsDir);
2817
- const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID3));
2818
- for (const cmd of commands) {
2819
- const filepath = join18(commandsDir, `${cmd.name}.md`);
2820
- writeGeneratedFile(filepath, cmd.content);
2821
- filesWritten.push(filepath);
2822
- }
2823
- }
2824
- if (effective.includes("ignore")) {}
2825
- if (effective.includes("models") && features.models) {
2826
- const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID3);
2827
- const guidance = generateModelGuidanceMarkdown(resolved);
2828
- if (guidance) {
2829
- const copilotDir = resolve16(githubDir, "copilot");
2830
- ensureDir(copilotDir);
2831
- const filepath = join18(copilotDir, "model-config.md");
2832
- writeGeneratedFile(filepath, guidance);
2833
- filesWritten.push(filepath);
2834
- }
2835
- }
2836
- return this.createResult(filesWritten, filesDeleted, warnings);
2837
- }
2838
- }
2839
-
2840
- // src/targets/cursor.ts
2841
- import { join as join19, resolve as resolve17 } from "path";
2842
- var TARGET_ID4 = "cursor";
29
+ `),L=t(C,"copilot-instructions.md");A(C),G(L,V),H.push(L)}}if(K.includes("agents")){let B=t(C,"copilot"),V=t(B,"agents");if(X)w(V),W.push(V);A(V);let L=Z.agents.filter((U)=>n(U,M0));for(let U of L){let O=T0(V,`${U.name}.md`);G(O,U.content),H.push(O)}}if(K.includes("skills")){let B=t(C,"copilot"),V=t(B,"skills");if(X)w(V),W.push(V);A(V);let L=Z.skills.filter((U)=>u(U,M0));for(let U of L){let O=T0(V,U.name);A(O);let P=T0(O,"SKILL.md");G(P,D(U)),H.push(P)}}if(K.includes("commands")){let B=t(C,"copilot"),V=t(B,"commands");if(X)w(V),W.push(V);A(V);let L=Z.commands.filter((U)=>k(U,M0));for(let U of L){let O=T0(V,`${U.name}.md`);G(O,U.content),H.push(O)}}if(K.includes("ignore"));if(K.includes("models")&&Z.models){let B=j(Z.models,$.modelProfile,M0),V=q0(B);if(V){let L=t(C,"copilot");A(L);let U=T0(L,"model-config.md");G(U,V),H.push(U)}}return this.createResult(H,W,_)}}import{join as G0,resolve as s}from"path";var L0="cursor";class A$ extends R{id=L0;name="Cursor";supportedFeatures=["rules","commands","agents","skills","hooks","mcp","ignore","models"];generate($){let{projectRoot:Q,baseDir:Y,features:Z,enabledFeatures:q,deleteExisting:X}=$,J=s(Q,Y),K=this.getEffectiveFeatures(q),H=[],W=[],_=[],C=s(J,".cursor");if(K.includes("rules")){let B=s(C,"rules");if(X)w(B),W.push(B);A(B);let V=Z.rules.filter((L)=>y(L,L0));for(let L of V){let U=L.meta.cursor??{},O={description:U.description??L.meta.description??"",alwaysApply:U.alwaysApply??L.meta.root??!1},P=U.globs??L.meta.globs;if(P)O.globs=P;let x=G0(B,`${L.name}.mdc`),b=v(O,L.content);G(x,b),H.push(x)}}if(K.includes("agents")){let B=s(C,"agents");if(X)w(B),W.push(B);A(B);let V=Z.models?j(Z.models,$.modelProfile,L0):null,L=Z.agents.filter((U)=>n(U,L0));for(let U of L){let O={name:U.name,description:U.meta.description??""},P=U.meta.cursor??{},b=V?.agents[U.name]?.model??P.model;if(b)O.model=b;let z=G0(B,`${U.name}.md`),m=v(O,U.content);G(z,m),H.push(z)}}if(K.includes("skills")){let B=s(C,"skills");if(X)w(B),W.push(B);A(B);let V=Z.skills.filter((L)=>u(L,L0));for(let L of V){let U=G0(B,L.name);A(U);let O=G0(U,"SKILL.md"),P=D(L);G(O,P),H.push(O)}}if(K.includes("commands")){let B=s(C,"commands");if(X)w(B),W.push(B);A(B);let V=Z.commands.filter((L)=>k(L,L0));for(let L of V){let U=G0(B,`${L.name}.md`);G(U,L.content),H.push(U)}}if(K.includes("hooks")){let B=s(C,"hooks.json");if(X)w(B),W.push(B);let V={};for(let L of Z.hooks){let U=o(L,L0);for(let[O,P]of Object.entries(U)){if(!V[O])V[O]=[];V[O].push(...P)}}if(Object.keys(V).length>0){let L=Z.hooks.find((U)=>U.version!==void 0)?.version??1;S(B,{version:L,hooks:V},{header:!1}),H.push(B)}}if(K.includes("mcp")){if(Object.entries(Z.mcpServers).length>0){let V=z1(Z.mcpServers),L=s(C,"mcp.json");S(L,V,{header:!1}),H.push(L)}}if(K.includes("ignore")){if(Z.ignorePatterns.length>0){let B=s(J,".cursorignore"),V=Z.ignorePatterns.join(`
30
+ `)+`
31
+ `;G(B,V),H.push(B)}}if(K.includes("models")&&Z.models){let B=j(Z.models,$.modelProfile,L0),V=w1(B);if(V){let L=s(C,"rules");A(L);let U=G0(L,"model-config.mdc");G(U,V,{header:!1}),H.push(U)}}return this.createResult(H,W,_)}}function z1($){let Q={};for(let[Y,Z]of Object.entries($))if(Z.url)Q[Y]={url:Z.url};else if(Z.command)Q[Y]={command:Z.command,...Z.args?{args:Z.args}:{},...Z.env?{env:Z.env}:{}};return{mcpServers:Q}}function w1($){if(!$.default&&!$.small&&Object.keys($.agents).length===0)return null;let Q={description:"Model configuration and selection guidelines for this workspace",alwaysApply:!0},Y=[];if(Y.push("# Model Configuration"),Y.push(""),Y.push("Use the following model preferences when working in this project."),Y.push(""),$.default||$.small){if(Y.push("## Default Models"),Y.push(""),$.default)Y.push(`- **Primary model**: ${$.default}`);if($.small)Y.push(`- **Lightweight tasks** (titles, summaries): ${$.small}`);Y.push("")}let Z=Object.entries($.agents);if(Z.length>0){Y.push("## Agent Model Assignments"),Y.push(""),Y.push("| Agent | Model | Temperature |"),Y.push("| --- | --- | --- |");for(let[q,X]of Z){let J=X.temperature!==void 0?String(X.temperature):"\u2014";Y.push(`| ${q} | ${X.model} | ${J} |`)}Y.push("")}if(Object.keys($.profiles).length>0){Y.push("## Available Profiles"),Y.push(""),Y.push("| Profile | Description | Default Model |"),Y.push("| --- | --- | --- |");for(let[q,X]of Object.entries($.profiles))Y.push(`| ${q} | ${X.description??"\u2014"} | ${X.default??"\u2014"} |`);Y.push("")}if($.activeProfile)Y.push(`**Active profile**: \`${$.activeProfile}\``),Y.push("");return v(Q,Y.join(`
32
+ `))}import{join as T2,resolve as P0}from"path";var N$="geminicli";class x$ extends R{id=N$;name="Gemini CLI";supportedFeatures=["rules","commands","mcp","ignore","skills","hooks"];generate($){let{projectRoot:Q,baseDir:Y,features:Z,enabledFeatures:q,deleteExisting:X}=$,J=P0(Q,Y),K=this.getEffectiveFeatures(q),H=[],W=[],_=[],C=P0(J,".gemini");if(K.includes("rules")){let B=Z.rules.filter((U)=>y(U,N$)),V=y0(B),L=_0(B);if(V.length>0){let U=V.map((P)=>P.content).join(`
2843
33
 
2844
- class CursorTarget extends BaseTarget {
2845
- id = TARGET_ID4;
2846
- name = "Cursor";
2847
- supportedFeatures = [
2848
- "rules",
2849
- "commands",
2850
- "agents",
2851
- "skills",
2852
- "hooks",
2853
- "mcp",
2854
- "ignore",
2855
- "models"
2856
- ];
2857
- generate(options) {
2858
- const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
2859
- const root = resolve17(projectRoot, baseDir);
2860
- const effective = this.getEffectiveFeatures(enabledFeatures);
2861
- const filesWritten = [];
2862
- const filesDeleted = [];
2863
- const warnings = [];
2864
- const cursorDir = resolve17(root, ".cursor");
2865
- if (effective.includes("rules")) {
2866
- const rulesDir = resolve17(cursorDir, "rules");
2867
- if (deleteExisting) {
2868
- removeIfExists(rulesDir);
2869
- filesDeleted.push(rulesDir);
2870
- }
2871
- ensureDir(rulesDir);
2872
- const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID4));
2873
- for (const rule of rules) {
2874
- const cursorMeta = rule.meta.cursor ?? {};
2875
- const frontmatter = {
2876
- description: cursorMeta.description ?? rule.meta.description ?? "",
2877
- alwaysApply: cursorMeta.alwaysApply ?? rule.meta.root ?? false
2878
- };
2879
- const globs = cursorMeta.globs ?? rule.meta.globs;
2880
- if (globs) {
2881
- frontmatter.globs = globs;
2882
- }
2883
- const filepath = join19(rulesDir, `${rule.name}.mdc`);
2884
- const content = serializeFrontmatter(frontmatter, rule.content);
2885
- writeGeneratedFile(filepath, content);
2886
- filesWritten.push(filepath);
2887
- }
2888
- }
2889
- if (effective.includes("agents")) {
2890
- const agentsDir = resolve17(cursorDir, "agents");
2891
- if (deleteExisting) {
2892
- removeIfExists(agentsDir);
2893
- filesDeleted.push(agentsDir);
2894
- }
2895
- ensureDir(agentsDir);
2896
- const resolvedModels = features.models ? resolveModels(features.models, options.modelProfile, TARGET_ID4) : null;
2897
- const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID4));
2898
- for (const agent of agents) {
2899
- const frontmatter = {
2900
- name: agent.name,
2901
- description: agent.meta.description ?? ""
2902
- };
2903
- const cursorMeta = agent.meta.cursor ?? {};
2904
- const modelsAgent = resolvedModels?.agents[agent.name];
2905
- const model = modelsAgent?.model ?? cursorMeta.model;
2906
- if (model) {
2907
- frontmatter.model = model;
2908
- }
2909
- const filepath = join19(agentsDir, `${agent.name}.md`);
2910
- const content = serializeFrontmatter(frontmatter, agent.content);
2911
- writeGeneratedFile(filepath, content);
2912
- filesWritten.push(filepath);
2913
- }
2914
- }
2915
- if (effective.includes("skills")) {
2916
- const skillsDir = resolve17(cursorDir, "skills");
2917
- if (deleteExisting) {
2918
- removeIfExists(skillsDir);
2919
- filesDeleted.push(skillsDir);
2920
- }
2921
- ensureDir(skillsDir);
2922
- const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID4));
2923
- for (const skill of skills) {
2924
- const skillSubDir = join19(skillsDir, skill.name);
2925
- ensureDir(skillSubDir);
2926
- const filepath = join19(skillSubDir, "SKILL.md");
2927
- const content = serializeSkill(skill);
2928
- writeGeneratedFile(filepath, content);
2929
- filesWritten.push(filepath);
2930
- }
2931
- }
2932
- if (effective.includes("commands")) {
2933
- const commandsDir = resolve17(cursorDir, "commands");
2934
- if (deleteExisting) {
2935
- removeIfExists(commandsDir);
2936
- filesDeleted.push(commandsDir);
2937
- }
2938
- ensureDir(commandsDir);
2939
- const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID4));
2940
- for (const cmd of commands) {
2941
- const filepath = join19(commandsDir, `${cmd.name}.md`);
2942
- writeGeneratedFile(filepath, cmd.content);
2943
- filesWritten.push(filepath);
2944
- }
2945
- }
2946
- if (effective.includes("hooks")) {
2947
- const hooksFilepath = resolve17(cursorDir, "hooks.json");
2948
- if (deleteExisting) {
2949
- removeIfExists(hooksFilepath);
2950
- filesDeleted.push(hooksFilepath);
2951
- }
2952
- const mergedHooks = {};
2953
- for (const hookSet of features.hooks) {
2954
- const events = resolveHooksForTarget(hookSet, TARGET_ID4);
2955
- for (const [event, entries] of Object.entries(events)) {
2956
- if (!mergedHooks[event]) {
2957
- mergedHooks[event] = [];
2958
- }
2959
- mergedHooks[event].push(...entries);
2960
- }
2961
- }
2962
- if (Object.keys(mergedHooks).length > 0) {
2963
- const hooksVersion = features.hooks.find((h) => h.version !== undefined)?.version ?? 1;
2964
- writeGeneratedJson(hooksFilepath, { version: hooksVersion, hooks: mergedHooks }, { header: false });
2965
- filesWritten.push(hooksFilepath);
2966
- }
2967
- }
2968
- if (effective.includes("mcp")) {
2969
- const mcpEntries = Object.entries(features.mcpServers);
2970
- if (mcpEntries.length > 0) {
2971
- const mcpConfig = buildCursorMcp(features.mcpServers);
2972
- const filepath = resolve17(cursorDir, "mcp.json");
2973
- writeGeneratedJson(filepath, mcpConfig, { header: false });
2974
- filesWritten.push(filepath);
2975
- }
2976
- }
2977
- if (effective.includes("ignore")) {
2978
- if (features.ignorePatterns.length > 0) {
2979
- const filepath = resolve17(root, ".cursorignore");
2980
- const content = features.ignorePatterns.join(`
2981
- `) + `
2982
- `;
2983
- writeGeneratedFile(filepath, content);
2984
- filesWritten.push(filepath);
2985
- }
2986
- }
2987
- if (effective.includes("models") && features.models) {
2988
- const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID4);
2989
- const guidanceContent = buildCursorModelGuidance(resolved);
2990
- if (guidanceContent) {
2991
- const rulesDir = resolve17(cursorDir, "rules");
2992
- ensureDir(rulesDir);
2993
- const filepath = join19(rulesDir, "model-config.mdc");
2994
- writeGeneratedFile(filepath, guidanceContent, { header: false });
2995
- filesWritten.push(filepath);
2996
- }
2997
- }
2998
- return this.createResult(filesWritten, filesDeleted, warnings);
2999
- }
3000
- }
3001
- function buildCursorMcp(servers) {
3002
- const mcpServers = {};
3003
- for (const [name, entry] of Object.entries(servers)) {
3004
- if (entry.url) {
3005
- mcpServers[name] = { url: entry.url };
3006
- } else if (entry.command) {
3007
- mcpServers[name] = {
3008
- command: entry.command,
3009
- ...entry.args ? { args: entry.args } : {},
3010
- ...entry.env ? { env: entry.env } : {}
3011
- };
3012
- }
3013
- }
3014
- return { mcpServers };
3015
- }
3016
- function buildCursorModelGuidance(resolved) {
3017
- if (!resolved.default && !resolved.small && Object.keys(resolved.agents).length === 0) {
3018
- return null;
3019
- }
3020
- const frontmatter = {
3021
- description: "Model configuration and selection guidelines for this workspace",
3022
- alwaysApply: true
3023
- };
3024
- const lines = [];
3025
- lines.push("# Model Configuration");
3026
- lines.push("");
3027
- lines.push("Use the following model preferences when working in this project.");
3028
- lines.push("");
3029
- if (resolved.default || resolved.small) {
3030
- lines.push("## Default Models");
3031
- lines.push("");
3032
- if (resolved.default) {
3033
- lines.push(`- **Primary model**: ${resolved.default}`);
3034
- }
3035
- if (resolved.small) {
3036
- lines.push(`- **Lightweight tasks** (titles, summaries): ${resolved.small}`);
3037
- }
3038
- lines.push("");
3039
- }
3040
- const agentEntries = Object.entries(resolved.agents);
3041
- if (agentEntries.length > 0) {
3042
- lines.push("## Agent Model Assignments");
3043
- lines.push("");
3044
- lines.push("| Agent | Model | Temperature |");
3045
- lines.push("| --- | --- | --- |");
3046
- for (const [name, assignment] of agentEntries) {
3047
- const temp = assignment.temperature !== undefined ? String(assignment.temperature) : "\u2014";
3048
- lines.push(`| ${name} | ${assignment.model} | ${temp} |`);
3049
- }
3050
- lines.push("");
3051
- }
3052
- if (Object.keys(resolved.profiles).length > 0) {
3053
- lines.push("## Available Profiles");
3054
- lines.push("");
3055
- lines.push("| Profile | Description | Default Model |");
3056
- lines.push("| --- | --- | --- |");
3057
- for (const [name, profile] of Object.entries(resolved.profiles)) {
3058
- lines.push(`| ${name} | ${profile.description ?? "\u2014"} | ${profile.default ?? "\u2014"} |`);
3059
- }
3060
- lines.push("");
3061
- }
3062
- if (resolved.activeProfile) {
3063
- lines.push(`**Active profile**: \`${resolved.activeProfile}\``);
3064
- lines.push("");
3065
- }
3066
- return serializeFrontmatter(frontmatter, lines.join(`
3067
- `));
3068
- }
3069
-
3070
- // src/targets/gemini-cli.ts
3071
- import { join as join20, resolve as resolve18 } from "path";
3072
- var TARGET_ID5 = "geminicli";
3073
-
3074
- class GeminiCliTarget extends BaseTarget {
3075
- id = TARGET_ID5;
3076
- name = "Gemini CLI";
3077
- supportedFeatures = [
3078
- "rules",
3079
- "commands",
3080
- "mcp",
3081
- "ignore",
3082
- "skills",
3083
- "hooks"
3084
- ];
3085
- generate(options) {
3086
- const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
3087
- const root = resolve18(projectRoot, baseDir);
3088
- const effective = this.getEffectiveFeatures(enabledFeatures);
3089
- const filesWritten = [];
3090
- const filesDeleted = [];
3091
- const warnings = [];
3092
- const geminiDir = resolve18(root, ".gemini");
3093
- if (effective.includes("rules")) {
3094
- const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID5));
3095
- const rootRules = getRootRules(rules);
3096
- const detailRules = getDetailRules(rules);
3097
- if (rootRules.length > 0) {
3098
- const geminiMd = rootRules.map((r) => r.content).join(`
3099
-
3100
- `);
3101
- const filepath = resolve18(root, "GEMINI.md");
3102
- writeGeneratedFile(filepath, geminiMd);
3103
- filesWritten.push(filepath);
3104
- }
3105
- if (detailRules.length > 0) {
3106
- const memoriesDir = resolve18(geminiDir, "memories");
3107
- if (deleteExisting) {
3108
- removeIfExists(memoriesDir);
3109
- filesDeleted.push(memoriesDir);
3110
- }
3111
- ensureDir(memoriesDir);
3112
- for (const rule of detailRules) {
3113
- const filepath = join20(memoriesDir, `${rule.name}.md`);
3114
- writeGeneratedFile(filepath, rule.content);
3115
- filesWritten.push(filepath);
3116
- }
3117
- }
3118
- }
3119
- if (effective.includes("commands")) {
3120
- const commandsDir = resolve18(geminiDir, "commands");
3121
- if (deleteExisting) {
3122
- removeIfExists(commandsDir);
3123
- filesDeleted.push(commandsDir);
3124
- }
3125
- ensureDir(commandsDir);
3126
- const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID5));
3127
- for (const cmd of commands) {
3128
- const toml = buildGeminiCommand(cmd.name, cmd.meta.description ?? "", cmd.content);
3129
- const filepath = join20(commandsDir, `${cmd.name}.toml`);
3130
- writeGeneratedFile(filepath, toml, { type: "md" });
3131
- filesWritten.push(filepath);
3132
- }
3133
- }
3134
- if (effective.includes("mcp")) {
3135
- const mcpEntries = Object.entries(features.mcpServers);
3136
- if (mcpEntries.length > 0) {
3137
- const settings = buildGeminiSettings(features.mcpServers);
3138
- const filepath = resolve18(geminiDir, "settings.json");
3139
- writeGeneratedJson(filepath, settings, { header: false });
3140
- filesWritten.push(filepath);
3141
- }
3142
- }
3143
- if (effective.includes("ignore")) {
3144
- if (features.ignorePatterns.length > 0) {
3145
- const filepath = resolve18(root, ".geminiignore");
3146
- const content = features.ignorePatterns.join(`
3147
- `) + `
3148
- `;
3149
- writeGeneratedFile(filepath, content);
3150
- filesWritten.push(filepath);
3151
- }
3152
- }
3153
- return this.createResult(filesWritten, filesDeleted, warnings);
3154
- }
3155
- }
3156
- function buildGeminiCommand(name, description, content) {
3157
- return `[command]
3158
- name = "${name}"
3159
- description = "${description}"
34
+ `),O=P0(J,"GEMINI.md");G(O,U),H.push(O)}if(L.length>0){let U=P0(C,"memories");if(X)w(U),W.push(U);A(U);for(let O of L){let P=T2(U,`${O.name}.md`);G(P,O.content),H.push(P)}}}if(K.includes("commands")){let B=P0(C,"commands");if(X)w(B),W.push(B);A(B);let V=Z.commands.filter((L)=>k(L,N$));for(let L of V){let U=F1(L.name,L.meta.description??"",L.content),O=T2(B,`${L.name}.toml`);G(O,U,{type:"md"}),H.push(O)}}if(K.includes("mcp")){if(Object.entries(Z.mcpServers).length>0){let V=I1(Z.mcpServers),L=P0(C,"settings.json");S(L,V,{header:!1}),H.push(L)}}if(K.includes("ignore")){if(Z.ignorePatterns.length>0){let B=P0(J,".geminiignore"),V=Z.ignorePatterns.join(`
35
+ `)+`
36
+ `;G(B,V),H.push(B)}}return this.createResult(H,W,_)}}function F1($,Q,Y){return`[command]
37
+ name = "${$}"
38
+ description = "${Q}"
3160
39
 
3161
40
  [prompt]
3162
41
  content = """
3163
- ${content}
42
+ ${Y}
3164
43
  """
3165
- `;
3166
- }
3167
- function buildGeminiSettings(servers) {
3168
- const mcpServers = {};
3169
- for (const [name, entry] of Object.entries(servers)) {
3170
- if (entry.command) {
3171
- mcpServers[name] = {
3172
- command: entry.command,
3173
- ...entry.args ? { args: entry.args } : {},
3174
- ...entry.env ? { env: entry.env } : {}
3175
- };
3176
- } else if (entry.url) {
3177
- mcpServers[name] = { url: entry.url };
3178
- }
3179
- }
3180
- return { mcpServers };
3181
- }
3182
-
3183
- // src/targets/mistral-vibe.ts
3184
- import { join as join21, resolve as resolve19 } from "path";
3185
- var TARGET_ID6 = "mistralvibe";
3186
-
3187
- class MistralVibeTarget extends BaseTarget {
3188
- id = TARGET_ID6;
3189
- name = "Mistral Vibe";
3190
- supportedFeatures = [
3191
- "rules",
3192
- "commands",
3193
- "agents",
3194
- "skills",
3195
- "mcp",
3196
- "ignore",
3197
- "models"
3198
- ];
3199
- generate(options) {
3200
- const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
3201
- const root = resolve19(projectRoot, baseDir);
3202
- const effective = this.getEffectiveFeatures(enabledFeatures);
3203
- const filesWritten = [];
3204
- const filesDeleted = [];
3205
- const warnings = [];
3206
- const vibeDir = resolve19(root, ".vibe");
3207
- ensureDir(vibeDir);
3208
- if (effective.includes("rules")) {
3209
- const rulesDir = resolve19(vibeDir, "rules");
3210
- if (deleteExisting) {
3211
- removeIfExists(rulesDir);
3212
- filesDeleted.push(rulesDir);
3213
- }
3214
- ensureDir(rulesDir);
3215
- const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID6));
3216
- for (const rule of rules) {
3217
- const filepath = join21(rulesDir, `${rule.name}.md`);
3218
- writeGeneratedFile(filepath, rule.content);
3219
- filesWritten.push(filepath);
3220
- }
3221
- }
3222
- if (effective.includes("agents")) {
3223
- const agentsDir = resolve19(vibeDir, "agents");
3224
- if (deleteExisting) {
3225
- removeIfExists(agentsDir);
3226
- filesDeleted.push(agentsDir);
3227
- }
3228
- ensureDir(agentsDir);
3229
- const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID6));
3230
- for (const agent of agents) {
3231
- const filepath = join21(agentsDir, `${agent.name}.md`);
3232
- writeGeneratedFile(filepath, agent.content);
3233
- filesWritten.push(filepath);
3234
- }
3235
- }
3236
- if (effective.includes("skills")) {
3237
- const skillsDir = resolve19(vibeDir, "skills");
3238
- if (deleteExisting) {
3239
- removeIfExists(skillsDir);
3240
- filesDeleted.push(skillsDir);
3241
- }
3242
- ensureDir(skillsDir);
3243
- const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID6));
3244
- for (const skill of skills) {
3245
- const skillSubDir = join21(skillsDir, skill.name);
3246
- ensureDir(skillSubDir);
3247
- const filepath = join21(skillSubDir, "SKILL.md");
3248
- writeGeneratedFile(filepath, serializeSkill(skill));
3249
- filesWritten.push(filepath);
3250
- }
3251
- }
3252
- if (effective.includes("commands")) {
3253
- const commandsDir = resolve19(vibeDir, "commands");
3254
- if (deleteExisting) {
3255
- removeIfExists(commandsDir);
3256
- filesDeleted.push(commandsDir);
3257
- }
3258
- ensureDir(commandsDir);
3259
- const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID6));
3260
- for (const command of commands) {
3261
- const filepath = join21(commandsDir, `${command.name}.md`);
3262
- writeGeneratedFile(filepath, command.content);
3263
- filesWritten.push(filepath);
3264
- }
3265
- }
3266
- let hasMcpConfig = false;
3267
- if (effective.includes("mcp")) {
3268
- const mcpEntries = Object.entries(features.mcpServers);
3269
- if (mcpEntries.length > 0) {
3270
- const filepath = resolve19(vibeDir, "mcp.json");
3271
- writeGeneratedJson(filepath, { mcpServers: features.mcpServers }, {
3272
- header: false
3273
- });
3274
- filesWritten.push(filepath);
3275
- hasMcpConfig = true;
3276
- }
3277
- }
3278
- if (effective.includes("ignore") && features.ignorePatterns.length > 0) {
3279
- const filepath = resolve19(root, ".vibeignore");
3280
- writeGeneratedFile(filepath, features.ignorePatterns.join(`
3281
- `) + `
3282
- `);
3283
- filesWritten.push(filepath);
3284
- }
3285
- let defaultModel;
3286
- let smallModel;
3287
- if (effective.includes("models") && features.models) {
3288
- const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID6);
3289
- defaultModel = resolved.default;
3290
- smallModel = resolved.small;
3291
- const guidance = generateModelGuidanceMarkdown(resolved);
3292
- if (guidance) {
3293
- const filepath = join21(vibeDir, "model-config.md");
3294
- writeGeneratedFile(filepath, guidance);
3295
- filesWritten.push(filepath);
3296
- }
3297
- }
3298
- const vibeConfig = buildVibeConfigToml({
3299
- hasMcpConfig,
3300
- defaultModel,
3301
- smallModel,
3302
- profile: options.modelProfile
3303
- });
3304
- if (vibeConfig.length > 0) {
3305
- const filepath = resolve19(vibeDir, "config.toml");
3306
- writeGeneratedFile(filepath, vibeConfig);
3307
- filesWritten.push(filepath);
3308
- }
3309
- return this.createResult(filesWritten, filesDeleted, warnings);
3310
- }
3311
- }
3312
- function buildVibeConfigToml(options) {
3313
- const lines = [];
3314
- if (options.defaultModel || options.smallModel || options.profile) {
3315
- lines.push("[models]");
3316
- if (options.defaultModel) {
3317
- lines.push(`default = "${escapeTomlString(options.defaultModel)}"`);
3318
- }
3319
- if (options.smallModel) {
3320
- lines.push(`small = "${escapeTomlString(options.smallModel)}"`);
3321
- }
3322
- if (options.profile) {
3323
- lines.push(`profile = "${escapeTomlString(options.profile)}"`);
3324
- }
3325
- lines.push("");
3326
- }
3327
- if (options.hasMcpConfig) {
3328
- lines.push("[mcp]");
3329
- lines.push('config_path = ".vibe/mcp.json"');
3330
- lines.push("");
3331
- }
3332
- return lines.join(`
3333
- `).trim();
3334
- }
3335
- function escapeTomlString(value) {
3336
- return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
3337
- }
3338
-
3339
- // src/utils/markdown.ts
3340
- function stripGeneratedHeader(content) {
3341
- return content.replace(/^<!-- Generated by agentpacks.*-->\n/, "").replace(/^\/\/ Generated by agentpacks.*\n/, "");
3342
- }
3343
- function packNameToIdentifier(packName) {
3344
- return packName.split(/[-_.]/).filter((part) => part.length > 0).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
3345
- }
3346
- function extractFirstHeading(content) {
3347
- const match = content.match(/^#{1,6}\s+(.+)$/m);
3348
- return match?.[1]?.trim() ?? null;
3349
- }
3350
- function combineMarkdown(sections, separator = `
44
+ `}function I1($){let Q={};for(let[Y,Z]of Object.entries($))if(Z.command)Q[Y]={command:Z.command,...Z.args?{args:Z.args}:{},...Z.env?{env:Z.env}:{}};else if(Z.url)Q[Y]={url:Z.url};return{mcpServers:Q}}import{join as z0,resolve as r}from"path";var w0="mistralvibe";class M$ extends R{id=w0;name="Mistral Vibe";supportedFeatures=["rules","commands","agents","skills","mcp","ignore","models"];generate($){let{projectRoot:Q,baseDir:Y,features:Z,enabledFeatures:q,deleteExisting:X}=$,J=r(Q,Y),K=this.getEffectiveFeatures(q),H=[],W=[],_=[],C=r(J,".vibe");if(A(C),K.includes("rules")){let O=r(C,"rules");if(X)w(O),W.push(O);A(O);let P=Z.rules.filter((x)=>y(x,w0));for(let x of P){let b=z0(O,`${x.name}.md`);G(b,x.content),H.push(b)}}if(K.includes("agents")){let O=r(C,"agents");if(X)w(O),W.push(O);A(O);let P=Z.agents.filter((x)=>n(x,w0));for(let x of P){let b=z0(O,`${x.name}.md`);G(b,x.content),H.push(b)}}if(K.includes("skills")){let O=r(C,"skills");if(X)w(O),W.push(O);A(O);let P=Z.skills.filter((x)=>u(x,w0));for(let x of P){let b=z0(O,x.name);A(b);let z=z0(b,"SKILL.md");G(z,D(x)),H.push(z)}}if(K.includes("commands")){let O=r(C,"commands");if(X)w(O),W.push(O);A(O);let P=Z.commands.filter((x)=>k(x,w0));for(let x of P){let b=z0(O,`${x.name}.md`);G(b,x.content),H.push(b)}}let B=!1;if(K.includes("mcp")){if(Object.entries(Z.mcpServers).length>0){let P=r(C,"mcp.json");S(P,{mcpServers:Z.mcpServers},{header:!1}),H.push(P),B=!0}}if(K.includes("ignore")&&Z.ignorePatterns.length>0){let O=r(J,".vibeignore");G(O,Z.ignorePatterns.join(`
45
+ `)+`
46
+ `),H.push(O)}let V,L;if(K.includes("models")&&Z.models){let O=j(Z.models,$.modelProfile,w0);V=O.default,L=O.small;let P=q0(O);if(P){let x=z0(C,"model-config.md");G(x,P),H.push(x)}}let U=E1({hasMcpConfig:B,defaultModel:V,smallModel:L,profile:$.modelProfile});if(U.length>0){let O=r(C,"config.toml");G(O,U),H.push(O)}return this.createResult(H,W,_)}}function E1($){let Q=[];if($.defaultModel||$.smallModel||$.profile){if(Q.push("[models]"),$.defaultModel)Q.push(`default = "${b$($.defaultModel)}"`);if($.smallModel)Q.push(`small = "${b$($.smallModel)}"`);if($.profile)Q.push(`profile = "${b$($.profile)}"`);Q.push("")}if($.hasMcpConfig)Q.push("[mcp]"),Q.push('config_path = ".vibe/mcp.json"'),Q.push("");return Q.join(`
47
+ `).trim()}function b$($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function K6($){return $.replace(/^<!-- Generated by agentpacks.*-->\n/,"").replace(/^\/\/ Generated by agentpacks.*\n/,"")}function R2($){return $.split(/[-_.]/).filter((Q)=>Q.length>0).map((Q)=>Q.charAt(0).toUpperCase()+Q.slice(1)).join("")}function J6($){return $.match(/^#{1,6}\s+(.+)$/m)?.[1]?.trim()??null}function O6($,Q=`
3351
48
 
3352
49
  ---
3353
50
 
3354
- `) {
3355
- return sections.filter(Boolean).join(separator);
3356
- }
3357
- function wrapSection(heading, content, level = 2) {
3358
- const prefix = "#".repeat(level);
3359
- return `${prefix} ${heading}
51
+ `){return $.filter(Boolean).join(Q)}function H6($,Q,Y=2){return`${"#".repeat(Y)} ${$}
3360
52
 
3361
- ${content}`;
3362
- }
53
+ ${Q}`}import{join as C0,resolve as U0}from"path";var B0="opencode";class G$ extends R{id=B0;name="OpenCode";supportedFeatures=["rules","commands","agents","skills","hooks","plugins","mcp","ignore","models"];generate($){let{projectRoot:Q,baseDir:Y,features:Z,enabledFeatures:q,deleteExisting:X}=$,J=U0(Q,Y),K=this.getEffectiveFeatures(q),H=[],W=[],_=[],C=U0(J,".opencode");if(K.includes("agents")){let B=U0(C,"agent");if(X)w(B),W.push(B);A(B);let V=Z.models?j(Z.models,$.modelProfile,B0):null,L=Z.agents.filter((U)=>n(U,B0));for(let U of L){let O=C0(B,`${U.name}.md`),P={},x=U.meta.opencode??{},b=V?.agents[U.name],z=b?.model??x.model,m=b?.temperature??x.temperature;if(z)P.model=z;if(m!==void 0)P.temperature=m;if(x.mode)P.mode=x.mode;if(x.top_p!==void 0)P.top_p=x.top_p;let V0=Object.keys(P).length>0?v(P,U.content):U.content;G(O,V0),H.push(O)}}if(K.includes("skills")){let B=U0(C,"skill");if(X)w(B),W.push(B);A(B);let V=Z.skills.filter((L)=>u(L,B0));for(let L of V){let U=C0(B,L.name);A(U);let O=C0(U,"SKILL.md");G(O,D(L)),H.push(O)}}if(K.includes("commands")){let B=U0(C,"command");if(X)w(B),W.push(B);A(B);let V=Z.commands.filter((L)=>k(L,B0));for(let L of V){let U=C0(B,`${L.name}.md`);G(U,L.content),H.push(U)}}if(K.includes("hooks")||K.includes("plugins")){let B=U0(C,"plugins");if(A(B),K.includes("hooks"))for(let V of Z.hooks){let L=o(V,B0);if(Object.keys(L).length>0){let U=C0(B,`agentpacks-${V.packName}.ts`),O=R1(V.packName,L);G(U,O,{type:"ts"}),H.push(U)}}if(K.includes("plugins"))for(let V of Z.plugins){let L=C0(B,`agentpacks-${V.packName}-${V.name}.${V.extension}`);G(L,V.content,{type:V.extension}),H.push(L)}}if(K.includes("mcp")||K.includes("models")){let B=U0(J,"opencode.json"),V={$schema:"https://opencode.ai/config.json"};if(K.includes("mcp")){if(Object.entries(Z.mcpServers).length>0)V.mcp=T1(Z.mcpServers)}if(K.includes("models")&&Z.models){let L=j(Z.models,$.modelProfile,B0);if(L.default)V.model=L.default;if(L.small)V.small_model=L.small;if(Object.keys(L.providers).length>0)V.provider=L.providers;let U=Object.entries(L.agents);if(U.length>0){let O={};for(let[P,x]of U){let b={model:x.model};if(x.temperature!==void 0)b.temperature=x.temperature;if(x.top_p!==void 0)b.top_p=x.top_p;O[P]=b}V.agent=O}}if(Object.keys(V).length>1)S(B,V,{header:!1}),H.push(B)}if(K.includes("rules")){let B=Z.rules.filter((L)=>y(L,B0)),V=_0(B);if(V.length>0){let L=U0(C,"memories");if(X)w(L),W.push(L);A(L);for(let U of V){let O=C0(L,`${U.name}.md`);G(O,U.content),H.push(O)}}}return this.createResult(H,W,_)}}function T1($){let Q={};for(let[Y,Z]of Object.entries($))if(Z.url)Q[Y]={type:"remote",url:Z.url,enabled:!0,...Z.headers&&Object.keys(Z.headers).length>0?{headers:Z.headers}:{}};else if(Z.command){let q=Z.args?[Z.command,...Z.args]:[Z.command];Q[Y]={type:"local",command:q,enabled:!0,...Z.env&&Object.keys(Z.env).length>0?{environment:Z.env}:{}}}return Q}function R1($,Q){let Y=R2($),Z=S1(Q),q=Object.entries(Z).map(([X,J])=>{let K=J.map((H)=>{return` ${H.matcher?`if (!/(?:${H.matcher})/.test(String(input?.tool ?? ""))) return;
54
+ `:""}await $\`${H.command}\`;`}).join(`
55
+ `);return` "${X}": async (input, output) => {
56
+ ${K}
57
+ },`}).join(`
58
+ `);return`import type { Plugin } from "@opencode-ai/plugin";
3363
59
 
3364
- // src/targets/opencode.ts
3365
- import { join as join22, resolve as resolve20 } from "path";
3366
- var TARGET_ID7 = "opencode";
3367
-
3368
- class OpenCodeTarget extends BaseTarget {
3369
- id = TARGET_ID7;
3370
- name = "OpenCode";
3371
- supportedFeatures = [
3372
- "rules",
3373
- "commands",
3374
- "agents",
3375
- "skills",
3376
- "hooks",
3377
- "plugins",
3378
- "mcp",
3379
- "ignore",
3380
- "models"
3381
- ];
3382
- generate(options) {
3383
- const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
3384
- const root = resolve20(projectRoot, baseDir);
3385
- const effective = this.getEffectiveFeatures(enabledFeatures);
3386
- const filesWritten = [];
3387
- const filesDeleted = [];
3388
- const warnings = [];
3389
- const opencodeDir = resolve20(root, ".opencode");
3390
- if (effective.includes("agents")) {
3391
- const agentDir = resolve20(opencodeDir, "agent");
3392
- if (deleteExisting) {
3393
- removeIfExists(agentDir);
3394
- filesDeleted.push(agentDir);
3395
- }
3396
- ensureDir(agentDir);
3397
- const resolvedModels = features.models ? resolveModels(features.models, options.modelProfile, TARGET_ID7) : null;
3398
- const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID7));
3399
- for (const agent of agents) {
3400
- const filepath = join22(agentDir, `${agent.name}.md`);
3401
- const fm = {};
3402
- const oc = agent.meta.opencode ?? {};
3403
- const modelsAgent = resolvedModels?.agents[agent.name];
3404
- const agentModel = modelsAgent?.model ?? oc.model;
3405
- const agentTemp = modelsAgent?.temperature ?? oc.temperature;
3406
- if (agentModel)
3407
- fm.model = agentModel;
3408
- if (agentTemp !== undefined)
3409
- fm.temperature = agentTemp;
3410
- if (oc.mode)
3411
- fm.mode = oc.mode;
3412
- if (oc.top_p !== undefined)
3413
- fm.top_p = oc.top_p;
3414
- const content = Object.keys(fm).length > 0 ? serializeFrontmatter(fm, agent.content) : agent.content;
3415
- writeGeneratedFile(filepath, content);
3416
- filesWritten.push(filepath);
3417
- }
3418
- }
3419
- if (effective.includes("skills")) {
3420
- const skillDir = resolve20(opencodeDir, "skill");
3421
- if (deleteExisting) {
3422
- removeIfExists(skillDir);
3423
- filesDeleted.push(skillDir);
3424
- }
3425
- ensureDir(skillDir);
3426
- const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID7));
3427
- for (const skill of skills) {
3428
- const skillSubDir = join22(skillDir, skill.name);
3429
- ensureDir(skillSubDir);
3430
- const filepath = join22(skillSubDir, "SKILL.md");
3431
- writeGeneratedFile(filepath, serializeSkill(skill));
3432
- filesWritten.push(filepath);
3433
- }
3434
- }
3435
- if (effective.includes("commands")) {
3436
- const cmdDir = resolve20(opencodeDir, "command");
3437
- if (deleteExisting) {
3438
- removeIfExists(cmdDir);
3439
- filesDeleted.push(cmdDir);
3440
- }
3441
- ensureDir(cmdDir);
3442
- const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID7));
3443
- for (const cmd of commands) {
3444
- const filepath = join22(cmdDir, `${cmd.name}.md`);
3445
- writeGeneratedFile(filepath, cmd.content);
3446
- filesWritten.push(filepath);
3447
- }
3448
- }
3449
- if (effective.includes("hooks") || effective.includes("plugins")) {
3450
- const pluginsDir = resolve20(opencodeDir, "plugins");
3451
- ensureDir(pluginsDir);
3452
- if (effective.includes("hooks")) {
3453
- for (const hookSet of features.hooks) {
3454
- const events = resolveHooksForTarget(hookSet, TARGET_ID7);
3455
- if (Object.keys(events).length > 0) {
3456
- const filepath = join22(pluginsDir, `agentpacks-${hookSet.packName}.ts`);
3457
- const content = generateOpenCodeHookPlugin(hookSet.packName, events);
3458
- writeGeneratedFile(filepath, content, { type: "ts" });
3459
- filesWritten.push(filepath);
3460
- }
3461
- }
3462
- }
3463
- if (effective.includes("plugins")) {
3464
- for (const plugin of features.plugins) {
3465
- const filepath = join22(pluginsDir, `agentpacks-${plugin.packName}-${plugin.name}.${plugin.extension}`);
3466
- writeGeneratedFile(filepath, plugin.content, {
3467
- type: plugin.extension
3468
- });
3469
- filesWritten.push(filepath);
3470
- }
3471
- }
3472
- }
3473
- if (effective.includes("mcp") || effective.includes("models")) {
3474
- const filepath = resolve20(root, "opencode.json");
3475
- const opencodeConfig = {
3476
- $schema: "https://opencode.ai/config.json"
3477
- };
3478
- if (effective.includes("mcp")) {
3479
- const mcpEntries = Object.entries(features.mcpServers);
3480
- if (mcpEntries.length > 0) {
3481
- opencodeConfig.mcp = buildOpenCodeMcpServers(features.mcpServers);
3482
- }
3483
- }
3484
- if (effective.includes("models") && features.models) {
3485
- const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID7);
3486
- if (resolved.default)
3487
- opencodeConfig.model = resolved.default;
3488
- if (resolved.small)
3489
- opencodeConfig.small_model = resolved.small;
3490
- if (Object.keys(resolved.providers).length > 0) {
3491
- opencodeConfig.provider = resolved.providers;
3492
- }
3493
- const agentEntries = Object.entries(resolved.agents);
3494
- if (agentEntries.length > 0) {
3495
- const agentConfig = {};
3496
- for (const [name, assignment] of agentEntries) {
3497
- const config = { model: assignment.model };
3498
- if (assignment.temperature !== undefined) {
3499
- config.temperature = assignment.temperature;
3500
- }
3501
- if (assignment.top_p !== undefined) {
3502
- config.top_p = assignment.top_p;
3503
- }
3504
- agentConfig[name] = config;
3505
- }
3506
- opencodeConfig.agent = agentConfig;
3507
- }
3508
- }
3509
- if (Object.keys(opencodeConfig).length > 1) {
3510
- writeGeneratedJson(filepath, opencodeConfig, { header: false });
3511
- filesWritten.push(filepath);
3512
- }
3513
- }
3514
- if (effective.includes("rules")) {
3515
- const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID7));
3516
- const detailRules = getDetailRules(rules);
3517
- if (detailRules.length > 0) {
3518
- const memoriesDir = resolve20(opencodeDir, "memories");
3519
- if (deleteExisting) {
3520
- removeIfExists(memoriesDir);
3521
- filesDeleted.push(memoriesDir);
3522
- }
3523
- ensureDir(memoriesDir);
3524
- for (const rule of detailRules) {
3525
- const filepath = join22(memoriesDir, `${rule.name}.md`);
3526
- writeGeneratedFile(filepath, rule.content);
3527
- filesWritten.push(filepath);
3528
- }
3529
- }
3530
- }
3531
- return this.createResult(filesWritten, filesDeleted, warnings);
3532
- }
3533
- }
3534
- function buildOpenCodeMcpServers(servers) {
3535
- const mcp = {};
3536
- for (const [name, entry] of Object.entries(servers)) {
3537
- if (entry.url) {
3538
- mcp[name] = {
3539
- type: "remote",
3540
- url: entry.url,
3541
- enabled: true,
3542
- ...entry.headers && Object.keys(entry.headers).length > 0 ? { headers: entry.headers } : {}
3543
- };
3544
- } else if (entry.command) {
3545
- const cmd = entry.args ? [entry.command, ...entry.args] : [entry.command];
3546
- mcp[name] = {
3547
- type: "local",
3548
- command: cmd,
3549
- enabled: true,
3550
- ...entry.env && Object.keys(entry.env).length > 0 ? { environment: entry.env } : {}
3551
- };
3552
- }
3553
- }
3554
- return mcp;
3555
- }
3556
- function generateOpenCodeHookPlugin(packName, events) {
3557
- const identifier = packNameToIdentifier(packName);
3558
- const hookMap = mapHookEvents(events);
3559
- const hookEntries = Object.entries(hookMap).map(([event, handlers]) => {
3560
- const body = handlers.map((h) => {
3561
- const matcherGuard = h.matcher ? `if (!/(?:${h.matcher})/.test(String(input?.tool ?? ""))) return;
3562
- ` : "";
3563
- return ` ${matcherGuard}await $\`${h.command}\`;`;
3564
- }).join(`
3565
- `);
3566
- return ` "${event}": async (input, output) => {
3567
- ${body}
3568
- },`;
3569
- }).join(`
3570
- `);
3571
- return `import type { Plugin } from "@opencode-ai/plugin";
3572
-
3573
- export const ${identifier}Plugin: Plugin = async ({ project, client, $, directory, worktree }) => {
60
+ export const ${Y}Plugin: Plugin = async ({ project, client, $, directory, worktree }) => {
3574
61
  return {
3575
- ${hookEntries}
62
+ ${q}
3576
63
  };
3577
64
  };
3578
- `;
3579
- }
3580
- function mapHookEvents(events) {
3581
- const mapped = {};
3582
- const eventMapping = {
3583
- sessionStart: "session.created",
3584
- postToolUse: "tool.execute.after",
3585
- preToolUse: "tool.execute.before",
3586
- stop: "session.idle",
3587
- afterFileEdit: "file.edited",
3588
- afterShellExecution: "command.executed"
3589
- };
3590
- for (const [event, handlers] of Object.entries(events)) {
3591
- const opencodeEvent = eventMapping[event] ?? event;
3592
- if (!mapped[opencodeEvent]) {
3593
- mapped[opencodeEvent] = [];
3594
- }
3595
- mapped[opencodeEvent].push(...handlers.filter((h) => h.command));
3596
- }
3597
- return mapped;
3598
- }
3599
-
3600
- // src/targets/registry.ts
3601
- var TARGETS = [
3602
- new OpenCodeTarget,
3603
- new CursorTarget,
3604
- new ClaudeCodeTarget,
3605
- new CodexCliTarget,
3606
- new MistralVibeTarget,
3607
- new GeminiCliTarget,
3608
- new CopilotTarget,
3609
- new AgentsMdTarget,
3610
- ClineTarget,
3611
- KiloTarget,
3612
- RooTarget,
3613
- QwenCodeTarget,
3614
- KiroTarget,
3615
- FactoryDroidTarget,
3616
- AntiGravityTarget,
3617
- JunieTarget,
3618
- AugmentCodeTarget,
3619
- WindsurfTarget,
3620
- WarpTarget,
3621
- ReplitTarget,
3622
- ZedTarget
3623
- ];
3624
- var targetMap = new Map(TARGETS.map((t) => [t.id, t]));
3625
- function getTarget(id) {
3626
- return targetMap.get(id);
3627
- }
3628
- function getAllTargets() {
3629
- return [...TARGETS];
3630
- }
3631
- function getTargets(ids) {
3632
- return ids.map((id) => targetMap.get(id)).filter((t) => t !== undefined);
3633
- }
3634
- function listTargetIds() {
3635
- return TARGETS.map((t) => t.id);
3636
- }
3637
- export {
3638
- saveLockfile,
3639
- resolveTargets,
3640
- resolveModels,
3641
- resolveLocalPack,
3642
- resolveFeatures,
3643
- resolveDependencies,
3644
- resolveAgentModel,
3645
- registrySourceKey,
3646
- parseRegistrySourceRef,
3647
- parseNpmSourceRef,
3648
- parseGitSourceRef,
3649
- loadWorkspaceConfig,
3650
- loadPackManifest,
3651
- loadLockfile,
3652
- listTargetIds,
3653
- isRegistryPackRef,
3654
- isNpmPackRef,
3655
- isLocalPackRef,
3656
- isGitPackRef,
3657
- installNpmSource,
3658
- installGitSource,
3659
- importFromRulesync,
3660
- importFromOpenCode,
3661
- importFromCursor,
3662
- importFromClaudeCode,
3663
- getTargets,
3664
- getTarget,
3665
- getAllTargets,
3666
- exportCursorPlugin,
3667
- computeIntegrity,
3668
- WorkspaceConfigSchema,
3669
- TARGET_IDS,
3670
- REPO_MODES,
3671
- PackManifestSchema,
3672
- PackLoader,
3673
- FeatureMerger,
3674
- FEATURE_IDS
3675
- };
65
+ `}function S1($){let Q={},Y={sessionStart:"session.created",postToolUse:"tool.execute.after",preToolUse:"tool.execute.before",stop:"session.idle",afterFileEdit:"file.edited",afterShellExecution:"command.executed"};for(let[Z,q]of Object.entries($)){let X=Y[Z]??Z;if(!Q[X])Q[X]=[];Q[X].push(...q.filter((J)=>J.command))}return Q}var z$=[new G$,new A$,new H$,new C$,new M$,new x$,new _$,C2,_2,A2,N2,x2,b2,M2,G2,z2,w2,F2,I2,E2],S2=new Map(z$.map(($)=>[$.id,$]));function y1($){return S2.get($)}function j1(){return[...z$]}function h1($){return $.map((Q)=>S2.get(Q)).filter((Q)=>Q!==void 0)}function v1(){return z$.map(($)=>$.id)}export{K9 as saveLockfile,g2 as resolveTargets,j as resolveModels,K1 as resolveLocalPack,k2 as resolveFeatures,D2 as resolveDependencies,D9 as resolveAgentModel,b1 as registrySourceKey,N1 as parseRegistrySourceRef,U$ as parseNpmSourceRef,$$ as parseGitSourceRef,f0 as loadWorkspaceConfig,p0 as loadPackManifest,V9 as loadLockfile,v1 as listTargetIds,x1 as isRegistryPackRef,H1 as isNpmPackRef,J1 as isLocalPackRef,X1 as isGitPackRef,_1 as installNpmSource,U1 as installGitSource,Z1 as importFromRulesync,Q1 as importFromOpenCode,r9 as importFromCursor,i9 as importFromClaudeCode,h1 as getTargets,y1 as getTarget,j1 as getAllTargets,c9 as exportCursorPlugin,c0 as computeIntegrity,u0 as WorkspaceConfigSchema,R$ as TARGET_IDS,S$ as REPO_MODES,D0 as PackManifestSchema,o0 as PackLoader,f$ as FeatureMerger,K0 as FEATURE_IDS};