agentpacks 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +168 -8
- package/dist/api.d.ts +2 -0
- package/dist/api.js +929 -409
- package/dist/cli/export-cmd.js +281 -149
- package/dist/cli/generate.js +740 -247
- package/dist/cli/import-cmd.js +57 -85
- package/dist/cli/info.d.ts +4 -0
- package/dist/cli/info.js +232 -0
- package/dist/cli/init.js +8 -36
- package/dist/cli/install.js +414 -129
- package/dist/cli/login.d.ts +9 -0
- package/dist/cli/login.js +202 -0
- package/dist/cli/models-explain.d.ts +16 -0
- package/dist/cli/models-explain.js +1205 -0
- package/dist/cli/pack/create.js +4 -32
- package/dist/cli/pack/enable.js +1 -29
- package/dist/cli/pack/list.js +266 -134
- package/dist/cli/pack/validate.js +274 -127
- package/dist/cli/publish.d.ts +8 -0
- package/dist/cli/publish.js +672 -0
- package/dist/cli/search.d.ts +12 -0
- package/dist/cli/search.js +210 -0
- package/dist/core/config.d.ts +2 -1
- package/dist/core/config.js +74 -117
- package/dist/core/dependency-resolver.js +4 -28
- package/dist/core/feature-merger.d.ts +7 -0
- package/dist/core/feature-merger.js +289 -29
- package/dist/core/index.js +283 -140
- package/dist/core/lockfile.js +0 -28
- package/dist/core/metarepo.js +74 -116
- package/dist/core/pack-loader.d.ts +2 -0
- package/dist/core/pack-loader.js +266 -133
- package/dist/core/profile-resolver.d.ts +75 -0
- package/dist/core/profile-resolver.js +111 -0
- package/dist/exporters/cursor-plugin.js +4 -32
- package/dist/exporters/index.js +4 -32
- package/dist/features/agents.d.ts +5 -0
- package/dist/features/agents.js +2 -30
- package/dist/features/commands.js +2 -30
- package/dist/features/hooks.js +2 -30
- package/dist/features/ignore.js +0 -28
- package/dist/features/index.d.ts +1 -0
- package/dist/features/index.js +176 -31
- package/dist/features/mcp.js +2 -30
- package/dist/features/models.d.ts +167 -0
- package/dist/features/models.js +293 -0
- package/dist/features/plugins.js +2 -30
- package/dist/features/rules.js +2 -30
- package/dist/features/skills.js +2 -30
- package/dist/importers/claude-code.js +10 -38
- package/dist/importers/cursor.js +15 -43
- package/dist/importers/opencode.js +16 -44
- package/dist/importers/rulesync.js +22 -50
- package/dist/index.js +1710 -538
- package/dist/node/api.js +929 -409
- package/dist/node/cli/export-cmd.js +281 -149
- package/dist/node/cli/generate.js +740 -247
- package/dist/node/cli/import-cmd.js +57 -85
- package/dist/node/cli/info.js +232 -0
- package/dist/node/cli/init.js +8 -36
- package/dist/node/cli/install.js +414 -129
- package/dist/node/cli/login.js +202 -0
- package/dist/node/cli/models-explain.js +1205 -0
- package/dist/node/cli/pack/create.js +4 -32
- package/dist/node/cli/pack/enable.js +1 -29
- package/dist/node/cli/pack/list.js +266 -134
- package/dist/node/cli/pack/validate.js +274 -127
- package/dist/node/cli/publish.js +672 -0
- package/dist/node/cli/search.js +210 -0
- package/dist/node/core/config.js +74 -117
- package/dist/node/core/dependency-resolver.js +4 -28
- package/dist/node/core/feature-merger.js +289 -29
- package/dist/node/core/index.js +283 -140
- package/dist/node/core/lockfile.js +0 -28
- package/dist/node/core/metarepo.js +74 -116
- package/dist/node/core/pack-loader.js +266 -133
- package/dist/node/core/profile-resolver.js +111 -0
- package/dist/node/exporters/cursor-plugin.js +4 -32
- package/dist/node/exporters/index.js +4 -32
- package/dist/node/features/agents.js +2 -30
- package/dist/node/features/commands.js +2 -30
- package/dist/node/features/hooks.js +2 -30
- package/dist/node/features/ignore.js +0 -28
- package/dist/node/features/index.js +176 -31
- package/dist/node/features/mcp.js +2 -30
- package/dist/node/features/models.js +293 -0
- package/dist/node/features/plugins.js +2 -30
- package/dist/node/features/rules.js +2 -30
- package/dist/node/features/skills.js +2 -30
- package/dist/node/importers/claude-code.js +10 -38
- package/dist/node/importers/cursor.js +15 -43
- package/dist/node/importers/opencode.js +16 -44
- package/dist/node/importers/rulesync.js +22 -50
- package/dist/node/index.js +1710 -538
- package/dist/node/sources/git-ref.js +7 -30
- package/dist/node/sources/git.js +7 -30
- package/dist/node/sources/index.js +337 -39
- package/dist/node/sources/local.js +0 -28
- package/dist/node/sources/npm-ref.js +0 -28
- package/dist/node/sources/npm.js +10 -37
- package/dist/node/sources/registry-ref.js +37 -0
- package/dist/node/sources/registry.js +355 -0
- package/dist/node/targets/additional-targets.js +196 -37
- package/dist/node/targets/agents-md.js +5 -33
- package/dist/node/targets/base-target.js +0 -28
- package/dist/node/targets/claude-code.js +211 -41
- package/dist/node/targets/codex-cli.js +7 -35
- package/dist/node/targets/copilot.js +202 -41
- package/dist/node/targets/cursor.js +188 -40
- package/dist/node/targets/gemini-cli.js +10 -38
- package/dist/node/targets/generic-md-target.js +196 -37
- package/dist/node/targets/index.js +414 -106
- package/dist/node/targets/opencode.js +171 -51
- package/dist/node/targets/registry.js +414 -106
- package/dist/node/utils/credentials.js +38 -0
- package/dist/node/utils/diff.js +22 -34
- package/dist/node/utils/filesystem.js +2 -30
- package/dist/node/utils/frontmatter.js +0 -28
- package/dist/node/utils/global.js +3 -31
- package/dist/node/utils/markdown.js +0 -28
- package/dist/node/utils/model-allowlist.js +110 -0
- package/dist/node/utils/model-guidance.js +78 -0
- package/dist/node/utils/registry-client.js +142 -0
- package/dist/node/utils/tarball.js +49 -0
- package/dist/sources/git-ref.js +7 -30
- package/dist/sources/git.d.ts +2 -2
- package/dist/sources/git.js +7 -30
- package/dist/sources/index.d.ts +2 -0
- package/dist/sources/index.js +337 -39
- package/dist/sources/local.js +0 -28
- package/dist/sources/npm-ref.js +0 -28
- package/dist/sources/npm.js +10 -37
- package/dist/sources/registry-ref.d.ts +30 -0
- package/dist/sources/registry-ref.js +37 -0
- package/dist/sources/registry.d.ts +18 -0
- package/dist/sources/registry.js +355 -0
- package/dist/targets/additional-targets.js +196 -37
- package/dist/targets/agents-md.js +5 -33
- package/dist/targets/base-target.d.ts +2 -0
- package/dist/targets/base-target.js +0 -28
- package/dist/targets/claude-code.js +211 -41
- package/dist/targets/codex-cli.js +7 -35
- package/dist/targets/copilot.js +202 -41
- package/dist/targets/cursor.js +188 -40
- package/dist/targets/gemini-cli.js +10 -38
- package/dist/targets/generic-md-target.js +196 -37
- package/dist/targets/index.js +414 -106
- package/dist/targets/opencode.js +171 -51
- package/dist/targets/registry.js +414 -106
- package/dist/utils/credentials.d.ts +19 -0
- package/dist/utils/credentials.js +38 -0
- package/dist/utils/diff.js +22 -34
- package/dist/utils/filesystem.js +2 -30
- package/dist/utils/frontmatter.js +0 -28
- package/dist/utils/global.js +3 -31
- package/dist/utils/markdown.js +0 -28
- package/dist/utils/model-allowlist.d.ts +39 -0
- package/dist/utils/model-allowlist.js +110 -0
- package/dist/utils/model-guidance.d.ts +6 -0
- package/dist/utils/model-guidance.js +78 -0
- package/dist/utils/registry-client.d.ts +141 -0
- package/dist/utils/registry-client.js +142 -0
- package/dist/utils/tarball.d.ts +13 -0
- package/dist/utils/tarball.js +49 -0
- package/package.json +171 -5
- package/templates/pack/models.json +38 -0
|
@@ -1,32 +1,4 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
7
|
-
var __toCommonJS = (from) => {
|
|
8
|
-
var entry = __moduleCache.get(from), desc;
|
|
9
|
-
if (entry)
|
|
10
|
-
return entry;
|
|
11
|
-
entry = __defProp({}, "__esModule", { value: true });
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function")
|
|
13
|
-
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
14
|
-
get: () => from[key],
|
|
15
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
-
}));
|
|
17
|
-
__moduleCache.set(from, entry);
|
|
18
|
-
return entry;
|
|
19
|
-
};
|
|
20
|
-
var __export = (target, all) => {
|
|
21
|
-
for (var name in all)
|
|
22
|
-
__defProp(target, name, {
|
|
23
|
-
get: all[name],
|
|
24
|
-
enumerable: true,
|
|
25
|
-
configurable: true,
|
|
26
|
-
set: (newValue) => all[name] = () => newValue
|
|
27
|
-
});
|
|
28
|
-
};
|
|
29
|
-
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
30
2
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
31
3
|
|
|
32
4
|
// src/utils/filesystem.ts
|
|
@@ -36,10 +8,10 @@ import {
|
|
|
36
8
|
readFileSync,
|
|
37
9
|
writeFileSync,
|
|
38
10
|
readdirSync,
|
|
11
|
+
rmSync,
|
|
39
12
|
statSync
|
|
40
13
|
} from "fs";
|
|
41
14
|
import { dirname, relative, join } from "path";
|
|
42
|
-
import { removeSync } from "fs-extra";
|
|
43
15
|
var GENERATED_HEADER_MD = "<!-- Generated by agentpacks. DO NOT EDIT. -->";
|
|
44
16
|
var GENERATED_HEADER_JSON = "// Generated by agentpacks. DO NOT EDIT.";
|
|
45
17
|
var GENERATED_HEADER_JS = "// Generated by agentpacks. DO NOT EDIT.";
|
|
@@ -80,7 +52,7 @@ function ensureDir(dirPath) {
|
|
|
80
52
|
}
|
|
81
53
|
function removeIfExists(targetPath) {
|
|
82
54
|
if (existsSync(targetPath)) {
|
|
83
|
-
|
|
55
|
+
rmSync(targetPath, { recursive: true, force: true });
|
|
84
56
|
}
|
|
85
57
|
}
|
|
86
58
|
function listFiles(dirPath, options = {}) {
|
|
@@ -279,6 +251,110 @@ function skillMatchesTarget(skill, targetId) {
|
|
|
279
251
|
return Array.isArray(targets) && targets.includes(targetId);
|
|
280
252
|
}
|
|
281
253
|
|
|
254
|
+
// src/core/profile-resolver.ts
|
|
255
|
+
function resolveModels(merged, modelProfile, targetId) {
|
|
256
|
+
let defaultModel = merged.default;
|
|
257
|
+
let smallModel = merged.small;
|
|
258
|
+
let agents = { ...merged.agents };
|
|
259
|
+
if (modelProfile && merged.profiles?.[modelProfile]) {
|
|
260
|
+
const resolvedProfile = resolveProfileInheritance(modelProfile, merged.profiles);
|
|
261
|
+
if (resolvedProfile.default)
|
|
262
|
+
defaultModel = resolvedProfile.default;
|
|
263
|
+
if (resolvedProfile.small)
|
|
264
|
+
smallModel = resolvedProfile.small;
|
|
265
|
+
if (resolvedProfile.agents) {
|
|
266
|
+
agents = { ...agents, ...resolvedProfile.agents };
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (targetId) {
|
|
270
|
+
const targetOverride = merged.overrides?.[targetId];
|
|
271
|
+
if (targetOverride) {
|
|
272
|
+
if (targetOverride.default)
|
|
273
|
+
defaultModel = targetOverride.default;
|
|
274
|
+
if (targetOverride.small)
|
|
275
|
+
smallModel = targetOverride.small;
|
|
276
|
+
if (targetOverride.agents) {
|
|
277
|
+
agents = { ...agents, ...targetOverride.agents };
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
const providers = {};
|
|
282
|
+
if (merged.providers) {
|
|
283
|
+
for (const [name, config] of Object.entries(merged.providers)) {
|
|
284
|
+
providers[name] = {
|
|
285
|
+
...config.options ? { options: config.options } : {},
|
|
286
|
+
...config.models ? { models: config.models } : {}
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
const profileNames = Object.keys(merged.profiles ?? {});
|
|
291
|
+
const profiles = {};
|
|
292
|
+
if (merged.profiles) {
|
|
293
|
+
for (const [name, profile] of Object.entries(merged.profiles)) {
|
|
294
|
+
profiles[name] = {
|
|
295
|
+
description: profile.description,
|
|
296
|
+
default: profile.default,
|
|
297
|
+
small: profile.small
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
default: defaultModel,
|
|
303
|
+
small: smallModel,
|
|
304
|
+
agents,
|
|
305
|
+
providers,
|
|
306
|
+
routing: merged.routing ?? [],
|
|
307
|
+
profileNames,
|
|
308
|
+
activeProfile: modelProfile,
|
|
309
|
+
profiles
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function resolveAgentModel(resolved, agentName, frontmatterModel) {
|
|
313
|
+
const fromModels = resolved.agents[agentName];
|
|
314
|
+
if (fromModels) {
|
|
315
|
+
return {
|
|
316
|
+
model: fromModels.model,
|
|
317
|
+
temperature: fromModels.temperature,
|
|
318
|
+
top_p: fromModels.top_p
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
if (frontmatterModel) {
|
|
322
|
+
return { model: frontmatterModel };
|
|
323
|
+
}
|
|
324
|
+
return {};
|
|
325
|
+
}
|
|
326
|
+
function resolveProfileInheritance(profileName, profiles) {
|
|
327
|
+
const visited = new Set;
|
|
328
|
+
return resolveProfileChain(profileName, profiles, visited, 0);
|
|
329
|
+
}
|
|
330
|
+
var MAX_INHERITANCE_DEPTH = 10;
|
|
331
|
+
function resolveProfileChain(name, profiles, visited, depth) {
|
|
332
|
+
if (depth > MAX_INHERITANCE_DEPTH) {
|
|
333
|
+
throw new Error(`Profile inheritance too deep (max ${MAX_INHERITANCE_DEPTH}): ${name}`);
|
|
334
|
+
}
|
|
335
|
+
if (visited.has(name)) {
|
|
336
|
+
throw new Error(`Circular profile inheritance detected: ${[...visited, name].join(" → ")}`);
|
|
337
|
+
}
|
|
338
|
+
const profile = profiles[name];
|
|
339
|
+
if (!profile) {
|
|
340
|
+
throw new Error(`Profile "${name}" not found`);
|
|
341
|
+
}
|
|
342
|
+
visited.add(name);
|
|
343
|
+
if (!profile.extends) {
|
|
344
|
+
return { ...profile };
|
|
345
|
+
}
|
|
346
|
+
const parent = resolveProfileChain(profile.extends, profiles, visited, depth + 1);
|
|
347
|
+
return {
|
|
348
|
+
description: profile.description ?? parent.description,
|
|
349
|
+
default: profile.default ?? parent.default,
|
|
350
|
+
small: profile.small ?? parent.small,
|
|
351
|
+
agents: {
|
|
352
|
+
...parent.agents,
|
|
353
|
+
...profile.agents
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
|
|
282
358
|
// src/targets/base-target.ts
|
|
283
359
|
class BaseTarget {
|
|
284
360
|
supportsFeature(feature) {
|
|
@@ -297,8 +373,81 @@ class BaseTarget {
|
|
|
297
373
|
}
|
|
298
374
|
}
|
|
299
375
|
|
|
376
|
+
// src/utils/model-guidance.ts
|
|
377
|
+
function generateModelGuidanceMarkdown(resolved) {
|
|
378
|
+
if (!resolved.default && !resolved.small && Object.keys(resolved.agents).length === 0 && Object.keys(resolved.profiles).length === 0) {
|
|
379
|
+
return null;
|
|
380
|
+
}
|
|
381
|
+
const lines = [];
|
|
382
|
+
lines.push("# Model Configuration");
|
|
383
|
+
lines.push("");
|
|
384
|
+
lines.push("Use the following model preferences when working in this project.");
|
|
385
|
+
lines.push("");
|
|
386
|
+
if (resolved.default || resolved.small) {
|
|
387
|
+
lines.push("## Default Models");
|
|
388
|
+
lines.push("");
|
|
389
|
+
if (resolved.default) {
|
|
390
|
+
lines.push(`- **Primary model**: ${resolved.default}`);
|
|
391
|
+
}
|
|
392
|
+
if (resolved.small) {
|
|
393
|
+
lines.push(`- **Lightweight tasks** (titles, summaries): ${resolved.small}`);
|
|
394
|
+
}
|
|
395
|
+
lines.push("");
|
|
396
|
+
}
|
|
397
|
+
const agentEntries = Object.entries(resolved.agents);
|
|
398
|
+
if (agentEntries.length > 0) {
|
|
399
|
+
lines.push("## Agent Model Assignments");
|
|
400
|
+
lines.push("");
|
|
401
|
+
lines.push("| Agent | Model | Temperature |");
|
|
402
|
+
lines.push("| --- | --- | --- |");
|
|
403
|
+
for (const [name, assignment] of agentEntries) {
|
|
404
|
+
const temp = assignment.temperature !== undefined ? String(assignment.temperature) : "—";
|
|
405
|
+
lines.push(`| ${name} | ${assignment.model} | ${temp} |`);
|
|
406
|
+
}
|
|
407
|
+
lines.push("");
|
|
408
|
+
}
|
|
409
|
+
if (Object.keys(resolved.profiles).length > 0) {
|
|
410
|
+
lines.push("## Available Profiles");
|
|
411
|
+
lines.push("");
|
|
412
|
+
lines.push("| Profile | Description | Default Model |");
|
|
413
|
+
lines.push("| --- | --- | --- |");
|
|
414
|
+
for (const [name, profile] of Object.entries(resolved.profiles)) {
|
|
415
|
+
lines.push(`| ${name} | ${profile.description ?? "—"} | ${profile.default ?? "—"} |`);
|
|
416
|
+
}
|
|
417
|
+
lines.push("");
|
|
418
|
+
}
|
|
419
|
+
if (resolved.activeProfile) {
|
|
420
|
+
lines.push(`**Active profile**: \`${resolved.activeProfile}\``);
|
|
421
|
+
lines.push("");
|
|
422
|
+
}
|
|
423
|
+
if (resolved.routing.length > 0) {
|
|
424
|
+
lines.push("## Task-Aware Routing");
|
|
425
|
+
lines.push("");
|
|
426
|
+
lines.push("Select the appropriate profile based on the task context:");
|
|
427
|
+
lines.push("");
|
|
428
|
+
lines.push("| Condition | Profile | Description |");
|
|
429
|
+
lines.push("| --- | --- | --- |");
|
|
430
|
+
for (const rule of resolved.routing) {
|
|
431
|
+
const conditions = Object.entries(rule.when).map(([k, v]) => `${k}=${v}`).join(", ");
|
|
432
|
+
const desc = rule.description ?? "—";
|
|
433
|
+
lines.push(`| ${conditions} | ${rule.use} | ${desc} |`);
|
|
434
|
+
}
|
|
435
|
+
lines.push("");
|
|
436
|
+
lines.push("### Condition Reference");
|
|
437
|
+
lines.push("");
|
|
438
|
+
lines.push("- **complexity**: low | medium | high | critical");
|
|
439
|
+
lines.push("- **urgency**: low | normal | high");
|
|
440
|
+
lines.push("- **budget**: minimal | standard | premium");
|
|
441
|
+
lines.push("- **contextWindowNeed**: small | medium | large | max");
|
|
442
|
+
lines.push("- **toolUseIntensity**: none | light | heavy");
|
|
443
|
+
lines.push("");
|
|
444
|
+
}
|
|
445
|
+
return lines.join(`
|
|
446
|
+
`);
|
|
447
|
+
}
|
|
448
|
+
|
|
300
449
|
// src/targets/copilot.ts
|
|
301
|
-
import { resolve
|
|
450
|
+
import { resolve, join as join3 } from "path";
|
|
302
451
|
var TARGET_ID = "copilot";
|
|
303
452
|
|
|
304
453
|
class CopilotTarget extends BaseTarget {
|
|
@@ -310,16 +459,17 @@ class CopilotTarget extends BaseTarget {
|
|
|
310
459
|
"agents",
|
|
311
460
|
"skills",
|
|
312
461
|
"mcp",
|
|
313
|
-
"ignore"
|
|
462
|
+
"ignore",
|
|
463
|
+
"models"
|
|
314
464
|
];
|
|
315
465
|
generate(options) {
|
|
316
466
|
const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
|
|
317
|
-
const root =
|
|
467
|
+
const root = resolve(projectRoot, baseDir);
|
|
318
468
|
const effective = this.getEffectiveFeatures(enabledFeatures);
|
|
319
469
|
const filesWritten = [];
|
|
320
470
|
const filesDeleted = [];
|
|
321
471
|
const warnings = [];
|
|
322
|
-
const githubDir =
|
|
472
|
+
const githubDir = resolve(root, ".github");
|
|
323
473
|
if (effective.includes("rules")) {
|
|
324
474
|
const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID));
|
|
325
475
|
if (rules.length > 0) {
|
|
@@ -328,15 +478,15 @@ class CopilotTarget extends BaseTarget {
|
|
|
328
478
|
---
|
|
329
479
|
|
|
330
480
|
`);
|
|
331
|
-
const filepath =
|
|
481
|
+
const filepath = resolve(githubDir, "copilot-instructions.md");
|
|
332
482
|
ensureDir(githubDir);
|
|
333
483
|
writeGeneratedFile(filepath, combinedContent);
|
|
334
484
|
filesWritten.push(filepath);
|
|
335
485
|
}
|
|
336
486
|
}
|
|
337
487
|
if (effective.includes("agents")) {
|
|
338
|
-
const copilotDir =
|
|
339
|
-
const agentsDir =
|
|
488
|
+
const copilotDir = resolve(githubDir, "copilot");
|
|
489
|
+
const agentsDir = resolve(copilotDir, "agents");
|
|
340
490
|
if (deleteExisting) {
|
|
341
491
|
removeIfExists(agentsDir);
|
|
342
492
|
filesDeleted.push(agentsDir);
|
|
@@ -350,8 +500,8 @@ class CopilotTarget extends BaseTarget {
|
|
|
350
500
|
}
|
|
351
501
|
}
|
|
352
502
|
if (effective.includes("skills")) {
|
|
353
|
-
const copilotDir =
|
|
354
|
-
const skillsDir =
|
|
503
|
+
const copilotDir = resolve(githubDir, "copilot");
|
|
504
|
+
const skillsDir = resolve(copilotDir, "skills");
|
|
355
505
|
if (deleteExisting) {
|
|
356
506
|
removeIfExists(skillsDir);
|
|
357
507
|
filesDeleted.push(skillsDir);
|
|
@@ -367,8 +517,8 @@ class CopilotTarget extends BaseTarget {
|
|
|
367
517
|
}
|
|
368
518
|
}
|
|
369
519
|
if (effective.includes("commands")) {
|
|
370
|
-
const copilotDir =
|
|
371
|
-
const commandsDir =
|
|
520
|
+
const copilotDir = resolve(githubDir, "copilot");
|
|
521
|
+
const commandsDir = resolve(copilotDir, "commands");
|
|
372
522
|
if (deleteExisting) {
|
|
373
523
|
removeIfExists(commandsDir);
|
|
374
524
|
filesDeleted.push(commandsDir);
|
|
@@ -382,6 +532,17 @@ class CopilotTarget extends BaseTarget {
|
|
|
382
532
|
}
|
|
383
533
|
}
|
|
384
534
|
if (effective.includes("ignore")) {}
|
|
535
|
+
if (effective.includes("models") && features.models) {
|
|
536
|
+
const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID);
|
|
537
|
+
const guidance = generateModelGuidanceMarkdown(resolved);
|
|
538
|
+
if (guidance) {
|
|
539
|
+
const copilotDir = resolve(githubDir, "copilot");
|
|
540
|
+
ensureDir(copilotDir);
|
|
541
|
+
const filepath = join3(copilotDir, "model-config.md");
|
|
542
|
+
writeGeneratedFile(filepath, guidance);
|
|
543
|
+
filesWritten.push(filepath);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
385
546
|
return this.createResult(filesWritten, filesDeleted, warnings);
|
|
386
547
|
}
|
|
387
548
|
}
|
|
@@ -1,32 +1,4 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
7
|
-
var __toCommonJS = (from) => {
|
|
8
|
-
var entry = __moduleCache.get(from), desc;
|
|
9
|
-
if (entry)
|
|
10
|
-
return entry;
|
|
11
|
-
entry = __defProp({}, "__esModule", { value: true });
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function")
|
|
13
|
-
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
14
|
-
get: () => from[key],
|
|
15
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
-
}));
|
|
17
|
-
__moduleCache.set(from, entry);
|
|
18
|
-
return entry;
|
|
19
|
-
};
|
|
20
|
-
var __export = (target, all) => {
|
|
21
|
-
for (var name in all)
|
|
22
|
-
__defProp(target, name, {
|
|
23
|
-
get: all[name],
|
|
24
|
-
enumerable: true,
|
|
25
|
-
configurable: true,
|
|
26
|
-
set: (newValue) => all[name] = () => newValue
|
|
27
|
-
});
|
|
28
|
-
};
|
|
29
|
-
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
30
2
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
31
3
|
|
|
32
4
|
// src/utils/filesystem.ts
|
|
@@ -36,10 +8,10 @@ import {
|
|
|
36
8
|
readFileSync,
|
|
37
9
|
writeFileSync,
|
|
38
10
|
readdirSync,
|
|
11
|
+
rmSync,
|
|
39
12
|
statSync
|
|
40
13
|
} from "fs";
|
|
41
14
|
import { dirname, relative, join } from "path";
|
|
42
|
-
import { removeSync } from "fs-extra";
|
|
43
15
|
var GENERATED_HEADER_MD = "<!-- Generated by agentpacks. DO NOT EDIT. -->";
|
|
44
16
|
var GENERATED_HEADER_JSON = "// Generated by agentpacks. DO NOT EDIT.";
|
|
45
17
|
var GENERATED_HEADER_JS = "// Generated by agentpacks. DO NOT EDIT.";
|
|
@@ -80,7 +52,7 @@ function ensureDir(dirPath) {
|
|
|
80
52
|
}
|
|
81
53
|
function removeIfExists(targetPath) {
|
|
82
54
|
if (existsSync(targetPath)) {
|
|
83
|
-
|
|
55
|
+
rmSync(targetPath, { recursive: true, force: true });
|
|
84
56
|
}
|
|
85
57
|
}
|
|
86
58
|
function listFiles(dirPath, options = {}) {
|
|
@@ -279,6 +251,110 @@ function skillMatchesTarget(skill, targetId) {
|
|
|
279
251
|
return Array.isArray(targets) && targets.includes(targetId);
|
|
280
252
|
}
|
|
281
253
|
|
|
254
|
+
// src/core/profile-resolver.ts
|
|
255
|
+
function resolveModels(merged, modelProfile, targetId) {
|
|
256
|
+
let defaultModel = merged.default;
|
|
257
|
+
let smallModel = merged.small;
|
|
258
|
+
let agents = { ...merged.agents };
|
|
259
|
+
if (modelProfile && merged.profiles?.[modelProfile]) {
|
|
260
|
+
const resolvedProfile = resolveProfileInheritance(modelProfile, merged.profiles);
|
|
261
|
+
if (resolvedProfile.default)
|
|
262
|
+
defaultModel = resolvedProfile.default;
|
|
263
|
+
if (resolvedProfile.small)
|
|
264
|
+
smallModel = resolvedProfile.small;
|
|
265
|
+
if (resolvedProfile.agents) {
|
|
266
|
+
agents = { ...agents, ...resolvedProfile.agents };
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (targetId) {
|
|
270
|
+
const targetOverride = merged.overrides?.[targetId];
|
|
271
|
+
if (targetOverride) {
|
|
272
|
+
if (targetOverride.default)
|
|
273
|
+
defaultModel = targetOverride.default;
|
|
274
|
+
if (targetOverride.small)
|
|
275
|
+
smallModel = targetOverride.small;
|
|
276
|
+
if (targetOverride.agents) {
|
|
277
|
+
agents = { ...agents, ...targetOverride.agents };
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
const providers = {};
|
|
282
|
+
if (merged.providers) {
|
|
283
|
+
for (const [name, config] of Object.entries(merged.providers)) {
|
|
284
|
+
providers[name] = {
|
|
285
|
+
...config.options ? { options: config.options } : {},
|
|
286
|
+
...config.models ? { models: config.models } : {}
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
const profileNames = Object.keys(merged.profiles ?? {});
|
|
291
|
+
const profiles = {};
|
|
292
|
+
if (merged.profiles) {
|
|
293
|
+
for (const [name, profile] of Object.entries(merged.profiles)) {
|
|
294
|
+
profiles[name] = {
|
|
295
|
+
description: profile.description,
|
|
296
|
+
default: profile.default,
|
|
297
|
+
small: profile.small
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
default: defaultModel,
|
|
303
|
+
small: smallModel,
|
|
304
|
+
agents,
|
|
305
|
+
providers,
|
|
306
|
+
routing: merged.routing ?? [],
|
|
307
|
+
profileNames,
|
|
308
|
+
activeProfile: modelProfile,
|
|
309
|
+
profiles
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function resolveAgentModel(resolved, agentName, frontmatterModel) {
|
|
313
|
+
const fromModels = resolved.agents[agentName];
|
|
314
|
+
if (fromModels) {
|
|
315
|
+
return {
|
|
316
|
+
model: fromModels.model,
|
|
317
|
+
temperature: fromModels.temperature,
|
|
318
|
+
top_p: fromModels.top_p
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
if (frontmatterModel) {
|
|
322
|
+
return { model: frontmatterModel };
|
|
323
|
+
}
|
|
324
|
+
return {};
|
|
325
|
+
}
|
|
326
|
+
function resolveProfileInheritance(profileName, profiles) {
|
|
327
|
+
const visited = new Set;
|
|
328
|
+
return resolveProfileChain(profileName, profiles, visited, 0);
|
|
329
|
+
}
|
|
330
|
+
var MAX_INHERITANCE_DEPTH = 10;
|
|
331
|
+
function resolveProfileChain(name, profiles, visited, depth) {
|
|
332
|
+
if (depth > MAX_INHERITANCE_DEPTH) {
|
|
333
|
+
throw new Error(`Profile inheritance too deep (max ${MAX_INHERITANCE_DEPTH}): ${name}`);
|
|
334
|
+
}
|
|
335
|
+
if (visited.has(name)) {
|
|
336
|
+
throw new Error(`Circular profile inheritance detected: ${[...visited, name].join(" → ")}`);
|
|
337
|
+
}
|
|
338
|
+
const profile = profiles[name];
|
|
339
|
+
if (!profile) {
|
|
340
|
+
throw new Error(`Profile "${name}" not found`);
|
|
341
|
+
}
|
|
342
|
+
visited.add(name);
|
|
343
|
+
if (!profile.extends) {
|
|
344
|
+
return { ...profile };
|
|
345
|
+
}
|
|
346
|
+
const parent = resolveProfileChain(profile.extends, profiles, visited, depth + 1);
|
|
347
|
+
return {
|
|
348
|
+
description: profile.description ?? parent.description,
|
|
349
|
+
default: profile.default ?? parent.default,
|
|
350
|
+
small: profile.small ?? parent.small,
|
|
351
|
+
agents: {
|
|
352
|
+
...parent.agents,
|
|
353
|
+
...profile.agents
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
|
|
282
358
|
// src/targets/base-target.ts
|
|
283
359
|
class BaseTarget {
|
|
284
360
|
supportsFeature(feature) {
|
|
@@ -298,7 +374,7 @@ class BaseTarget {
|
|
|
298
374
|
}
|
|
299
375
|
|
|
300
376
|
// src/targets/cursor.ts
|
|
301
|
-
import { resolve
|
|
377
|
+
import { resolve, join as join3 } from "path";
|
|
302
378
|
var TARGET_ID = "cursor";
|
|
303
379
|
|
|
304
380
|
class CursorTarget extends BaseTarget {
|
|
@@ -311,18 +387,19 @@ class CursorTarget extends BaseTarget {
|
|
|
311
387
|
"skills",
|
|
312
388
|
"hooks",
|
|
313
389
|
"mcp",
|
|
314
|
-
"ignore"
|
|
390
|
+
"ignore",
|
|
391
|
+
"models"
|
|
315
392
|
];
|
|
316
393
|
generate(options) {
|
|
317
394
|
const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
|
|
318
|
-
const root =
|
|
395
|
+
const root = resolve(projectRoot, baseDir);
|
|
319
396
|
const effective = this.getEffectiveFeatures(enabledFeatures);
|
|
320
397
|
const filesWritten = [];
|
|
321
398
|
const filesDeleted = [];
|
|
322
399
|
const warnings = [];
|
|
323
|
-
const cursorDir =
|
|
400
|
+
const cursorDir = resolve(root, ".cursor");
|
|
324
401
|
if (effective.includes("rules")) {
|
|
325
|
-
const rulesDir =
|
|
402
|
+
const rulesDir = resolve(cursorDir, "rules");
|
|
326
403
|
if (deleteExisting) {
|
|
327
404
|
removeIfExists(rulesDir);
|
|
328
405
|
filesDeleted.push(rulesDir);
|
|
@@ -346,18 +423,25 @@ class CursorTarget extends BaseTarget {
|
|
|
346
423
|
}
|
|
347
424
|
}
|
|
348
425
|
if (effective.includes("agents")) {
|
|
349
|
-
const agentsDir =
|
|
426
|
+
const agentsDir = resolve(cursorDir, "agents");
|
|
350
427
|
if (deleteExisting) {
|
|
351
428
|
removeIfExists(agentsDir);
|
|
352
429
|
filesDeleted.push(agentsDir);
|
|
353
430
|
}
|
|
354
431
|
ensureDir(agentsDir);
|
|
432
|
+
const resolvedModels = features.models ? resolveModels(features.models, options.modelProfile, TARGET_ID) : null;
|
|
355
433
|
const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID));
|
|
356
434
|
for (const agent of agents) {
|
|
357
435
|
const frontmatter = {
|
|
358
436
|
name: agent.name,
|
|
359
437
|
description: agent.meta.description ?? ""
|
|
360
438
|
};
|
|
439
|
+
const cursorMeta = agent.meta.cursor ?? {};
|
|
440
|
+
const modelsAgent = resolvedModels?.agents[agent.name];
|
|
441
|
+
const model = modelsAgent?.model ?? cursorMeta.model;
|
|
442
|
+
if (model) {
|
|
443
|
+
frontmatter.model = model;
|
|
444
|
+
}
|
|
361
445
|
const filepath = join3(agentsDir, `${agent.name}.md`);
|
|
362
446
|
const content = serializeFrontmatter(frontmatter, agent.content);
|
|
363
447
|
writeGeneratedFile(filepath, content);
|
|
@@ -365,7 +449,7 @@ class CursorTarget extends BaseTarget {
|
|
|
365
449
|
}
|
|
366
450
|
}
|
|
367
451
|
if (effective.includes("skills")) {
|
|
368
|
-
const skillsDir =
|
|
452
|
+
const skillsDir = resolve(cursorDir, "skills");
|
|
369
453
|
if (deleteExisting) {
|
|
370
454
|
removeIfExists(skillsDir);
|
|
371
455
|
filesDeleted.push(skillsDir);
|
|
@@ -386,7 +470,7 @@ class CursorTarget extends BaseTarget {
|
|
|
386
470
|
}
|
|
387
471
|
}
|
|
388
472
|
if (effective.includes("commands")) {
|
|
389
|
-
const commandsDir =
|
|
473
|
+
const commandsDir = resolve(cursorDir, "commands");
|
|
390
474
|
if (deleteExisting) {
|
|
391
475
|
removeIfExists(commandsDir);
|
|
392
476
|
filesDeleted.push(commandsDir);
|
|
@@ -403,14 +487,14 @@ class CursorTarget extends BaseTarget {
|
|
|
403
487
|
const mcpEntries = Object.entries(features.mcpServers);
|
|
404
488
|
if (mcpEntries.length > 0) {
|
|
405
489
|
const mcpConfig = buildCursorMcp(features.mcpServers);
|
|
406
|
-
const filepath =
|
|
490
|
+
const filepath = resolve(cursorDir, "mcp.json");
|
|
407
491
|
writeGeneratedJson(filepath, mcpConfig, { header: false });
|
|
408
492
|
filesWritten.push(filepath);
|
|
409
493
|
}
|
|
410
494
|
}
|
|
411
495
|
if (effective.includes("ignore")) {
|
|
412
496
|
if (features.ignorePatterns.length > 0) {
|
|
413
|
-
const filepath =
|
|
497
|
+
const filepath = resolve(root, ".cursorignore");
|
|
414
498
|
const content = features.ignorePatterns.join(`
|
|
415
499
|
`) + `
|
|
416
500
|
`;
|
|
@@ -418,6 +502,17 @@ class CursorTarget extends BaseTarget {
|
|
|
418
502
|
filesWritten.push(filepath);
|
|
419
503
|
}
|
|
420
504
|
}
|
|
505
|
+
if (effective.includes("models") && features.models) {
|
|
506
|
+
const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID);
|
|
507
|
+
const guidanceContent = buildCursorModelGuidance(resolved);
|
|
508
|
+
if (guidanceContent) {
|
|
509
|
+
const rulesDir = resolve(cursorDir, "rules");
|
|
510
|
+
ensureDir(rulesDir);
|
|
511
|
+
const filepath = join3(rulesDir, "model-config.mdc");
|
|
512
|
+
writeGeneratedFile(filepath, guidanceContent, { header: false });
|
|
513
|
+
filesWritten.push(filepath);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
421
516
|
return this.createResult(filesWritten, filesDeleted, warnings);
|
|
422
517
|
}
|
|
423
518
|
}
|
|
@@ -436,6 +531,59 @@ function buildCursorMcp(servers) {
|
|
|
436
531
|
}
|
|
437
532
|
return { mcpServers };
|
|
438
533
|
}
|
|
534
|
+
function buildCursorModelGuidance(resolved) {
|
|
535
|
+
if (!resolved.default && !resolved.small && Object.keys(resolved.agents).length === 0) {
|
|
536
|
+
return null;
|
|
537
|
+
}
|
|
538
|
+
const frontmatter = {
|
|
539
|
+
description: "Model configuration and selection guidelines for this workspace",
|
|
540
|
+
alwaysApply: true
|
|
541
|
+
};
|
|
542
|
+
const lines = [];
|
|
543
|
+
lines.push("# Model Configuration");
|
|
544
|
+
lines.push("");
|
|
545
|
+
lines.push("Use the following model preferences when working in this project.");
|
|
546
|
+
lines.push("");
|
|
547
|
+
if (resolved.default || resolved.small) {
|
|
548
|
+
lines.push("## Default Models");
|
|
549
|
+
lines.push("");
|
|
550
|
+
if (resolved.default) {
|
|
551
|
+
lines.push(`- **Primary model**: ${resolved.default}`);
|
|
552
|
+
}
|
|
553
|
+
if (resolved.small) {
|
|
554
|
+
lines.push(`- **Lightweight tasks** (titles, summaries): ${resolved.small}`);
|
|
555
|
+
}
|
|
556
|
+
lines.push("");
|
|
557
|
+
}
|
|
558
|
+
const agentEntries = Object.entries(resolved.agents);
|
|
559
|
+
if (agentEntries.length > 0) {
|
|
560
|
+
lines.push("## Agent Model Assignments");
|
|
561
|
+
lines.push("");
|
|
562
|
+
lines.push("| Agent | Model | Temperature |");
|
|
563
|
+
lines.push("| --- | --- | --- |");
|
|
564
|
+
for (const [name, assignment] of agentEntries) {
|
|
565
|
+
const temp = assignment.temperature !== undefined ? String(assignment.temperature) : "—";
|
|
566
|
+
lines.push(`| ${name} | ${assignment.model} | ${temp} |`);
|
|
567
|
+
}
|
|
568
|
+
lines.push("");
|
|
569
|
+
}
|
|
570
|
+
if (Object.keys(resolved.profiles).length > 0) {
|
|
571
|
+
lines.push("## Available Profiles");
|
|
572
|
+
lines.push("");
|
|
573
|
+
lines.push("| Profile | Description | Default Model |");
|
|
574
|
+
lines.push("| --- | --- | --- |");
|
|
575
|
+
for (const [name, profile] of Object.entries(resolved.profiles)) {
|
|
576
|
+
lines.push(`| ${name} | ${profile.description ?? "—"} | ${profile.default ?? "—"} |`);
|
|
577
|
+
}
|
|
578
|
+
lines.push("");
|
|
579
|
+
}
|
|
580
|
+
if (resolved.activeProfile) {
|
|
581
|
+
lines.push(`**Active profile**: \`${resolved.activeProfile}\``);
|
|
582
|
+
lines.push("");
|
|
583
|
+
}
|
|
584
|
+
return serializeFrontmatter(frontmatter, lines.join(`
|
|
585
|
+
`));
|
|
586
|
+
}
|
|
439
587
|
export {
|
|
440
588
|
CursorTarget
|
|
441
589
|
};
|