agentpacks 0.9.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -14
- package/dist/api.js +403 -179
- package/dist/cli/export-cmd.js +58 -5
- package/dist/cli/generate.js +268 -59
- package/dist/cli/import-cmd.js +203 -95
- package/dist/cli/install.js +1 -0
- package/dist/cli/models-explain.js +56 -0
- package/dist/cli/pack/list.js +56 -0
- package/dist/cli/pack/validate.js +143 -18
- package/dist/cli/publish.js +1 -0
- package/dist/core/config.d.ts +1 -1
- package/dist/core/config.js +1 -0
- package/dist/core/index.js +56 -0
- package/dist/core/metarepo.js +1 -0
- package/dist/core/pack-loader.js +56 -0
- package/dist/exporters/cursor-plugin.js +109 -22
- package/dist/exporters/index.js +109 -22
- package/dist/features/index.d.ts +1 -1
- package/dist/features/index.js +59 -0
- package/dist/features/skills.d.ts +22 -0
- package/dist/features/skills.js +60 -1
- package/dist/importers/cursor.js +122 -26
- package/dist/importers/opencode.js +138 -24
- package/dist/importers/rulesync.js +147 -33
- package/dist/index.js +484 -244
- package/dist/node/api.js +403 -179
- package/dist/node/cli/export-cmd.js +58 -5
- package/dist/node/cli/generate.js +268 -59
- package/dist/node/cli/import-cmd.js +203 -95
- package/dist/node/cli/install.js +1 -0
- package/dist/node/cli/models-explain.js +56 -0
- package/dist/node/cli/pack/list.js +56 -0
- package/dist/node/cli/pack/validate.js +143 -18
- package/dist/node/cli/publish.js +1 -0
- package/dist/node/core/config.js +1 -0
- package/dist/node/core/index.js +56 -0
- package/dist/node/core/metarepo.js +1 -0
- package/dist/node/core/pack-loader.js +56 -0
- package/dist/node/exporters/cursor-plugin.js +109 -22
- package/dist/node/exporters/index.js +109 -22
- package/dist/node/features/index.js +59 -0
- package/dist/node/features/skills.js +60 -1
- package/dist/node/importers/cursor.js +122 -26
- package/dist/node/importers/opencode.js +138 -24
- package/dist/node/importers/rulesync.js +147 -33
- package/dist/node/index.js +484 -244
- package/dist/node/targets/claude-code.js +56 -1
- package/dist/node/targets/codex-cli.js +56 -1
- package/dist/node/targets/copilot.js +56 -1
- package/dist/node/targets/cursor.js +56 -5
- package/dist/node/targets/index.js +268 -59
- package/dist/node/targets/mistral-vibe.js +661 -0
- package/dist/node/targets/opencode.js +56 -1
- package/dist/node/targets/registry.js +267 -59
- package/dist/node/utils/model-allowlist.js +6 -2
- package/dist/targets/claude-code.js +56 -1
- package/dist/targets/codex-cli.js +56 -1
- package/dist/targets/copilot.js +56 -1
- package/dist/targets/cursor.js +56 -5
- package/dist/targets/index.d.ts +1 -0
- package/dist/targets/index.js +268 -59
- package/dist/targets/mistral-vibe.d.ts +13 -0
- package/dist/targets/mistral-vibe.js +661 -0
- package/dist/targets/opencode.js +56 -1
- package/dist/targets/registry.js +267 -59
- package/dist/utils/model-allowlist.js +6 -2
- package/package.json +15 -3
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ var TARGET_IDS = [
|
|
|
12
12
|
"cursor",
|
|
13
13
|
"claudecode",
|
|
14
14
|
"codexcli",
|
|
15
|
+
"mistralvibe",
|
|
15
16
|
"geminicli",
|
|
16
17
|
"copilot",
|
|
17
18
|
"agentsmd",
|
|
@@ -352,6 +353,8 @@ function agentMatchesTarget(agent, targetId) {
|
|
|
352
353
|
// src/features/skills.ts
|
|
353
354
|
import { readFileSync as readFileSync6, existsSync as existsSync3 } from "fs";
|
|
354
355
|
import { basename as basename4, join as join2 } from "path";
|
|
356
|
+
var SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
357
|
+
var SKILL_NAME_MAX_LENGTH = 64;
|
|
355
358
|
function parseSkills(skillsDir, packName) {
|
|
356
359
|
const dirs = listDirs(skillsDir);
|
|
357
360
|
const skills = [];
|
|
@@ -375,6 +378,59 @@ function parseSkillFile(filepath, skillDir, packName) {
|
|
|
375
378
|
content
|
|
376
379
|
};
|
|
377
380
|
}
|
|
381
|
+
function buildSkillFrontmatter(skill) {
|
|
382
|
+
return {
|
|
383
|
+
...skill.meta,
|
|
384
|
+
name: skill.name
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
function serializeSkill(skill) {
|
|
388
|
+
return serializeFrontmatter(buildSkillFrontmatter(skill), skill.content);
|
|
389
|
+
}
|
|
390
|
+
function normalizeImportedSkillMarkdown(source, skillName) {
|
|
391
|
+
const { data, content } = parseFrontmatter(source);
|
|
392
|
+
const normalized = {
|
|
393
|
+
...data,
|
|
394
|
+
name: skillName
|
|
395
|
+
};
|
|
396
|
+
let addedDescription = false;
|
|
397
|
+
const description = normalized.description;
|
|
398
|
+
if (typeof description !== "string" || description.trim().length === 0) {
|
|
399
|
+
normalized.description = `Imported skill: ${skillName}`;
|
|
400
|
+
addedDescription = true;
|
|
401
|
+
}
|
|
402
|
+
return {
|
|
403
|
+
content: serializeFrontmatter(normalized, content),
|
|
404
|
+
addedDescription
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
function validateAgentSkillsFrontmatter(skill) {
|
|
408
|
+
const errors = [];
|
|
409
|
+
const dirName = basename4(skill.sourceDir);
|
|
410
|
+
const declaredName = skill.meta.name;
|
|
411
|
+
if (typeof declaredName !== "string" || declaredName.trim().length === 0) {
|
|
412
|
+
errors.push('Missing required frontmatter field "name".');
|
|
413
|
+
} else {
|
|
414
|
+
if (declaredName.length > SKILL_NAME_MAX_LENGTH) {
|
|
415
|
+
errors.push(`Invalid "name": must be at most ${SKILL_NAME_MAX_LENGTH} characters.`);
|
|
416
|
+
}
|
|
417
|
+
if (!SKILL_NAME_PATTERN.test(declaredName)) {
|
|
418
|
+
errors.push('Invalid "name": use lowercase letters, numbers, and single hyphens only.');
|
|
419
|
+
}
|
|
420
|
+
if (declaredName !== dirName) {
|
|
421
|
+
errors.push(`Invalid "name": must match containing directory "${dirName}".`);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
const description = skill.meta.description;
|
|
425
|
+
if (typeof description !== "string" || description.trim().length === 0) {
|
|
426
|
+
errors.push('Missing required frontmatter field "description".');
|
|
427
|
+
}
|
|
428
|
+
const allowedTools = skill.meta["allowed-tools"];
|
|
429
|
+
if (allowedTools !== undefined && (!Array.isArray(allowedTools) || allowedTools.some((tool) => typeof tool !== "string" || tool.length === 0))) {
|
|
430
|
+
errors.push('Invalid "allowed-tools": expected an array of non-empty strings.');
|
|
431
|
+
}
|
|
432
|
+
return errors;
|
|
433
|
+
}
|
|
378
434
|
function skillMatchesTarget(skill, targetId) {
|
|
379
435
|
const { targets } = skill.meta;
|
|
380
436
|
if (!targets || targets === "*")
|
|
@@ -1518,7 +1574,7 @@ class OpenCodeTarget extends BaseTarget {
|
|
|
1518
1574
|
const skillSubDir = join10(skillDir, skill.name);
|
|
1519
1575
|
ensureDir(skillSubDir);
|
|
1520
1576
|
const filepath = join10(skillSubDir, "SKILL.md");
|
|
1521
|
-
writeGeneratedFile(filepath, skill
|
|
1577
|
+
writeGeneratedFile(filepath, serializeSkill(skill));
|
|
1522
1578
|
filesWritten.push(filepath);
|
|
1523
1579
|
}
|
|
1524
1580
|
}
|
|
@@ -1773,12 +1829,8 @@ class CursorTarget extends BaseTarget {
|
|
|
1773
1829
|
for (const skill of skills) {
|
|
1774
1830
|
const skillSubDir = join11(skillsDir, skill.name);
|
|
1775
1831
|
ensureDir(skillSubDir);
|
|
1776
|
-
const frontmatter = {
|
|
1777
|
-
name: skill.name,
|
|
1778
|
-
description: skill.meta.description ?? ""
|
|
1779
|
-
};
|
|
1780
1832
|
const filepath = join11(skillSubDir, "SKILL.md");
|
|
1781
|
-
const content =
|
|
1833
|
+
const content = serializeSkill(skill);
|
|
1782
1834
|
writeGeneratedFile(filepath, content);
|
|
1783
1835
|
filesWritten.push(filepath);
|
|
1784
1836
|
}
|
|
@@ -2078,7 +2130,7 @@ ${content}`;
|
|
|
2078
2130
|
const skillSubDir = join12(skillsDir, skill.name);
|
|
2079
2131
|
ensureDir(skillSubDir);
|
|
2080
2132
|
const filepath = join12(skillSubDir, "SKILL.md");
|
|
2081
|
-
writeGeneratedFile(filepath, skill
|
|
2133
|
+
writeGeneratedFile(filepath, serializeSkill(skill));
|
|
2082
2134
|
filesWritten.push(filepath);
|
|
2083
2135
|
}
|
|
2084
2136
|
}
|
|
@@ -2208,7 +2260,7 @@ class CodexCliTarget extends BaseTarget {
|
|
|
2208
2260
|
const skillSubDir = join13(skillsDir, skill.name);
|
|
2209
2261
|
ensureDir(skillSubDir);
|
|
2210
2262
|
const filepath = join13(skillSubDir, "SKILL.md");
|
|
2211
|
-
writeGeneratedFile(filepath, skill
|
|
2263
|
+
writeGeneratedFile(filepath, serializeSkill(skill));
|
|
2212
2264
|
filesWritten.push(filepath);
|
|
2213
2265
|
}
|
|
2214
2266
|
}
|
|
@@ -2216,12 +2268,168 @@ class CodexCliTarget extends BaseTarget {
|
|
|
2216
2268
|
}
|
|
2217
2269
|
}
|
|
2218
2270
|
|
|
2219
|
-
// src/targets/
|
|
2271
|
+
// src/targets/mistral-vibe.ts
|
|
2220
2272
|
import { resolve as resolve11, join as join14 } from "path";
|
|
2221
|
-
var TARGET_ID5 = "
|
|
2273
|
+
var TARGET_ID5 = "mistralvibe";
|
|
2222
2274
|
|
|
2223
|
-
class
|
|
2275
|
+
class MistralVibeTarget extends BaseTarget {
|
|
2224
2276
|
id = TARGET_ID5;
|
|
2277
|
+
name = "Mistral Vibe";
|
|
2278
|
+
supportedFeatures = [
|
|
2279
|
+
"rules",
|
|
2280
|
+
"commands",
|
|
2281
|
+
"agents",
|
|
2282
|
+
"skills",
|
|
2283
|
+
"mcp",
|
|
2284
|
+
"ignore",
|
|
2285
|
+
"models"
|
|
2286
|
+
];
|
|
2287
|
+
generate(options) {
|
|
2288
|
+
const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
|
|
2289
|
+
const root = resolve11(projectRoot, baseDir);
|
|
2290
|
+
const effective = this.getEffectiveFeatures(enabledFeatures);
|
|
2291
|
+
const filesWritten = [];
|
|
2292
|
+
const filesDeleted = [];
|
|
2293
|
+
const warnings = [];
|
|
2294
|
+
const vibeDir = resolve11(root, ".vibe");
|
|
2295
|
+
ensureDir(vibeDir);
|
|
2296
|
+
if (effective.includes("rules")) {
|
|
2297
|
+
const rulesDir = resolve11(vibeDir, "rules");
|
|
2298
|
+
if (deleteExisting) {
|
|
2299
|
+
removeIfExists(rulesDir);
|
|
2300
|
+
filesDeleted.push(rulesDir);
|
|
2301
|
+
}
|
|
2302
|
+
ensureDir(rulesDir);
|
|
2303
|
+
const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID5));
|
|
2304
|
+
for (const rule of rules) {
|
|
2305
|
+
const filepath = join14(rulesDir, `${rule.name}.md`);
|
|
2306
|
+
writeGeneratedFile(filepath, rule.content);
|
|
2307
|
+
filesWritten.push(filepath);
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2310
|
+
if (effective.includes("agents")) {
|
|
2311
|
+
const agentsDir = resolve11(vibeDir, "agents");
|
|
2312
|
+
if (deleteExisting) {
|
|
2313
|
+
removeIfExists(agentsDir);
|
|
2314
|
+
filesDeleted.push(agentsDir);
|
|
2315
|
+
}
|
|
2316
|
+
ensureDir(agentsDir);
|
|
2317
|
+
const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID5));
|
|
2318
|
+
for (const agent of agents) {
|
|
2319
|
+
const filepath = join14(agentsDir, `${agent.name}.md`);
|
|
2320
|
+
writeGeneratedFile(filepath, agent.content);
|
|
2321
|
+
filesWritten.push(filepath);
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2324
|
+
if (effective.includes("skills")) {
|
|
2325
|
+
const skillsDir = resolve11(vibeDir, "skills");
|
|
2326
|
+
if (deleteExisting) {
|
|
2327
|
+
removeIfExists(skillsDir);
|
|
2328
|
+
filesDeleted.push(skillsDir);
|
|
2329
|
+
}
|
|
2330
|
+
ensureDir(skillsDir);
|
|
2331
|
+
const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID5));
|
|
2332
|
+
for (const skill of skills) {
|
|
2333
|
+
const skillSubDir = join14(skillsDir, skill.name);
|
|
2334
|
+
ensureDir(skillSubDir);
|
|
2335
|
+
const filepath = join14(skillSubDir, "SKILL.md");
|
|
2336
|
+
writeGeneratedFile(filepath, serializeSkill(skill));
|
|
2337
|
+
filesWritten.push(filepath);
|
|
2338
|
+
}
|
|
2339
|
+
}
|
|
2340
|
+
if (effective.includes("commands")) {
|
|
2341
|
+
const commandsDir = resolve11(vibeDir, "commands");
|
|
2342
|
+
if (deleteExisting) {
|
|
2343
|
+
removeIfExists(commandsDir);
|
|
2344
|
+
filesDeleted.push(commandsDir);
|
|
2345
|
+
}
|
|
2346
|
+
ensureDir(commandsDir);
|
|
2347
|
+
const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID5));
|
|
2348
|
+
for (const command of commands) {
|
|
2349
|
+
const filepath = join14(commandsDir, `${command.name}.md`);
|
|
2350
|
+
writeGeneratedFile(filepath, command.content);
|
|
2351
|
+
filesWritten.push(filepath);
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
let hasMcpConfig = false;
|
|
2355
|
+
if (effective.includes("mcp")) {
|
|
2356
|
+
const mcpEntries = Object.entries(features.mcpServers);
|
|
2357
|
+
if (mcpEntries.length > 0) {
|
|
2358
|
+
const filepath = resolve11(vibeDir, "mcp.json");
|
|
2359
|
+
writeGeneratedJson(filepath, { mcpServers: features.mcpServers }, {
|
|
2360
|
+
header: false
|
|
2361
|
+
});
|
|
2362
|
+
filesWritten.push(filepath);
|
|
2363
|
+
hasMcpConfig = true;
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
if (effective.includes("ignore") && features.ignorePatterns.length > 0) {
|
|
2367
|
+
const filepath = resolve11(root, ".vibeignore");
|
|
2368
|
+
writeGeneratedFile(filepath, features.ignorePatterns.join(`
|
|
2369
|
+
`) + `
|
|
2370
|
+
`);
|
|
2371
|
+
filesWritten.push(filepath);
|
|
2372
|
+
}
|
|
2373
|
+
let defaultModel;
|
|
2374
|
+
let smallModel;
|
|
2375
|
+
if (effective.includes("models") && features.models) {
|
|
2376
|
+
const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID5);
|
|
2377
|
+
defaultModel = resolved.default;
|
|
2378
|
+
smallModel = resolved.small;
|
|
2379
|
+
const guidance = generateModelGuidanceMarkdown(resolved);
|
|
2380
|
+
if (guidance) {
|
|
2381
|
+
const filepath = join14(vibeDir, "model-config.md");
|
|
2382
|
+
writeGeneratedFile(filepath, guidance);
|
|
2383
|
+
filesWritten.push(filepath);
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2386
|
+
const vibeConfig = buildVibeConfigToml({
|
|
2387
|
+
hasMcpConfig,
|
|
2388
|
+
defaultModel,
|
|
2389
|
+
smallModel,
|
|
2390
|
+
profile: options.modelProfile
|
|
2391
|
+
});
|
|
2392
|
+
if (vibeConfig.length > 0) {
|
|
2393
|
+
const filepath = resolve11(vibeDir, "config.toml");
|
|
2394
|
+
writeGeneratedFile(filepath, vibeConfig);
|
|
2395
|
+
filesWritten.push(filepath);
|
|
2396
|
+
}
|
|
2397
|
+
return this.createResult(filesWritten, filesDeleted, warnings);
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
function buildVibeConfigToml(options) {
|
|
2401
|
+
const lines = [];
|
|
2402
|
+
if (options.defaultModel || options.smallModel || options.profile) {
|
|
2403
|
+
lines.push("[models]");
|
|
2404
|
+
if (options.defaultModel) {
|
|
2405
|
+
lines.push(`default = "${escapeTomlString(options.defaultModel)}"`);
|
|
2406
|
+
}
|
|
2407
|
+
if (options.smallModel) {
|
|
2408
|
+
lines.push(`small = "${escapeTomlString(options.smallModel)}"`);
|
|
2409
|
+
}
|
|
2410
|
+
if (options.profile) {
|
|
2411
|
+
lines.push(`profile = "${escapeTomlString(options.profile)}"`);
|
|
2412
|
+
}
|
|
2413
|
+
lines.push("");
|
|
2414
|
+
}
|
|
2415
|
+
if (options.hasMcpConfig) {
|
|
2416
|
+
lines.push("[mcp]");
|
|
2417
|
+
lines.push('config_path = ".vibe/mcp.json"');
|
|
2418
|
+
lines.push("");
|
|
2419
|
+
}
|
|
2420
|
+
return lines.join(`
|
|
2421
|
+
`).trim();
|
|
2422
|
+
}
|
|
2423
|
+
function escapeTomlString(value) {
|
|
2424
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
// src/targets/gemini-cli.ts
|
|
2428
|
+
import { resolve as resolve12, join as join15 } from "path";
|
|
2429
|
+
var TARGET_ID6 = "geminicli";
|
|
2430
|
+
|
|
2431
|
+
class GeminiCliTarget extends BaseTarget {
|
|
2432
|
+
id = TARGET_ID6;
|
|
2225
2433
|
name = "Gemini CLI";
|
|
2226
2434
|
supportedFeatures = [
|
|
2227
2435
|
"rules",
|
|
@@ -2233,49 +2441,49 @@ class GeminiCliTarget extends BaseTarget {
|
|
|
2233
2441
|
];
|
|
2234
2442
|
generate(options) {
|
|
2235
2443
|
const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
|
|
2236
|
-
const root =
|
|
2444
|
+
const root = resolve12(projectRoot, baseDir);
|
|
2237
2445
|
const effective = this.getEffectiveFeatures(enabledFeatures);
|
|
2238
2446
|
const filesWritten = [];
|
|
2239
2447
|
const filesDeleted = [];
|
|
2240
2448
|
const warnings = [];
|
|
2241
|
-
const geminiDir =
|
|
2449
|
+
const geminiDir = resolve12(root, ".gemini");
|
|
2242
2450
|
if (effective.includes("rules")) {
|
|
2243
|
-
const rules = features.rules.filter((r) => ruleMatchesTarget(r,
|
|
2451
|
+
const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID6));
|
|
2244
2452
|
const rootRules = getRootRules(rules);
|
|
2245
2453
|
const detailRules = getDetailRules(rules);
|
|
2246
2454
|
if (rootRules.length > 0) {
|
|
2247
2455
|
const geminiMd = rootRules.map((r) => r.content).join(`
|
|
2248
2456
|
|
|
2249
2457
|
`);
|
|
2250
|
-
const filepath =
|
|
2458
|
+
const filepath = resolve12(root, "GEMINI.md");
|
|
2251
2459
|
writeGeneratedFile(filepath, geminiMd);
|
|
2252
2460
|
filesWritten.push(filepath);
|
|
2253
2461
|
}
|
|
2254
2462
|
if (detailRules.length > 0) {
|
|
2255
|
-
const memoriesDir =
|
|
2463
|
+
const memoriesDir = resolve12(geminiDir, "memories");
|
|
2256
2464
|
if (deleteExisting) {
|
|
2257
2465
|
removeIfExists(memoriesDir);
|
|
2258
2466
|
filesDeleted.push(memoriesDir);
|
|
2259
2467
|
}
|
|
2260
2468
|
ensureDir(memoriesDir);
|
|
2261
2469
|
for (const rule of detailRules) {
|
|
2262
|
-
const filepath =
|
|
2470
|
+
const filepath = join15(memoriesDir, `${rule.name}.md`);
|
|
2263
2471
|
writeGeneratedFile(filepath, rule.content);
|
|
2264
2472
|
filesWritten.push(filepath);
|
|
2265
2473
|
}
|
|
2266
2474
|
}
|
|
2267
2475
|
}
|
|
2268
2476
|
if (effective.includes("commands")) {
|
|
2269
|
-
const commandsDir =
|
|
2477
|
+
const commandsDir = resolve12(geminiDir, "commands");
|
|
2270
2478
|
if (deleteExisting) {
|
|
2271
2479
|
removeIfExists(commandsDir);
|
|
2272
2480
|
filesDeleted.push(commandsDir);
|
|
2273
2481
|
}
|
|
2274
2482
|
ensureDir(commandsDir);
|
|
2275
|
-
const commands = features.commands.filter((c) => commandMatchesTarget(c,
|
|
2483
|
+
const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID6));
|
|
2276
2484
|
for (const cmd of commands) {
|
|
2277
2485
|
const toml = buildGeminiCommand(cmd.name, cmd.meta.description ?? "", cmd.content);
|
|
2278
|
-
const filepath =
|
|
2486
|
+
const filepath = join15(commandsDir, `${cmd.name}.toml`);
|
|
2279
2487
|
writeGeneratedFile(filepath, toml, { type: "md" });
|
|
2280
2488
|
filesWritten.push(filepath);
|
|
2281
2489
|
}
|
|
@@ -2284,14 +2492,14 @@ class GeminiCliTarget extends BaseTarget {
|
|
|
2284
2492
|
const mcpEntries = Object.entries(features.mcpServers);
|
|
2285
2493
|
if (mcpEntries.length > 0) {
|
|
2286
2494
|
const settings = buildGeminiSettings(features.mcpServers);
|
|
2287
|
-
const filepath =
|
|
2495
|
+
const filepath = resolve12(geminiDir, "settings.json");
|
|
2288
2496
|
writeGeneratedJson(filepath, settings, { header: false });
|
|
2289
2497
|
filesWritten.push(filepath);
|
|
2290
2498
|
}
|
|
2291
2499
|
}
|
|
2292
2500
|
if (effective.includes("ignore")) {
|
|
2293
2501
|
if (features.ignorePatterns.length > 0) {
|
|
2294
|
-
const filepath =
|
|
2502
|
+
const filepath = resolve12(root, ".geminiignore");
|
|
2295
2503
|
const content = features.ignorePatterns.join(`
|
|
2296
2504
|
`) + `
|
|
2297
2505
|
`;
|
|
@@ -2330,11 +2538,11 @@ function buildGeminiSettings(servers) {
|
|
|
2330
2538
|
}
|
|
2331
2539
|
|
|
2332
2540
|
// src/targets/copilot.ts
|
|
2333
|
-
import { resolve as
|
|
2334
|
-
var
|
|
2541
|
+
import { resolve as resolve13, join as join16 } from "path";
|
|
2542
|
+
var TARGET_ID7 = "copilot";
|
|
2335
2543
|
|
|
2336
2544
|
class CopilotTarget extends BaseTarget {
|
|
2337
|
-
id =
|
|
2545
|
+
id = TARGET_ID7;
|
|
2338
2546
|
name = "GitHub Copilot";
|
|
2339
2547
|
supportedFeatures = [
|
|
2340
2548
|
"rules",
|
|
@@ -2347,81 +2555,81 @@ class CopilotTarget extends BaseTarget {
|
|
|
2347
2555
|
];
|
|
2348
2556
|
generate(options) {
|
|
2349
2557
|
const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
|
|
2350
|
-
const root =
|
|
2558
|
+
const root = resolve13(projectRoot, baseDir);
|
|
2351
2559
|
const effective = this.getEffectiveFeatures(enabledFeatures);
|
|
2352
2560
|
const filesWritten = [];
|
|
2353
2561
|
const filesDeleted = [];
|
|
2354
2562
|
const warnings = [];
|
|
2355
|
-
const githubDir =
|
|
2563
|
+
const githubDir = resolve13(root, ".github");
|
|
2356
2564
|
if (effective.includes("rules")) {
|
|
2357
|
-
const rules = features.rules.filter((r) => ruleMatchesTarget(r,
|
|
2565
|
+
const rules = features.rules.filter((r) => ruleMatchesTarget(r, TARGET_ID7));
|
|
2358
2566
|
if (rules.length > 0) {
|
|
2359
2567
|
const combinedContent = rules.map((r) => r.content).join(`
|
|
2360
2568
|
|
|
2361
2569
|
---
|
|
2362
2570
|
|
|
2363
2571
|
`);
|
|
2364
|
-
const filepath =
|
|
2572
|
+
const filepath = resolve13(githubDir, "copilot-instructions.md");
|
|
2365
2573
|
ensureDir(githubDir);
|
|
2366
2574
|
writeGeneratedFile(filepath, combinedContent);
|
|
2367
2575
|
filesWritten.push(filepath);
|
|
2368
2576
|
}
|
|
2369
2577
|
}
|
|
2370
2578
|
if (effective.includes("agents")) {
|
|
2371
|
-
const copilotDir =
|
|
2372
|
-
const agentsDir =
|
|
2579
|
+
const copilotDir = resolve13(githubDir, "copilot");
|
|
2580
|
+
const agentsDir = resolve13(copilotDir, "agents");
|
|
2373
2581
|
if (deleteExisting) {
|
|
2374
2582
|
removeIfExists(agentsDir);
|
|
2375
2583
|
filesDeleted.push(agentsDir);
|
|
2376
2584
|
}
|
|
2377
2585
|
ensureDir(agentsDir);
|
|
2378
|
-
const agents = features.agents.filter((a) => agentMatchesTarget(a,
|
|
2586
|
+
const agents = features.agents.filter((a) => agentMatchesTarget(a, TARGET_ID7));
|
|
2379
2587
|
for (const agent of agents) {
|
|
2380
|
-
const filepath =
|
|
2588
|
+
const filepath = join16(agentsDir, `${agent.name}.md`);
|
|
2381
2589
|
writeGeneratedFile(filepath, agent.content);
|
|
2382
2590
|
filesWritten.push(filepath);
|
|
2383
2591
|
}
|
|
2384
2592
|
}
|
|
2385
2593
|
if (effective.includes("skills")) {
|
|
2386
|
-
const copilotDir =
|
|
2387
|
-
const skillsDir =
|
|
2594
|
+
const copilotDir = resolve13(githubDir, "copilot");
|
|
2595
|
+
const skillsDir = resolve13(copilotDir, "skills");
|
|
2388
2596
|
if (deleteExisting) {
|
|
2389
2597
|
removeIfExists(skillsDir);
|
|
2390
2598
|
filesDeleted.push(skillsDir);
|
|
2391
2599
|
}
|
|
2392
2600
|
ensureDir(skillsDir);
|
|
2393
|
-
const skills = features.skills.filter((s) => skillMatchesTarget(s,
|
|
2601
|
+
const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID7));
|
|
2394
2602
|
for (const skill of skills) {
|
|
2395
|
-
const skillSubDir =
|
|
2603
|
+
const skillSubDir = join16(skillsDir, skill.name);
|
|
2396
2604
|
ensureDir(skillSubDir);
|
|
2397
|
-
const filepath =
|
|
2398
|
-
writeGeneratedFile(filepath, skill
|
|
2605
|
+
const filepath = join16(skillSubDir, "SKILL.md");
|
|
2606
|
+
writeGeneratedFile(filepath, serializeSkill(skill));
|
|
2399
2607
|
filesWritten.push(filepath);
|
|
2400
2608
|
}
|
|
2401
2609
|
}
|
|
2402
2610
|
if (effective.includes("commands")) {
|
|
2403
|
-
const copilotDir =
|
|
2404
|
-
const commandsDir =
|
|
2611
|
+
const copilotDir = resolve13(githubDir, "copilot");
|
|
2612
|
+
const commandsDir = resolve13(copilotDir, "commands");
|
|
2405
2613
|
if (deleteExisting) {
|
|
2406
2614
|
removeIfExists(commandsDir);
|
|
2407
2615
|
filesDeleted.push(commandsDir);
|
|
2408
2616
|
}
|
|
2409
2617
|
ensureDir(commandsDir);
|
|
2410
|
-
const commands = features.commands.filter((c) => commandMatchesTarget(c,
|
|
2618
|
+
const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID7));
|
|
2411
2619
|
for (const cmd of commands) {
|
|
2412
|
-
const filepath =
|
|
2620
|
+
const filepath = join16(commandsDir, `${cmd.name}.md`);
|
|
2413
2621
|
writeGeneratedFile(filepath, cmd.content);
|
|
2414
2622
|
filesWritten.push(filepath);
|
|
2415
2623
|
}
|
|
2416
2624
|
}
|
|
2417
2625
|
if (effective.includes("ignore")) {}
|
|
2418
2626
|
if (effective.includes("models") && features.models) {
|
|
2419
|
-
const resolved = resolveModels(features.models, options.modelProfile,
|
|
2627
|
+
const resolved = resolveModels(features.models, options.modelProfile, TARGET_ID7);
|
|
2420
2628
|
const guidance = generateModelGuidanceMarkdown(resolved);
|
|
2421
2629
|
if (guidance) {
|
|
2422
|
-
const copilotDir =
|
|
2630
|
+
const copilotDir = resolve13(githubDir, "copilot");
|
|
2423
2631
|
ensureDir(copilotDir);
|
|
2424
|
-
const filepath =
|
|
2632
|
+
const filepath = join16(copilotDir, "model-config.md");
|
|
2425
2633
|
writeGeneratedFile(filepath, guidance);
|
|
2426
2634
|
filesWritten.push(filepath);
|
|
2427
2635
|
}
|
|
@@ -2431,14 +2639,14 @@ class CopilotTarget extends BaseTarget {
|
|
|
2431
2639
|
}
|
|
2432
2640
|
|
|
2433
2641
|
// src/targets/agents-md.ts
|
|
2434
|
-
import { resolve as
|
|
2642
|
+
import { resolve as resolve14 } from "path";
|
|
2435
2643
|
class AgentsMdTarget extends BaseTarget {
|
|
2436
2644
|
id = "agentsmd";
|
|
2437
2645
|
name = "AGENTS.md";
|
|
2438
2646
|
supportedFeatures = ["rules"];
|
|
2439
2647
|
generate(options) {
|
|
2440
2648
|
const { projectRoot, baseDir, features } = options;
|
|
2441
|
-
const root =
|
|
2649
|
+
const root = resolve14(projectRoot, baseDir);
|
|
2442
2650
|
const filesWritten = [];
|
|
2443
2651
|
const warnings = [];
|
|
2444
2652
|
const rootRules = getRootRules(features.rules);
|
|
@@ -2450,7 +2658,7 @@ class AgentsMdTarget extends BaseTarget {
|
|
|
2450
2658
|
const content = sections.join(`
|
|
2451
2659
|
|
|
2452
2660
|
`);
|
|
2453
|
-
const filepath =
|
|
2661
|
+
const filepath = resolve14(root, "AGENTS.md");
|
|
2454
2662
|
writeGeneratedFile(filepath, content);
|
|
2455
2663
|
filesWritten.push(filepath);
|
|
2456
2664
|
return this.createResult(filesWritten, [], warnings);
|
|
@@ -2458,7 +2666,7 @@ class AgentsMdTarget extends BaseTarget {
|
|
|
2458
2666
|
}
|
|
2459
2667
|
|
|
2460
2668
|
// src/targets/generic-md-target.ts
|
|
2461
|
-
import { resolve as
|
|
2669
|
+
import { resolve as resolve15, join as join17 } from "path";
|
|
2462
2670
|
function createGenericMdTarget(config) {
|
|
2463
2671
|
return new GenericMdTarget(config);
|
|
2464
2672
|
}
|
|
@@ -2477,16 +2685,16 @@ class GenericMdTarget extends BaseTarget {
|
|
|
2477
2685
|
}
|
|
2478
2686
|
generate(options) {
|
|
2479
2687
|
const { projectRoot, baseDir, features, enabledFeatures, deleteExisting } = options;
|
|
2480
|
-
const root =
|
|
2688
|
+
const root = resolve15(projectRoot, baseDir);
|
|
2481
2689
|
const effective = this.getEffectiveFeatures(enabledFeatures);
|
|
2482
2690
|
const filesWritten = [];
|
|
2483
2691
|
const filesDeleted = [];
|
|
2484
2692
|
const warnings = [];
|
|
2485
|
-
const configDir =
|
|
2693
|
+
const configDir = resolve15(root, this.config.configDir);
|
|
2486
2694
|
const rulesSubDir = this.config.rulesDir ?? "rules";
|
|
2487
2695
|
const ext = this.config.ruleExtension ?? ".md";
|
|
2488
2696
|
if (effective.includes("rules")) {
|
|
2489
|
-
const rulesDir =
|
|
2697
|
+
const rulesDir = resolve15(configDir, rulesSubDir);
|
|
2490
2698
|
if (deleteExisting) {
|
|
2491
2699
|
removeIfExists(rulesDir);
|
|
2492
2700
|
filesDeleted.push(rulesDir);
|
|
@@ -2494,13 +2702,13 @@ class GenericMdTarget extends BaseTarget {
|
|
|
2494
2702
|
ensureDir(rulesDir);
|
|
2495
2703
|
const rules = features.rules.filter((r) => ruleMatchesTarget(r, this.id));
|
|
2496
2704
|
for (const rule of rules) {
|
|
2497
|
-
const filepath =
|
|
2705
|
+
const filepath = join17(rulesDir, `${rule.name}${ext}`);
|
|
2498
2706
|
writeGeneratedFile(filepath, rule.content);
|
|
2499
2707
|
filesWritten.push(filepath);
|
|
2500
2708
|
}
|
|
2501
2709
|
}
|
|
2502
2710
|
if (effective.includes("commands")) {
|
|
2503
|
-
const commandsDir =
|
|
2711
|
+
const commandsDir = resolve15(configDir, "commands");
|
|
2504
2712
|
if (deleteExisting) {
|
|
2505
2713
|
removeIfExists(commandsDir);
|
|
2506
2714
|
filesDeleted.push(commandsDir);
|
|
@@ -2508,7 +2716,7 @@ class GenericMdTarget extends BaseTarget {
|
|
|
2508
2716
|
ensureDir(commandsDir);
|
|
2509
2717
|
const commands = features.commands.filter((c) => commandMatchesTarget(c, this.id));
|
|
2510
2718
|
for (const cmd of commands) {
|
|
2511
|
-
const filepath =
|
|
2719
|
+
const filepath = join17(commandsDir, `${cmd.name}.md`);
|
|
2512
2720
|
writeGeneratedFile(filepath, cmd.content);
|
|
2513
2721
|
filesWritten.push(filepath);
|
|
2514
2722
|
}
|
|
@@ -2517,7 +2725,7 @@ class GenericMdTarget extends BaseTarget {
|
|
|
2517
2725
|
const mcpEntries = Object.entries(features.mcpServers);
|
|
2518
2726
|
if (mcpEntries.length > 0) {
|
|
2519
2727
|
const mcpDir = this.config.mcpInConfigDir ? configDir : root;
|
|
2520
|
-
const filepath =
|
|
2728
|
+
const filepath = resolve15(mcpDir, "mcp.json");
|
|
2521
2729
|
writeGeneratedJson(filepath, { mcpServers: features.mcpServers }, {
|
|
2522
2730
|
header: false
|
|
2523
2731
|
});
|
|
@@ -2526,7 +2734,7 @@ class GenericMdTarget extends BaseTarget {
|
|
|
2526
2734
|
}
|
|
2527
2735
|
if (effective.includes("ignore") && this.config.ignoreFile) {
|
|
2528
2736
|
if (features.ignorePatterns.length > 0) {
|
|
2529
|
-
const filepath =
|
|
2737
|
+
const filepath = resolve15(root, this.config.ignoreFile);
|
|
2530
2738
|
writeGeneratedFile(filepath, features.ignorePatterns.join(`
|
|
2531
2739
|
`) + `
|
|
2532
2740
|
`);
|
|
@@ -2538,7 +2746,7 @@ class GenericMdTarget extends BaseTarget {
|
|
|
2538
2746
|
const guidance = generateModelGuidanceMarkdown(resolved);
|
|
2539
2747
|
if (guidance) {
|
|
2540
2748
|
ensureDir(configDir);
|
|
2541
|
-
const filepath =
|
|
2749
|
+
const filepath = join17(configDir, "model-config.md");
|
|
2542
2750
|
writeGeneratedFile(filepath, guidance);
|
|
2543
2751
|
filesWritten.push(filepath);
|
|
2544
2752
|
}
|
|
@@ -2650,6 +2858,7 @@ var TARGETS = [
|
|
|
2650
2858
|
new CursorTarget,
|
|
2651
2859
|
new ClaudeCodeTarget,
|
|
2652
2860
|
new CodexCliTarget,
|
|
2861
|
+
new MistralVibeTarget,
|
|
2653
2862
|
new GeminiCliTarget,
|
|
2654
2863
|
new CopilotTarget,
|
|
2655
2864
|
new AgentsMdTarget,
|
|
@@ -2682,12 +2891,12 @@ function listTargetIds() {
|
|
|
2682
2891
|
}
|
|
2683
2892
|
|
|
2684
2893
|
// src/exporters/cursor-plugin.ts
|
|
2685
|
-
import { resolve as
|
|
2894
|
+
import { resolve as resolve16, join as join18 } from "path";
|
|
2686
2895
|
import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
2687
2896
|
function exportCursorPlugin(pack, outputDir) {
|
|
2688
2897
|
const filesWritten = [];
|
|
2689
2898
|
const pluginName = normalizeCursorPluginName(pack.manifest.name);
|
|
2690
|
-
const pluginDir =
|
|
2899
|
+
const pluginDir = resolve16(outputDir, pluginName);
|
|
2691
2900
|
mkdirSync4(pluginDir, { recursive: true });
|
|
2692
2901
|
const manifest = {
|
|
2693
2902
|
name: pluginName
|
|
@@ -2718,7 +2927,7 @@ function exportCursorPlugin(pack, outputDir) {
|
|
|
2718
2927
|
manifest.keywords = pack.manifest.tags;
|
|
2719
2928
|
}
|
|
2720
2929
|
if (pack.rules.length > 0) {
|
|
2721
|
-
const rulesDir =
|
|
2930
|
+
const rulesDir = join18(pluginDir, "rules");
|
|
2722
2931
|
ensureDir(rulesDir);
|
|
2723
2932
|
manifest.rules = "rules";
|
|
2724
2933
|
for (const rule of pack.rules) {
|
|
@@ -2731,13 +2940,13 @@ function exportCursorPlugin(pack, outputDir) {
|
|
|
2731
2940
|
if (globs)
|
|
2732
2941
|
fm.globs = globs;
|
|
2733
2942
|
const filename = `${rule.name}.mdc`;
|
|
2734
|
-
const filepath =
|
|
2943
|
+
const filepath = join18(rulesDir, filename);
|
|
2735
2944
|
writeFileSync4(filepath, serializeFrontmatter(fm, rule.content));
|
|
2736
2945
|
filesWritten.push(filepath);
|
|
2737
2946
|
}
|
|
2738
2947
|
}
|
|
2739
2948
|
if (pack.agents.length > 0) {
|
|
2740
|
-
const agentsDir =
|
|
2949
|
+
const agentsDir = join18(pluginDir, "agents");
|
|
2741
2950
|
ensureDir(agentsDir);
|
|
2742
2951
|
manifest.agents = "agents";
|
|
2743
2952
|
for (const agent of pack.agents) {
|
|
@@ -2746,29 +2955,26 @@ function exportCursorPlugin(pack, outputDir) {
|
|
|
2746
2955
|
description: agent.meta.description ?? ""
|
|
2747
2956
|
};
|
|
2748
2957
|
const filename = `${agent.name}.md`;
|
|
2749
|
-
const filepath =
|
|
2958
|
+
const filepath = join18(agentsDir, filename);
|
|
2750
2959
|
writeFileSync4(filepath, serializeFrontmatter(fm, agent.content));
|
|
2751
2960
|
filesWritten.push(filepath);
|
|
2752
2961
|
}
|
|
2753
2962
|
}
|
|
2754
2963
|
if (pack.skills.length > 0) {
|
|
2755
|
-
const skillsDir =
|
|
2964
|
+
const skillsDir = join18(pluginDir, "skills");
|
|
2756
2965
|
ensureDir(skillsDir);
|
|
2757
2966
|
manifest.skills = "skills";
|
|
2758
2967
|
for (const skill of pack.skills) {
|
|
2759
|
-
const skillSubDir =
|
|
2968
|
+
const skillSubDir = join18(skillsDir, skill.name);
|
|
2760
2969
|
ensureDir(skillSubDir);
|
|
2761
|
-
const
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
};
|
|
2765
|
-
const filepath = join17(skillSubDir, "SKILL.md");
|
|
2766
|
-
writeFileSync4(filepath, serializeFrontmatter(fm, skill.content));
|
|
2970
|
+
const filepath = join18(skillSubDir, "SKILL.md");
|
|
2971
|
+
const content = serializeFrontmatter(buildSkillFrontmatter(skill), skill.content);
|
|
2972
|
+
writeFileSync4(filepath, content);
|
|
2767
2973
|
filesWritten.push(filepath);
|
|
2768
2974
|
}
|
|
2769
2975
|
}
|
|
2770
2976
|
if (pack.commands.length > 0) {
|
|
2771
|
-
const commandsDir =
|
|
2977
|
+
const commandsDir = join18(pluginDir, "commands");
|
|
2772
2978
|
ensureDir(commandsDir);
|
|
2773
2979
|
manifest.commands = "commands";
|
|
2774
2980
|
for (const cmd of pack.commands) {
|
|
@@ -2779,7 +2985,7 @@ function exportCursorPlugin(pack, outputDir) {
|
|
|
2779
2985
|
fm.description = cmd.meta.description;
|
|
2780
2986
|
}
|
|
2781
2987
|
const filename = `${cmd.name}.md`;
|
|
2782
|
-
const filepath =
|
|
2988
|
+
const filepath = join18(commandsDir, filename);
|
|
2783
2989
|
writeFileSync4(filepath, serializeFrontmatter(fm, cmd.content));
|
|
2784
2990
|
filesWritten.push(filepath);
|
|
2785
2991
|
}
|
|
@@ -2787,9 +2993,9 @@ function exportCursorPlugin(pack, outputDir) {
|
|
|
2787
2993
|
if (pack.hooks) {
|
|
2788
2994
|
const events = resolveHooksForTarget(pack.hooks, "cursor");
|
|
2789
2995
|
if (Object.keys(events).length > 0) {
|
|
2790
|
-
const hooksDir =
|
|
2996
|
+
const hooksDir = join18(pluginDir, "hooks");
|
|
2791
2997
|
ensureDir(hooksDir);
|
|
2792
|
-
const filepath =
|
|
2998
|
+
const filepath = join18(hooksDir, "hooks.json");
|
|
2793
2999
|
writeFileSync4(filepath, JSON.stringify({ version: pack.hooks.version ?? 1, hooks: events }, null, 2) + `
|
|
2794
3000
|
`);
|
|
2795
3001
|
filesWritten.push(filepath);
|
|
@@ -2798,14 +3004,14 @@ function exportCursorPlugin(pack, outputDir) {
|
|
|
2798
3004
|
}
|
|
2799
3005
|
if (pack.mcp && Object.keys(pack.mcp.servers).length > 0) {
|
|
2800
3006
|
manifest.mcpServers = ".mcp.json";
|
|
2801
|
-
const filepath =
|
|
3007
|
+
const filepath = join18(pluginDir, ".mcp.json");
|
|
2802
3008
|
writeFileSync4(filepath, JSON.stringify({ mcpServers: pack.mcp.servers }, null, 2) + `
|
|
2803
3009
|
`);
|
|
2804
3010
|
filesWritten.push(filepath);
|
|
2805
3011
|
}
|
|
2806
|
-
const manifestDir =
|
|
3012
|
+
const manifestDir = join18(pluginDir, ".cursor-plugin");
|
|
2807
3013
|
ensureDir(manifestDir);
|
|
2808
|
-
const manifestPath =
|
|
3014
|
+
const manifestPath = join18(manifestDir, "plugin.json");
|
|
2809
3015
|
writeFileSync4(manifestPath, JSON.stringify(manifest, null, 2) + `
|
|
2810
3016
|
`);
|
|
2811
3017
|
filesWritten.push(manifestPath);
|
|
@@ -2830,10 +3036,10 @@ function toCursorPluginAuthor(author) {
|
|
|
2830
3036
|
|
|
2831
3037
|
// src/importers/rulesync.ts
|
|
2832
3038
|
import { existsSync as existsSync10, readFileSync as readFileSync10, copyFileSync, writeFileSync as writeFileSync5 } from "fs";
|
|
2833
|
-
import { resolve as
|
|
3039
|
+
import { resolve as resolve17, join as join19, basename as basename6 } from "path";
|
|
2834
3040
|
import { parse as parseJsonc2 } from "jsonc-parser";
|
|
2835
3041
|
function importFromRulesync(projectRoot, outputPackDir) {
|
|
2836
|
-
const rulesyncDir =
|
|
3042
|
+
const rulesyncDir = resolve17(projectRoot, ".rulesync");
|
|
2837
3043
|
const warnings = [];
|
|
2838
3044
|
const filesImported = [];
|
|
2839
3045
|
if (!existsSync10(rulesyncDir)) {
|
|
@@ -2844,79 +3050,85 @@ function importFromRulesync(projectRoot, outputPackDir) {
|
|
|
2844
3050
|
configGenerated: false
|
|
2845
3051
|
};
|
|
2846
3052
|
}
|
|
2847
|
-
const packDir = outputPackDir ??
|
|
3053
|
+
const packDir = outputPackDir ?? resolve17(projectRoot, "packs", "default");
|
|
2848
3054
|
ensureDir(packDir);
|
|
2849
|
-
const rulesDir =
|
|
3055
|
+
const rulesDir = resolve17(rulesyncDir, "rules");
|
|
2850
3056
|
if (existsSync10(rulesDir)) {
|
|
2851
|
-
const outRulesDir =
|
|
3057
|
+
const outRulesDir = resolve17(packDir, "rules");
|
|
2852
3058
|
ensureDir(outRulesDir);
|
|
2853
3059
|
const files = listFiles(rulesDir, { extension: ".md" });
|
|
2854
3060
|
for (const file of files) {
|
|
2855
|
-
const dest =
|
|
3061
|
+
const dest = join19(outRulesDir, basename6(file));
|
|
2856
3062
|
copyFileSync(file, dest);
|
|
2857
3063
|
filesImported.push(dest);
|
|
2858
3064
|
}
|
|
2859
3065
|
}
|
|
2860
|
-
const commandsDir =
|
|
3066
|
+
const commandsDir = resolve17(rulesyncDir, "commands");
|
|
2861
3067
|
if (existsSync10(commandsDir)) {
|
|
2862
|
-
const outCommandsDir =
|
|
3068
|
+
const outCommandsDir = resolve17(packDir, "commands");
|
|
2863
3069
|
ensureDir(outCommandsDir);
|
|
2864
3070
|
const files = listFiles(commandsDir, { extension: ".md" });
|
|
2865
3071
|
for (const file of files) {
|
|
2866
|
-
const dest =
|
|
3072
|
+
const dest = join19(outCommandsDir, basename6(file));
|
|
2867
3073
|
copyFileSync(file, dest);
|
|
2868
3074
|
filesImported.push(dest);
|
|
2869
3075
|
}
|
|
2870
3076
|
}
|
|
2871
|
-
const subagentsDir =
|
|
3077
|
+
const subagentsDir = resolve17(rulesyncDir, "subagents");
|
|
2872
3078
|
if (existsSync10(subagentsDir)) {
|
|
2873
|
-
const outAgentsDir =
|
|
3079
|
+
const outAgentsDir = resolve17(packDir, "agents");
|
|
2874
3080
|
ensureDir(outAgentsDir);
|
|
2875
3081
|
const files = listFiles(subagentsDir, { extension: ".md" });
|
|
2876
3082
|
for (const file of files) {
|
|
2877
|
-
const dest =
|
|
3083
|
+
const dest = join19(outAgentsDir, basename6(file));
|
|
2878
3084
|
copyFileSync(file, dest);
|
|
2879
3085
|
filesImported.push(dest);
|
|
2880
3086
|
}
|
|
2881
3087
|
}
|
|
2882
|
-
const skillsDir =
|
|
3088
|
+
const skillsDir = resolve17(rulesyncDir, "skills");
|
|
2883
3089
|
if (existsSync10(skillsDir)) {
|
|
2884
|
-
const outSkillsDir =
|
|
3090
|
+
const outSkillsDir = resolve17(packDir, "skills");
|
|
2885
3091
|
ensureDir(outSkillsDir);
|
|
2886
3092
|
const skillDirs = listDirs(skillsDir);
|
|
2887
3093
|
for (const skillDir of skillDirs) {
|
|
2888
3094
|
const skillName = basename6(skillDir);
|
|
2889
3095
|
if (skillName.startsWith("."))
|
|
2890
3096
|
continue;
|
|
2891
|
-
const skillMd =
|
|
3097
|
+
const skillMd = join19(skillDir, "SKILL.md");
|
|
2892
3098
|
if (existsSync10(skillMd)) {
|
|
2893
|
-
const outSkillDir =
|
|
3099
|
+
const outSkillDir = join19(outSkillsDir, skillName);
|
|
2894
3100
|
ensureDir(outSkillDir);
|
|
2895
|
-
|
|
2896
|
-
|
|
3101
|
+
const rawSkill = readFileSync10(skillMd, "utf-8");
|
|
3102
|
+
const normalized = normalizeImportedSkillMarkdown(rawSkill, skillName);
|
|
3103
|
+
const dest = join19(outSkillDir, "SKILL.md");
|
|
3104
|
+
writeFileSync5(dest, normalized.content);
|
|
3105
|
+
filesImported.push(dest);
|
|
3106
|
+
if (normalized.addedDescription) {
|
|
3107
|
+
warnings.push(`skills/${skillName}/SKILL.md missing description; added import placeholder.`);
|
|
3108
|
+
}
|
|
2897
3109
|
}
|
|
2898
3110
|
}
|
|
2899
3111
|
}
|
|
2900
|
-
const hooksJson =
|
|
3112
|
+
const hooksJson = resolve17(rulesyncDir, "hooks.json");
|
|
2901
3113
|
if (existsSync10(hooksJson)) {
|
|
2902
|
-
const outHooksDir =
|
|
3114
|
+
const outHooksDir = resolve17(packDir, "hooks");
|
|
2903
3115
|
ensureDir(outHooksDir);
|
|
2904
|
-
copyFileSync(hooksJson,
|
|
2905
|
-
filesImported.push(
|
|
3116
|
+
copyFileSync(hooksJson, join19(outHooksDir, "hooks.json"));
|
|
3117
|
+
filesImported.push(join19(outHooksDir, "hooks.json"));
|
|
2906
3118
|
}
|
|
2907
|
-
const mcpJson =
|
|
3119
|
+
const mcpJson = resolve17(rulesyncDir, "mcp.json");
|
|
2908
3120
|
if (existsSync10(mcpJson)) {
|
|
2909
|
-
copyFileSync(mcpJson,
|
|
2910
|
-
filesImported.push(
|
|
3121
|
+
copyFileSync(mcpJson, join19(packDir, "mcp.json"));
|
|
3122
|
+
filesImported.push(join19(packDir, "mcp.json"));
|
|
2911
3123
|
}
|
|
2912
|
-
const aiIgnore =
|
|
2913
|
-
const rulesyncIgnore =
|
|
3124
|
+
const aiIgnore = resolve17(rulesyncDir, ".aiignore");
|
|
3125
|
+
const rulesyncIgnore = resolve17(projectRoot, ".rulesyncignore");
|
|
2914
3126
|
if (existsSync10(aiIgnore)) {
|
|
2915
|
-
copyFileSync(aiIgnore,
|
|
2916
|
-
filesImported.push(
|
|
3127
|
+
copyFileSync(aiIgnore, join19(packDir, "ignore"));
|
|
3128
|
+
filesImported.push(join19(packDir, "ignore"));
|
|
2917
3129
|
} else if (existsSync10(rulesyncIgnore)) {
|
|
2918
|
-
copyFileSync(rulesyncIgnore,
|
|
2919
|
-
filesImported.push(
|
|
3130
|
+
copyFileSync(rulesyncIgnore, join19(packDir, "ignore"));
|
|
3131
|
+
filesImported.push(join19(packDir, "ignore"));
|
|
2920
3132
|
}
|
|
2921
3133
|
const packJson = {
|
|
2922
3134
|
name: "default",
|
|
@@ -2928,14 +3140,14 @@ function importFromRulesync(projectRoot, outputPackDir) {
|
|
|
2928
3140
|
targets: "*",
|
|
2929
3141
|
features: "*"
|
|
2930
3142
|
};
|
|
2931
|
-
writeFileSync5(
|
|
3143
|
+
writeFileSync5(join19(packDir, "pack.json"), JSON.stringify(packJson, null, 2) + `
|
|
2932
3144
|
`);
|
|
2933
|
-
filesImported.push(
|
|
3145
|
+
filesImported.push(join19(packDir, "pack.json"));
|
|
2934
3146
|
let configGenerated = false;
|
|
2935
|
-
const rulesyncConfig =
|
|
3147
|
+
const rulesyncConfig = resolve17(projectRoot, "rulesync.jsonc");
|
|
2936
3148
|
if (existsSync10(rulesyncConfig)) {
|
|
2937
3149
|
const agentpacksConfig = convertRulesyncConfig(rulesyncConfig, packDir);
|
|
2938
|
-
const configPath =
|
|
3150
|
+
const configPath = resolve17(projectRoot, "agentpacks.jsonc");
|
|
2939
3151
|
writeFileSync5(configPath, agentpacksConfig);
|
|
2940
3152
|
configGenerated = true;
|
|
2941
3153
|
}
|
|
@@ -2949,7 +3161,7 @@ function convertRulesyncConfig(rulesyncPath, _packDir) {
|
|
|
2949
3161
|
const baseDirs = parsed.baseDirs ?? ["."];
|
|
2950
3162
|
const global = parsed.global ?? false;
|
|
2951
3163
|
const deleteVal = parsed.delete ?? true;
|
|
2952
|
-
const relPackDir = "./" +
|
|
3164
|
+
const relPackDir = "./" + join19("packs", "default");
|
|
2953
3165
|
const config = {
|
|
2954
3166
|
$schema: "https://unpkg.com/agentpacks/schema.json",
|
|
2955
3167
|
packs: [relPackDir],
|
|
@@ -2967,9 +3179,9 @@ function convertRulesyncConfig(rulesyncPath, _packDir) {
|
|
|
2967
3179
|
|
|
2968
3180
|
// src/importers/cursor.ts
|
|
2969
3181
|
import { existsSync as existsSync11, readFileSync as readFileSync11, writeFileSync as writeFileSync6, copyFileSync as copyFileSync2 } from "fs";
|
|
2970
|
-
import { resolve as
|
|
3182
|
+
import { resolve as resolve18, join as join20, basename as basename7 } from "path";
|
|
2971
3183
|
function importFromCursor(projectRoot, outputPackDir) {
|
|
2972
|
-
const cursorDir =
|
|
3184
|
+
const cursorDir = resolve18(projectRoot, ".cursor");
|
|
2973
3185
|
const warnings = [];
|
|
2974
3186
|
const filesImported = [];
|
|
2975
3187
|
if (!existsSync11(cursorDir)) {
|
|
@@ -2980,11 +3192,11 @@ function importFromCursor(projectRoot, outputPackDir) {
|
|
|
2980
3192
|
configGenerated: false
|
|
2981
3193
|
};
|
|
2982
3194
|
}
|
|
2983
|
-
const packDir = outputPackDir ??
|
|
3195
|
+
const packDir = outputPackDir ?? resolve18(projectRoot, "packs", "cursor-import");
|
|
2984
3196
|
ensureDir(packDir);
|
|
2985
|
-
const rulesDir =
|
|
3197
|
+
const rulesDir = resolve18(cursorDir, "rules");
|
|
2986
3198
|
if (existsSync11(rulesDir)) {
|
|
2987
|
-
const outRulesDir =
|
|
3199
|
+
const outRulesDir = resolve18(packDir, "rules");
|
|
2988
3200
|
ensureDir(outRulesDir);
|
|
2989
3201
|
const files = listFiles(rulesDir, { extension: ".mdc" });
|
|
2990
3202
|
for (const file of files) {
|
|
@@ -3000,64 +3212,70 @@ function importFromCursor(projectRoot, outputPackDir) {
|
|
|
3000
3212
|
meta.cursor = { ...data };
|
|
3001
3213
|
const mdContent = buildAgentpacksRule(meta, content);
|
|
3002
3214
|
const name = basename7(file, ".mdc");
|
|
3003
|
-
const dest =
|
|
3215
|
+
const dest = join20(outRulesDir, `${name}.md`);
|
|
3004
3216
|
writeFileSync6(dest, mdContent);
|
|
3005
3217
|
filesImported.push(dest);
|
|
3006
3218
|
}
|
|
3007
3219
|
const mdFiles = listFiles(rulesDir, { extension: ".md" });
|
|
3008
3220
|
for (const file of mdFiles) {
|
|
3009
|
-
const dest =
|
|
3221
|
+
const dest = join20(outRulesDir, basename7(file));
|
|
3010
3222
|
copyFileSync2(file, dest);
|
|
3011
3223
|
filesImported.push(dest);
|
|
3012
3224
|
}
|
|
3013
3225
|
}
|
|
3014
|
-
const agentsDir =
|
|
3226
|
+
const agentsDir = resolve18(cursorDir, "agents");
|
|
3015
3227
|
if (existsSync11(agentsDir)) {
|
|
3016
|
-
const outDir =
|
|
3228
|
+
const outDir = resolve18(packDir, "agents");
|
|
3017
3229
|
ensureDir(outDir);
|
|
3018
3230
|
const files = listFiles(agentsDir, { extension: ".md" });
|
|
3019
3231
|
for (const file of files) {
|
|
3020
|
-
const dest =
|
|
3232
|
+
const dest = join20(outDir, basename7(file));
|
|
3021
3233
|
copyFileSync2(file, dest);
|
|
3022
3234
|
filesImported.push(dest);
|
|
3023
3235
|
}
|
|
3024
3236
|
}
|
|
3025
|
-
const skillsDir =
|
|
3237
|
+
const skillsDir = resolve18(cursorDir, "skills");
|
|
3026
3238
|
if (existsSync11(skillsDir)) {
|
|
3027
|
-
const outDir =
|
|
3239
|
+
const outDir = resolve18(packDir, "skills");
|
|
3028
3240
|
ensureDir(outDir);
|
|
3029
3241
|
const dirs = listDirs(skillsDir);
|
|
3030
3242
|
for (const dir of dirs) {
|
|
3031
3243
|
const name = basename7(dir);
|
|
3032
|
-
const skillMd =
|
|
3244
|
+
const skillMd = join20(dir, "SKILL.md");
|
|
3033
3245
|
if (existsSync11(skillMd)) {
|
|
3034
|
-
const outSkillDir =
|
|
3246
|
+
const outSkillDir = join20(outDir, name);
|
|
3035
3247
|
ensureDir(outSkillDir);
|
|
3036
|
-
|
|
3037
|
-
|
|
3248
|
+
const rawSkill = readFileSync11(skillMd, "utf-8");
|
|
3249
|
+
const normalized = normalizeImportedSkillMarkdown(rawSkill, name);
|
|
3250
|
+
const dest = join20(outSkillDir, "SKILL.md");
|
|
3251
|
+
writeFileSync6(dest, normalized.content);
|
|
3252
|
+
filesImported.push(dest);
|
|
3253
|
+
if (normalized.addedDescription) {
|
|
3254
|
+
warnings.push(`skills/${name}/SKILL.md missing description; added import placeholder.`);
|
|
3255
|
+
}
|
|
3038
3256
|
}
|
|
3039
3257
|
}
|
|
3040
3258
|
}
|
|
3041
|
-
const commandsDir =
|
|
3259
|
+
const commandsDir = resolve18(cursorDir, "commands");
|
|
3042
3260
|
if (existsSync11(commandsDir)) {
|
|
3043
|
-
const outDir =
|
|
3261
|
+
const outDir = resolve18(packDir, "commands");
|
|
3044
3262
|
ensureDir(outDir);
|
|
3045
3263
|
const files = listFiles(commandsDir, { extension: ".md" });
|
|
3046
3264
|
for (const file of files) {
|
|
3047
|
-
const dest =
|
|
3265
|
+
const dest = join20(outDir, basename7(file));
|
|
3048
3266
|
copyFileSync2(file, dest);
|
|
3049
3267
|
filesImported.push(dest);
|
|
3050
3268
|
}
|
|
3051
3269
|
}
|
|
3052
|
-
const mcpJson =
|
|
3270
|
+
const mcpJson = resolve18(cursorDir, "mcp.json");
|
|
3053
3271
|
if (existsSync11(mcpJson)) {
|
|
3054
|
-
copyFileSync2(mcpJson,
|
|
3055
|
-
filesImported.push(
|
|
3272
|
+
copyFileSync2(mcpJson, join20(packDir, "mcp.json"));
|
|
3273
|
+
filesImported.push(join20(packDir, "mcp.json"));
|
|
3056
3274
|
}
|
|
3057
|
-
const cursorIgnore =
|
|
3275
|
+
const cursorIgnore = resolve18(projectRoot, ".cursorignore");
|
|
3058
3276
|
if (existsSync11(cursorIgnore)) {
|
|
3059
|
-
copyFileSync2(cursorIgnore,
|
|
3060
|
-
filesImported.push(
|
|
3277
|
+
copyFileSync2(cursorIgnore, join20(packDir, "ignore"));
|
|
3278
|
+
filesImported.push(join20(packDir, "ignore"));
|
|
3061
3279
|
}
|
|
3062
3280
|
writePackJson(packDir, "cursor-import", filesImported);
|
|
3063
3281
|
return { packDir, filesImported, warnings, configGenerated: false };
|
|
@@ -3086,7 +3304,7 @@ function writePackJson(packDir, name, filesImported) {
|
|
|
3086
3304
|
targets: "*",
|
|
3087
3305
|
features: "*"
|
|
3088
3306
|
};
|
|
3089
|
-
const dest =
|
|
3307
|
+
const dest = join20(packDir, "pack.json");
|
|
3090
3308
|
writeFileSync6(dest, JSON.stringify(packJson, null, 2) + `
|
|
3091
3309
|
`);
|
|
3092
3310
|
filesImported.push(dest);
|
|
@@ -3094,12 +3312,12 @@ function writePackJson(packDir, name, filesImported) {
|
|
|
3094
3312
|
|
|
3095
3313
|
// src/importers/claude-code.ts
|
|
3096
3314
|
import { existsSync as existsSync12, readFileSync as readFileSync12, writeFileSync as writeFileSync7, copyFileSync as copyFileSync3 } from "fs";
|
|
3097
|
-
import { resolve as
|
|
3315
|
+
import { resolve as resolve19, join as join21, basename as basename8 } from "path";
|
|
3098
3316
|
function importFromClaudeCode(projectRoot, outputPackDir) {
|
|
3099
3317
|
const warnings = [];
|
|
3100
3318
|
const filesImported = [];
|
|
3101
|
-
const claudeDir =
|
|
3102
|
-
const hasClaudeMd = existsSync12(
|
|
3319
|
+
const claudeDir = resolve19(projectRoot, ".claude");
|
|
3320
|
+
const hasClaudeMd = existsSync12(resolve19(projectRoot, "CLAUDE.md"));
|
|
3103
3321
|
const hasClaudeDir = existsSync12(claudeDir);
|
|
3104
3322
|
if (!hasClaudeMd && !hasClaudeDir) {
|
|
3105
3323
|
return {
|
|
@@ -3109,12 +3327,12 @@ function importFromClaudeCode(projectRoot, outputPackDir) {
|
|
|
3109
3327
|
configGenerated: false
|
|
3110
3328
|
};
|
|
3111
3329
|
}
|
|
3112
|
-
const packDir = outputPackDir ??
|
|
3330
|
+
const packDir = outputPackDir ?? resolve19(projectRoot, "packs", "claude-import");
|
|
3113
3331
|
ensureDir(packDir);
|
|
3114
|
-
const rulesDir =
|
|
3332
|
+
const rulesDir = resolve19(packDir, "rules");
|
|
3115
3333
|
ensureDir(rulesDir);
|
|
3116
3334
|
if (hasClaudeMd) {
|
|
3117
|
-
const raw = readFileSync12(
|
|
3335
|
+
const raw = readFileSync12(resolve19(projectRoot, "CLAUDE.md"), "utf-8");
|
|
3118
3336
|
const ruleContent = [
|
|
3119
3337
|
"---",
|
|
3120
3338
|
"root: true",
|
|
@@ -3124,21 +3342,21 @@ function importFromClaudeCode(projectRoot, outputPackDir) {
|
|
|
3124
3342
|
raw
|
|
3125
3343
|
].join(`
|
|
3126
3344
|
`);
|
|
3127
|
-
const dest =
|
|
3345
|
+
const dest = join21(rulesDir, "claude-root.md");
|
|
3128
3346
|
writeFileSync7(dest, ruleContent);
|
|
3129
3347
|
filesImported.push(dest);
|
|
3130
3348
|
}
|
|
3131
3349
|
if (hasClaudeDir) {
|
|
3132
|
-
const claudeRulesDir =
|
|
3350
|
+
const claudeRulesDir = resolve19(claudeDir, "rules");
|
|
3133
3351
|
if (existsSync12(claudeRulesDir)) {
|
|
3134
3352
|
const files = listFiles(claudeRulesDir, { extension: ".md" });
|
|
3135
3353
|
for (const file of files) {
|
|
3136
|
-
const dest =
|
|
3354
|
+
const dest = join21(rulesDir, basename8(file));
|
|
3137
3355
|
copyFileSync3(file, dest);
|
|
3138
3356
|
filesImported.push(dest);
|
|
3139
3357
|
}
|
|
3140
3358
|
}
|
|
3141
|
-
const settingsPath =
|
|
3359
|
+
const settingsPath = resolve19(claudeDir, "settings.json");
|
|
3142
3360
|
if (existsSync12(settingsPath)) {
|
|
3143
3361
|
try {
|
|
3144
3362
|
const raw = readFileSync12(settingsPath, "utf-8");
|
|
@@ -3146,7 +3364,7 @@ function importFromClaudeCode(projectRoot, outputPackDir) {
|
|
|
3146
3364
|
const mcpServers = settings.mcpServers ?? settings.mcp_servers;
|
|
3147
3365
|
if (mcpServers && typeof mcpServers === "object") {
|
|
3148
3366
|
const mcpConfig = { servers: mcpServers };
|
|
3149
|
-
const dest =
|
|
3367
|
+
const dest = join21(packDir, "mcp.json");
|
|
3150
3368
|
writeFileSync7(dest, JSON.stringify(mcpConfig, null, 2) + `
|
|
3151
3369
|
`);
|
|
3152
3370
|
filesImported.push(dest);
|
|
@@ -3166,7 +3384,7 @@ function importFromClaudeCode(projectRoot, outputPackDir) {
|
|
|
3166
3384
|
targets: "*",
|
|
3167
3385
|
features: "*"
|
|
3168
3386
|
};
|
|
3169
|
-
const packJsonPath =
|
|
3387
|
+
const packJsonPath = join21(packDir, "pack.json");
|
|
3170
3388
|
writeFileSync7(packJsonPath, JSON.stringify(packJson, null, 2) + `
|
|
3171
3389
|
`);
|
|
3172
3390
|
filesImported.push(packJsonPath);
|
|
@@ -3175,11 +3393,11 @@ function importFromClaudeCode(projectRoot, outputPackDir) {
|
|
|
3175
3393
|
|
|
3176
3394
|
// src/importers/opencode.ts
|
|
3177
3395
|
import { existsSync as existsSync13, readFileSync as readFileSync13, writeFileSync as writeFileSync8, copyFileSync as copyFileSync4 } from "fs";
|
|
3178
|
-
import { resolve as
|
|
3396
|
+
import { resolve as resolve20, join as join22, basename as basename9 } from "path";
|
|
3179
3397
|
function importFromOpenCode(projectRoot, outputPackDir) {
|
|
3180
3398
|
const warnings = [];
|
|
3181
3399
|
const filesImported = [];
|
|
3182
|
-
const ocDir =
|
|
3400
|
+
const ocDir = resolve20(projectRoot, ".opencode");
|
|
3183
3401
|
if (!existsSync13(ocDir)) {
|
|
3184
3402
|
return {
|
|
3185
3403
|
packDir: "",
|
|
@@ -3188,45 +3406,51 @@ function importFromOpenCode(projectRoot, outputPackDir) {
|
|
|
3188
3406
|
configGenerated: false
|
|
3189
3407
|
};
|
|
3190
3408
|
}
|
|
3191
|
-
const packDir = outputPackDir ??
|
|
3409
|
+
const packDir = outputPackDir ?? resolve20(projectRoot, "packs", "opencode-import");
|
|
3192
3410
|
ensureDir(packDir);
|
|
3193
|
-
importDirMd(
|
|
3194
|
-
importDirMd(
|
|
3195
|
-
importDirMd(
|
|
3196
|
-
const skillDir =
|
|
3411
|
+
importDirMd(resolve20(ocDir, "rules"), resolve20(packDir, "rules"), filesImported);
|
|
3412
|
+
importDirMd(resolve20(ocDir, "commands"), resolve20(packDir, "commands"), filesImported);
|
|
3413
|
+
importDirMd(resolve20(ocDir, "agents"), resolve20(packDir, "agents"), filesImported);
|
|
3414
|
+
const skillDir = resolve20(ocDir, "skill");
|
|
3197
3415
|
if (existsSync13(skillDir)) {
|
|
3198
|
-
const outSkillDir =
|
|
3416
|
+
const outSkillDir = resolve20(packDir, "skills");
|
|
3199
3417
|
ensureDir(outSkillDir);
|
|
3200
3418
|
const dirs = listDirs(skillDir);
|
|
3201
3419
|
for (const dir of dirs) {
|
|
3202
3420
|
const name = basename9(dir);
|
|
3203
3421
|
if (name.startsWith("."))
|
|
3204
3422
|
continue;
|
|
3205
|
-
const skillMd =
|
|
3423
|
+
const skillMd = join22(dir, "SKILL.md");
|
|
3206
3424
|
if (existsSync13(skillMd)) {
|
|
3207
|
-
const outDir =
|
|
3425
|
+
const outDir = join22(outSkillDir, name);
|
|
3208
3426
|
ensureDir(outDir);
|
|
3209
|
-
|
|
3210
|
-
|
|
3427
|
+
const rawSkill = readFileSync13(skillMd, "utf-8");
|
|
3428
|
+
const normalized = normalizeImportedSkillMarkdown(rawSkill, name);
|
|
3429
|
+
const dest2 = join22(outDir, "SKILL.md");
|
|
3430
|
+
writeFileSync8(dest2, normalized.content);
|
|
3431
|
+
filesImported.push(dest2);
|
|
3432
|
+
if (normalized.addedDescription) {
|
|
3433
|
+
warnings.push(`skills/${name}/SKILL.md missing description; added import placeholder.`);
|
|
3434
|
+
}
|
|
3211
3435
|
}
|
|
3212
3436
|
}
|
|
3213
3437
|
}
|
|
3214
|
-
const pluginsDir =
|
|
3438
|
+
const pluginsDir = resolve20(ocDir, "plugins");
|
|
3215
3439
|
if (existsSync13(pluginsDir)) {
|
|
3216
|
-
const outPluginsDir =
|
|
3440
|
+
const outPluginsDir = resolve20(packDir, "plugins");
|
|
3217
3441
|
ensureDir(outPluginsDir);
|
|
3218
3442
|
const files = listFiles(pluginsDir);
|
|
3219
3443
|
for (const file of files) {
|
|
3220
3444
|
if (file.endsWith(".ts") || file.endsWith(".js")) {
|
|
3221
|
-
const dest2 =
|
|
3445
|
+
const dest2 = join22(outPluginsDir, basename9(file));
|
|
3222
3446
|
copyFileSync4(file, dest2);
|
|
3223
3447
|
filesImported.push(dest2);
|
|
3224
3448
|
}
|
|
3225
3449
|
}
|
|
3226
3450
|
}
|
|
3227
|
-
const agentsMd =
|
|
3451
|
+
const agentsMd = resolve20(projectRoot, "AGENTS.md");
|
|
3228
3452
|
if (existsSync13(agentsMd)) {
|
|
3229
|
-
const outRulesDir =
|
|
3453
|
+
const outRulesDir = resolve20(packDir, "rules");
|
|
3230
3454
|
ensureDir(outRulesDir);
|
|
3231
3455
|
const raw = readFileSync13(agentsMd, "utf-8");
|
|
3232
3456
|
const ruleContent = [
|
|
@@ -3238,18 +3462,18 @@ function importFromOpenCode(projectRoot, outputPackDir) {
|
|
|
3238
3462
|
raw
|
|
3239
3463
|
].join(`
|
|
3240
3464
|
`);
|
|
3241
|
-
const dest2 =
|
|
3465
|
+
const dest2 = join22(outRulesDir, "agents-md-root.md");
|
|
3242
3466
|
writeFileSync8(dest2, ruleContent);
|
|
3243
3467
|
filesImported.push(dest2);
|
|
3244
3468
|
}
|
|
3245
|
-
const ocJson =
|
|
3469
|
+
const ocJson = resolve20(projectRoot, "opencode.json");
|
|
3246
3470
|
if (existsSync13(ocJson)) {
|
|
3247
3471
|
try {
|
|
3248
3472
|
const raw = readFileSync13(ocJson, "utf-8");
|
|
3249
3473
|
const config = JSON.parse(raw);
|
|
3250
3474
|
const mcpObj = config.mcp;
|
|
3251
3475
|
if (mcpObj) {
|
|
3252
|
-
const dest2 =
|
|
3476
|
+
const dest2 = join22(packDir, "mcp.json");
|
|
3253
3477
|
writeFileSync8(dest2, JSON.stringify({ servers: mcpObj }, null, 2) + `
|
|
3254
3478
|
`);
|
|
3255
3479
|
filesImported.push(dest2);
|
|
@@ -3258,10 +3482,10 @@ function importFromOpenCode(projectRoot, outputPackDir) {
|
|
|
3258
3482
|
warnings.push("Failed to parse opencode.json");
|
|
3259
3483
|
}
|
|
3260
3484
|
}
|
|
3261
|
-
const ocIgnore =
|
|
3485
|
+
const ocIgnore = resolve20(projectRoot, ".opencodeignore");
|
|
3262
3486
|
if (existsSync13(ocIgnore)) {
|
|
3263
|
-
copyFileSync4(ocIgnore,
|
|
3264
|
-
filesImported.push(
|
|
3487
|
+
copyFileSync4(ocIgnore, join22(packDir, "ignore"));
|
|
3488
|
+
filesImported.push(join22(packDir, "ignore"));
|
|
3265
3489
|
}
|
|
3266
3490
|
const packJson = {
|
|
3267
3491
|
name: "opencode-import",
|
|
@@ -3273,7 +3497,7 @@ function importFromOpenCode(projectRoot, outputPackDir) {
|
|
|
3273
3497
|
targets: "*",
|
|
3274
3498
|
features: "*"
|
|
3275
3499
|
};
|
|
3276
|
-
const dest =
|
|
3500
|
+
const dest = join22(packDir, "pack.json");
|
|
3277
3501
|
writeFileSync8(dest, JSON.stringify(packJson, null, 2) + `
|
|
3278
3502
|
`);
|
|
3279
3503
|
filesImported.push(dest);
|
|
@@ -3285,14 +3509,14 @@ function importDirMd(srcDir, outDir, filesImported) {
|
|
|
3285
3509
|
ensureDir(outDir);
|
|
3286
3510
|
const files = listFiles(srcDir, { extension: ".md" });
|
|
3287
3511
|
for (const file of files) {
|
|
3288
|
-
const dest =
|
|
3512
|
+
const dest = join22(outDir, basename9(file));
|
|
3289
3513
|
copyFileSync4(file, dest);
|
|
3290
3514
|
filesImported.push(dest);
|
|
3291
3515
|
}
|
|
3292
3516
|
}
|
|
3293
3517
|
|
|
3294
3518
|
// src/cli/export-cmd.ts
|
|
3295
|
-
import { resolve as
|
|
3519
|
+
import { resolve as resolve21 } from "path";
|
|
3296
3520
|
import chalk from "chalk";
|
|
3297
3521
|
function runExport(projectRoot, options) {
|
|
3298
3522
|
const config = loadWorkspaceConfig(projectRoot);
|
|
@@ -3311,7 +3535,7 @@ function runExport(projectRoot, options) {
|
|
|
3311
3535
|
console.log(chalk.red(`Pack "${options.pack}" not found.`));
|
|
3312
3536
|
return;
|
|
3313
3537
|
}
|
|
3314
|
-
const outputDir =
|
|
3538
|
+
const outputDir = resolve21(projectRoot, options.output ?? "dist/cursor-plugins");
|
|
3315
3539
|
switch (options.format) {
|
|
3316
3540
|
case "cursor-plugin": {
|
|
3317
3541
|
let totalFiles = 0;
|
|
@@ -3799,10 +4023,10 @@ class RegistryApiError extends Error {
|
|
|
3799
4023
|
|
|
3800
4024
|
// src/utils/credentials.ts
|
|
3801
4025
|
import { existsSync as existsSync16, readFileSync as readFileSync16, writeFileSync as writeFileSync9, mkdirSync as mkdirSync5 } from "fs";
|
|
3802
|
-
import { join as
|
|
4026
|
+
import { join as join23, dirname as dirname2 } from "path";
|
|
3803
4027
|
import { homedir } from "os";
|
|
3804
|
-
var CONFIG_DIR =
|
|
3805
|
-
var CREDENTIALS_FILE =
|
|
4028
|
+
var CONFIG_DIR = join23(homedir(), ".config", "agentpacks");
|
|
4029
|
+
var CREDENTIALS_FILE = join23(CONFIG_DIR, "credentials.json");
|
|
3806
4030
|
function loadCredentials() {
|
|
3807
4031
|
if (!existsSync16(CREDENTIALS_FILE)) {
|
|
3808
4032
|
return { registryUrl: "https://registry.agentpacks.dev" };
|
|
@@ -3891,16 +4115,16 @@ function formatBytes(bytes) {
|
|
|
3891
4115
|
|
|
3892
4116
|
// src/cli/init.ts
|
|
3893
4117
|
import { existsSync as existsSync17, copyFileSync as copyFileSync5, writeFileSync as writeFileSync10 } from "fs";
|
|
3894
|
-
import { resolve as
|
|
4118
|
+
import { resolve as resolve22, join as join24 } from "path";
|
|
3895
4119
|
import chalk5 from "chalk";
|
|
3896
4120
|
function runInit(projectRoot) {
|
|
3897
|
-
const configPath =
|
|
3898
|
-
const packsDir =
|
|
4121
|
+
const configPath = resolve22(projectRoot, "agentpacks.jsonc");
|
|
4122
|
+
const packsDir = resolve22(projectRoot, "packs", "default");
|
|
3899
4123
|
if (existsSync17(configPath)) {
|
|
3900
4124
|
console.log(chalk5.yellow("agentpacks.jsonc already exists. Skipping config creation."));
|
|
3901
4125
|
} else {
|
|
3902
|
-
const templateDir =
|
|
3903
|
-
const templateConfig =
|
|
4126
|
+
const templateDir = resolve22(import.meta.dirname, "..", "..", "templates");
|
|
4127
|
+
const templateConfig = resolve22(templateDir, "workspace", "agentpacks.jsonc");
|
|
3904
4128
|
if (existsSync17(templateConfig)) {
|
|
3905
4129
|
copyFileSync5(templateConfig, configPath);
|
|
3906
4130
|
} else {
|
|
@@ -3931,10 +4155,10 @@ function runInit(projectRoot) {
|
|
|
3931
4155
|
console.log(chalk5.yellow("packs/default/ already exists. Skipping pack scaffold."));
|
|
3932
4156
|
} else {
|
|
3933
4157
|
ensureDir(packsDir);
|
|
3934
|
-
ensureDir(
|
|
3935
|
-
ensureDir(
|
|
3936
|
-
ensureDir(
|
|
3937
|
-
ensureDir(
|
|
4158
|
+
ensureDir(join24(packsDir, "rules"));
|
|
4159
|
+
ensureDir(join24(packsDir, "commands"));
|
|
4160
|
+
ensureDir(join24(packsDir, "agents"));
|
|
4161
|
+
ensureDir(join24(packsDir, "skills"));
|
|
3938
4162
|
const packJson = {
|
|
3939
4163
|
name: "default",
|
|
3940
4164
|
version: "1.0.0",
|
|
@@ -3945,11 +4169,11 @@ function runInit(projectRoot) {
|
|
|
3945
4169
|
targets: "*",
|
|
3946
4170
|
features: "*"
|
|
3947
4171
|
};
|
|
3948
|
-
writeFileSync10(
|
|
4172
|
+
writeFileSync10(join24(packsDir, "pack.json"), JSON.stringify(packJson, null, 2) + `
|
|
3949
4173
|
`);
|
|
3950
|
-
const templateRule =
|
|
4174
|
+
const templateRule = resolve22(import.meta.dirname, "..", "..", "templates", "pack", "rules", "overview.md");
|
|
3951
4175
|
if (existsSync17(templateRule)) {
|
|
3952
|
-
copyFileSync5(templateRule,
|
|
4176
|
+
copyFileSync5(templateRule, join24(packsDir, "rules", "overview.md"));
|
|
3953
4177
|
}
|
|
3954
4178
|
console.log(chalk5.green("Created packs/default/ with scaffold"));
|
|
3955
4179
|
}
|
|
@@ -3963,12 +4187,12 @@ Next steps:`), `
|
|
|
3963
4187
|
// src/utils/tarball.ts
|
|
3964
4188
|
import { execSync as execSync2 } from "child_process";
|
|
3965
4189
|
import { readFileSync as readFileSync17, existsSync as existsSync18, mkdirSync as mkdirSync6, rmSync as rmSync2 } from "fs";
|
|
3966
|
-
import { join as
|
|
4190
|
+
import { join as join25, resolve as resolve23 } from "path";
|
|
3967
4191
|
import { createHash as createHash2 } from "crypto";
|
|
3968
4192
|
import { tmpdir } from "os";
|
|
3969
4193
|
async function createTarball(packDir) {
|
|
3970
|
-
const absDir =
|
|
3971
|
-
const tmpFile =
|
|
4194
|
+
const absDir = resolve23(packDir);
|
|
4195
|
+
const tmpFile = join25(tmpdir(), `agentpacks-${Date.now()}.tgz`);
|
|
3972
4196
|
try {
|
|
3973
4197
|
execSync2(`tar -czf "${tmpFile}" -C "${absDir}" .`, {
|
|
3974
4198
|
stdio: "pipe"
|
|
@@ -3983,7 +4207,7 @@ async function createTarball(packDir) {
|
|
|
3983
4207
|
}
|
|
3984
4208
|
async function extractTarball(data, targetDir) {
|
|
3985
4209
|
mkdirSync6(targetDir, { recursive: true });
|
|
3986
|
-
const tmpFile =
|
|
4210
|
+
const tmpFile = join25(tmpdir(), `agentpacks-${Date.now()}.tgz`);
|
|
3987
4211
|
try {
|
|
3988
4212
|
const buffer = Buffer.from(data);
|
|
3989
4213
|
const { writeFileSync: writeFileSync11 } = await import("fs");
|
|
@@ -4004,7 +4228,7 @@ function computeTarballIntegrity(data) {
|
|
|
4004
4228
|
|
|
4005
4229
|
// src/sources/registry.ts
|
|
4006
4230
|
import { existsSync as existsSync19, mkdirSync as mkdirSync7, readdirSync as readdirSync3, rmSync as rmSync3 } from "fs";
|
|
4007
|
-
import { resolve as
|
|
4231
|
+
import { resolve as resolve24, join as join26 } from "path";
|
|
4008
4232
|
async function installRegistrySource(projectRoot, source, lockfile, options = {}) {
|
|
4009
4233
|
const parsed = parseRegistrySourceRef(source);
|
|
4010
4234
|
const sourceKey = registrySourceKey(parsed);
|
|
@@ -4033,8 +4257,8 @@ async function installRegistrySource(projectRoot, source, lockfile, options = {}
|
|
|
4033
4257
|
throw new Error(`Integrity mismatch for ${parsed.packName}@${targetVersion}. ` + `Expected ${expectedIntegrity}, got ${localIntegrity}.`);
|
|
4034
4258
|
}
|
|
4035
4259
|
}
|
|
4036
|
-
const curatedDir =
|
|
4037
|
-
const packOutDir =
|
|
4260
|
+
const curatedDir = resolve24(projectRoot, ".agentpacks", ".curated");
|
|
4261
|
+
const packOutDir = resolve24(curatedDir, parsed.packName);
|
|
4038
4262
|
if (existsSync19(packOutDir)) {
|
|
4039
4263
|
rmSync3(packOutDir, { recursive: true, force: true });
|
|
4040
4264
|
}
|
|
@@ -4071,7 +4295,7 @@ function buildClientConfig(registryUrl) {
|
|
|
4071
4295
|
function collectFiles2(dir, out) {
|
|
4072
4296
|
const entries = readdirSync3(dir, { withFileTypes: true });
|
|
4073
4297
|
for (const entry of entries) {
|
|
4074
|
-
const full =
|
|
4298
|
+
const full = join26(dir, entry.name);
|
|
4075
4299
|
if (entry.isDirectory()) {
|
|
4076
4300
|
collectFiles2(full, out);
|
|
4077
4301
|
} else {
|
|
@@ -4186,9 +4410,9 @@ async function runLogin(options) {
|
|
|
4186
4410
|
|
|
4187
4411
|
// src/cli/models-explain.ts
|
|
4188
4412
|
import chalk8 from "chalk";
|
|
4189
|
-
import { resolve as
|
|
4413
|
+
import { resolve as resolve25 } from "path";
|
|
4190
4414
|
function runModelsExplain(options) {
|
|
4191
|
-
const projectRoot =
|
|
4415
|
+
const projectRoot = resolve25(options.config ?? ".");
|
|
4192
4416
|
const config = loadWorkspaceConfig(projectRoot);
|
|
4193
4417
|
const loader = new PackLoader(projectRoot, config);
|
|
4194
4418
|
const { packs } = loader.loadAll();
|
|
@@ -4320,19 +4544,19 @@ function matchTaskToRouting(task, routing) {
|
|
|
4320
4544
|
|
|
4321
4545
|
// src/cli/pack/create.ts
|
|
4322
4546
|
import { existsSync as existsSync20, writeFileSync as writeFileSync11 } from "fs";
|
|
4323
|
-
import { resolve as
|
|
4547
|
+
import { resolve as resolve26, join as join27 } from "path";
|
|
4324
4548
|
import chalk9 from "chalk";
|
|
4325
4549
|
function runPackCreate(projectRoot, name) {
|
|
4326
|
-
const packDir =
|
|
4550
|
+
const packDir = resolve26(projectRoot, "packs", name);
|
|
4327
4551
|
if (existsSync20(packDir)) {
|
|
4328
4552
|
console.log(chalk9.red(`Pack "${name}" already exists at packs/${name}/`));
|
|
4329
4553
|
return;
|
|
4330
4554
|
}
|
|
4331
4555
|
ensureDir(packDir);
|
|
4332
|
-
ensureDir(
|
|
4333
|
-
ensureDir(
|
|
4334
|
-
ensureDir(
|
|
4335
|
-
ensureDir(
|
|
4556
|
+
ensureDir(join27(packDir, "rules"));
|
|
4557
|
+
ensureDir(join27(packDir, "commands"));
|
|
4558
|
+
ensureDir(join27(packDir, "agents"));
|
|
4559
|
+
ensureDir(join27(packDir, "skills"));
|
|
4336
4560
|
const packJson = {
|
|
4337
4561
|
name,
|
|
4338
4562
|
version: "1.0.0",
|
|
@@ -4343,20 +4567,20 @@ function runPackCreate(projectRoot, name) {
|
|
|
4343
4567
|
targets: "*",
|
|
4344
4568
|
features: "*"
|
|
4345
4569
|
};
|
|
4346
|
-
writeFileSync11(
|
|
4570
|
+
writeFileSync11(join27(packDir, "pack.json"), JSON.stringify(packJson, null, 2) + `
|
|
4347
4571
|
`);
|
|
4348
4572
|
console.log(chalk9.green(`Created pack "${name}" at packs/${name}/`));
|
|
4349
4573
|
console.log(chalk9.dim(" Add rules, commands, agents, skills, hooks, plugins, mcp.json, or ignore files."));
|
|
4350
|
-
console.log(chalk9.dim(` Then add "${
|
|
4574
|
+
console.log(chalk9.dim(` Then add "${join27("./packs", name)}" to packs[] in agentpacks.jsonc.`));
|
|
4351
4575
|
}
|
|
4352
4576
|
|
|
4353
4577
|
// src/cli/pack/enable.ts
|
|
4354
4578
|
import { readFileSync as readFileSync18, writeFileSync as writeFileSync12, existsSync as existsSync21 } from "fs";
|
|
4355
|
-
import { resolve as
|
|
4579
|
+
import { resolve as resolve27 } from "path";
|
|
4356
4580
|
import chalk10 from "chalk";
|
|
4357
4581
|
var CONFIG_FILENAME = "agentpacks.jsonc";
|
|
4358
4582
|
function readConfigRaw(projectRoot) {
|
|
4359
|
-
const filepath =
|
|
4583
|
+
const filepath = resolve27(projectRoot, CONFIG_FILENAME);
|
|
4360
4584
|
if (!existsSync21(filepath)) {
|
|
4361
4585
|
throw new Error(`No ${CONFIG_FILENAME} found. Run 'agentpacks init' first.`);
|
|
4362
4586
|
}
|
|
@@ -4392,7 +4616,7 @@ function runPackDisable(projectRoot, packName) {
|
|
|
4392
4616
|
}
|
|
4393
4617
|
list.push(packName);
|
|
4394
4618
|
const updated = writeDisabled(raw, list, match);
|
|
4395
|
-
const filepath =
|
|
4619
|
+
const filepath = resolve27(projectRoot, CONFIG_FILENAME);
|
|
4396
4620
|
writeFileSync12(filepath, updated);
|
|
4397
4621
|
console.log(chalk10.green(`Disabled pack "${packName}".`));
|
|
4398
4622
|
console.log(chalk10.dim("Run 'agentpacks generate' to regenerate configs."));
|
|
@@ -4406,7 +4630,7 @@ function runPackEnable(projectRoot, packName) {
|
|
|
4406
4630
|
}
|
|
4407
4631
|
const newList = list.filter((n) => n !== packName);
|
|
4408
4632
|
const updated = writeDisabled(raw, newList, match);
|
|
4409
|
-
const filepath =
|
|
4633
|
+
const filepath = resolve27(projectRoot, CONFIG_FILENAME);
|
|
4410
4634
|
writeFileSync12(filepath, updated);
|
|
4411
4635
|
console.log(chalk10.green(`Enabled pack "${packName}".`));
|
|
4412
4636
|
console.log(chalk10.dim("Run 'agentpacks generate' to regenerate configs."));
|
|
@@ -4466,7 +4690,7 @@ function runPackList(projectRoot) {
|
|
|
4466
4690
|
|
|
4467
4691
|
// src/cli/pack/validate.ts
|
|
4468
4692
|
import { existsSync as existsSync22 } from "fs";
|
|
4469
|
-
import { resolve as
|
|
4693
|
+
import { resolve as resolve28, join as join28, basename as basename10 } from "path";
|
|
4470
4694
|
import chalk12 from "chalk";
|
|
4471
4695
|
function runPackValidate(projectRoot) {
|
|
4472
4696
|
const config = loadWorkspaceConfig(projectRoot);
|
|
@@ -4480,7 +4704,7 @@ Validating pack: ${packRef}`));
|
|
|
4480
4704
|
hasErrors = true;
|
|
4481
4705
|
continue;
|
|
4482
4706
|
}
|
|
4483
|
-
const packJsonPath =
|
|
4707
|
+
const packJsonPath = resolve28(packDir, "pack.json");
|
|
4484
4708
|
if (!existsSync22(packJsonPath)) {
|
|
4485
4709
|
console.log(chalk12.yellow(" warn: No pack.json found. Name will be inferred from directory."));
|
|
4486
4710
|
} else {
|
|
@@ -4495,14 +4719,30 @@ Validating pack: ${packRef}`));
|
|
|
4495
4719
|
}
|
|
4496
4720
|
const subdirs = ["rules", "commands", "agents", "skills"];
|
|
4497
4721
|
for (const sub of subdirs) {
|
|
4498
|
-
const subDir =
|
|
4722
|
+
const subDir = join28(packDir, sub);
|
|
4499
4723
|
if (existsSync22(subDir)) {
|
|
4500
4724
|
if (sub === "skills") {
|
|
4501
4725
|
const skillDirs = listDirs(subDir);
|
|
4502
4726
|
for (const skillDir of skillDirs) {
|
|
4503
|
-
const
|
|
4727
|
+
const skillName = basename10(skillDir);
|
|
4728
|
+
const skillMd = join28(skillDir, "SKILL.md");
|
|
4504
4729
|
if (!existsSync22(skillMd)) {
|
|
4505
|
-
console.log(chalk12.yellow(` warn: skills/${
|
|
4730
|
+
console.log(chalk12.yellow(` warn: skills/${skillName} missing SKILL.md`));
|
|
4731
|
+
continue;
|
|
4732
|
+
}
|
|
4733
|
+
try {
|
|
4734
|
+
const parsed = parseSkillFile(skillMd, skillDir, "__validation__");
|
|
4735
|
+
const skillErrors = validateAgentSkillsFrontmatter(parsed);
|
|
4736
|
+
for (const err of skillErrors) {
|
|
4737
|
+
console.log(chalk12.red(` ERROR skills/${skillName}/SKILL.md: ${err}`));
|
|
4738
|
+
}
|
|
4739
|
+
if (skillErrors.length > 0) {
|
|
4740
|
+
hasErrors = true;
|
|
4741
|
+
}
|
|
4742
|
+
} catch (err) {
|
|
4743
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
4744
|
+
console.log(chalk12.red(` ERROR skills/${skillName}/SKILL.md: failed to parse (${message})`));
|
|
4745
|
+
hasErrors = true;
|
|
4506
4746
|
}
|
|
4507
4747
|
}
|
|
4508
4748
|
console.log(chalk12.green(` ${sub}/: ${skillDirs.length} skill(s)`));
|
|
@@ -4514,15 +4754,15 @@ Validating pack: ${packRef}`));
|
|
|
4514
4754
|
}
|
|
4515
4755
|
const optionalFiles = ["mcp.json", "ignore", ".aiignore"];
|
|
4516
4756
|
for (const file of optionalFiles) {
|
|
4517
|
-
if (existsSync22(
|
|
4757
|
+
if (existsSync22(join28(packDir, file))) {
|
|
4518
4758
|
console.log(chalk12.green(` ${file}: present`));
|
|
4519
4759
|
}
|
|
4520
4760
|
}
|
|
4521
|
-
const hooksJson =
|
|
4761
|
+
const hooksJson = join28(packDir, "hooks", "hooks.json");
|
|
4522
4762
|
if (existsSync22(hooksJson)) {
|
|
4523
4763
|
console.log(chalk12.green(" hooks/hooks.json: present"));
|
|
4524
4764
|
}
|
|
4525
|
-
const pluginsDir =
|
|
4765
|
+
const pluginsDir = join28(packDir, "plugins");
|
|
4526
4766
|
if (existsSync22(pluginsDir)) {
|
|
4527
4767
|
const pluginFiles = [
|
|
4528
4768
|
...listFiles(pluginsDir, { extension: ".ts" }),
|
|
@@ -4530,7 +4770,7 @@ Validating pack: ${packRef}`));
|
|
|
4530
4770
|
];
|
|
4531
4771
|
console.log(chalk12.green(` plugins/: ${pluginFiles.length} file(s)`));
|
|
4532
4772
|
}
|
|
4533
|
-
const modelsJsonPath =
|
|
4773
|
+
const modelsJsonPath = join28(packDir, "models.json");
|
|
4534
4774
|
if (existsSync22(modelsJsonPath)) {
|
|
4535
4775
|
try {
|
|
4536
4776
|
const parsed = parseModels(packDir, "validate");
|
|
@@ -4561,13 +4801,13 @@ Validating pack: ${packRef}`));
|
|
|
4561
4801
|
}
|
|
4562
4802
|
function resolvePackDir(projectRoot, packRef) {
|
|
4563
4803
|
if (packRef.startsWith("./") || packRef.startsWith("../")) {
|
|
4564
|
-
return
|
|
4804
|
+
return resolve28(projectRoot, packRef);
|
|
4565
4805
|
}
|
|
4566
|
-
return
|
|
4806
|
+
return resolve28(projectRoot, packRef);
|
|
4567
4807
|
}
|
|
4568
4808
|
|
|
4569
4809
|
// src/cli/publish.ts
|
|
4570
|
-
import { resolve as
|
|
4810
|
+
import { resolve as resolve29 } from "path";
|
|
4571
4811
|
import { existsSync as existsSync23 } from "fs";
|
|
4572
4812
|
import chalk13 from "chalk";
|
|
4573
4813
|
async function runPublish(projectRoot, options) {
|
|
@@ -4576,8 +4816,8 @@ async function runPublish(projectRoot, options) {
|
|
|
4576
4816
|
console.log(chalk13.red("Not authenticated. Run `agentpacks login` first."));
|
|
4577
4817
|
process.exit(1);
|
|
4578
4818
|
}
|
|
4579
|
-
const packDir =
|
|
4580
|
-
const packJsonPath =
|
|
4819
|
+
const packDir = resolve29(projectRoot);
|
|
4820
|
+
const packJsonPath = resolve29(packDir, "pack.json");
|
|
4581
4821
|
if (!existsSync23(packJsonPath)) {
|
|
4582
4822
|
console.log(chalk13.red("No pack.json found. Are you in a pack directory?"));
|
|
4583
4823
|
process.exit(1);
|
|
@@ -4662,23 +4902,23 @@ async function runSearch(query, options) {
|
|
|
4662
4902
|
|
|
4663
4903
|
// src/index.ts
|
|
4664
4904
|
import { Command } from "commander";
|
|
4665
|
-
import { resolve as
|
|
4905
|
+
import { resolve as resolve30 } from "path";
|
|
4666
4906
|
var program = new Command;
|
|
4667
4907
|
program.name("agentpacks").description("Composable AI agent configuration manager. Pack-based rules, commands, skills, hooks, and MCP sync across OpenCode, Cursor, Claude Code, Codex, Gemini, Copilot, and more.").version("0.1.0");
|
|
4668
4908
|
program.command("init").description("Initialize agentpacks in the current project").action(() => {
|
|
4669
|
-
runInit(
|
|
4909
|
+
runInit(resolve30("."));
|
|
4670
4910
|
});
|
|
4671
4911
|
program.command("generate").description("Generate tool configs from active packs").option("-t, --targets <targets>", "Comma-separated target IDs or '*' for all").option("-f, --features <features>", "Comma-separated feature IDs or '*' for all").option("--dry-run", "Preview changes without writing files").option("--diff", "Show diff of what would change").option("-v, --verbose", "Enable verbose logging").action((options) => {
|
|
4672
|
-
runGenerate(
|
|
4912
|
+
runGenerate(resolve30("."), options);
|
|
4673
4913
|
});
|
|
4674
4914
|
program.command("install").description("Install remote packs (git, npm) into local cache").option("--update", "Re-resolve all refs (ignore lockfile)").option("--frozen", "Fail if lockfile is missing or incomplete").option("-v, --verbose", "Enable verbose logging").action(async (options) => {
|
|
4675
|
-
await runInstall(
|
|
4915
|
+
await runInstall(resolve30("."), options);
|
|
4676
4916
|
});
|
|
4677
4917
|
program.command("export").description("Export packs to target-native format (e.g. Cursor plugin)").requiredOption("--format <format>", "Export format (cursor-plugin)").option("-o, --output <dir>", "Output directory").option("--pack <name>", "Export a specific pack only").option("-v, --verbose", "Enable verbose logging").action((options) => {
|
|
4678
|
-
runExport(
|
|
4918
|
+
runExport(resolve30("."), options);
|
|
4679
4919
|
});
|
|
4680
4920
|
program.command("import").description("Import from existing tool configurations").requiredOption("--from <source>", "Import source (rulesync)").option("-o, --output <dir>", "Output pack directory").action((options) => {
|
|
4681
|
-
runImport(
|
|
4921
|
+
runImport(resolve30("."), options);
|
|
4682
4922
|
});
|
|
4683
4923
|
program.command("search [query]").description("Search for packs in the registry").option("--tags <tags>", "Filter by tags (comma-separated)").option("--targets <targets>", "Filter by targets (comma-separated)").option("--sort <sort>", "Sort by: downloads, updated, name, weekly").option("-l, --limit <limit>", "Max results to show").option("-v, --verbose", "Show additional details").action(async (query, options) => {
|
|
4684
4924
|
await runSearch(query ?? "", options);
|
|
@@ -4687,7 +4927,7 @@ program.command("info <pack>").description("Show detailed pack information from
|
|
|
4687
4927
|
await runInfo(packName);
|
|
4688
4928
|
});
|
|
4689
4929
|
program.command("publish").description("Publish a pack to the registry").option("-v, --verbose", "Enable verbose logging").action(async (options) => {
|
|
4690
|
-
await runPublish(
|
|
4930
|
+
await runPublish(resolve30("."), options);
|
|
4691
4931
|
});
|
|
4692
4932
|
program.command("login").description("Authenticate with the agentpacks registry").option("--token <token>", "API token").option("--registry <url>", "Registry URL").action(async (options) => {
|
|
4693
4933
|
await runLogin(options);
|
|
@@ -4698,18 +4938,18 @@ modelsCmd.command("explain").description("Explain model profile and routing reso
|
|
|
4698
4938
|
});
|
|
4699
4939
|
var packCmd = program.command("pack").description("Manage packs");
|
|
4700
4940
|
packCmd.command("create <name>").description("Create a new pack scaffold").action((name) => {
|
|
4701
|
-
runPackCreate(
|
|
4941
|
+
runPackCreate(resolve30("."), name);
|
|
4702
4942
|
});
|
|
4703
4943
|
packCmd.command("list").description("List all configured packs and their status").action(() => {
|
|
4704
|
-
runPackList(
|
|
4944
|
+
runPackList(resolve30("."));
|
|
4705
4945
|
});
|
|
4706
4946
|
packCmd.command("validate").description("Validate all configured packs").action(() => {
|
|
4707
|
-
runPackValidate(
|
|
4947
|
+
runPackValidate(resolve30("."));
|
|
4708
4948
|
});
|
|
4709
4949
|
packCmd.command("enable <name>").description("Enable a previously disabled pack").action((name) => {
|
|
4710
|
-
runPackEnable(
|
|
4950
|
+
runPackEnable(resolve30("."), name);
|
|
4711
4951
|
});
|
|
4712
4952
|
packCmd.command("disable <name>").description("Disable a pack without removing it").action((name) => {
|
|
4713
|
-
runPackDisable(
|
|
4953
|
+
runPackDisable(resolve30("."), name);
|
|
4714
4954
|
});
|
|
4715
4955
|
program.parse();
|