agentsmesh 0.2.1 → 0.2.3
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/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/dist/cli.js +894 -527
- package/dist/cli.js.map +1 -1
- package/package.json +22 -24
package/dist/cli.js
CHANGED
|
@@ -406,6 +406,7 @@ import { normalize as normalizePath } from "path";
|
|
|
406
406
|
import { basename as basename2 } from "path";
|
|
407
407
|
|
|
408
408
|
// src/targets/junie/constants.ts
|
|
409
|
+
var JUNIE_TARGET = "junie";
|
|
409
410
|
var JUNIE_DIR = ".junie";
|
|
410
411
|
var JUNIE_GUIDELINES = `${JUNIE_DIR}/guidelines.md`;
|
|
411
412
|
var JUNIE_CI_GUIDELINES = `${JUNIE_DIR}/ci-guidelines.md`;
|
|
@@ -418,6 +419,12 @@ var JUNIE_RULES_DIR = `${JUNIE_DIR}/rules`;
|
|
|
418
419
|
var JUNIE_COMMANDS_DIR = `${JUNIE_DIR}/commands`;
|
|
419
420
|
var JUNIE_AGENTS_DIR = `${JUNIE_DIR}/agents`;
|
|
420
421
|
var JUNIE_IGNORE = ".aiignore";
|
|
422
|
+
var JUNIE_CANONICAL_ROOT_RULE = ".agentsmesh/rules/_root.md";
|
|
423
|
+
var JUNIE_CANONICAL_RULES_DIR = ".agentsmesh/rules";
|
|
424
|
+
var JUNIE_CANONICAL_COMMANDS_DIR = ".agentsmesh/commands";
|
|
425
|
+
var JUNIE_CANONICAL_AGENTS_DIR = ".agentsmesh/agents";
|
|
426
|
+
var JUNIE_CANONICAL_MCP = ".agentsmesh/mcp.json";
|
|
427
|
+
var JUNIE_CANONICAL_IGNORE = ".agentsmesh/ignore";
|
|
421
428
|
|
|
422
429
|
// src/core/import-reference-map-shared.ts
|
|
423
430
|
import { basename, dirname as dirname3, join as join3, relative } from "path";
|
|
@@ -775,6 +782,9 @@ async function buildCodexCliImportPaths(refs, projectRoot) {
|
|
|
775
782
|
refs.set("AGENTS.md", `${AB_RULES2}/_root.md`);
|
|
776
783
|
refs.set("codex.md", `${AB_RULES2}/_root.md`);
|
|
777
784
|
await addScopedAgentsMappings(refs, projectRoot);
|
|
785
|
+
for (const absPath of await listFiles(projectRoot, ".codex/instructions")) {
|
|
786
|
+
addSimpleFileMapping(refs, rel(projectRoot, absPath), AB_RULES2, ".md");
|
|
787
|
+
}
|
|
778
788
|
for (const absPath of await listFiles(projectRoot, ".codex/rules")) {
|
|
779
789
|
const relPath = rel(projectRoot, absPath);
|
|
780
790
|
if (relPath.endsWith(".rules")) {
|
|
@@ -1107,6 +1117,69 @@ init_markdown();
|
|
|
1107
1117
|
// src/targets/import-metadata.ts
|
|
1108
1118
|
import { basename as basename3 } from "path";
|
|
1109
1119
|
init_markdown();
|
|
1120
|
+
|
|
1121
|
+
// src/targets/root-instruction-paragraph.ts
|
|
1122
|
+
var ROOT_INSTRUCTION_BODY_LEGACY = "AgentsMesh is a config sync library for AI coding tools. The only canonical source of truth is `.agentsmesh/`; files emitted into target formats such as `AGENTS.md`, `.claude/`, `.cursor/`, `.junie/`, and similar directories are generated artifacts. When making changes, edit canonical config first, then regenerate and verify the target outputs. Preserve the library's bidirectional contract: import native tool config into canonical form, generate back to target-specific layouts, and keep projected or embedded features round-trippable rather than treating them as plain text exports.";
|
|
1123
|
+
var ROOT_INSTRUCTION_BODY = "AgentsMesh is a config sync library for AI coding tools. The only canonical source of truth is the `.agentsmesh` directory at the project root; files emitted into target formats such as `AGENTS.md`, `.claude/`, `.cursor/`, `.junie/`, and similar directories are generated artifacts. When making changes, edit canonical config first, then regenerate and verify the target outputs. Preserve the library's bidirectional contract: import native tool config into canonical form, generate back to target-specific layouts, and keep projected or embedded features round-trippable rather than treating them as plain text exports.";
|
|
1124
|
+
var LEGACY_AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH = ROOT_INSTRUCTION_BODY_LEGACY;
|
|
1125
|
+
var LEGACY_AGENTSMESH_ROOT_INSTRUCTION_SECTION = `## Project-Specific Rules
|
|
1126
|
+
|
|
1127
|
+
${ROOT_INSTRUCTION_BODY_LEGACY}`;
|
|
1128
|
+
var AGENTSMESH_CONTRACT_WITH_LEGACY_BODY = `## AgentsMesh Generation Contract
|
|
1129
|
+
|
|
1130
|
+
${ROOT_INSTRUCTION_BODY_LEGACY}`;
|
|
1131
|
+
var AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH = `## AgentsMesh Generation Contract
|
|
1132
|
+
|
|
1133
|
+
${ROOT_INSTRUCTION_BODY}`;
|
|
1134
|
+
function normalizeWhitespace(value) {
|
|
1135
|
+
return value.replace(/\s+/g, " ").trim();
|
|
1136
|
+
}
|
|
1137
|
+
function appendAgentsmeshRootInstructionParagraph(content) {
|
|
1138
|
+
const trimmed = content.trim();
|
|
1139
|
+
if (normalizeWhitespace(trimmed).includes(
|
|
1140
|
+
normalizeWhitespace(AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH)
|
|
1141
|
+
)) {
|
|
1142
|
+
return trimmed;
|
|
1143
|
+
}
|
|
1144
|
+
if (normalizeWhitespace(trimmed).includes(
|
|
1145
|
+
normalizeWhitespace(LEGACY_AGENTSMESH_ROOT_INSTRUCTION_SECTION)
|
|
1146
|
+
)) {
|
|
1147
|
+
return trimmed.replace(
|
|
1148
|
+
LEGACY_AGENTSMESH_ROOT_INSTRUCTION_SECTION,
|
|
1149
|
+
AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH
|
|
1150
|
+
);
|
|
1151
|
+
}
|
|
1152
|
+
if (normalizeWhitespace(trimmed).includes(normalizeWhitespace(AGENTSMESH_CONTRACT_WITH_LEGACY_BODY))) {
|
|
1153
|
+
return trimmed.replace(
|
|
1154
|
+
AGENTSMESH_CONTRACT_WITH_LEGACY_BODY,
|
|
1155
|
+
AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
if (normalizeWhitespace(trimmed).includes(
|
|
1159
|
+
normalizeWhitespace(LEGACY_AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH)
|
|
1160
|
+
)) {
|
|
1161
|
+
return trimmed.replace(
|
|
1162
|
+
LEGACY_AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH,
|
|
1163
|
+
AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH
|
|
1164
|
+
);
|
|
1165
|
+
}
|
|
1166
|
+
return trimmed ? `${trimmed}
|
|
1167
|
+
|
|
1168
|
+
${AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH}` : AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH;
|
|
1169
|
+
}
|
|
1170
|
+
function stripAgentsmeshRootInstructionParagraph(content) {
|
|
1171
|
+
return content.replace(`
|
|
1172
|
+
|
|
1173
|
+
${AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH}`, "").replace(`
|
|
1174
|
+
|
|
1175
|
+
${AGENTSMESH_CONTRACT_WITH_LEGACY_BODY}`, "").replace(`
|
|
1176
|
+
|
|
1177
|
+
${LEGACY_AGENTSMESH_ROOT_INSTRUCTION_SECTION}`, "").replace(`
|
|
1178
|
+
|
|
1179
|
+
${LEGACY_AGENTSMESH_ROOT_INSTRUCTION_PARAGRAPH}`, "").trim();
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
// src/targets/import-metadata.ts
|
|
1110
1183
|
function toStringArray3(value) {
|
|
1111
1184
|
if (Array.isArray(value)) {
|
|
1112
1185
|
return value.filter((entry) => typeof entry === "string").map((entry) => entry.trim()).filter(Boolean);
|
|
@@ -1135,11 +1208,12 @@ function serializeCanonicalRuleFrontmatter(destinationPath, frontmatter) {
|
|
|
1135
1208
|
}
|
|
1136
1209
|
async function serializeImportedRuleWithFallback(destinationPath, importedFrontmatter, body) {
|
|
1137
1210
|
const existingFrontmatter = await readExistingFrontmatter(destinationPath);
|
|
1211
|
+
const normalizedBody = basename3(destinationPath, ".md") === "_root" ? stripAgentsmeshRootInstructionParagraph(body) : body.trim();
|
|
1138
1212
|
const mergedFrontmatter = serializeCanonicalRuleFrontmatter(
|
|
1139
1213
|
destinationPath,
|
|
1140
1214
|
pruneUndefined({ ...existingFrontmatter, ...importedFrontmatter })
|
|
1141
1215
|
);
|
|
1142
|
-
return serializeFrontmatter(mergedFrontmatter,
|
|
1216
|
+
return serializeFrontmatter(mergedFrontmatter, normalizedBody || "");
|
|
1143
1217
|
}
|
|
1144
1218
|
async function serializeImportedCommandWithFallback(destinationPath, imported, body) {
|
|
1145
1219
|
const existingFrontmatter = await readExistingFrontmatter(destinationPath);
|
|
@@ -1191,16 +1265,35 @@ async function importFileDirectory(opts) {
|
|
|
1191
1265
|
// src/targets/claude-code/importer-mappers.ts
|
|
1192
1266
|
init_markdown();
|
|
1193
1267
|
import { basename as basename4, join as join5 } from "path";
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
var
|
|
1268
|
+
|
|
1269
|
+
// src/targets/claude-code/constants.ts
|
|
1270
|
+
var CLAUDE_CODE_TARGET = "claude-code";
|
|
1271
|
+
var CLAUDE_ROOT = ".claude/CLAUDE.md";
|
|
1272
|
+
var CLAUDE_LEGACY_ROOT = "CLAUDE.md";
|
|
1273
|
+
var CLAUDE_RULES_DIR = ".claude/rules";
|
|
1274
|
+
var CLAUDE_COMMANDS_DIR = ".claude/commands";
|
|
1275
|
+
var CLAUDE_AGENTS_DIR = ".claude/agents";
|
|
1276
|
+
var CLAUDE_SKILLS_DIR = ".claude/skills";
|
|
1277
|
+
var CLAUDE_SETTINGS = ".claude/settings.json";
|
|
1278
|
+
var CLAUDE_IGNORE = ".claudeignore";
|
|
1279
|
+
var CLAUDE_MCP_JSON = ".mcp.json";
|
|
1280
|
+
var CLAUDE_CANONICAL_RULES_DIR = ".agentsmesh/rules";
|
|
1281
|
+
var CLAUDE_CANONICAL_COMMANDS_DIR = ".agentsmesh/commands";
|
|
1282
|
+
var CLAUDE_CANONICAL_AGENTS_DIR = ".agentsmesh/agents";
|
|
1283
|
+
var CLAUDE_CANONICAL_SKILLS_DIR = ".agentsmesh/skills";
|
|
1284
|
+
var CLAUDE_CANONICAL_MCP = ".agentsmesh/mcp.json";
|
|
1285
|
+
var CLAUDE_CANONICAL_PERMISSIONS = ".agentsmesh/permissions.yaml";
|
|
1286
|
+
var CLAUDE_CANONICAL_HOOKS = ".agentsmesh/hooks.yaml";
|
|
1287
|
+
var CLAUDE_CANONICAL_IGNORE = ".agentsmesh/ignore";
|
|
1288
|
+
|
|
1289
|
+
// src/targets/claude-code/importer-mappers.ts
|
|
1197
1290
|
async function mapClaudeRuleFile(srcPath, destDir, normalizeTo) {
|
|
1198
1291
|
const name = basename4(srcPath, ".md");
|
|
1199
1292
|
const destPath = join5(destDir, `${name}.md`);
|
|
1200
1293
|
const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
|
|
1201
1294
|
return {
|
|
1202
1295
|
destPath,
|
|
1203
|
-
toPath: `${
|
|
1296
|
+
toPath: `${CLAUDE_CANONICAL_RULES_DIR}/${name}.md`,
|
|
1204
1297
|
feature: "rules",
|
|
1205
1298
|
content: await serializeImportedRuleWithFallback(
|
|
1206
1299
|
destPath,
|
|
@@ -1212,7 +1305,7 @@ async function mapClaudeRuleFile(srcPath, destDir, normalizeTo) {
|
|
|
1212
1305
|
function mapClaudeMarkdownFile(srcPath, destDir, feature, normalizeTo) {
|
|
1213
1306
|
const name = basename4(srcPath, ".md");
|
|
1214
1307
|
const destPath = join5(destDir, `${name}.md`);
|
|
1215
|
-
const basePath = feature === "commands" ?
|
|
1308
|
+
const basePath = feature === "commands" ? CLAUDE_CANONICAL_COMMANDS_DIR : CLAUDE_CANONICAL_AGENTS_DIR;
|
|
1216
1309
|
return {
|
|
1217
1310
|
destPath,
|
|
1218
1311
|
toPath: `${basePath}/${name}.md`,
|
|
@@ -1248,11 +1341,6 @@ function hasHookText(entry) {
|
|
|
1248
1341
|
|
|
1249
1342
|
// src/targets/claude-code/settings-helpers.ts
|
|
1250
1343
|
import { stringify as yamlStringify2 } from "yaml";
|
|
1251
|
-
var CLAUDE_SETTINGS = ".claude/settings.json";
|
|
1252
|
-
var CLAUDE_MCP_JSON = ".mcp.json";
|
|
1253
|
-
var AB_MCP = ".agentsmesh/mcp.json";
|
|
1254
|
-
var AB_PERMISSIONS = ".agentsmesh/permissions.yaml";
|
|
1255
|
-
var AB_HOOKS = ".agentsmesh/hooks.yaml";
|
|
1256
1344
|
function claudeHooksToCanonical(hooks) {
|
|
1257
1345
|
const result = {};
|
|
1258
1346
|
for (const [event, entries] of Object.entries(hooks)) {
|
|
@@ -1289,13 +1377,13 @@ async function importMcpJson(projectRoot, results) {
|
|
|
1289
1377
|
}
|
|
1290
1378
|
if (parsed.mcpServers && typeof parsed.mcpServers === "object") {
|
|
1291
1379
|
const mcpContent = JSON.stringify({ mcpServers: parsed.mcpServers }, null, 2);
|
|
1292
|
-
const destPath = join6(projectRoot,
|
|
1380
|
+
const destPath = join6(projectRoot, CLAUDE_CANONICAL_MCP);
|
|
1293
1381
|
await mkdirp(dirname5(destPath));
|
|
1294
1382
|
await writeFileAtomic(destPath, mcpContent);
|
|
1295
1383
|
results.push({
|
|
1296
1384
|
fromTool: "claude-code",
|
|
1297
1385
|
fromPath: mcpPath,
|
|
1298
|
-
toPath:
|
|
1386
|
+
toPath: CLAUDE_CANONICAL_MCP,
|
|
1299
1387
|
feature: "mcp"
|
|
1300
1388
|
});
|
|
1301
1389
|
}
|
|
@@ -1313,13 +1401,13 @@ async function importSettings(projectRoot, results) {
|
|
|
1313
1401
|
const alreadyImportedMcp = results.some((r) => r.feature === "mcp");
|
|
1314
1402
|
if (!alreadyImportedMcp && settings.mcpServers && typeof settings.mcpServers === "object") {
|
|
1315
1403
|
const mcpContent = JSON.stringify({ mcpServers: settings.mcpServers }, null, 2);
|
|
1316
|
-
const destPath = join6(projectRoot,
|
|
1404
|
+
const destPath = join6(projectRoot, CLAUDE_CANONICAL_MCP);
|
|
1317
1405
|
await mkdirp(dirname5(destPath));
|
|
1318
1406
|
await writeFileAtomic(destPath, mcpContent);
|
|
1319
1407
|
results.push({
|
|
1320
1408
|
fromTool: "claude-code",
|
|
1321
1409
|
fromPath: settingsPath,
|
|
1322
|
-
toPath:
|
|
1410
|
+
toPath: CLAUDE_CANONICAL_MCP,
|
|
1323
1411
|
feature: "mcp"
|
|
1324
1412
|
});
|
|
1325
1413
|
}
|
|
@@ -1330,13 +1418,13 @@ async function importSettings(projectRoot, results) {
|
|
|
1330
1418
|
const deny = Array.isArray(perms.deny) ? perms.deny.filter((s) => typeof s === "string") : [];
|
|
1331
1419
|
if (allow.length > 0 || deny.length > 0) {
|
|
1332
1420
|
const permContent = yamlStringify2({ allow, deny });
|
|
1333
|
-
const destPath = join6(projectRoot,
|
|
1421
|
+
const destPath = join6(projectRoot, CLAUDE_CANONICAL_PERMISSIONS);
|
|
1334
1422
|
await mkdirp(dirname5(destPath));
|
|
1335
1423
|
await writeFileAtomic(destPath, permContent);
|
|
1336
1424
|
results.push({
|
|
1337
1425
|
fromTool: "claude-code",
|
|
1338
1426
|
fromPath: settingsPath,
|
|
1339
|
-
toPath:
|
|
1427
|
+
toPath: CLAUDE_CANONICAL_PERMISSIONS,
|
|
1340
1428
|
feature: "permissions"
|
|
1341
1429
|
});
|
|
1342
1430
|
}
|
|
@@ -1346,13 +1434,13 @@ async function importSettings(projectRoot, results) {
|
|
|
1346
1434
|
const canonicalHooks = claudeHooksToCanonical(rawHooks);
|
|
1347
1435
|
if (Object.keys(canonicalHooks).length > 0) {
|
|
1348
1436
|
const hooksContent = yamlStringify2(canonicalHooks);
|
|
1349
|
-
const destPath = join6(projectRoot,
|
|
1437
|
+
const destPath = join6(projectRoot, CLAUDE_CANONICAL_HOOKS);
|
|
1350
1438
|
await mkdirp(dirname5(destPath));
|
|
1351
1439
|
await writeFileAtomic(destPath, hooksContent);
|
|
1352
1440
|
results.push({
|
|
1353
1441
|
fromTool: "claude-code",
|
|
1354
1442
|
fromPath: settingsPath,
|
|
1355
|
-
toPath:
|
|
1443
|
+
toPath: CLAUDE_CANONICAL_HOOKS,
|
|
1356
1444
|
feature: "hooks"
|
|
1357
1445
|
});
|
|
1358
1446
|
}
|
|
@@ -1360,18 +1448,6 @@ async function importSettings(projectRoot, results) {
|
|
|
1360
1448
|
}
|
|
1361
1449
|
|
|
1362
1450
|
// src/targets/claude-code/importer.ts
|
|
1363
|
-
var CLAUDE_MD = ".claude/CLAUDE.md";
|
|
1364
|
-
var CLAUDE_MD_LEGACY = "CLAUDE.md";
|
|
1365
|
-
var CLAUDE_RULES_DIR = ".claude/rules";
|
|
1366
|
-
var CLAUDE_COMMANDS_DIR = ".claude/commands";
|
|
1367
|
-
var CLAUDE_AGENTS_DIR = ".claude/agents";
|
|
1368
|
-
var CLAUDE_SKILLS_DIR = ".claude/skills";
|
|
1369
|
-
var CLAUDEIGNORE = ".claudeignore";
|
|
1370
|
-
var AB_RULES4 = ".agentsmesh/rules";
|
|
1371
|
-
var AB_COMMANDS4 = ".agentsmesh/commands";
|
|
1372
|
-
var AB_AGENTS4 = ".agentsmesh/agents";
|
|
1373
|
-
var AB_SKILLS2 = ".agentsmesh/skills";
|
|
1374
|
-
var AB_IGNORE = ".agentsmesh/ignore";
|
|
1375
1451
|
async function importFromClaudeCode(projectRoot) {
|
|
1376
1452
|
const results = [];
|
|
1377
1453
|
const normalize = await createImportReferenceNormalizer("claude-code", projectRoot);
|
|
@@ -1385,10 +1461,10 @@ async function importFromClaudeCode(projectRoot) {
|
|
|
1385
1461
|
return results;
|
|
1386
1462
|
}
|
|
1387
1463
|
async function importRules(projectRoot, results, normalize) {
|
|
1388
|
-
const destDir = join7(projectRoot,
|
|
1389
|
-
const primaryClaudePath = join7(projectRoot,
|
|
1464
|
+
const destDir = join7(projectRoot, CLAUDE_CANONICAL_RULES_DIR);
|
|
1465
|
+
const primaryClaudePath = join7(projectRoot, CLAUDE_ROOT);
|
|
1390
1466
|
const primaryContent = await readFileSafe(primaryClaudePath);
|
|
1391
|
-
const legacyClaudePath = join7(projectRoot,
|
|
1467
|
+
const legacyClaudePath = join7(projectRoot, CLAUDE_LEGACY_ROOT);
|
|
1392
1468
|
const legacyContent = primaryContent === null ? await readFileSafe(legacyClaudePath) : null;
|
|
1393
1469
|
const claudeContent = primaryContent ?? legacyContent;
|
|
1394
1470
|
const claudePath = primaryContent !== null ? primaryClaudePath : legacyClaudePath;
|
|
@@ -1403,7 +1479,7 @@ async function importRules(projectRoot, results, normalize) {
|
|
|
1403
1479
|
results.push({
|
|
1404
1480
|
fromTool: "claude-code",
|
|
1405
1481
|
fromPath: claudePath,
|
|
1406
|
-
toPath: `${
|
|
1482
|
+
toPath: `${CLAUDE_CANONICAL_RULES_DIR}/_root.md`,
|
|
1407
1483
|
feature: "rules"
|
|
1408
1484
|
});
|
|
1409
1485
|
}
|
|
@@ -1420,7 +1496,7 @@ async function importRules(projectRoot, results, normalize) {
|
|
|
1420
1496
|
);
|
|
1421
1497
|
}
|
|
1422
1498
|
async function importCommands(projectRoot, results, normalize) {
|
|
1423
|
-
const destDir = join7(projectRoot,
|
|
1499
|
+
const destDir = join7(projectRoot, CLAUDE_CANONICAL_COMMANDS_DIR);
|
|
1424
1500
|
const commandsDir = join7(projectRoot, CLAUDE_COMMANDS_DIR);
|
|
1425
1501
|
results.push(
|
|
1426
1502
|
...await importFileDirectory({
|
|
@@ -1434,7 +1510,7 @@ async function importCommands(projectRoot, results, normalize) {
|
|
|
1434
1510
|
);
|
|
1435
1511
|
}
|
|
1436
1512
|
async function importAgents(projectRoot, results, normalize) {
|
|
1437
|
-
const destDir = join7(projectRoot,
|
|
1513
|
+
const destDir = join7(projectRoot, CLAUDE_CANONICAL_AGENTS_DIR);
|
|
1438
1514
|
const agentsDir = join7(projectRoot, CLAUDE_AGENTS_DIR);
|
|
1439
1515
|
results.push(
|
|
1440
1516
|
...await importFileDirectory({
|
|
@@ -1449,7 +1525,7 @@ async function importAgents(projectRoot, results, normalize) {
|
|
|
1449
1525
|
}
|
|
1450
1526
|
async function importSkills(projectRoot, results, normalize) {
|
|
1451
1527
|
const skillsBaseDir = join7(projectRoot, CLAUDE_SKILLS_DIR);
|
|
1452
|
-
const destBase = join7(projectRoot,
|
|
1528
|
+
const destBase = join7(projectRoot, CLAUDE_CANONICAL_SKILLS_DIR);
|
|
1453
1529
|
const allFiles = await readDirRecursive(skillsBaseDir);
|
|
1454
1530
|
const skillMdFiles = allFiles.filter((f) => f.endsWith("SKILL.md"));
|
|
1455
1531
|
for (const skillMdPath of skillMdFiles) {
|
|
@@ -1464,7 +1540,7 @@ async function importSkills(projectRoot, results, normalize) {
|
|
|
1464
1540
|
const destPath = join7(destSkillDir, relPath);
|
|
1465
1541
|
await mkdirp(dirname6(destPath));
|
|
1466
1542
|
await writeFileAtomic(destPath, normalize(fileContent, filePath, destPath));
|
|
1467
|
-
const toPath = `${
|
|
1543
|
+
const toPath = `${CLAUDE_CANONICAL_SKILLS_DIR}/${skillName}/${relPath}`;
|
|
1468
1544
|
results.push({
|
|
1469
1545
|
fromTool: "claude-code",
|
|
1470
1546
|
fromPath: filePath,
|
|
@@ -1475,16 +1551,16 @@ async function importSkills(projectRoot, results, normalize) {
|
|
|
1475
1551
|
}
|
|
1476
1552
|
}
|
|
1477
1553
|
async function importIgnore(projectRoot, results) {
|
|
1478
|
-
const ignorePath = join7(projectRoot,
|
|
1554
|
+
const ignorePath = join7(projectRoot, CLAUDE_IGNORE);
|
|
1479
1555
|
const content = await readFileSafe(ignorePath);
|
|
1480
1556
|
if (content === null) return;
|
|
1481
|
-
const destPath = join7(projectRoot,
|
|
1557
|
+
const destPath = join7(projectRoot, CLAUDE_CANONICAL_IGNORE);
|
|
1482
1558
|
await mkdirp(dirname6(destPath));
|
|
1483
1559
|
await writeFileAtomic(destPath, content);
|
|
1484
1560
|
results.push({
|
|
1485
1561
|
fromTool: "claude-code",
|
|
1486
1562
|
fromPath: ignorePath,
|
|
1487
|
-
toPath:
|
|
1563
|
+
toPath: CLAUDE_CANONICAL_IGNORE,
|
|
1488
1564
|
feature: "ignore"
|
|
1489
1565
|
});
|
|
1490
1566
|
}
|
|
@@ -1525,9 +1601,23 @@ function toStringRecord(value) {
|
|
|
1525
1601
|
);
|
|
1526
1602
|
}
|
|
1527
1603
|
|
|
1604
|
+
// src/targets/cline/constants.ts
|
|
1605
|
+
var CLINE_TARGET = "cline";
|
|
1606
|
+
var CLINE_RULES_DIR = ".clinerules";
|
|
1607
|
+
var CLINE_IGNORE = ".clineignore";
|
|
1608
|
+
var CLINE_MCP_SETTINGS = ".cline/mcp_settings.json";
|
|
1609
|
+
var CLINE_SKILLS_DIR = ".cline/skills";
|
|
1610
|
+
var CLINE_WORKFLOWS_DIR = ".clinerules/workflows";
|
|
1611
|
+
var CLINE_AGENTS_MD = "AGENTS.md";
|
|
1612
|
+
var CLINE_HOOKS_DIR = ".clinerules/hooks";
|
|
1613
|
+
var CLINE_CANONICAL_RULES_DIR = ".agentsmesh/rules";
|
|
1614
|
+
var CLINE_CANONICAL_COMMANDS_DIR = ".agentsmesh/commands";
|
|
1615
|
+
var CLINE_CANONICAL_IGNORE = ".agentsmesh/ignore";
|
|
1616
|
+
var CLINE_CANONICAL_MCP = ".agentsmesh/mcp.json";
|
|
1617
|
+
var CLINE_CANONICAL_AGENTS_DIR = ".agentsmesh/agents";
|
|
1618
|
+
var CLINE_CANONICAL_SKILLS_DIR = ".agentsmesh/skills";
|
|
1619
|
+
|
|
1528
1620
|
// src/targets/cline/importer-mappers.ts
|
|
1529
|
-
var AGENTSMESH_RULES = ".agentsmesh/rules";
|
|
1530
|
-
var AGENTSMESH_COMMANDS = ".agentsmesh/commands";
|
|
1531
1621
|
async function mapClineRuleFile(srcPath, destDir, normalizeTo) {
|
|
1532
1622
|
if (srcPath.includes("/workflows/")) return null;
|
|
1533
1623
|
const name = basename6(srcPath, ".md");
|
|
@@ -1545,7 +1635,7 @@ async function mapClineRuleFile(srcPath, destDir, normalizeTo) {
|
|
|
1545
1635
|
});
|
|
1546
1636
|
return {
|
|
1547
1637
|
destPath,
|
|
1548
|
-
toPath: `${
|
|
1638
|
+
toPath: `${CLINE_CANONICAL_RULES_DIR}/${name}.md`,
|
|
1549
1639
|
feature: "rules",
|
|
1550
1640
|
content: await serializeImportedRuleWithFallback(destPath, canonicalFm, body)
|
|
1551
1641
|
};
|
|
@@ -1574,7 +1664,7 @@ async function mapClineWorkflowFile(srcPath, destDir, normalizeTo) {
|
|
|
1574
1664
|
}
|
|
1575
1665
|
return {
|
|
1576
1666
|
destPath,
|
|
1577
|
-
toPath: `${
|
|
1667
|
+
toPath: `${CLINE_CANONICAL_COMMANDS_DIR}/${name}.md`,
|
|
1578
1668
|
feature: "commands",
|
|
1579
1669
|
content: await serializeImportedCommandWithFallback(
|
|
1580
1670
|
destPath,
|
|
@@ -1589,18 +1679,8 @@ async function mapClineWorkflowFile(srcPath, destDir, normalizeTo) {
|
|
|
1589
1679
|
};
|
|
1590
1680
|
}
|
|
1591
1681
|
|
|
1592
|
-
// src/targets/cline/constants.ts
|
|
1593
|
-
var CLINE_RULES_DIR = ".clinerules";
|
|
1594
|
-
var CLINE_IGNORE = ".clineignore";
|
|
1595
|
-
var CLINE_MCP_SETTINGS = ".cline/mcp_settings.json";
|
|
1596
|
-
var CLINE_SKILLS_DIR = ".cline/skills";
|
|
1597
|
-
var CLINE_WORKFLOWS_DIR = ".clinerules/workflows";
|
|
1598
|
-
var CLINE_AGENTS_MD = "AGENTS.md";
|
|
1599
|
-
var CLINE_HOOKS_DIR = ".clinerules/hooks";
|
|
1600
|
-
|
|
1601
1682
|
// src/targets/cline/mcp-mapper.ts
|
|
1602
1683
|
import { join as join9 } from "path";
|
|
1603
|
-
var AGENTSMESH_MCP = ".agentsmesh/mcp.json";
|
|
1604
1684
|
function mapClineServerToCanonical(raw) {
|
|
1605
1685
|
if (!raw || typeof raw !== "object") return null;
|
|
1606
1686
|
const obj = raw;
|
|
@@ -1642,13 +1722,13 @@ async function importClineMcp(projectRoot, results) {
|
|
|
1642
1722
|
if (Object.keys(mcpServers).length > 0) {
|
|
1643
1723
|
await mkdirp(join9(projectRoot, ".agentsmesh"));
|
|
1644
1724
|
await writeFileAtomic(
|
|
1645
|
-
join9(projectRoot,
|
|
1725
|
+
join9(projectRoot, CLINE_CANONICAL_MCP),
|
|
1646
1726
|
JSON.stringify({ mcpServers }, null, 2)
|
|
1647
1727
|
);
|
|
1648
1728
|
results.push({
|
|
1649
|
-
fromTool:
|
|
1729
|
+
fromTool: CLINE_TARGET,
|
|
1650
1730
|
fromPath: mcpPath,
|
|
1651
|
-
toPath:
|
|
1731
|
+
toPath: CLINE_CANONICAL_MCP,
|
|
1652
1732
|
feature: "mcp"
|
|
1653
1733
|
});
|
|
1654
1734
|
}
|
|
@@ -1659,8 +1739,6 @@ async function importClineMcp(projectRoot, results) {
|
|
|
1659
1739
|
import { readdir as readdir2 } from "fs/promises";
|
|
1660
1740
|
import { join as join10 } from "path";
|
|
1661
1741
|
init_markdown();
|
|
1662
|
-
var AGENTSMESH_AGENTS = ".agentsmesh/agents";
|
|
1663
|
-
var AGENTSMESH_SKILLS = ".agentsmesh/skills";
|
|
1664
1742
|
async function importClineSkills(projectRoot, results, normalize) {
|
|
1665
1743
|
const skillsDir = join10(projectRoot, CLINE_SKILLS_DIR);
|
|
1666
1744
|
const skillDirs = [];
|
|
@@ -1683,7 +1761,7 @@ async function importClineSkills(projectRoot, results, normalize) {
|
|
|
1683
1761
|
const rawParsed = parseFrontmatter(content);
|
|
1684
1762
|
const projectedAgent = parseProjectedAgentSkillFrontmatter(rawParsed.frontmatter, name);
|
|
1685
1763
|
if (projectedAgent) {
|
|
1686
|
-
const destAgentsDir = join10(projectRoot,
|
|
1764
|
+
const destAgentsDir = join10(projectRoot, CLINE_CANONICAL_AGENTS_DIR);
|
|
1687
1765
|
await mkdirp(destAgentsDir);
|
|
1688
1766
|
const agentPath = join10(destAgentsDir, `${projectedAgent.name}.md`);
|
|
1689
1767
|
await writeFileAtomic(
|
|
@@ -1691,17 +1769,17 @@ async function importClineSkills(projectRoot, results, normalize) {
|
|
|
1691
1769
|
serializeImportedAgent(projectedAgent, normalize(rawParsed.body, skillMdPath, agentPath))
|
|
1692
1770
|
);
|
|
1693
1771
|
results.push({
|
|
1694
|
-
fromTool:
|
|
1772
|
+
fromTool: CLINE_TARGET,
|
|
1695
1773
|
fromPath: skillMdPath,
|
|
1696
|
-
toPath: `${
|
|
1774
|
+
toPath: `${CLINE_CANONICAL_AGENTS_DIR}/${projectedAgent.name}.md`,
|
|
1697
1775
|
feature: "agents"
|
|
1698
1776
|
});
|
|
1699
1777
|
continue;
|
|
1700
1778
|
}
|
|
1701
|
-
const destSkillPath = join10(projectRoot,
|
|
1779
|
+
const destSkillPath = join10(projectRoot, CLINE_CANONICAL_SKILLS_DIR, name, "SKILL.md");
|
|
1702
1780
|
const normalized = normalize(content, skillMdPath, destSkillPath);
|
|
1703
1781
|
const { frontmatter, body } = parseFrontmatter(normalized);
|
|
1704
|
-
const destSkillDir = join10(projectRoot,
|
|
1782
|
+
const destSkillDir = join10(projectRoot, CLINE_CANONICAL_SKILLS_DIR, name);
|
|
1705
1783
|
await mkdirp(destSkillDir);
|
|
1706
1784
|
const canonicalFm = {
|
|
1707
1785
|
description: typeof frontmatter.description === "string" ? frontmatter.description : void 0
|
|
@@ -1710,9 +1788,9 @@ async function importClineSkills(projectRoot, results, normalize) {
|
|
|
1710
1788
|
const skillContent = Object.keys(canonicalFm).length > 0 ? serializeFrontmatter(canonicalFm, body.trim() || "") : body.trim() || "";
|
|
1711
1789
|
await writeFileAtomic(destSkillPath, skillContent);
|
|
1712
1790
|
results.push({
|
|
1713
|
-
fromTool:
|
|
1791
|
+
fromTool: CLINE_TARGET,
|
|
1714
1792
|
fromPath: skillMdPath,
|
|
1715
|
-
toPath: `${
|
|
1793
|
+
toPath: `${CLINE_CANONICAL_SKILLS_DIR}/${name}/SKILL.md`,
|
|
1716
1794
|
feature: "skills"
|
|
1717
1795
|
});
|
|
1718
1796
|
const allFiles = await readDirRecursive(skillPath);
|
|
@@ -1725,9 +1803,9 @@ async function importClineSkills(projectRoot, results, normalize) {
|
|
|
1725
1803
|
await mkdirp(join10(destSupportPath, ".."));
|
|
1726
1804
|
await writeFileAtomic(destSupportPath, normalize(supportContent, absPath, destSupportPath));
|
|
1727
1805
|
results.push({
|
|
1728
|
-
fromTool:
|
|
1806
|
+
fromTool: CLINE_TARGET,
|
|
1729
1807
|
fromPath: absPath,
|
|
1730
|
-
toPath: `${
|
|
1808
|
+
toPath: `${CLINE_CANONICAL_SKILLS_DIR}/${name}/${relPath}`,
|
|
1731
1809
|
feature: "skills"
|
|
1732
1810
|
});
|
|
1733
1811
|
}
|
|
@@ -1735,13 +1813,10 @@ async function importClineSkills(projectRoot, results, normalize) {
|
|
|
1735
1813
|
}
|
|
1736
1814
|
|
|
1737
1815
|
// src/targets/cline/importer.ts
|
|
1738
|
-
var AGENTSMESH_RULES2 = ".agentsmesh/rules";
|
|
1739
|
-
var AGENTSMESH_COMMANDS2 = ".agentsmesh/commands";
|
|
1740
|
-
var AGENTSMESH_IGNORE = ".agentsmesh/ignore";
|
|
1741
1816
|
async function importFromCline(projectRoot) {
|
|
1742
1817
|
const results = [];
|
|
1743
|
-
const normalize = await createImportReferenceNormalizer(
|
|
1744
|
-
const destRulesDir = join11(projectRoot,
|
|
1818
|
+
const normalize = await createImportReferenceNormalizer(CLINE_TARGET, projectRoot);
|
|
1819
|
+
const destRulesDir = join11(projectRoot, CLINE_CANONICAL_RULES_DIR);
|
|
1745
1820
|
const clineRulesPath = join11(projectRoot, CLINE_RULES_DIR);
|
|
1746
1821
|
const clineRulesRaw = join11(projectRoot, CLINE_RULES_DIR);
|
|
1747
1822
|
let clineRulesIsFile = false;
|
|
@@ -1765,7 +1840,7 @@ async function importFromCline(projectRoot) {
|
|
|
1765
1840
|
results.push({
|
|
1766
1841
|
fromTool: "cline",
|
|
1767
1842
|
fromPath: clineRulesRaw,
|
|
1768
|
-
toPath: `${
|
|
1843
|
+
toPath: `${CLINE_CANONICAL_RULES_DIR}/_root.md`,
|
|
1769
1844
|
feature: "rules"
|
|
1770
1845
|
});
|
|
1771
1846
|
}
|
|
@@ -1774,7 +1849,7 @@ async function importFromCline(projectRoot) {
|
|
|
1774
1849
|
const rootPath = join11(clineRulesPath, "_root.md");
|
|
1775
1850
|
const rootContent = await readFileSafe(rootPath);
|
|
1776
1851
|
if (rootContent === null) {
|
|
1777
|
-
const agentsMdPath = join11(projectRoot,
|
|
1852
|
+
const agentsMdPath = join11(projectRoot, CLINE_AGENTS_MD);
|
|
1778
1853
|
const agentsMdContent = await readFileSafe(agentsMdPath);
|
|
1779
1854
|
if (agentsMdContent !== null) {
|
|
1780
1855
|
rootSourcePath = agentsMdPath;
|
|
@@ -1790,7 +1865,7 @@ async function importFromCline(projectRoot) {
|
|
|
1790
1865
|
results.push({
|
|
1791
1866
|
fromTool: "cline",
|
|
1792
1867
|
fromPath: agentsMdPath,
|
|
1793
|
-
toPath: `${
|
|
1868
|
+
toPath: `${CLINE_CANONICAL_RULES_DIR}/_root.md`,
|
|
1794
1869
|
feature: "rules"
|
|
1795
1870
|
});
|
|
1796
1871
|
} else {
|
|
@@ -1811,7 +1886,7 @@ async function importFromCline(projectRoot) {
|
|
|
1811
1886
|
results.push({
|
|
1812
1887
|
fromTool: "cline",
|
|
1813
1888
|
fromPath: first,
|
|
1814
|
-
toPath: `${
|
|
1889
|
+
toPath: `${CLINE_CANONICAL_RULES_DIR}/_root.md`,
|
|
1815
1890
|
feature: "rules"
|
|
1816
1891
|
});
|
|
1817
1892
|
}
|
|
@@ -1829,7 +1904,7 @@ async function importFromCline(projectRoot) {
|
|
|
1829
1904
|
results.push({
|
|
1830
1905
|
fromTool: "cline",
|
|
1831
1906
|
fromPath: rootPath,
|
|
1832
|
-
toPath: `${
|
|
1907
|
+
toPath: `${CLINE_CANONICAL_RULES_DIR}/_root.md`,
|
|
1833
1908
|
feature: "rules"
|
|
1834
1909
|
});
|
|
1835
1910
|
}
|
|
@@ -1858,18 +1933,18 @@ async function importFromCline(projectRoot) {
|
|
|
1858
1933
|
}
|
|
1859
1934
|
if (patterns.length > 0) {
|
|
1860
1935
|
await mkdirp(join11(projectRoot, ".agentsmesh"));
|
|
1861
|
-
const destIgnorePath = join11(projectRoot,
|
|
1936
|
+
const destIgnorePath = join11(projectRoot, CLINE_CANONICAL_IGNORE);
|
|
1862
1937
|
await writeFileAtomic(destIgnorePath, patterns.join("\n"));
|
|
1863
1938
|
results.push({
|
|
1864
1939
|
fromTool: "cline",
|
|
1865
1940
|
fromPath: ignorePath,
|
|
1866
|
-
toPath:
|
|
1941
|
+
toPath: CLINE_CANONICAL_IGNORE,
|
|
1867
1942
|
feature: "ignore"
|
|
1868
1943
|
});
|
|
1869
1944
|
}
|
|
1870
1945
|
}
|
|
1871
1946
|
await importClineMcp(projectRoot, results);
|
|
1872
|
-
const destCommandsDir = join11(projectRoot,
|
|
1947
|
+
const destCommandsDir = join11(projectRoot, CLINE_CANONICAL_COMMANDS_DIR);
|
|
1873
1948
|
if (!clineRulesIsFile) {
|
|
1874
1949
|
results.push(
|
|
1875
1950
|
...await importFileDirectory({
|
|
@@ -1893,9 +1968,31 @@ init_markdown();
|
|
|
1893
1968
|
// src/targets/cursor/importer-mappers.ts
|
|
1894
1969
|
init_markdown();
|
|
1895
1970
|
import { basename as basename7, join as join12 } from "path";
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
var
|
|
1971
|
+
|
|
1972
|
+
// src/targets/cursor/constants.ts
|
|
1973
|
+
var CURSOR_TARGET = "cursor";
|
|
1974
|
+
var CURSOR_COMPAT_AGENTS = "AGENTS.md";
|
|
1975
|
+
var CURSOR_LEGACY_RULES = ".cursorrules";
|
|
1976
|
+
var CURSOR_RULES_DIR = ".cursor/rules";
|
|
1977
|
+
var CURSOR_GENERAL_RULE = `${CURSOR_RULES_DIR}/general.mdc`;
|
|
1978
|
+
var CURSOR_COMMANDS_DIR = ".cursor/commands";
|
|
1979
|
+
var CURSOR_AGENTS_DIR = ".cursor/agents";
|
|
1980
|
+
var CURSOR_SKILLS_DIR = ".cursor/skills";
|
|
1981
|
+
var CURSOR_MCP = ".cursor/mcp.json";
|
|
1982
|
+
var CURSOR_HOOKS = ".cursor/hooks.json";
|
|
1983
|
+
var CURSOR_SETTINGS = ".cursor/settings.json";
|
|
1984
|
+
var CURSOR_IGNORE = ".cursorignore";
|
|
1985
|
+
var CURSOR_INDEXING_IGNORE = ".cursorindexingignore";
|
|
1986
|
+
var CURSOR_CANONICAL_RULES_DIR = ".agentsmesh/rules";
|
|
1987
|
+
var CURSOR_CANONICAL_COMMANDS_DIR = ".agentsmesh/commands";
|
|
1988
|
+
var CURSOR_CANONICAL_AGENTS_DIR = ".agentsmesh/agents";
|
|
1989
|
+
var CURSOR_CANONICAL_SKILLS_DIR = ".agentsmesh/skills";
|
|
1990
|
+
var CURSOR_CANONICAL_MCP = ".agentsmesh/mcp.json";
|
|
1991
|
+
var CURSOR_CANONICAL_PERMISSIONS = ".agentsmesh/permissions.yaml";
|
|
1992
|
+
var CURSOR_CANONICAL_HOOKS = ".agentsmesh/hooks.yaml";
|
|
1993
|
+
var CURSOR_CANONICAL_IGNORE = ".agentsmesh/ignore";
|
|
1994
|
+
|
|
1995
|
+
// src/targets/cursor/importer-mappers.ts
|
|
1899
1996
|
async function mapCursorRuleFile(srcPath, destDir, normalizeTo, onRootRule) {
|
|
1900
1997
|
const name = basename7(srcPath, ".mdc");
|
|
1901
1998
|
const destPath = join12(destDir, `${name}.md`);
|
|
@@ -1906,7 +2003,7 @@ async function mapCursorRuleFile(srcPath, destDir, normalizeTo, onRootRule) {
|
|
|
1906
2003
|
delete canonicalFm.alwaysApply;
|
|
1907
2004
|
return {
|
|
1908
2005
|
destPath,
|
|
1909
|
-
toPath: `${
|
|
2006
|
+
toPath: `${CURSOR_CANONICAL_RULES_DIR}/${name}.md`,
|
|
1910
2007
|
feature: "rules",
|
|
1911
2008
|
content: await serializeImportedRuleWithFallback(destPath, canonicalFm, body)
|
|
1912
2009
|
};
|
|
@@ -1919,7 +2016,7 @@ async function mapCursorCommandFile(srcPath, destDir, normalizeTo) {
|
|
|
1919
2016
|
const allowedTools = fromCamel.length > 0 ? fromCamel : toToolsArray(frontmatter["allowed-tools"]);
|
|
1920
2017
|
return {
|
|
1921
2018
|
destPath,
|
|
1922
|
-
toPath: `${
|
|
2019
|
+
toPath: `${CURSOR_CANONICAL_COMMANDS_DIR}/${name}.md`,
|
|
1923
2020
|
feature: "commands",
|
|
1924
2021
|
content: await serializeImportedCommandWithFallback(
|
|
1925
2022
|
destPath,
|
|
@@ -1938,7 +2035,7 @@ function mapCursorAgentFile(srcPath, destDir, normalizeTo) {
|
|
|
1938
2035
|
const destPath = join12(destDir, `${name}.md`);
|
|
1939
2036
|
return {
|
|
1940
2037
|
destPath,
|
|
1941
|
-
toPath: `${
|
|
2038
|
+
toPath: `${CURSOR_CANONICAL_AGENTS_DIR}/${name}.md`,
|
|
1942
2039
|
feature: "agents",
|
|
1943
2040
|
content: normalizeTo(destPath)
|
|
1944
2041
|
};
|
|
@@ -1947,13 +2044,6 @@ function mapCursorAgentFile(srcPath, destDir, normalizeTo) {
|
|
|
1947
2044
|
// src/targets/cursor/settings-helpers.ts
|
|
1948
2045
|
import { join as join13, dirname as dirname7 } from "path";
|
|
1949
2046
|
import { stringify as yamlStringify3 } from "yaml";
|
|
1950
|
-
var CURSOR_SETTINGS = ".cursor/settings.json";
|
|
1951
|
-
var CURSOR_HOOKS = ".cursor/hooks.json";
|
|
1952
|
-
var CURSORIGNORE = ".cursorignore";
|
|
1953
|
-
var CURSORINDEXINGIGNORE = ".cursorindexingignore";
|
|
1954
|
-
var AB_PERMISSIONS2 = ".agentsmesh/permissions.yaml";
|
|
1955
|
-
var AB_HOOKS2 = ".agentsmesh/hooks.yaml";
|
|
1956
|
-
var AB_IGNORE2 = ".agentsmesh/ignore";
|
|
1957
2047
|
function cursorHooksToCanonical(hooks) {
|
|
1958
2048
|
const result = {};
|
|
1959
2049
|
for (const [event, entries] of Object.entries(hooks)) {
|
|
@@ -1989,13 +2079,13 @@ async function importSettings2(projectRoot, results) {
|
|
|
1989
2079
|
const canonical = cursorHooksToCanonical(hooksFile.hooks);
|
|
1990
2080
|
if (Object.keys(canonical).length > 0) {
|
|
1991
2081
|
const hooksContent = yamlStringify3(canonical);
|
|
1992
|
-
const destPath = join13(projectRoot,
|
|
2082
|
+
const destPath = join13(projectRoot, CURSOR_CANONICAL_HOOKS);
|
|
1993
2083
|
await mkdirp(dirname7(destPath));
|
|
1994
2084
|
await writeFileAtomic(destPath, hooksContent);
|
|
1995
2085
|
results.push({
|
|
1996
2086
|
fromTool: "cursor",
|
|
1997
2087
|
fromPath: hooksJsonPath,
|
|
1998
|
-
toPath:
|
|
2088
|
+
toPath: CURSOR_CANONICAL_HOOKS,
|
|
1999
2089
|
feature: "hooks"
|
|
2000
2090
|
});
|
|
2001
2091
|
hooksImportedFromHooksJson = true;
|
|
@@ -2020,13 +2110,13 @@ async function importSettings2(projectRoot, results) {
|
|
|
2020
2110
|
const deny = Array.isArray(perms.deny) ? perms.deny.filter((s) => typeof s === "string") : [];
|
|
2021
2111
|
if (allow.length > 0 || deny.length > 0) {
|
|
2022
2112
|
const permContent = yamlStringify3({ allow, deny });
|
|
2023
|
-
const destPath = join13(projectRoot,
|
|
2113
|
+
const destPath = join13(projectRoot, CURSOR_CANONICAL_PERMISSIONS);
|
|
2024
2114
|
await mkdirp(dirname7(destPath));
|
|
2025
2115
|
await writeFileAtomic(destPath, permContent);
|
|
2026
2116
|
results.push({
|
|
2027
2117
|
fromTool: "cursor",
|
|
2028
2118
|
fromPath: settingsPath,
|
|
2029
|
-
toPath:
|
|
2119
|
+
toPath: CURSOR_CANONICAL_PERMISSIONS,
|
|
2030
2120
|
feature: "permissions"
|
|
2031
2121
|
});
|
|
2032
2122
|
}
|
|
@@ -2036,13 +2126,13 @@ async function importSettings2(projectRoot, results) {
|
|
|
2036
2126
|
const canonicalHooks = cursorHooksToCanonical(rawHooks);
|
|
2037
2127
|
if (Object.keys(canonicalHooks).length > 0) {
|
|
2038
2128
|
const hooksContent = yamlStringify3(canonicalHooks);
|
|
2039
|
-
const destPath = join13(projectRoot,
|
|
2129
|
+
const destPath = join13(projectRoot, CURSOR_CANONICAL_HOOKS);
|
|
2040
2130
|
await mkdirp(dirname7(destPath));
|
|
2041
2131
|
await writeFileAtomic(destPath, hooksContent);
|
|
2042
2132
|
results.push({
|
|
2043
2133
|
fromTool: "cursor",
|
|
2044
2134
|
fromPath: settingsPath,
|
|
2045
|
-
toPath:
|
|
2135
|
+
toPath: CURSOR_CANONICAL_HOOKS,
|
|
2046
2136
|
feature: "hooks"
|
|
2047
2137
|
});
|
|
2048
2138
|
}
|
|
@@ -2050,8 +2140,8 @@ async function importSettings2(projectRoot, results) {
|
|
|
2050
2140
|
}
|
|
2051
2141
|
async function importIgnore2(projectRoot, results) {
|
|
2052
2142
|
const sources = [
|
|
2053
|
-
{ path: join13(projectRoot,
|
|
2054
|
-
{ path: join13(projectRoot,
|
|
2143
|
+
{ path: join13(projectRoot, CURSOR_IGNORE), label: CURSOR_IGNORE },
|
|
2144
|
+
{ path: join13(projectRoot, CURSOR_INDEXING_IGNORE), label: CURSOR_INDEXING_IGNORE }
|
|
2055
2145
|
];
|
|
2056
2146
|
const patterns = [];
|
|
2057
2147
|
const importedFrom = [];
|
|
@@ -2067,23 +2157,21 @@ async function importIgnore2(projectRoot, results) {
|
|
|
2067
2157
|
}
|
|
2068
2158
|
}
|
|
2069
2159
|
if (patterns.length === 0) return;
|
|
2070
|
-
const destPath = join13(projectRoot,
|
|
2160
|
+
const destPath = join13(projectRoot, CURSOR_CANONICAL_IGNORE);
|
|
2071
2161
|
await mkdirp(dirname7(destPath));
|
|
2072
2162
|
await writeFileAtomic(destPath, patterns.join("\n") + "\n");
|
|
2073
2163
|
results.push({
|
|
2074
2164
|
fromTool: "cursor",
|
|
2075
2165
|
fromPath: join13(projectRoot, importedFrom[0]),
|
|
2076
|
-
toPath:
|
|
2166
|
+
toPath: CURSOR_CANONICAL_IGNORE,
|
|
2077
2167
|
feature: "ignore"
|
|
2078
2168
|
});
|
|
2079
2169
|
}
|
|
2080
2170
|
|
|
2081
2171
|
// src/targets/cursor/skills-helpers.ts
|
|
2082
2172
|
import { join as join14, basename as basename8, dirname as dirname8, relative as relative3 } from "path";
|
|
2083
|
-
var CURSOR_SKILLS_DIR = ".cursor/skills";
|
|
2084
|
-
var AB_SKILLS3 = ".agentsmesh/skills";
|
|
2085
2173
|
async function importSkills2(projectRoot, results, normalize) {
|
|
2086
|
-
const destBase = join14(projectRoot,
|
|
2174
|
+
const destBase = join14(projectRoot, CURSOR_CANONICAL_SKILLS_DIR);
|
|
2087
2175
|
const skillsDir = join14(projectRoot, CURSOR_SKILLS_DIR);
|
|
2088
2176
|
const allFiles = await readDirRecursive(skillsDir);
|
|
2089
2177
|
const mdFiles = allFiles.filter((f) => f.endsWith(".md"));
|
|
@@ -2105,7 +2193,7 @@ async function importSkills2(projectRoot, results, normalize) {
|
|
|
2105
2193
|
results.push({
|
|
2106
2194
|
fromTool: "cursor",
|
|
2107
2195
|
fromPath: filePath,
|
|
2108
|
-
toPath: `${
|
|
2196
|
+
toPath: `${CURSOR_CANONICAL_SKILLS_DIR}/${skillName}/${relPath}`,
|
|
2109
2197
|
feature: "skills"
|
|
2110
2198
|
});
|
|
2111
2199
|
}
|
|
@@ -2122,23 +2210,13 @@ async function importSkills2(projectRoot, results, normalize) {
|
|
|
2122
2210
|
results.push({
|
|
2123
2211
|
fromTool: "cursor",
|
|
2124
2212
|
fromPath: srcPath,
|
|
2125
|
-
toPath: `${
|
|
2213
|
+
toPath: `${CURSOR_CANONICAL_SKILLS_DIR}/${name}/SKILL.md`,
|
|
2126
2214
|
feature: "skills"
|
|
2127
2215
|
});
|
|
2128
2216
|
}
|
|
2129
2217
|
}
|
|
2130
2218
|
|
|
2131
2219
|
// src/targets/cursor/importer.ts
|
|
2132
|
-
var AGENTS_MD = "AGENTS.md";
|
|
2133
|
-
var CURSORRULES = ".cursorrules";
|
|
2134
|
-
var CURSOR_RULES_DIR = ".cursor/rules";
|
|
2135
|
-
var CURSOR_COMMANDS_DIR = ".cursor/commands";
|
|
2136
|
-
var CURSOR_AGENTS_DIR = ".cursor/agents";
|
|
2137
|
-
var CURSOR_MCP = ".cursor/mcp.json";
|
|
2138
|
-
var AB_RULES6 = ".agentsmesh/rules";
|
|
2139
|
-
var AB_COMMANDS6 = ".agentsmesh/commands";
|
|
2140
|
-
var AB_AGENTS6 = ".agentsmesh/agents";
|
|
2141
|
-
var AB_MCP2 = ".agentsmesh/mcp.json";
|
|
2142
2220
|
async function importFromCursor(projectRoot) {
|
|
2143
2221
|
const results = [];
|
|
2144
2222
|
const normalize = await createImportReferenceNormalizer("cursor", projectRoot);
|
|
@@ -2152,9 +2230,9 @@ async function importFromCursor(projectRoot) {
|
|
|
2152
2230
|
return results;
|
|
2153
2231
|
}
|
|
2154
2232
|
async function importRules2(projectRoot, results, normalize) {
|
|
2155
|
-
const destDir = join15(projectRoot,
|
|
2233
|
+
const destDir = join15(projectRoot, CURSOR_CANONICAL_RULES_DIR);
|
|
2156
2234
|
let rootWritten = false;
|
|
2157
|
-
const agentsPath = join15(projectRoot,
|
|
2235
|
+
const agentsPath = join15(projectRoot, CURSOR_COMPAT_AGENTS);
|
|
2158
2236
|
const agentsContent = await readFileSafe(agentsPath);
|
|
2159
2237
|
if (agentsContent !== null) {
|
|
2160
2238
|
rootWritten = true;
|
|
@@ -2168,7 +2246,7 @@ async function importRules2(projectRoot, results, normalize) {
|
|
|
2168
2246
|
results.push({
|
|
2169
2247
|
fromTool: "cursor",
|
|
2170
2248
|
fromPath: agentsPath,
|
|
2171
|
-
toPath: `${
|
|
2249
|
+
toPath: `${CURSOR_CANONICAL_RULES_DIR}/_root.md`,
|
|
2172
2250
|
feature: "rules"
|
|
2173
2251
|
});
|
|
2174
2252
|
}
|
|
@@ -2195,7 +2273,7 @@ async function importRules2(projectRoot, results, normalize) {
|
|
|
2195
2273
|
})
|
|
2196
2274
|
);
|
|
2197
2275
|
if (!rootWritten) {
|
|
2198
|
-
const cursorRulesPath = join15(projectRoot,
|
|
2276
|
+
const cursorRulesPath = join15(projectRoot, CURSOR_LEGACY_RULES);
|
|
2199
2277
|
const cursorRulesContent = await readFileSafe(cursorRulesPath);
|
|
2200
2278
|
if (cursorRulesContent !== null) {
|
|
2201
2279
|
await mkdirp(destDir);
|
|
@@ -2209,14 +2287,14 @@ async function importRules2(projectRoot, results, normalize) {
|
|
|
2209
2287
|
results.push({
|
|
2210
2288
|
fromTool: "cursor",
|
|
2211
2289
|
fromPath: cursorRulesPath,
|
|
2212
|
-
toPath: `${
|
|
2290
|
+
toPath: `${CURSOR_CANONICAL_RULES_DIR}/_root.md`,
|
|
2213
2291
|
feature: "rules"
|
|
2214
2292
|
});
|
|
2215
2293
|
}
|
|
2216
2294
|
}
|
|
2217
2295
|
}
|
|
2218
2296
|
async function importCommands2(projectRoot, results, normalize) {
|
|
2219
|
-
const destDir = join15(projectRoot,
|
|
2297
|
+
const destDir = join15(projectRoot, CURSOR_CANONICAL_COMMANDS_DIR);
|
|
2220
2298
|
const commandsDir = join15(projectRoot, CURSOR_COMMANDS_DIR);
|
|
2221
2299
|
results.push(
|
|
2222
2300
|
...await importFileDirectory({
|
|
@@ -2230,7 +2308,7 @@ async function importCommands2(projectRoot, results, normalize) {
|
|
|
2230
2308
|
);
|
|
2231
2309
|
}
|
|
2232
2310
|
async function importAgents2(projectRoot, results, normalize) {
|
|
2233
|
-
const destDir = join15(projectRoot,
|
|
2311
|
+
const destDir = join15(projectRoot, CURSOR_CANONICAL_AGENTS_DIR);
|
|
2234
2312
|
const agentsDir = join15(projectRoot, CURSOR_AGENTS_DIR);
|
|
2235
2313
|
results.push(
|
|
2236
2314
|
...await importFileDirectory({
|
|
@@ -2254,29 +2332,43 @@ async function importMcp(projectRoot, results) {
|
|
|
2254
2332
|
return;
|
|
2255
2333
|
}
|
|
2256
2334
|
if (!parsed || typeof parsed !== "object" || !("mcpServers" in parsed)) return;
|
|
2257
|
-
const destPath = join15(projectRoot,
|
|
2335
|
+
const destPath = join15(projectRoot, CURSOR_CANONICAL_MCP);
|
|
2258
2336
|
await mkdirp(dirname9(destPath));
|
|
2259
2337
|
await writeFileAtomic(destPath, content);
|
|
2260
2338
|
results.push({
|
|
2261
2339
|
fromTool: "cursor",
|
|
2262
2340
|
fromPath: mcpPath,
|
|
2263
|
-
toPath:
|
|
2341
|
+
toPath: CURSOR_CANONICAL_MCP,
|
|
2264
2342
|
feature: "mcp"
|
|
2265
2343
|
});
|
|
2266
2344
|
}
|
|
2267
2345
|
|
|
2268
2346
|
// src/targets/codex-cli/importer.ts
|
|
2269
|
-
import { join as join19, relative as relative5, dirname as dirname11, basename as
|
|
2347
|
+
import { join as join19, relative as relative5, dirname as dirname11, basename as basename11 } from "path";
|
|
2270
2348
|
init_markdown();
|
|
2271
2349
|
|
|
2272
2350
|
// src/targets/codex-cli/constants.ts
|
|
2351
|
+
var CODEX_TARGET = "codex-cli";
|
|
2273
2352
|
var CODEX_MD = "codex.md";
|
|
2274
|
-
var
|
|
2353
|
+
var AGENTS_MD = "AGENTS.md";
|
|
2275
2354
|
var CODEX_SKILLS_DIR = ".agents/skills";
|
|
2276
2355
|
var CODEX_SKILLS_FALLBACK_DIR = ".codex/skills";
|
|
2277
2356
|
var CODEX_CONFIG_TOML = ".codex/config.toml";
|
|
2357
|
+
var CODEX_INSTRUCTIONS_DIR = ".codex/instructions";
|
|
2278
2358
|
var CODEX_RULES_DIR = ".codex/rules";
|
|
2279
2359
|
var CODEX_AGENTS_DIR = ".codex/agents";
|
|
2360
|
+
var CODEX_CANONICAL_RULES_DIR = ".agentsmesh/rules";
|
|
2361
|
+
var CODEX_CANONICAL_COMMANDS_DIR = ".agentsmesh/commands";
|
|
2362
|
+
var CODEX_CANONICAL_AGENTS_DIR = ".agentsmesh/agents";
|
|
2363
|
+
var CODEX_CANONICAL_SKILLS_DIR = ".agentsmesh/skills";
|
|
2364
|
+
var CODEX_CANONICAL_MCP = ".agentsmesh/mcp.json";
|
|
2365
|
+
var CODEX_RULE_EMBED_MARKER = "am-codex-rule:v1";
|
|
2366
|
+
var CODEX_RULE_EMBED_JSON_PREFIX = "# am-json: ";
|
|
2367
|
+
var CODEX_RULE_EMBED_B64_BEGIN = "# am-body-b64-begin";
|
|
2368
|
+
var CODEX_RULE_EMBED_B64_END = "# am-body-b64-end";
|
|
2369
|
+
var CODEX_RULE_EMBED_B64_LINE = "# am64:";
|
|
2370
|
+
var CODEX_RULE_INDEX_START = "<!-- agentsmesh:codex-rule-index:start -->";
|
|
2371
|
+
var CODEX_RULE_INDEX_END = "<!-- agentsmesh:codex-rule-index:end -->";
|
|
2280
2372
|
|
|
2281
2373
|
// src/targets/codex-cli/import-codex-non-root-rules.ts
|
|
2282
2374
|
import { join as join16, basename as basename9 } from "path";
|
|
@@ -2284,18 +2376,13 @@ init_markdown();
|
|
|
2284
2376
|
|
|
2285
2377
|
// src/targets/codex-cli/codex-rules-embed.ts
|
|
2286
2378
|
import { Buffer as Buffer2 } from "buffer";
|
|
2287
|
-
var MARKER = "am-codex-rule:v1";
|
|
2288
|
-
var JSON_PREFIX = "# am-json: ";
|
|
2289
|
-
var B64_BEGIN = "# am-body-b64-begin";
|
|
2290
|
-
var B64_END = "# am-body-b64-end";
|
|
2291
|
-
var B64_LINE = "# am64:";
|
|
2292
2379
|
function tryParseEmbeddedCanonicalFromCodexRules(content) {
|
|
2293
|
-
if (!content.includes(
|
|
2294
|
-
const jsonLine = content.split("\n").find((l) => l.startsWith(
|
|
2380
|
+
if (!content.includes(CODEX_RULE_EMBED_MARKER)) return null;
|
|
2381
|
+
const jsonLine = content.split("\n").find((l) => l.startsWith(CODEX_RULE_EMBED_JSON_PREFIX));
|
|
2295
2382
|
if (!jsonLine) return null;
|
|
2296
2383
|
let parsed;
|
|
2297
2384
|
try {
|
|
2298
|
-
parsed = JSON.parse(jsonLine.slice(
|
|
2385
|
+
parsed = JSON.parse(jsonLine.slice(CODEX_RULE_EMBED_JSON_PREFIX.length));
|
|
2299
2386
|
} catch {
|
|
2300
2387
|
return null;
|
|
2301
2388
|
}
|
|
@@ -2307,16 +2394,16 @@ function tryParseEmbeddedCanonicalFromCodexRules(content) {
|
|
|
2307
2394
|
let inB64 = false;
|
|
2308
2395
|
for (const line of content.split("\n")) {
|
|
2309
2396
|
const t = line.trimEnd();
|
|
2310
|
-
if (t ===
|
|
2397
|
+
if (t === CODEX_RULE_EMBED_B64_BEGIN) {
|
|
2311
2398
|
inB64 = true;
|
|
2312
2399
|
continue;
|
|
2313
2400
|
}
|
|
2314
|
-
if (t ===
|
|
2401
|
+
if (t === CODEX_RULE_EMBED_B64_END) {
|
|
2315
2402
|
inB64 = false;
|
|
2316
2403
|
continue;
|
|
2317
2404
|
}
|
|
2318
|
-
if (inB64 && t.startsWith(
|
|
2319
|
-
chunks.push(t.slice(
|
|
2405
|
+
if (inB64 && t.startsWith(CODEX_RULE_EMBED_B64_LINE)) {
|
|
2406
|
+
chunks.push(t.slice(CODEX_RULE_EMBED_B64_LINE.length));
|
|
2320
2407
|
}
|
|
2321
2408
|
}
|
|
2322
2409
|
if (chunks.length === 0) return null;
|
|
@@ -2329,7 +2416,6 @@ function tryParseEmbeddedCanonicalFromCodexRules(content) {
|
|
|
2329
2416
|
}
|
|
2330
2417
|
|
|
2331
2418
|
// src/targets/codex-cli/import-codex-non-root-rules.ts
|
|
2332
|
-
var AB_RULES7 = ".agentsmesh/rules";
|
|
2333
2419
|
async function importCodexNonRootRuleFiles(projectRoot, destDir, normalize) {
|
|
2334
2420
|
const results = [];
|
|
2335
2421
|
const codexRulesPath = join16(projectRoot, CODEX_RULES_DIR);
|
|
@@ -2347,9 +2433,9 @@ async function importCodexNonRootRuleFiles(projectRoot, destDir, normalize) {
|
|
|
2347
2433
|
const outContent = await serializeImportedRuleWithFallback(destPath, outFm, body);
|
|
2348
2434
|
await writeFileAtomic(destPath, outContent);
|
|
2349
2435
|
results.push({
|
|
2350
|
-
fromTool:
|
|
2436
|
+
fromTool: CODEX_TARGET,
|
|
2351
2437
|
fromPath: srcPath,
|
|
2352
|
-
toPath: `${
|
|
2438
|
+
toPath: `${CODEX_CANONICAL_RULES_DIR}/${slug}.md`,
|
|
2353
2439
|
feature: "rules"
|
|
2354
2440
|
});
|
|
2355
2441
|
}
|
|
@@ -2386,9 +2472,9 @@ async function importCodexNonRootRuleFiles(projectRoot, destDir, normalize) {
|
|
|
2386
2472
|
await writeFileAtomic(destPath, outContent);
|
|
2387
2473
|
}
|
|
2388
2474
|
results.push({
|
|
2389
|
-
fromTool:
|
|
2475
|
+
fromTool: CODEX_TARGET,
|
|
2390
2476
|
fromPath: srcPath,
|
|
2391
|
-
toPath: `${
|
|
2477
|
+
toPath: `${CODEX_CANONICAL_RULES_DIR}/${slug}.md`,
|
|
2392
2478
|
feature: "rules"
|
|
2393
2479
|
});
|
|
2394
2480
|
}
|
|
@@ -2397,10 +2483,76 @@ async function importCodexNonRootRuleFiles(projectRoot, destDir, normalize) {
|
|
|
2397
2483
|
return results;
|
|
2398
2484
|
}
|
|
2399
2485
|
|
|
2486
|
+
// src/targets/codex-cli/instruction-mirror.ts
|
|
2487
|
+
init_markdown();
|
|
2488
|
+
import { basename as basename10 } from "path";
|
|
2489
|
+
function ruleSlug(source) {
|
|
2490
|
+
return basename10(source, ".md");
|
|
2491
|
+
}
|
|
2492
|
+
function codexInstructionMirrorPath(rule) {
|
|
2493
|
+
return `${CODEX_INSTRUCTIONS_DIR}/${ruleSlug(rule.source)}.md`;
|
|
2494
|
+
}
|
|
2495
|
+
function serializeCodexInstructionMirror(rule) {
|
|
2496
|
+
const frontmatter = {
|
|
2497
|
+
root: rule.root,
|
|
2498
|
+
description: rule.description || void 0,
|
|
2499
|
+
globs: rule.globs.length > 0 ? rule.globs : void 0,
|
|
2500
|
+
targets: rule.targets.length > 0 ? rule.targets : void 0,
|
|
2501
|
+
codex_emit: rule.codexEmit || void 0,
|
|
2502
|
+
codex_instruction: rule.codexInstructionVariant && rule.codexInstructionVariant !== "default" ? rule.codexInstructionVariant : void 0
|
|
2503
|
+
};
|
|
2504
|
+
Object.keys(frontmatter).forEach((key) => {
|
|
2505
|
+
if (frontmatter[key] === void 0) delete frontmatter[key];
|
|
2506
|
+
});
|
|
2507
|
+
return serializeFrontmatter(frontmatter, rule.body.trim() || "");
|
|
2508
|
+
}
|
|
2509
|
+
function summarizeRule(rule) {
|
|
2510
|
+
const scopes = [];
|
|
2511
|
+
if (rule.root) {
|
|
2512
|
+
scopes.push("Applies to the whole project.");
|
|
2513
|
+
} else if (rule.globs.length > 0) {
|
|
2514
|
+
scopes.push(`Applies to ${rule.globs.map((glob) => `\`${glob}\``).join(", ")}.`);
|
|
2515
|
+
} else {
|
|
2516
|
+
scopes.push("General guidance with no file glob restriction.");
|
|
2517
|
+
}
|
|
2518
|
+
if (rule.codexInstructionVariant === "override") {
|
|
2519
|
+
scopes.push("Override guidance when this rule conflicts with broader instructions.");
|
|
2520
|
+
}
|
|
2521
|
+
if (rule.codexEmit === "execution") {
|
|
2522
|
+
scopes.push(`Enforced in \`${CODEX_RULES_DIR}/${ruleSlug(rule.source)}.rules\`.`);
|
|
2523
|
+
}
|
|
2524
|
+
if (rule.targets.length > 0) {
|
|
2525
|
+
scopes.push(`Targeted to ${rule.targets.map((target10) => `\`${target10}\``).join(", ")}.`);
|
|
2526
|
+
}
|
|
2527
|
+
return scopes.join(" ");
|
|
2528
|
+
}
|
|
2529
|
+
function appendCodexRuleIndex(rootBody, rules) {
|
|
2530
|
+
const trimmed = rootBody.trim();
|
|
2531
|
+
const additionalRules = rules.filter((rule) => !rule.root);
|
|
2532
|
+
if (additionalRules.length === 0) return trimmed;
|
|
2533
|
+
const entries = additionalRules.map((rule) => {
|
|
2534
|
+
const label = rule.description || ruleSlug(rule.source);
|
|
2535
|
+
return `- [${label}](${codexInstructionMirrorPath(rule)}): ${summarizeRule(rule)}`;
|
|
2536
|
+
});
|
|
2537
|
+
const section = [
|
|
2538
|
+
CODEX_RULE_INDEX_START,
|
|
2539
|
+
"## Additional Rule Files",
|
|
2540
|
+
...entries,
|
|
2541
|
+
CODEX_RULE_INDEX_END
|
|
2542
|
+
].join("\n");
|
|
2543
|
+
return trimmed ? `${trimmed}
|
|
2544
|
+
|
|
2545
|
+
${section}` : section;
|
|
2546
|
+
}
|
|
2547
|
+
function stripCodexRuleIndex(content) {
|
|
2548
|
+
const escapedStart = CODEX_RULE_INDEX_START.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2549
|
+
const escapedEnd = CODEX_RULE_INDEX_END.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2550
|
+
return content.replace(new RegExp(`\\n?${escapedStart}[\\s\\S]*?${escapedEnd}\\n?`, "g"), "\n").trim();
|
|
2551
|
+
}
|
|
2552
|
+
|
|
2400
2553
|
// src/targets/codex-cli/mcp-helpers.ts
|
|
2401
2554
|
import { join as join17 } from "path";
|
|
2402
2555
|
import { parse as parseToml } from "smol-toml";
|
|
2403
|
-
var AB_MCP3 = ".agentsmesh/mcp.json";
|
|
2404
2556
|
function mapTomlServerToCanonical(raw) {
|
|
2405
2557
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
|
|
2406
2558
|
const obj = raw;
|
|
@@ -2441,11 +2593,14 @@ async function importMcp2(projectRoot, results) {
|
|
|
2441
2593
|
}
|
|
2442
2594
|
if (Object.keys(mcpServers).length === 0) return;
|
|
2443
2595
|
await mkdirp(join17(projectRoot, ".agentsmesh"));
|
|
2444
|
-
await writeFileAtomic(
|
|
2596
|
+
await writeFileAtomic(
|
|
2597
|
+
join17(projectRoot, CODEX_CANONICAL_MCP),
|
|
2598
|
+
JSON.stringify({ mcpServers }, null, 2)
|
|
2599
|
+
);
|
|
2445
2600
|
results.push({
|
|
2446
|
-
fromTool:
|
|
2601
|
+
fromTool: CODEX_TARGET,
|
|
2447
2602
|
fromPath: configPath,
|
|
2448
|
-
toPath:
|
|
2603
|
+
toPath: CODEX_CANONICAL_MCP,
|
|
2449
2604
|
feature: "mcp"
|
|
2450
2605
|
});
|
|
2451
2606
|
}
|
|
@@ -2469,9 +2624,6 @@ async function removePathIfExists(path) {
|
|
|
2469
2624
|
}
|
|
2470
2625
|
|
|
2471
2626
|
// src/targets/codex-cli/skills-helpers.ts
|
|
2472
|
-
var AB_COMMANDS7 = ".agentsmesh/commands";
|
|
2473
|
-
var AB_AGENTS7 = ".agentsmesh/agents";
|
|
2474
|
-
var AB_SKILLS4 = ".agentsmesh/skills";
|
|
2475
2627
|
async function importSkills3(projectRoot, results, normalize) {
|
|
2476
2628
|
for (const skillsRoot of [CODEX_SKILLS_DIR, CODEX_SKILLS_FALLBACK_DIR]) {
|
|
2477
2629
|
const skillsDir = join18(projectRoot, skillsRoot);
|
|
@@ -2491,13 +2643,13 @@ async function importSkills3(projectRoot, results, normalize) {
|
|
|
2491
2643
|
if (!skillMdContent) continue;
|
|
2492
2644
|
importedAny = true;
|
|
2493
2645
|
const skillName = ent.name;
|
|
2494
|
-
const destSkillPath = join18(projectRoot,
|
|
2646
|
+
const destSkillPath = join18(projectRoot, CODEX_CANONICAL_SKILLS_DIR, skillName, "SKILL.md");
|
|
2495
2647
|
const normalized = normalize(skillMdContent, skillMdPath, destSkillPath);
|
|
2496
2648
|
const { frontmatter, body } = parseFrontmatter(normalized);
|
|
2497
2649
|
const command = parseCommandSkillFrontmatter(frontmatter, ent.name);
|
|
2498
2650
|
if (command) {
|
|
2499
|
-
await removePathIfExists(join18(projectRoot,
|
|
2500
|
-
const destCommandsDir = join18(projectRoot,
|
|
2651
|
+
await removePathIfExists(join18(projectRoot, CODEX_CANONICAL_SKILLS_DIR, skillName));
|
|
2652
|
+
const destCommandsDir = join18(projectRoot, CODEX_CANONICAL_COMMANDS_DIR);
|
|
2501
2653
|
await mkdirp(destCommandsDir);
|
|
2502
2654
|
const commandPath = join18(destCommandsDir, `${command.name}.md`);
|
|
2503
2655
|
await writeFileAtomic(
|
|
@@ -2505,17 +2657,17 @@ async function importSkills3(projectRoot, results, normalize) {
|
|
|
2505
2657
|
serializeImportedCommand(command, normalize(body, skillMdPath, commandPath))
|
|
2506
2658
|
);
|
|
2507
2659
|
results.push({
|
|
2508
|
-
fromTool:
|
|
2660
|
+
fromTool: CODEX_TARGET,
|
|
2509
2661
|
fromPath: skillMdPath,
|
|
2510
|
-
toPath: `${
|
|
2662
|
+
toPath: `${CODEX_CANONICAL_COMMANDS_DIR}/${command.name}.md`,
|
|
2511
2663
|
feature: "commands"
|
|
2512
2664
|
});
|
|
2513
2665
|
continue;
|
|
2514
2666
|
}
|
|
2515
2667
|
const projectedAgent = parseProjectedAgentSkillFrontmatter(frontmatter, ent.name);
|
|
2516
2668
|
if (projectedAgent) {
|
|
2517
|
-
await removePathIfExists(join18(projectRoot,
|
|
2518
|
-
const destAgentsDir = join18(projectRoot,
|
|
2669
|
+
await removePathIfExists(join18(projectRoot, CODEX_CANONICAL_SKILLS_DIR, skillName));
|
|
2670
|
+
const destAgentsDir = join18(projectRoot, CODEX_CANONICAL_AGENTS_DIR);
|
|
2519
2671
|
await mkdirp(destAgentsDir);
|
|
2520
2672
|
const agentPath = join18(destAgentsDir, `${projectedAgent.name}.md`);
|
|
2521
2673
|
await writeFileAtomic(
|
|
@@ -2523,14 +2675,14 @@ async function importSkills3(projectRoot, results, normalize) {
|
|
|
2523
2675
|
serializeImportedAgent(projectedAgent, normalize(body, skillMdPath, agentPath))
|
|
2524
2676
|
);
|
|
2525
2677
|
results.push({
|
|
2526
|
-
fromTool:
|
|
2678
|
+
fromTool: CODEX_TARGET,
|
|
2527
2679
|
fromPath: skillMdPath,
|
|
2528
|
-
toPath: `${
|
|
2680
|
+
toPath: `${CODEX_CANONICAL_AGENTS_DIR}/${projectedAgent.name}.md`,
|
|
2529
2681
|
feature: "agents"
|
|
2530
2682
|
});
|
|
2531
2683
|
continue;
|
|
2532
2684
|
}
|
|
2533
|
-
const destSkillDir = join18(projectRoot,
|
|
2685
|
+
const destSkillDir = join18(projectRoot, CODEX_CANONICAL_SKILLS_DIR, skillName);
|
|
2534
2686
|
await mkdirp(destSkillDir);
|
|
2535
2687
|
const canonicalFm = {
|
|
2536
2688
|
description: typeof frontmatter.description === "string" ? frontmatter.description : void 0
|
|
@@ -2539,9 +2691,9 @@ async function importSkills3(projectRoot, results, normalize) {
|
|
|
2539
2691
|
const outContent = Object.keys(canonicalFm).length > 0 ? serializeFrontmatter(canonicalFm, body.trim() || "") : body.trim() || "";
|
|
2540
2692
|
await writeFileAtomic(destSkillPath, outContent);
|
|
2541
2693
|
results.push({
|
|
2542
|
-
fromTool:
|
|
2694
|
+
fromTool: CODEX_TARGET,
|
|
2543
2695
|
fromPath: skillMdPath,
|
|
2544
|
-
toPath: `${
|
|
2696
|
+
toPath: `${CODEX_CANONICAL_SKILLS_DIR}/${skillName}/SKILL.md`,
|
|
2545
2697
|
feature: "skills"
|
|
2546
2698
|
});
|
|
2547
2699
|
const allFiles = await readDirRecursive(skillPath);
|
|
@@ -2554,9 +2706,9 @@ async function importSkills3(projectRoot, results, normalize) {
|
|
|
2554
2706
|
await mkdirp(dirname10(destPath));
|
|
2555
2707
|
await writeFileAtomic(destPath, normalize(fileContent, absPath, destPath));
|
|
2556
2708
|
results.push({
|
|
2557
|
-
fromTool:
|
|
2709
|
+
fromTool: CODEX_TARGET,
|
|
2558
2710
|
fromPath: absPath,
|
|
2559
|
-
toPath: `${
|
|
2711
|
+
toPath: `${CODEX_CANONICAL_SKILLS_DIR}/${skillName}/${relPath}`,
|
|
2560
2712
|
feature: "skills"
|
|
2561
2713
|
});
|
|
2562
2714
|
}
|
|
@@ -2569,10 +2721,9 @@ async function importSkills3(projectRoot, results, normalize) {
|
|
|
2569
2721
|
|
|
2570
2722
|
// src/targets/codex-cli/importer.ts
|
|
2571
2723
|
import { parse as parseToml2 } from "smol-toml";
|
|
2572
|
-
var AB_RULES8 = ".agentsmesh/rules";
|
|
2573
2724
|
async function importFromCodex(projectRoot) {
|
|
2574
2725
|
const results = [];
|
|
2575
|
-
const normalize = await createImportReferenceNormalizer(
|
|
2726
|
+
const normalize = await createImportReferenceNormalizer(CODEX_TARGET, projectRoot);
|
|
2576
2727
|
const normalizeWindsurf = await createImportReferenceNormalizer("windsurf", projectRoot);
|
|
2577
2728
|
await importRules3(projectRoot, results, normalize, normalizeWindsurf);
|
|
2578
2729
|
await importSkills3(projectRoot, results, normalize);
|
|
@@ -2582,7 +2733,7 @@ async function importFromCodex(projectRoot) {
|
|
|
2582
2733
|
}
|
|
2583
2734
|
async function importAgents3(projectRoot, results, normalize) {
|
|
2584
2735
|
const agentsPath = join19(projectRoot, CODEX_AGENTS_DIR);
|
|
2585
|
-
const agentsDestDir = join19(projectRoot,
|
|
2736
|
+
const agentsDestDir = join19(projectRoot, CODEX_CANONICAL_AGENTS_DIR);
|
|
2586
2737
|
try {
|
|
2587
2738
|
const agentFiles = await readDirRecursive(agentsPath);
|
|
2588
2739
|
const tomlFiles = agentFiles.filter((f) => f.endsWith(".toml"));
|
|
@@ -2591,7 +2742,7 @@ async function importAgents3(projectRoot, results, normalize) {
|
|
|
2591
2742
|
if (!content) continue;
|
|
2592
2743
|
const parsed = parseToml2(content);
|
|
2593
2744
|
if (!parsed || typeof parsed !== "object") continue;
|
|
2594
|
-
const name = typeof parsed.name === "string" ? parsed.name :
|
|
2745
|
+
const name = typeof parsed.name === "string" ? parsed.name : basename11(srcPath, ".toml");
|
|
2595
2746
|
const description = typeof parsed.description === "string" ? parsed.description : "";
|
|
2596
2747
|
const body = typeof parsed.developer_instructions === "string" ? parsed.developer_instructions.trim() : "";
|
|
2597
2748
|
const model = typeof parsed.model === "string" ? parsed.model : "";
|
|
@@ -2617,9 +2768,9 @@ async function importAgents3(projectRoot, results, normalize) {
|
|
|
2617
2768
|
const outContent = serializeImportedAgent(agent, normalizedBody);
|
|
2618
2769
|
await writeFileAtomic(destPath, outContent);
|
|
2619
2770
|
results.push({
|
|
2620
|
-
fromTool:
|
|
2771
|
+
fromTool: CODEX_TARGET,
|
|
2621
2772
|
fromPath: srcPath,
|
|
2622
|
-
toPath:
|
|
2773
|
+
toPath: `${CODEX_CANONICAL_AGENTS_DIR}/${name}.md`,
|
|
2623
2774
|
feature: "agents"
|
|
2624
2775
|
});
|
|
2625
2776
|
}
|
|
@@ -2628,16 +2779,17 @@ async function importAgents3(projectRoot, results, normalize) {
|
|
|
2628
2779
|
}
|
|
2629
2780
|
async function importRules3(projectRoot, results, normalize, normalizeWindsurf) {
|
|
2630
2781
|
const codexPath = join19(projectRoot, CODEX_MD);
|
|
2631
|
-
const agentsPath = join19(projectRoot,
|
|
2782
|
+
const agentsPath = join19(projectRoot, AGENTS_MD);
|
|
2632
2783
|
const agentsContent = await readFileSafe(agentsPath);
|
|
2633
2784
|
const codexContent = await readFileSafe(codexPath);
|
|
2634
2785
|
const sourcePath = agentsContent !== null ? agentsPath : codexPath;
|
|
2635
|
-
const destDir = join19(projectRoot,
|
|
2786
|
+
const destDir = join19(projectRoot, CODEX_CANONICAL_RULES_DIR);
|
|
2636
2787
|
const content = agentsContent ?? codexContent;
|
|
2637
2788
|
if (content !== null) {
|
|
2638
2789
|
await mkdirp(destDir);
|
|
2639
2790
|
const destPath = join19(destDir, "_root.md");
|
|
2640
|
-
const
|
|
2791
|
+
const stripped = sourcePath === agentsPath ? stripCodexRuleIndex(content) : content;
|
|
2792
|
+
const normalizedContent = sourcePath === agentsPath ? normalize(normalizeWindsurf(stripped, sourcePath, destPath), sourcePath, destPath) : normalize(stripped, sourcePath, destPath);
|
|
2641
2793
|
const { frontmatter, body } = parseFrontmatter(normalizedContent);
|
|
2642
2794
|
const outFm = frontmatter.root === true ? frontmatter : { ...frontmatter, root: true };
|
|
2643
2795
|
const outContent = await serializeImportedRuleWithFallback(destPath, outFm, body);
|
|
@@ -2645,10 +2797,11 @@ async function importRules3(projectRoot, results, normalize, normalizeWindsurf)
|
|
|
2645
2797
|
results.push({
|
|
2646
2798
|
fromTool: "codex-cli",
|
|
2647
2799
|
fromPath: sourcePath,
|
|
2648
|
-
toPath: `${
|
|
2800
|
+
toPath: `${CODEX_CANONICAL_RULES_DIR}/_root.md`,
|
|
2649
2801
|
feature: "rules"
|
|
2650
2802
|
});
|
|
2651
2803
|
}
|
|
2804
|
+
await importInstructionMirrors(projectRoot, destDir, results, normalize);
|
|
2652
2805
|
results.push(...await importCodexNonRootRuleFiles(projectRoot, destDir, normalize));
|
|
2653
2806
|
results.push(
|
|
2654
2807
|
...await importFileDirectory({
|
|
@@ -2671,7 +2824,7 @@ async function importRules3(projectRoot, results, normalize, normalizeWindsurf)
|
|
|
2671
2824
|
const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
|
|
2672
2825
|
return {
|
|
2673
2826
|
destPath,
|
|
2674
|
-
toPath: `${
|
|
2827
|
+
toPath: `${CODEX_CANONICAL_RULES_DIR}/${ruleName}.md`,
|
|
2675
2828
|
feature: "rules",
|
|
2676
2829
|
content: await serializeImportedRuleWithFallback(
|
|
2677
2830
|
destPath,
|
|
@@ -2688,13 +2841,39 @@ async function importRules3(projectRoot, results, normalize, normalizeWindsurf)
|
|
|
2688
2841
|
})
|
|
2689
2842
|
);
|
|
2690
2843
|
}
|
|
2844
|
+
async function importInstructionMirrors(projectRoot, destDir, results, normalize) {
|
|
2845
|
+
try {
|
|
2846
|
+
const files = await readDirRecursive(join19(projectRoot, CODEX_INSTRUCTIONS_DIR));
|
|
2847
|
+
const instructionFiles = files.filter((file) => file.endsWith(".md"));
|
|
2848
|
+
for (const srcPath of instructionFiles) {
|
|
2849
|
+
const slug = basename11(srcPath, ".md");
|
|
2850
|
+
if (slug === "_root") continue;
|
|
2851
|
+
const content = await readFileSafe(srcPath);
|
|
2852
|
+
if (!content) continue;
|
|
2853
|
+
const destPath = join19(destDir, `${slug}.md`);
|
|
2854
|
+
const { frontmatter, body } = parseFrontmatter(normalize(content, srcPath, destPath));
|
|
2855
|
+
await mkdirp(destDir);
|
|
2856
|
+
const outFm = frontmatter.root === true ? frontmatter : { ...frontmatter, root: false };
|
|
2857
|
+
const outContent = await serializeImportedRuleWithFallback(destPath, outFm, body);
|
|
2858
|
+
await writeFileAtomic(destPath, outContent);
|
|
2859
|
+
results.push({
|
|
2860
|
+
fromTool: CODEX_TARGET,
|
|
2861
|
+
fromPath: srcPath,
|
|
2862
|
+
toPath: `${CODEX_CANONICAL_RULES_DIR}/${slug}.md`,
|
|
2863
|
+
feature: "rules"
|
|
2864
|
+
});
|
|
2865
|
+
}
|
|
2866
|
+
} catch {
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2691
2869
|
|
|
2692
2870
|
// src/targets/windsurf/importer.ts
|
|
2693
|
-
import { join as join21, basename as
|
|
2871
|
+
import { join as join21, basename as basename13, dirname as dirname12, relative as relative6 } from "path";
|
|
2694
2872
|
init_markdown();
|
|
2695
2873
|
import { stringify as yamlStringify4 } from "yaml";
|
|
2696
2874
|
|
|
2697
2875
|
// src/targets/windsurf/constants.ts
|
|
2876
|
+
var WINDSURF_TARGET = "windsurf";
|
|
2698
2877
|
var WINDSURF_RULES_ROOT = ".windsurfrules";
|
|
2699
2878
|
var WINDSURF_RULES_DIR = ".windsurf/rules";
|
|
2700
2879
|
var WINDSURF_IGNORE = ".windsurfignore";
|
|
@@ -2705,14 +2884,18 @@ var WINDSURF_MCP_EXAMPLE_FILE = ".windsurf/mcp_config.example.json";
|
|
|
2705
2884
|
var WINDSURF_MCP_CONFIG_FILE = ".windsurf/mcp_config.json";
|
|
2706
2885
|
var WINDSURF_WORKFLOWS_DIR = ".windsurf/workflows";
|
|
2707
2886
|
var WINDSURF_SKILLS_DIR = ".windsurf/skills";
|
|
2887
|
+
var WINDSURF_CANONICAL_RULES_DIR = ".agentsmesh/rules";
|
|
2888
|
+
var WINDSURF_CANONICAL_COMMANDS_DIR = ".agentsmesh/commands";
|
|
2889
|
+
var WINDSURF_CANONICAL_AGENTS_DIR = ".agentsmesh/agents";
|
|
2890
|
+
var WINDSURF_CANONICAL_SKILLS_DIR = ".agentsmesh/skills";
|
|
2891
|
+
var WINDSURF_CANONICAL_IGNORE = ".agentsmesh/ignore";
|
|
2892
|
+
var WINDSURF_CANONICAL_HOOKS = ".agentsmesh/hooks.yaml";
|
|
2893
|
+
var WINDSURF_CANONICAL_MCP = ".agentsmesh/mcp.json";
|
|
2708
2894
|
|
|
2709
2895
|
// src/targets/windsurf/workflows-skills-helpers.ts
|
|
2710
|
-
import { join as join20, basename as
|
|
2896
|
+
import { join as join20, basename as basename12 } from "path";
|
|
2711
2897
|
import { readdir as readdir4 } from "fs/promises";
|
|
2712
2898
|
init_markdown();
|
|
2713
|
-
var AGENTSMESH_COMMANDS3 = ".agentsmesh/commands";
|
|
2714
|
-
var AGENTSMESH_AGENTS2 = ".agentsmesh/agents";
|
|
2715
|
-
var AGENTSMESH_SKILLS2 = ".agentsmesh/skills";
|
|
2716
2899
|
function toStringArray5(value) {
|
|
2717
2900
|
if (Array.isArray(value)) {
|
|
2718
2901
|
return value.filter((entry) => typeof entry === "string").map((entry) => entry.trim()).filter(Boolean);
|
|
@@ -2726,11 +2909,11 @@ async function importWorkflows(projectRoot, results, normalize) {
|
|
|
2726
2909
|
const workflowsDir = join20(projectRoot, WINDSURF_WORKFLOWS_DIR);
|
|
2727
2910
|
const workflowFiles = await readDirRecursive(workflowsDir);
|
|
2728
2911
|
const workflowMdFiles = workflowFiles.filter((f) => f.endsWith(".md"));
|
|
2729
|
-
const destCommandsDir = join20(projectRoot,
|
|
2912
|
+
const destCommandsDir = join20(projectRoot, WINDSURF_CANONICAL_COMMANDS_DIR);
|
|
2730
2913
|
for (const srcPath of workflowMdFiles) {
|
|
2731
2914
|
const content = await readFileSafe(srcPath);
|
|
2732
2915
|
if (!content) continue;
|
|
2733
|
-
const name =
|
|
2916
|
+
const name = basename12(srcPath, ".md");
|
|
2734
2917
|
await mkdirp(destCommandsDir);
|
|
2735
2918
|
const destPath = join20(destCommandsDir, `${name}.md`);
|
|
2736
2919
|
const normalized = normalize(content, srcPath, destPath);
|
|
@@ -2750,9 +2933,9 @@ async function importWorkflows(projectRoot, results, normalize) {
|
|
|
2750
2933
|
);
|
|
2751
2934
|
await writeFileAtomic(destPath, outContent);
|
|
2752
2935
|
results.push({
|
|
2753
|
-
fromTool:
|
|
2936
|
+
fromTool: WINDSURF_TARGET,
|
|
2754
2937
|
fromPath: srcPath,
|
|
2755
|
-
toPath: `${
|
|
2938
|
+
toPath: `${WINDSURF_CANONICAL_COMMANDS_DIR}/${name}.md`,
|
|
2756
2939
|
feature: "commands"
|
|
2757
2940
|
});
|
|
2758
2941
|
}
|
|
@@ -2770,8 +2953,8 @@ async function importSkills4(projectRoot, results, normalize) {
|
|
|
2770
2953
|
const rawParsed = parseFrontmatter(skillContent);
|
|
2771
2954
|
const projectedAgent = parseProjectedAgentSkillFrontmatter(rawParsed.frontmatter, ent.name);
|
|
2772
2955
|
if (projectedAgent) {
|
|
2773
|
-
await removePathIfExists(join20(projectRoot,
|
|
2774
|
-
const destAgentsDir = join20(projectRoot,
|
|
2956
|
+
await removePathIfExists(join20(projectRoot, WINDSURF_CANONICAL_SKILLS_DIR, ent.name));
|
|
2957
|
+
const destAgentsDir = join20(projectRoot, WINDSURF_CANONICAL_AGENTS_DIR);
|
|
2775
2958
|
await mkdirp(destAgentsDir);
|
|
2776
2959
|
const agentPath = join20(destAgentsDir, `${projectedAgent.name}.md`);
|
|
2777
2960
|
await writeFileAtomic(
|
|
@@ -2779,22 +2962,22 @@ async function importSkills4(projectRoot, results, normalize) {
|
|
|
2779
2962
|
serializeImportedAgent(projectedAgent, normalize(rawParsed.body, skillMdPath, agentPath))
|
|
2780
2963
|
);
|
|
2781
2964
|
results.push({
|
|
2782
|
-
fromTool:
|
|
2965
|
+
fromTool: WINDSURF_TARGET,
|
|
2783
2966
|
fromPath: skillMdPath,
|
|
2784
|
-
toPath: `${
|
|
2967
|
+
toPath: `${WINDSURF_CANONICAL_AGENTS_DIR}/${projectedAgent.name}.md`,
|
|
2785
2968
|
feature: "agents"
|
|
2786
2969
|
});
|
|
2787
2970
|
continue;
|
|
2788
2971
|
}
|
|
2789
|
-
const destSkillDir = join20(projectRoot,
|
|
2972
|
+
const destSkillDir = join20(projectRoot, WINDSURF_CANONICAL_SKILLS_DIR, ent.name);
|
|
2790
2973
|
const destSkillPath = join20(destSkillDir, "SKILL.md");
|
|
2791
2974
|
const normalized = normalize(skillContent, skillMdPath, destSkillPath);
|
|
2792
2975
|
await mkdirp(destSkillDir);
|
|
2793
2976
|
await writeFileAtomic(destSkillPath, normalized);
|
|
2794
2977
|
results.push({
|
|
2795
|
-
fromTool:
|
|
2978
|
+
fromTool: WINDSURF_TARGET,
|
|
2796
2979
|
fromPath: skillMdPath,
|
|
2797
|
-
toPath: `${
|
|
2980
|
+
toPath: `${WINDSURF_CANONICAL_SKILLS_DIR}/${ent.name}/SKILL.md`,
|
|
2798
2981
|
feature: "skills"
|
|
2799
2982
|
});
|
|
2800
2983
|
const allSkillFiles = await readDirRecursive(skillPath);
|
|
@@ -2807,9 +2990,9 @@ async function importSkills4(projectRoot, results, normalize) {
|
|
|
2807
2990
|
await mkdirp(join20(destSupportPath, ".."));
|
|
2808
2991
|
await writeFileAtomic(destSupportPath, normalize(supportContent, absPath, destSupportPath));
|
|
2809
2992
|
results.push({
|
|
2810
|
-
fromTool:
|
|
2993
|
+
fromTool: WINDSURF_TARGET,
|
|
2811
2994
|
fromPath: absPath,
|
|
2812
|
-
toPath: `${
|
|
2995
|
+
toPath: `${WINDSURF_CANONICAL_SKILLS_DIR}/${ent.name}/${relPath}`,
|
|
2813
2996
|
feature: "skills"
|
|
2814
2997
|
});
|
|
2815
2998
|
}
|
|
@@ -2819,15 +3002,11 @@ async function importSkills4(projectRoot, results, normalize) {
|
|
|
2819
3002
|
}
|
|
2820
3003
|
|
|
2821
3004
|
// src/targets/windsurf/importer.ts
|
|
2822
|
-
var AGENTSMESH_RULES3 = ".agentsmesh/rules";
|
|
2823
|
-
var AGENTSMESH_IGNORE2 = ".agentsmesh/ignore";
|
|
2824
|
-
var AGENTSMESH_HOOKS = ".agentsmesh/hooks.yaml";
|
|
2825
|
-
var AGENTSMESH_MCP2 = ".agentsmesh/mcp.json";
|
|
2826
3005
|
async function importFromWindsurf(projectRoot) {
|
|
2827
3006
|
const results = [];
|
|
2828
|
-
const normalize = await createImportReferenceNormalizer(
|
|
3007
|
+
const normalize = await createImportReferenceNormalizer(WINDSURF_TARGET, projectRoot);
|
|
2829
3008
|
const normalizeCodex = await createImportReferenceNormalizer("codex-cli", projectRoot);
|
|
2830
|
-
const destRulesDir = join21(projectRoot,
|
|
3009
|
+
const destRulesDir = join21(projectRoot, WINDSURF_CANONICAL_RULES_DIR);
|
|
2831
3010
|
const rootPath = join21(projectRoot, WINDSURF_RULES_ROOT);
|
|
2832
3011
|
const rootContent = await readFileSafe(rootPath);
|
|
2833
3012
|
if (rootContent !== null) {
|
|
@@ -2839,7 +3018,7 @@ async function importFromWindsurf(projectRoot) {
|
|
|
2839
3018
|
results.push({
|
|
2840
3019
|
fromTool: "windsurf",
|
|
2841
3020
|
fromPath: rootPath,
|
|
2842
|
-
toPath: `${
|
|
3021
|
+
toPath: `${WINDSURF_CANONICAL_RULES_DIR}/_root.md`,
|
|
2843
3022
|
feature: "rules"
|
|
2844
3023
|
});
|
|
2845
3024
|
}
|
|
@@ -2859,7 +3038,7 @@ async function importFromWindsurf(projectRoot) {
|
|
|
2859
3038
|
results.push({
|
|
2860
3039
|
fromTool: "windsurf",
|
|
2861
3040
|
fromPath: agentsMdPath,
|
|
2862
|
-
toPath: `${
|
|
3041
|
+
toPath: `${WINDSURF_CANONICAL_RULES_DIR}/_root.md`,
|
|
2863
3042
|
feature: "rules"
|
|
2864
3043
|
});
|
|
2865
3044
|
}
|
|
@@ -2882,7 +3061,7 @@ async function importFromWindsurf(projectRoot) {
|
|
|
2882
3061
|
const destPath = join21(destRulesDir, `${ruleName}.md`);
|
|
2883
3062
|
return {
|
|
2884
3063
|
destPath,
|
|
2885
|
-
toPath: `${
|
|
3064
|
+
toPath: `${WINDSURF_CANONICAL_RULES_DIR}/${ruleName}.md`,
|
|
2886
3065
|
feature: "rules",
|
|
2887
3066
|
content: await serializeImportedRuleWithFallback(
|
|
2888
3067
|
destPath,
|
|
@@ -2902,7 +3081,7 @@ async function importFromWindsurf(projectRoot) {
|
|
|
2902
3081
|
fromTool: "windsurf",
|
|
2903
3082
|
normalize,
|
|
2904
3083
|
mapEntry: async ({ srcPath, normalizeTo }) => {
|
|
2905
|
-
const name =
|
|
3084
|
+
const name = basename13(srcPath, ".md");
|
|
2906
3085
|
if (name === "_root" && rootContent !== null) return null;
|
|
2907
3086
|
const destPath = join21(destRulesDir, `${name}.md`);
|
|
2908
3087
|
const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
|
|
@@ -2913,7 +3092,7 @@ async function importFromWindsurf(projectRoot) {
|
|
|
2913
3092
|
}
|
|
2914
3093
|
return {
|
|
2915
3094
|
destPath,
|
|
2916
|
-
toPath: `${
|
|
3095
|
+
toPath: `${WINDSURF_CANONICAL_RULES_DIR}/${name}.md`,
|
|
2917
3096
|
feature: "rules",
|
|
2918
3097
|
content: await serializeImportedRuleWithFallback(
|
|
2919
3098
|
destPath,
|
|
@@ -2939,12 +3118,12 @@ async function importFromWindsurf(projectRoot) {
|
|
|
2939
3118
|
}
|
|
2940
3119
|
if (patterns.length > 0) {
|
|
2941
3120
|
await mkdirp(join21(projectRoot, ".agentsmesh"));
|
|
2942
|
-
const destIgnorePath = join21(projectRoot,
|
|
3121
|
+
const destIgnorePath = join21(projectRoot, WINDSURF_CANONICAL_IGNORE);
|
|
2943
3122
|
await writeFileAtomic(destIgnorePath, patterns.join("\n"));
|
|
2944
3123
|
results.push({
|
|
2945
3124
|
fromTool: "windsurf",
|
|
2946
3125
|
fromPath: ignorePath,
|
|
2947
|
-
toPath:
|
|
3126
|
+
toPath: WINDSURF_CANONICAL_IGNORE,
|
|
2948
3127
|
feature: "ignore"
|
|
2949
3128
|
});
|
|
2950
3129
|
}
|
|
@@ -2964,13 +3143,13 @@ async function importHooks(projectRoot, results) {
|
|
|
2964
3143
|
if (!parsed.hooks || typeof parsed.hooks !== "object" || Array.isArray(parsed.hooks)) return;
|
|
2965
3144
|
const canonical = windsurfHooksToCanonical(parsed.hooks);
|
|
2966
3145
|
if (Object.keys(canonical).length === 0) return;
|
|
2967
|
-
const destPath = join21(projectRoot,
|
|
3146
|
+
const destPath = join21(projectRoot, WINDSURF_CANONICAL_HOOKS);
|
|
2968
3147
|
await mkdirp(dirname12(destPath));
|
|
2969
3148
|
await writeFileAtomic(destPath, yamlStringify4(canonical));
|
|
2970
3149
|
results.push({
|
|
2971
|
-
fromTool:
|
|
3150
|
+
fromTool: WINDSURF_TARGET,
|
|
2972
3151
|
fromPath: hooksPath,
|
|
2973
|
-
toPath:
|
|
3152
|
+
toPath: WINDSURF_CANONICAL_HOOKS,
|
|
2974
3153
|
feature: "hooks"
|
|
2975
3154
|
});
|
|
2976
3155
|
} catch {
|
|
@@ -3033,13 +3212,13 @@ async function importMcp3(projectRoot, results) {
|
|
|
3033
3212
|
try {
|
|
3034
3213
|
const parsed = JSON.parse(content);
|
|
3035
3214
|
if (!parsed.mcpServers || typeof parsed.mcpServers !== "object") continue;
|
|
3036
|
-
const destPath = join21(projectRoot,
|
|
3215
|
+
const destPath = join21(projectRoot, WINDSURF_CANONICAL_MCP);
|
|
3037
3216
|
await mkdirp(dirname12(destPath));
|
|
3038
3217
|
await writeFileAtomic(destPath, JSON.stringify({ mcpServers: parsed.mcpServers }, null, 2));
|
|
3039
3218
|
results.push({
|
|
3040
|
-
fromTool:
|
|
3219
|
+
fromTool: WINDSURF_TARGET,
|
|
3041
3220
|
fromPath: srcPath,
|
|
3042
|
-
toPath:
|
|
3221
|
+
toPath: WINDSURF_CANONICAL_MCP,
|
|
3043
3222
|
feature: "mcp"
|
|
3044
3223
|
});
|
|
3045
3224
|
return;
|
|
@@ -3049,10 +3228,11 @@ async function importMcp3(projectRoot, results) {
|
|
|
3049
3228
|
}
|
|
3050
3229
|
|
|
3051
3230
|
// src/targets/copilot/importer.ts
|
|
3052
|
-
import { join as join24, basename as
|
|
3231
|
+
import { join as join24, basename as basename17 } from "path";
|
|
3053
3232
|
init_markdown();
|
|
3054
3233
|
|
|
3055
3234
|
// src/targets/copilot/constants.ts
|
|
3235
|
+
var COPILOT_TARGET = "copilot";
|
|
3056
3236
|
var COPILOT_INSTRUCTIONS = ".github/copilot-instructions.md";
|
|
3057
3237
|
var COPILOT_CONTEXT_DIR = ".github/copilot";
|
|
3058
3238
|
var COPILOT_INSTRUCTIONS_DIR = ".github/instructions";
|
|
@@ -3060,10 +3240,16 @@ var COPILOT_PROMPTS_DIR = ".github/prompts";
|
|
|
3060
3240
|
var COPILOT_HOOKS_DIR = ".github/hooks";
|
|
3061
3241
|
var COPILOT_SKILLS_DIR = ".github/skills";
|
|
3062
3242
|
var COPILOT_AGENTS_DIR = ".github/agents";
|
|
3243
|
+
var COPILOT_CANONICAL_RULES_DIR = ".agentsmesh/rules";
|
|
3244
|
+
var COPILOT_CANONICAL_COMMANDS_DIR = ".agentsmesh/commands";
|
|
3245
|
+
var COPILOT_CANONICAL_AGENTS_DIR = ".agentsmesh/agents";
|
|
3246
|
+
var COPILOT_CANONICAL_SKILLS_DIR = ".agentsmesh/skills";
|
|
3247
|
+
var COPILOT_CANONICAL_HOOKS = ".agentsmesh/hooks.yaml";
|
|
3248
|
+
var COPILOT_LEGACY_HOOKS_DIR = ".github/copilot-hooks";
|
|
3063
3249
|
|
|
3064
3250
|
// src/targets/copilot/command-prompt.ts
|
|
3065
3251
|
init_markdown();
|
|
3066
|
-
import { basename as
|
|
3252
|
+
import { basename as basename14 } from "path";
|
|
3067
3253
|
function toStringArray6(value) {
|
|
3068
3254
|
if (Array.isArray(value)) {
|
|
3069
3255
|
return value.filter((entry) => typeof entry === "string" && entry.length > 0);
|
|
@@ -3092,7 +3278,7 @@ function serializeCommandPrompt(command) {
|
|
|
3092
3278
|
}
|
|
3093
3279
|
function parseCommandPromptFrontmatter(frontmatter, promptPath) {
|
|
3094
3280
|
const nameFromMetadata = typeof frontmatter["x-agentsmesh-name"] === "string" ? frontmatter["x-agentsmesh-name"] : "";
|
|
3095
|
-
const name = (nameFromMetadata ||
|
|
3281
|
+
const name = (nameFromMetadata || basename14(promptPath, ".prompt.md")).trim();
|
|
3096
3282
|
const allowedToolsFromMetadata = toStringArray6(frontmatter["x-agentsmesh-allowed-tools"]);
|
|
3097
3283
|
const allowedTools = allowedToolsFromMetadata.length > 0 ? allowedToolsFromMetadata : toStringArray6(frontmatter.tools);
|
|
3098
3284
|
return {
|
|
@@ -3112,9 +3298,8 @@ function serializeImportedCommand2(command, body) {
|
|
|
3112
3298
|
}
|
|
3113
3299
|
|
|
3114
3300
|
// src/targets/copilot/hook-parser.ts
|
|
3115
|
-
import { join as join22, dirname as dirname13, basename as
|
|
3301
|
+
import { join as join22, dirname as dirname13, basename as basename15 } from "path";
|
|
3116
3302
|
import { stringify as yamlStringify5 } from "yaml";
|
|
3117
|
-
var AB_HOOKS3 = ".agentsmesh/hooks.yaml";
|
|
3118
3303
|
function mapCopilotHookEvent(event) {
|
|
3119
3304
|
switch (event) {
|
|
3120
3305
|
case "preToolUse":
|
|
@@ -3176,36 +3361,35 @@ async function importHooks2(projectRoot, results) {
|
|
|
3176
3361
|
}
|
|
3177
3362
|
}
|
|
3178
3363
|
}
|
|
3179
|
-
const legacyDir = join22(projectRoot,
|
|
3364
|
+
const legacyDir = join22(projectRoot, COPILOT_LEGACY_HOOKS_DIR);
|
|
3180
3365
|
const legacyFiles = await readDirRecursive(legacyDir).catch(() => []);
|
|
3181
3366
|
const shFiles = legacyFiles.filter(
|
|
3182
|
-
(file) => dirname13(file) === legacyDir && /^[^-]+-\d+\.sh$/i.test(
|
|
3367
|
+
(file) => dirname13(file) === legacyDir && /^[^-]+-\d+\.sh$/i.test(basename15(file))
|
|
3183
3368
|
);
|
|
3184
3369
|
for (const srcPath of shFiles) {
|
|
3185
3370
|
const content = await readFileSafe(srcPath);
|
|
3186
3371
|
if (!content) continue;
|
|
3187
|
-
const name =
|
|
3372
|
+
const name = basename15(srcPath, ".sh");
|
|
3188
3373
|
const dashIdx = name.lastIndexOf("-");
|
|
3189
3374
|
const phase = dashIdx > 0 ? name.slice(0, dashIdx) : name;
|
|
3190
3375
|
if (!hooks[phase]) hooks[phase] = [];
|
|
3191
3376
|
hooks[phase].push({ matcher: "*", command: extractWrapperCommand(content), type: "command" });
|
|
3192
3377
|
}
|
|
3193
3378
|
if (Object.keys(hooks).length === 0) return;
|
|
3194
|
-
const destPath = join22(projectRoot,
|
|
3379
|
+
const destPath = join22(projectRoot, COPILOT_CANONICAL_HOOKS);
|
|
3195
3380
|
await mkdirp(dirname13(destPath));
|
|
3196
3381
|
await writeFileAtomic(destPath, yamlStringify5(hooks));
|
|
3197
3382
|
results.push({
|
|
3198
|
-
fromTool:
|
|
3383
|
+
fromTool: COPILOT_TARGET,
|
|
3199
3384
|
fromPath: join22(projectRoot, COPILOT_HOOKS_DIR),
|
|
3200
|
-
toPath:
|
|
3385
|
+
toPath: COPILOT_CANONICAL_HOOKS,
|
|
3201
3386
|
feature: "hooks"
|
|
3202
3387
|
});
|
|
3203
3388
|
}
|
|
3204
3389
|
|
|
3205
3390
|
// src/targets/copilot/agents-skills-helpers.ts
|
|
3206
|
-
import { join as join23, basename as
|
|
3391
|
+
import { join as join23, basename as basename16, dirname as dirname14 } from "path";
|
|
3207
3392
|
init_markdown();
|
|
3208
|
-
var AB_AGENTS8 = ".agentsmesh/agents";
|
|
3209
3393
|
async function importAgents4(projectRoot, results, normalize) {
|
|
3210
3394
|
const agentsDir = join23(projectRoot, COPILOT_AGENTS_DIR);
|
|
3211
3395
|
let files;
|
|
@@ -3215,11 +3399,11 @@ async function importAgents4(projectRoot, results, normalize) {
|
|
|
3215
3399
|
return;
|
|
3216
3400
|
}
|
|
3217
3401
|
const agentFiles = files.filter((f) => f.endsWith(".agent.md"));
|
|
3218
|
-
const destDir = join23(projectRoot,
|
|
3402
|
+
const destDir = join23(projectRoot, COPILOT_CANONICAL_AGENTS_DIR);
|
|
3219
3403
|
for (const srcPath of agentFiles) {
|
|
3220
3404
|
const content = await readFileSafe(srcPath);
|
|
3221
3405
|
if (!content) continue;
|
|
3222
|
-
const base =
|
|
3406
|
+
const base = basename16(srcPath, ".agent.md");
|
|
3223
3407
|
await mkdirp(destDir);
|
|
3224
3408
|
const destPath = join23(destDir, `${base}.md`);
|
|
3225
3409
|
const { frontmatter, body } = parseFrontmatter(normalize(content, srcPath, destPath));
|
|
@@ -3237,9 +3421,9 @@ async function importAgents4(projectRoot, results, normalize) {
|
|
|
3237
3421
|
const outContent = serializeFrontmatter(canonicalFm, body.trim());
|
|
3238
3422
|
await writeFileAtomic(destPath, outContent);
|
|
3239
3423
|
results.push({
|
|
3240
|
-
fromTool:
|
|
3424
|
+
fromTool: COPILOT_TARGET,
|
|
3241
3425
|
fromPath: srcPath,
|
|
3242
|
-
toPath: `${
|
|
3426
|
+
toPath: `${COPILOT_CANONICAL_AGENTS_DIR}/${base}.md`,
|
|
3243
3427
|
feature: "agents"
|
|
3244
3428
|
});
|
|
3245
3429
|
}
|
|
@@ -3250,8 +3434,8 @@ async function importSkills5(projectRoot, results, normalize) {
|
|
|
3250
3434
|
for (const skillMdPath of skillMdFiles) {
|
|
3251
3435
|
const content = await readFileSafe(skillMdPath);
|
|
3252
3436
|
if (!content) continue;
|
|
3253
|
-
const skillName =
|
|
3254
|
-
const destSkillDir = join23(projectRoot,
|
|
3437
|
+
const skillName = basename16(dirname14(skillMdPath));
|
|
3438
|
+
const destSkillDir = join23(projectRoot, COPILOT_CANONICAL_SKILLS_DIR, skillName);
|
|
3255
3439
|
const allSkillFiles = await readDirRecursive(dirname14(skillMdPath));
|
|
3256
3440
|
for (const absPath of allSkillFiles) {
|
|
3257
3441
|
const fileContent = await readFileSafe(absPath);
|
|
@@ -3261,9 +3445,9 @@ async function importSkills5(projectRoot, results, normalize) {
|
|
|
3261
3445
|
await mkdirp(dirname14(destPath));
|
|
3262
3446
|
await writeFileAtomic(destPath, normalize(fileContent, absPath, destPath));
|
|
3263
3447
|
results.push({
|
|
3264
|
-
fromTool:
|
|
3448
|
+
fromTool: COPILOT_TARGET,
|
|
3265
3449
|
fromPath: absPath,
|
|
3266
|
-
toPath:
|
|
3450
|
+
toPath: `${COPILOT_CANONICAL_SKILLS_DIR}/${skillName}/${relPath}`,
|
|
3267
3451
|
feature: "skills"
|
|
3268
3452
|
});
|
|
3269
3453
|
}
|
|
@@ -3271,12 +3455,10 @@ async function importSkills5(projectRoot, results, normalize) {
|
|
|
3271
3455
|
}
|
|
3272
3456
|
|
|
3273
3457
|
// src/targets/copilot/importer.ts
|
|
3274
|
-
var AGENTSMESH_RULES4 = ".agentsmesh/rules";
|
|
3275
|
-
var AB_COMMANDS8 = ".agentsmesh/commands";
|
|
3276
3458
|
async function importFromCopilot(projectRoot) {
|
|
3277
3459
|
const results = [];
|
|
3278
|
-
const normalize = await createImportReferenceNormalizer(
|
|
3279
|
-
const destDir = join24(projectRoot,
|
|
3460
|
+
const normalize = await createImportReferenceNormalizer(COPILOT_TARGET, projectRoot);
|
|
3461
|
+
const destDir = join24(projectRoot, COPILOT_CANONICAL_RULES_DIR);
|
|
3280
3462
|
const instructionsPath = join24(projectRoot, COPILOT_INSTRUCTIONS);
|
|
3281
3463
|
const instructionsContent = await readFileSafe(instructionsPath);
|
|
3282
3464
|
if (instructionsContent !== null) {
|
|
@@ -3292,7 +3474,7 @@ async function importFromCopilot(projectRoot) {
|
|
|
3292
3474
|
results.push({
|
|
3293
3475
|
fromTool: "copilot",
|
|
3294
3476
|
fromPath: instructionsPath,
|
|
3295
|
-
toPath: `${
|
|
3477
|
+
toPath: `${COPILOT_CANONICAL_RULES_DIR}/_root.md`,
|
|
3296
3478
|
feature: "rules"
|
|
3297
3479
|
});
|
|
3298
3480
|
}
|
|
@@ -3305,7 +3487,7 @@ async function importFromCopilot(projectRoot) {
|
|
|
3305
3487
|
fromTool: "copilot",
|
|
3306
3488
|
normalize,
|
|
3307
3489
|
mapEntry: async ({ srcPath, normalizeTo }) => {
|
|
3308
|
-
const destFileName = `${
|
|
3490
|
+
const destFileName = `${basename17(srcPath, ".instructions.md")}.md`;
|
|
3309
3491
|
const destPath = join24(destDir, destFileName);
|
|
3310
3492
|
const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
|
|
3311
3493
|
const globs = toGlobsArray(frontmatter.globs);
|
|
@@ -3319,7 +3501,7 @@ async function importFromCopilot(projectRoot) {
|
|
|
3319
3501
|
});
|
|
3320
3502
|
return {
|
|
3321
3503
|
destPath,
|
|
3322
|
-
toPath: `${
|
|
3504
|
+
toPath: `${COPILOT_CANONICAL_RULES_DIR}/${destFileName}`,
|
|
3323
3505
|
feature: "rules",
|
|
3324
3506
|
content: await serializeImportedRuleWithFallback(destPath, canonicalFm, body)
|
|
3325
3507
|
};
|
|
@@ -3335,7 +3517,7 @@ async function importFromCopilot(projectRoot) {
|
|
|
3335
3517
|
fromTool: "copilot",
|
|
3336
3518
|
normalize,
|
|
3337
3519
|
mapEntry: async ({ srcPath, normalizeTo }) => {
|
|
3338
|
-
const base = srcPath.endsWith(".instructions.md") ?
|
|
3520
|
+
const base = srcPath.endsWith(".instructions.md") ? basename17(srcPath, ".instructions.md") : basename17(srcPath, ".md");
|
|
3339
3521
|
const destPath = join24(destDir, `${base}.md`);
|
|
3340
3522
|
const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
|
|
3341
3523
|
const globs = toGlobsArray(
|
|
@@ -3351,7 +3533,7 @@ async function importFromCopilot(projectRoot) {
|
|
|
3351
3533
|
});
|
|
3352
3534
|
return {
|
|
3353
3535
|
destPath,
|
|
3354
|
-
toPath: `${
|
|
3536
|
+
toPath: `${COPILOT_CANONICAL_RULES_DIR}/${base}.md`,
|
|
3355
3537
|
feature: "rules",
|
|
3356
3538
|
content: await serializeImportedRuleWithFallback(destPath, canonicalFm, body)
|
|
3357
3539
|
};
|
|
@@ -3366,7 +3548,7 @@ async function importFromCopilot(projectRoot) {
|
|
|
3366
3548
|
}
|
|
3367
3549
|
async function importCommands3(projectRoot, results, normalize) {
|
|
3368
3550
|
const promptsDir = join24(projectRoot, COPILOT_PROMPTS_DIR);
|
|
3369
|
-
const destDir = join24(projectRoot,
|
|
3551
|
+
const destDir = join24(projectRoot, COPILOT_CANONICAL_COMMANDS_DIR);
|
|
3370
3552
|
results.push(
|
|
3371
3553
|
...await importFileDirectory({
|
|
3372
3554
|
srcDir: promptsDir,
|
|
@@ -3375,13 +3557,13 @@ async function importCommands3(projectRoot, results, normalize) {
|
|
|
3375
3557
|
fromTool: "copilot",
|
|
3376
3558
|
normalize,
|
|
3377
3559
|
mapEntry: ({ srcPath, content }) => {
|
|
3378
|
-
const previewDest = join24(destDir, `${
|
|
3560
|
+
const previewDest = join24(destDir, `${basename17(srcPath, ".prompt.md")}.md`);
|
|
3379
3561
|
const { frontmatter, body } = parseFrontmatter(normalize(content, srcPath, previewDest));
|
|
3380
3562
|
const command = parseCommandPromptFrontmatter(frontmatter, srcPath);
|
|
3381
3563
|
const destPath = join24(destDir, `${command.name}.md`);
|
|
3382
3564
|
return {
|
|
3383
3565
|
destPath,
|
|
3384
|
-
toPath: `${
|
|
3566
|
+
toPath: `${COPILOT_CANONICAL_COMMANDS_DIR}/${command.name}.md`,
|
|
3385
3567
|
feature: "commands",
|
|
3386
3568
|
content: serializeImportedCommand2(command, body)
|
|
3387
3569
|
};
|
|
@@ -3391,7 +3573,7 @@ async function importCommands3(projectRoot, results, normalize) {
|
|
|
3391
3573
|
}
|
|
3392
3574
|
|
|
3393
3575
|
// src/targets/continue/importer.ts
|
|
3394
|
-
import { basename as
|
|
3576
|
+
import { basename as basename19, extname, join as join26 } from "path";
|
|
3395
3577
|
import { parse as parseYaml } from "yaml";
|
|
3396
3578
|
init_markdown();
|
|
3397
3579
|
|
|
@@ -3399,7 +3581,7 @@ init_markdown();
|
|
|
3399
3581
|
import { readdir as readdir5 } from "fs/promises";
|
|
3400
3582
|
import { dirname as dirname15, join as join25, relative as relative7 } from "path";
|
|
3401
3583
|
init_markdown();
|
|
3402
|
-
var
|
|
3584
|
+
var AB_SKILLS2 = ".agentsmesh/skills";
|
|
3403
3585
|
function generateEmbeddedSkills(canonical, skillsDir) {
|
|
3404
3586
|
const outputs = [];
|
|
3405
3587
|
for (const skill of canonical.skills) {
|
|
@@ -3434,7 +3616,7 @@ async function importEmbeddedSkills(projectRoot, skillsDir, fromTool, results, n
|
|
|
3434
3616
|
const sourceSkillFile = join25(sourceSkillDir, "SKILL.md");
|
|
3435
3617
|
const sourceSkillContent = await readFileSafe(sourceSkillFile);
|
|
3436
3618
|
if (sourceSkillContent === null) continue;
|
|
3437
|
-
const destinationSkillDir = join25(projectRoot,
|
|
3619
|
+
const destinationSkillDir = join25(projectRoot, AB_SKILLS2, entry.name);
|
|
3438
3620
|
const destinationSkillFile = join25(destinationSkillDir, "SKILL.md");
|
|
3439
3621
|
const { frontmatter, body } = parseFrontmatter(
|
|
3440
3622
|
normalize(sourceSkillContent, sourceSkillFile, destinationSkillFile)
|
|
@@ -3450,7 +3632,7 @@ async function importEmbeddedSkills(projectRoot, skillsDir, fromTool, results, n
|
|
|
3450
3632
|
results.push({
|
|
3451
3633
|
fromTool,
|
|
3452
3634
|
fromPath: sourceSkillFile,
|
|
3453
|
-
toPath: `${
|
|
3635
|
+
toPath: `${AB_SKILLS2}/${entry.name}/SKILL.md`,
|
|
3454
3636
|
feature: "skills"
|
|
3455
3637
|
});
|
|
3456
3638
|
const sourceFiles = await readDirRecursive(sourceSkillDir);
|
|
@@ -3465,7 +3647,7 @@ async function importEmbeddedSkills(projectRoot, skillsDir, fromTool, results, n
|
|
|
3465
3647
|
results.push({
|
|
3466
3648
|
fromTool,
|
|
3467
3649
|
fromPath: sourcePath,
|
|
3468
|
-
toPath: `${
|
|
3650
|
+
toPath: `${AB_SKILLS2}/${entry.name}/${relativePath}`,
|
|
3469
3651
|
feature: "skills"
|
|
3470
3652
|
});
|
|
3471
3653
|
}
|
|
@@ -3474,15 +3656,19 @@ async function importEmbeddedSkills(projectRoot, skillsDir, fromTool, results, n
|
|
|
3474
3656
|
|
|
3475
3657
|
// src/targets/continue/command-rule.ts
|
|
3476
3658
|
init_markdown();
|
|
3477
|
-
import { basename as
|
|
3659
|
+
import { basename as basename18 } from "path";
|
|
3478
3660
|
|
|
3479
3661
|
// src/targets/continue/constants.ts
|
|
3662
|
+
var CONTINUE_TARGET = "continue";
|
|
3480
3663
|
var CONTINUE_RULES_DIR = ".continue/rules";
|
|
3481
3664
|
var CONTINUE_PROMPTS_DIR = ".continue/prompts";
|
|
3482
3665
|
var CONTINUE_MCP_DIR = ".continue/mcpServers";
|
|
3483
3666
|
var CONTINUE_MCP_FILE = `${CONTINUE_MCP_DIR}/agentsmesh.json`;
|
|
3484
3667
|
var CONTINUE_ROOT_RULE = `${CONTINUE_RULES_DIR}/_root.md`;
|
|
3485
3668
|
var CONTINUE_SKILLS_DIR = ".continue/skills";
|
|
3669
|
+
var CONTINUE_CANONICAL_RULES_DIR = ".agentsmesh/rules";
|
|
3670
|
+
var CONTINUE_CANONICAL_COMMANDS_DIR = ".agentsmesh/commands";
|
|
3671
|
+
var CONTINUE_CANONICAL_MCP = ".agentsmesh/mcp.json";
|
|
3486
3672
|
|
|
3487
3673
|
// src/targets/continue/command-rule.ts
|
|
3488
3674
|
function toStringArray7(value) {
|
|
@@ -3511,7 +3697,7 @@ function serializeCommandRule(command) {
|
|
|
3511
3697
|
return serializeFrontmatter(frontmatter, command.body.trim() || "");
|
|
3512
3698
|
}
|
|
3513
3699
|
function parseCommandRuleFrontmatter(frontmatter, filePath) {
|
|
3514
|
-
const fileName =
|
|
3700
|
+
const fileName = basename18(filePath, ".md");
|
|
3515
3701
|
const fromMetadata = typeof frontmatter["x-agentsmesh-name"] === "string" ? frontmatter["x-agentsmesh-name"] : "";
|
|
3516
3702
|
const name = (fromMetadata || fileName).trim();
|
|
3517
3703
|
return {
|
|
@@ -3531,9 +3717,6 @@ function serializeImportedCommand3(command, body) {
|
|
|
3531
3717
|
}
|
|
3532
3718
|
|
|
3533
3719
|
// src/targets/continue/importer.ts
|
|
3534
|
-
var AB_RULES9 = ".agentsmesh/rules";
|
|
3535
|
-
var AB_COMMANDS9 = ".agentsmesh/commands";
|
|
3536
|
-
var AB_MCP4 = ".agentsmesh/mcp.json";
|
|
3537
3720
|
function readMcpServers(content, extension) {
|
|
3538
3721
|
const parsed = extension === ".json" ? JSON.parse(content) : parseYaml(content) ?? {};
|
|
3539
3722
|
const rawServers = parsed.mcpServers;
|
|
@@ -3558,7 +3741,7 @@ function readMcpServers(content, extension) {
|
|
|
3558
3741
|
}
|
|
3559
3742
|
async function importFromContinue(projectRoot) {
|
|
3560
3743
|
const results = [];
|
|
3561
|
-
const normalize = await createImportReferenceNormalizer(
|
|
3744
|
+
const normalize = await createImportReferenceNormalizer(CONTINUE_TARGET, projectRoot);
|
|
3562
3745
|
await importRules4(projectRoot, results, normalize);
|
|
3563
3746
|
await importCommands4(projectRoot, results, normalize);
|
|
3564
3747
|
await importEmbeddedSkills(projectRoot, CONTINUE_SKILLS_DIR, "continue", results, normalize);
|
|
@@ -3572,8 +3755,8 @@ async function importRules4(projectRoot, results, normalize) {
|
|
|
3572
3755
|
for (const srcPath of files) {
|
|
3573
3756
|
const source = await readFileSafe(srcPath);
|
|
3574
3757
|
if (!source) continue;
|
|
3575
|
-
const name =
|
|
3576
|
-
const destPath = join26(projectRoot,
|
|
3758
|
+
const name = basename19(srcPath, ".md");
|
|
3759
|
+
const destPath = join26(projectRoot, CONTINUE_CANONICAL_RULES_DIR, `${name}.md`);
|
|
3577
3760
|
const { frontmatter, body } = parseFrontmatter(normalize(source, srcPath, destPath));
|
|
3578
3761
|
const canonicalFrontmatter = {
|
|
3579
3762
|
description: typeof frontmatter.description === "string" ? frontmatter.description : void 0,
|
|
@@ -3587,7 +3770,7 @@ async function importRules4(projectRoot, results, normalize) {
|
|
|
3587
3770
|
results.push({
|
|
3588
3771
|
fromTool: "continue",
|
|
3589
3772
|
fromPath: srcPath,
|
|
3590
|
-
toPath: `${
|
|
3773
|
+
toPath: `${CONTINUE_CANONICAL_RULES_DIR}/${name}.md`,
|
|
3591
3774
|
feature: "rules"
|
|
3592
3775
|
});
|
|
3593
3776
|
}
|
|
@@ -3599,12 +3782,12 @@ async function importCommands4(projectRoot, results, normalize) {
|
|
|
3599
3782
|
for (const srcPath of files) {
|
|
3600
3783
|
const source = await readFileSafe(srcPath);
|
|
3601
3784
|
if (!source) continue;
|
|
3602
|
-
const name =
|
|
3603
|
-
const destPath = join26(projectRoot,
|
|
3785
|
+
const name = basename19(srcPath, ".md");
|
|
3786
|
+
const destPath = join26(projectRoot, CONTINUE_CANONICAL_COMMANDS_DIR, `${name}.md`);
|
|
3604
3787
|
const { frontmatter, body } = parseFrontmatter(normalize(source, srcPath, destPath));
|
|
3605
3788
|
const command = parseCommandRuleFrontmatter(frontmatter, srcPath);
|
|
3606
3789
|
const commandName = command.name || name;
|
|
3607
|
-
const commandPath = join26(projectRoot,
|
|
3790
|
+
const commandPath = join26(projectRoot, CONTINUE_CANONICAL_COMMANDS_DIR, `${commandName}.md`);
|
|
3608
3791
|
const content = await serializeImportedCommandWithFallback(
|
|
3609
3792
|
commandPath,
|
|
3610
3793
|
{
|
|
@@ -3619,7 +3802,7 @@ async function importCommands4(projectRoot, results, normalize) {
|
|
|
3619
3802
|
results.push({
|
|
3620
3803
|
fromTool: "continue",
|
|
3621
3804
|
fromPath: srcPath,
|
|
3622
|
-
toPath: `${
|
|
3805
|
+
toPath: `${CONTINUE_CANONICAL_COMMANDS_DIR}/${commandName}.md`,
|
|
3623
3806
|
feature: "commands"
|
|
3624
3807
|
});
|
|
3625
3808
|
}
|
|
@@ -3637,22 +3820,21 @@ async function importMcp4(projectRoot, results) {
|
|
|
3637
3820
|
importedFrom.push(srcPath);
|
|
3638
3821
|
}
|
|
3639
3822
|
if (Object.keys(mergedServers).length === 0) return;
|
|
3640
|
-
const destPath = join26(projectRoot,
|
|
3823
|
+
const destPath = join26(projectRoot, CONTINUE_CANONICAL_MCP);
|
|
3641
3824
|
await writeFileAtomic(destPath, JSON.stringify({ mcpServers: mergedServers }, null, 2));
|
|
3642
3825
|
for (const fromPath of importedFrom) {
|
|
3643
|
-
results.push({
|
|
3826
|
+
results.push({
|
|
3827
|
+
fromTool: CONTINUE_TARGET,
|
|
3828
|
+
fromPath,
|
|
3829
|
+
toPath: CONTINUE_CANONICAL_MCP,
|
|
3830
|
+
feature: "mcp"
|
|
3831
|
+
});
|
|
3644
3832
|
}
|
|
3645
3833
|
}
|
|
3646
3834
|
|
|
3647
3835
|
// src/targets/junie/importer.ts
|
|
3648
|
-
import { basename as
|
|
3836
|
+
import { basename as basename20, join as join27 } from "path";
|
|
3649
3837
|
init_markdown();
|
|
3650
|
-
var AB_RULE = ".agentsmesh/rules/_root.md";
|
|
3651
|
-
var AB_RULES_DIR = ".agentsmesh/rules";
|
|
3652
|
-
var AB_COMMANDS_DIR = ".agentsmesh/commands";
|
|
3653
|
-
var AB_AGENTS_DIR = ".agentsmesh/agents";
|
|
3654
|
-
var AB_MCP5 = ".agentsmesh/mcp.json";
|
|
3655
|
-
var AB_IGNORE3 = ".agentsmesh/ignore";
|
|
3656
3838
|
function readMcpServers2(content) {
|
|
3657
3839
|
const parsed = JSON.parse(content);
|
|
3658
3840
|
const rawServers = parsed.mcpServers;
|
|
@@ -3685,7 +3867,7 @@ function readMcpServers2(content) {
|
|
|
3685
3867
|
}
|
|
3686
3868
|
async function importRules5(projectRoot, results, normalize) {
|
|
3687
3869
|
const sources = [JUNIE_DOT_AGENTS, JUNIE_GUIDELINES, JUNIE_CI_GUIDELINES, JUNIE_AGENTS_FALLBACK];
|
|
3688
|
-
const destPath = join27(projectRoot,
|
|
3870
|
+
const destPath = join27(projectRoot, JUNIE_CANONICAL_ROOT_RULE);
|
|
3689
3871
|
for (const relPath of sources) {
|
|
3690
3872
|
const srcPath = join27(projectRoot, relPath);
|
|
3691
3873
|
const content = await readFileSafe(srcPath);
|
|
@@ -3701,13 +3883,18 @@ async function importRules5(projectRoot, results, normalize) {
|
|
|
3701
3883
|
body
|
|
3702
3884
|
);
|
|
3703
3885
|
await writeFileAtomic(destPath, output);
|
|
3704
|
-
results.push({
|
|
3886
|
+
results.push({
|
|
3887
|
+
fromTool: JUNIE_TARGET,
|
|
3888
|
+
fromPath: srcPath,
|
|
3889
|
+
toPath: JUNIE_CANONICAL_ROOT_RULE,
|
|
3890
|
+
feature: "rules"
|
|
3891
|
+
});
|
|
3705
3892
|
return;
|
|
3706
3893
|
}
|
|
3707
3894
|
}
|
|
3708
3895
|
async function importNonRootRules(projectRoot, results, normalize) {
|
|
3709
|
-
const srcDir = join27(projectRoot,
|
|
3710
|
-
const destDir = join27(projectRoot,
|
|
3896
|
+
const srcDir = join27(projectRoot, JUNIE_RULES_DIR);
|
|
3897
|
+
const destDir = join27(projectRoot, JUNIE_CANONICAL_RULES_DIR);
|
|
3711
3898
|
results.push(
|
|
3712
3899
|
...await importFileDirectory({
|
|
3713
3900
|
srcDir,
|
|
@@ -3716,7 +3903,7 @@ async function importNonRootRules(projectRoot, results, normalize) {
|
|
|
3716
3903
|
fromTool: "junie",
|
|
3717
3904
|
normalize,
|
|
3718
3905
|
mapEntry: async ({ srcPath, normalizeTo }) => {
|
|
3719
|
-
const name =
|
|
3906
|
+
const name = basename20(srcPath, ".md");
|
|
3720
3907
|
if (!name) return null;
|
|
3721
3908
|
const destPath = join27(destDir, `${name}.md`);
|
|
3722
3909
|
const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
|
|
@@ -3731,7 +3918,7 @@ async function importNonRootRules(projectRoot, results, normalize) {
|
|
|
3731
3918
|
);
|
|
3732
3919
|
return {
|
|
3733
3920
|
destPath,
|
|
3734
|
-
toPath: `${
|
|
3921
|
+
toPath: `${JUNIE_CANONICAL_RULES_DIR}/${name}.md`,
|
|
3735
3922
|
feature: "rules",
|
|
3736
3923
|
content: output
|
|
3737
3924
|
};
|
|
@@ -3746,14 +3933,19 @@ async function importMcp5(projectRoot, results) {
|
|
|
3746
3933
|
const servers = readMcpServers2(content);
|
|
3747
3934
|
if (Object.keys(servers).length === 0) return;
|
|
3748
3935
|
await writeFileAtomic(
|
|
3749
|
-
join27(projectRoot,
|
|
3936
|
+
join27(projectRoot, JUNIE_CANONICAL_MCP),
|
|
3750
3937
|
JSON.stringify({ mcpServers: servers }, null, 2)
|
|
3751
3938
|
);
|
|
3752
|
-
results.push({
|
|
3939
|
+
results.push({
|
|
3940
|
+
fromTool: JUNIE_TARGET,
|
|
3941
|
+
fromPath: srcPath,
|
|
3942
|
+
toPath: JUNIE_CANONICAL_MCP,
|
|
3943
|
+
feature: "mcp"
|
|
3944
|
+
});
|
|
3753
3945
|
}
|
|
3754
3946
|
async function importCommands5(projectRoot, results, normalize) {
|
|
3755
3947
|
const srcDir = join27(projectRoot, JUNIE_COMMANDS_DIR);
|
|
3756
|
-
const destDir = join27(projectRoot,
|
|
3948
|
+
const destDir = join27(projectRoot, JUNIE_CANONICAL_COMMANDS_DIR);
|
|
3757
3949
|
results.push(
|
|
3758
3950
|
...await importFileDirectory({
|
|
3759
3951
|
srcDir,
|
|
@@ -3762,7 +3954,7 @@ async function importCommands5(projectRoot, results, normalize) {
|
|
|
3762
3954
|
fromTool: "junie",
|
|
3763
3955
|
normalize,
|
|
3764
3956
|
mapEntry: async ({ srcPath, normalizeTo }) => {
|
|
3765
|
-
const name =
|
|
3957
|
+
const name = basename20(srcPath, ".md");
|
|
3766
3958
|
if (!name) return null;
|
|
3767
3959
|
const destPath = join27(destDir, `${name}.md`);
|
|
3768
3960
|
const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
|
|
@@ -3778,7 +3970,7 @@ async function importCommands5(projectRoot, results, normalize) {
|
|
|
3778
3970
|
);
|
|
3779
3971
|
return {
|
|
3780
3972
|
destPath,
|
|
3781
|
-
toPath: `${
|
|
3973
|
+
toPath: `${JUNIE_CANONICAL_COMMANDS_DIR}/${name}.md`,
|
|
3782
3974
|
feature: "commands",
|
|
3783
3975
|
content: normalized
|
|
3784
3976
|
};
|
|
@@ -3788,7 +3980,7 @@ async function importCommands5(projectRoot, results, normalize) {
|
|
|
3788
3980
|
}
|
|
3789
3981
|
async function importAgents5(projectRoot, results, normalize) {
|
|
3790
3982
|
const srcDir = join27(projectRoot, JUNIE_AGENTS_DIR);
|
|
3791
|
-
const destDir = join27(projectRoot,
|
|
3983
|
+
const destDir = join27(projectRoot, JUNIE_CANONICAL_AGENTS_DIR);
|
|
3792
3984
|
results.push(
|
|
3793
3985
|
...await importFileDirectory({
|
|
3794
3986
|
srcDir,
|
|
@@ -3797,13 +3989,13 @@ async function importAgents5(projectRoot, results, normalize) {
|
|
|
3797
3989
|
fromTool: "junie",
|
|
3798
3990
|
normalize,
|
|
3799
3991
|
mapEntry: ({ srcPath, normalizeTo }) => {
|
|
3800
|
-
const name =
|
|
3992
|
+
const name = basename20(srcPath, ".md");
|
|
3801
3993
|
if (!name) return null;
|
|
3802
3994
|
const destPath = join27(destDir, `${name}.md`);
|
|
3803
3995
|
const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
|
|
3804
3996
|
return {
|
|
3805
3997
|
destPath,
|
|
3806
|
-
toPath: `${
|
|
3998
|
+
toPath: `${JUNIE_CANONICAL_AGENTS_DIR}/${name}.md`,
|
|
3807
3999
|
feature: "agents",
|
|
3808
4000
|
content: serializeFrontmatter(frontmatter, body.trim() || "")
|
|
3809
4001
|
};
|
|
@@ -3815,28 +4007,33 @@ async function importIgnore3(projectRoot, results) {
|
|
|
3815
4007
|
const srcPath = join27(projectRoot, JUNIE_IGNORE);
|
|
3816
4008
|
const content = await readFileSafe(srcPath);
|
|
3817
4009
|
if (content === null) return;
|
|
3818
|
-
await writeFileAtomic(join27(projectRoot,
|
|
3819
|
-
results.push({
|
|
4010
|
+
await writeFileAtomic(join27(projectRoot, JUNIE_CANONICAL_IGNORE), content.trimEnd());
|
|
4011
|
+
results.push({
|
|
4012
|
+
fromTool: JUNIE_TARGET,
|
|
4013
|
+
fromPath: srcPath,
|
|
4014
|
+
toPath: JUNIE_CANONICAL_IGNORE,
|
|
4015
|
+
feature: "ignore"
|
|
4016
|
+
});
|
|
3820
4017
|
}
|
|
3821
4018
|
async function importFromJunie(projectRoot) {
|
|
3822
4019
|
const results = [];
|
|
3823
|
-
const normalize = await createImportReferenceNormalizer(
|
|
4020
|
+
const normalize = await createImportReferenceNormalizer(JUNIE_TARGET, projectRoot);
|
|
3824
4021
|
await importRules5(projectRoot, results, normalize);
|
|
3825
4022
|
await importNonRootRules(projectRoot, results, normalize);
|
|
3826
4023
|
await importCommands5(projectRoot, results, normalize);
|
|
3827
4024
|
await importAgents5(projectRoot, results, normalize);
|
|
3828
|
-
await importEmbeddedSkills(projectRoot, JUNIE_SKILLS_DIR,
|
|
4025
|
+
await importEmbeddedSkills(projectRoot, JUNIE_SKILLS_DIR, JUNIE_TARGET, results, normalize);
|
|
3829
4026
|
await importMcp5(projectRoot, results);
|
|
3830
4027
|
await importIgnore3(projectRoot, results);
|
|
3831
4028
|
return results;
|
|
3832
4029
|
}
|
|
3833
4030
|
|
|
3834
4031
|
// src/targets/gemini-cli/importer.ts
|
|
3835
|
-
import { join as join31, basename as
|
|
4032
|
+
import { join as join31, basename as basename22, dirname as dirname16, relative as relative9 } from "path";
|
|
3836
4033
|
init_markdown();
|
|
3837
4034
|
|
|
3838
4035
|
// src/targets/gemini-cli/importer-mappers.ts
|
|
3839
|
-
import { basename as
|
|
4036
|
+
import { basename as basename21, join as join29, relative as relative8 } from "path";
|
|
3840
4037
|
import { parse as parseToml4 } from "smol-toml";
|
|
3841
4038
|
|
|
3842
4039
|
// src/targets/gemini-cli/format-helpers.ts
|
|
@@ -3846,6 +4043,7 @@ import { stringify as stringifyYaml } from "yaml";
|
|
|
3846
4043
|
init_markdown();
|
|
3847
4044
|
|
|
3848
4045
|
// src/targets/gemini-cli/constants.ts
|
|
4046
|
+
var GEMINI_TARGET = "gemini-cli";
|
|
3849
4047
|
var GEMINI_ROOT = "GEMINI.md";
|
|
3850
4048
|
var GEMINI_COMPAT_AGENTS = "AGENTS.md";
|
|
3851
4049
|
var GEMINI_RULES_DIR = ".gemini/rules";
|
|
@@ -3858,11 +4056,16 @@ var GEMINI_SKILLS_DIR = ".gemini/skills";
|
|
|
3858
4056
|
var GEMINI_AGENTS_DIR = ".gemini/agents";
|
|
3859
4057
|
var GEMINI_SYSTEM = ".gemini/system.md";
|
|
3860
4058
|
var GEMINI_DEFAULT_POLICIES_FILE = `${GEMINI_POLICIES_DIR}/permissions.toml`;
|
|
4059
|
+
var GEMINI_CANONICAL_RULES_DIR = ".agentsmesh/rules";
|
|
4060
|
+
var GEMINI_CANONICAL_COMMANDS_DIR = ".agentsmesh/commands";
|
|
4061
|
+
var GEMINI_CANONICAL_AGENTS_DIR = ".agentsmesh/agents";
|
|
4062
|
+
var GEMINI_CANONICAL_SKILLS_DIR = ".agentsmesh/skills";
|
|
4063
|
+
var GEMINI_CANONICAL_MCP = ".agentsmesh/mcp.json";
|
|
4064
|
+
var GEMINI_CANONICAL_HOOKS = ".agentsmesh/hooks.yaml";
|
|
4065
|
+
var GEMINI_CANONICAL_IGNORE = ".agentsmesh/ignore";
|
|
4066
|
+
var GEMINI_CANONICAL_PERMISSIONS = ".agentsmesh/permissions.yaml";
|
|
3861
4067
|
|
|
3862
4068
|
// src/targets/gemini-cli/format-helpers.ts
|
|
3863
|
-
var AGENTSMESH_MCP3 = ".agentsmesh/mcp.json";
|
|
3864
|
-
var AGENTSMESH_HOOKS2 = ".agentsmesh/hooks.yaml";
|
|
3865
|
-
var AGENTSMESH_IGNORE3 = ".agentsmesh/ignore";
|
|
3866
4069
|
function mapGeminiHookEvent(event) {
|
|
3867
4070
|
switch (event) {
|
|
3868
4071
|
case "BeforeTool":
|
|
@@ -3912,25 +4115,25 @@ async function importGeminiSettings(projectRoot, results) {
|
|
|
3912
4115
|
if (!settings) return;
|
|
3913
4116
|
const mcpServers = settings.mcpServers;
|
|
3914
4117
|
if (mcpServers !== void 0 && typeof mcpServers === "object" && mcpServers !== null && Object.keys(mcpServers).length > 0) {
|
|
3915
|
-
const mcpPath = join28(projectRoot,
|
|
4118
|
+
const mcpPath = join28(projectRoot, GEMINI_CANONICAL_MCP);
|
|
3916
4119
|
await mkdirp(join28(projectRoot, ".agentsmesh"));
|
|
3917
4120
|
await writeFileAtomic(mcpPath, JSON.stringify({ mcpServers }, null, 2));
|
|
3918
4121
|
results.push({
|
|
3919
4122
|
fromTool: "gemini-cli",
|
|
3920
4123
|
fromPath: settingsPath,
|
|
3921
|
-
toPath:
|
|
4124
|
+
toPath: GEMINI_CANONICAL_MCP,
|
|
3922
4125
|
feature: "mcp"
|
|
3923
4126
|
});
|
|
3924
4127
|
}
|
|
3925
4128
|
const ignorePatterns = settings.ignorePatterns;
|
|
3926
4129
|
if (Array.isArray(ignorePatterns) && ignorePatterns.length > 0 && ignorePatterns.every((p) => typeof p === "string")) {
|
|
3927
|
-
const ignorePath = join28(projectRoot,
|
|
4130
|
+
const ignorePath = join28(projectRoot, GEMINI_CANONICAL_IGNORE);
|
|
3928
4131
|
await mkdirp(join28(projectRoot, ".agentsmesh"));
|
|
3929
4132
|
await writeFileAtomic(ignorePath, ignorePatterns.join("\n") + "\n");
|
|
3930
4133
|
results.push({
|
|
3931
4134
|
fromTool: "gemini-cli",
|
|
3932
4135
|
fromPath: settingsPath,
|
|
3933
|
-
toPath:
|
|
4136
|
+
toPath: GEMINI_CANONICAL_IGNORE,
|
|
3934
4137
|
feature: "ignore"
|
|
3935
4138
|
});
|
|
3936
4139
|
}
|
|
@@ -3967,13 +4170,13 @@ async function importGeminiSettings(projectRoot, results) {
|
|
|
3967
4170
|
);
|
|
3968
4171
|
if (mappedHooks.length > 0) {
|
|
3969
4172
|
const hooksYaml = Object.fromEntries(mappedHooks);
|
|
3970
|
-
const hooksPath = join28(projectRoot,
|
|
4173
|
+
const hooksPath = join28(projectRoot, GEMINI_CANONICAL_HOOKS);
|
|
3971
4174
|
await mkdirp(join28(projectRoot, ".agentsmesh"));
|
|
3972
4175
|
await writeFileAtomic(hooksPath, stringifyYaml(hooksYaml, { lineWidth: 0 }).trimEnd());
|
|
3973
4176
|
results.push({
|
|
3974
4177
|
fromTool: "gemini-cli",
|
|
3975
4178
|
fromPath: settingsPath,
|
|
3976
|
-
toPath:
|
|
4179
|
+
toPath: GEMINI_CANONICAL_HOOKS,
|
|
3977
4180
|
feature: "hooks"
|
|
3978
4181
|
});
|
|
3979
4182
|
}
|
|
@@ -3986,12 +4189,12 @@ async function importGeminiIgnore(projectRoot, results) {
|
|
|
3986
4189
|
const patterns = geminiIgnoreContent.split(/\r?\n/).map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
3987
4190
|
if (patterns.length > 0) {
|
|
3988
4191
|
await mkdirp(join28(projectRoot, ".agentsmesh"));
|
|
3989
|
-
const ignorePath = join28(projectRoot,
|
|
4192
|
+
const ignorePath = join28(projectRoot, GEMINI_CANONICAL_IGNORE);
|
|
3990
4193
|
await writeFileAtomic(ignorePath, patterns.join("\n") + "\n");
|
|
3991
4194
|
results.push({
|
|
3992
4195
|
fromTool: "gemini-cli",
|
|
3993
4196
|
fromPath: geminiIgnorePath,
|
|
3994
|
-
toPath:
|
|
4197
|
+
toPath: GEMINI_CANONICAL_IGNORE,
|
|
3995
4198
|
feature: "ignore"
|
|
3996
4199
|
});
|
|
3997
4200
|
}
|
|
@@ -3999,10 +4202,8 @@ async function importGeminiIgnore(projectRoot, results) {
|
|
|
3999
4202
|
}
|
|
4000
4203
|
|
|
4001
4204
|
// src/targets/gemini-cli/importer-mappers.ts
|
|
4002
|
-
var AGENTSMESH_RULES5 = ".agentsmesh/rules";
|
|
4003
|
-
var AGENTSMESH_COMMANDS4 = ".agentsmesh/commands";
|
|
4004
4205
|
async function mapGeminiRuleFile(srcPath, destDir, normalizeTo) {
|
|
4005
|
-
const destFileName = `${
|
|
4206
|
+
const destFileName = `${basename21(srcPath, ".md")}.md`;
|
|
4006
4207
|
const destPath = join29(destDir, destFileName);
|
|
4007
4208
|
const { frontmatter, body } = parseFlexibleFrontmatter(normalizeTo(destPath));
|
|
4008
4209
|
const globs = toGlobsArray(frontmatter.globs);
|
|
@@ -4016,7 +4217,7 @@ async function mapGeminiRuleFile(srcPath, destDir, normalizeTo) {
|
|
|
4016
4217
|
});
|
|
4017
4218
|
return {
|
|
4018
4219
|
destPath,
|
|
4019
|
-
toPath: `${
|
|
4220
|
+
toPath: `${GEMINI_CANONICAL_RULES_DIR}/${destFileName}`,
|
|
4020
4221
|
feature: "rules",
|
|
4021
4222
|
content: await serializeImportedRuleWithFallback(destPath, canonicalFm, body)
|
|
4022
4223
|
};
|
|
@@ -4033,7 +4234,7 @@ async function mapGeminiCommandFile(srcPath, destDir, normalizeTo, geminiCommand
|
|
|
4033
4234
|
const allowedTools = fromCamel.length > 0 ? fromCamel : fromKebab;
|
|
4034
4235
|
return {
|
|
4035
4236
|
destPath,
|
|
4036
|
-
toPath: `${
|
|
4237
|
+
toPath: `${GEMINI_CANONICAL_COMMANDS_DIR}/${name}.md`,
|
|
4037
4238
|
feature: "commands",
|
|
4038
4239
|
content: await serializeImportedCommandWithFallback(
|
|
4039
4240
|
destPath,
|
|
@@ -4063,7 +4264,6 @@ function parseTomlCommand(normalized) {
|
|
|
4063
4264
|
import { parse as parseToml5 } from "smol-toml";
|
|
4064
4265
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
4065
4266
|
import { join as join30 } from "path";
|
|
4066
|
-
var AB_PERMISSIONS3 = ".agentsmesh/permissions.yaml";
|
|
4067
4267
|
function unescapeRegexLiteral(value) {
|
|
4068
4268
|
return value.replace(/\\(.)/g, "$1");
|
|
4069
4269
|
}
|
|
@@ -4153,28 +4353,24 @@ async function importGeminiPolicies(projectRoot) {
|
|
|
4153
4353
|
}
|
|
4154
4354
|
if (allow.length === 0 && deny.length === 0) return results;
|
|
4155
4355
|
await mkdirp(join30(projectRoot, ".agentsmesh"));
|
|
4156
|
-
const outPath = join30(projectRoot,
|
|
4356
|
+
const outPath = join30(projectRoot, GEMINI_CANONICAL_PERMISSIONS);
|
|
4157
4357
|
const yaml = stringifyYaml2({ allow, deny });
|
|
4158
4358
|
await writeFileAtomic(outPath, yaml.trimEnd() + "\n");
|
|
4159
4359
|
results.push({
|
|
4160
|
-
fromTool:
|
|
4360
|
+
fromTool: GEMINI_TARGET,
|
|
4161
4361
|
fromPath: join30(projectRoot, GEMINI_POLICIES_DIR),
|
|
4162
|
-
toPath:
|
|
4362
|
+
toPath: GEMINI_CANONICAL_PERMISSIONS,
|
|
4163
4363
|
feature: "permissions"
|
|
4164
4364
|
});
|
|
4165
4365
|
return results;
|
|
4166
4366
|
}
|
|
4167
4367
|
|
|
4168
4368
|
// src/targets/gemini-cli/importer.ts
|
|
4169
|
-
var AGENTSMESH_RULES6 = ".agentsmesh/rules";
|
|
4170
|
-
var AGENTSMESH_COMMANDS5 = ".agentsmesh/commands";
|
|
4171
|
-
var AGENTSMESH_AGENTS3 = ".agentsmesh/agents";
|
|
4172
|
-
var AGENTSMESH_SKILLS3 = ".agentsmesh/skills";
|
|
4173
4369
|
async function importFromGemini(projectRoot) {
|
|
4174
4370
|
const results = [];
|
|
4175
|
-
const normalize = await createImportReferenceNormalizer(
|
|
4176
|
-
const rulesDir = join31(projectRoot,
|
|
4177
|
-
const commandsDir = join31(projectRoot,
|
|
4371
|
+
const normalize = await createImportReferenceNormalizer(GEMINI_TARGET, projectRoot);
|
|
4372
|
+
const rulesDir = join31(projectRoot, GEMINI_CANONICAL_RULES_DIR);
|
|
4373
|
+
const commandsDir = join31(projectRoot, GEMINI_CANONICAL_COMMANDS_DIR);
|
|
4178
4374
|
const geminiRootPath = join31(projectRoot, GEMINI_ROOT);
|
|
4179
4375
|
const compatAgentsRootPath = join31(projectRoot, GEMINI_COMPAT_AGENTS);
|
|
4180
4376
|
const compatInnerRootPath = join31(projectRoot, GEMINI_COMPAT_INNER_ROOT);
|
|
@@ -4204,7 +4400,7 @@ async function importFromGemini(projectRoot) {
|
|
|
4204
4400
|
results.push({
|
|
4205
4401
|
fromTool: "gemini-cli",
|
|
4206
4402
|
fromPath: rootSourcePath,
|
|
4207
|
-
toPath: `${
|
|
4403
|
+
toPath: `${GEMINI_CANONICAL_RULES_DIR}/_root.md`,
|
|
4208
4404
|
feature: "rules"
|
|
4209
4405
|
});
|
|
4210
4406
|
}
|
|
@@ -4232,15 +4428,15 @@ async function importFromGemini(projectRoot) {
|
|
|
4232
4428
|
);
|
|
4233
4429
|
const geminiSkillsPath = join31(projectRoot, GEMINI_SKILLS_DIR);
|
|
4234
4430
|
const skillDirs = await readDirRecursive(geminiSkillsPath);
|
|
4235
|
-
const skillMdFiles = skillDirs.filter((f) =>
|
|
4431
|
+
const skillMdFiles = skillDirs.filter((f) => basename22(f) === "SKILL.md");
|
|
4236
4432
|
for (const srcPath of skillMdFiles) {
|
|
4237
4433
|
const content = await readFileSafe(srcPath);
|
|
4238
4434
|
if (!content) continue;
|
|
4239
|
-
const skillName =
|
|
4435
|
+
const skillName = basename22(srcPath.slice(0, -"/SKILL.md".length));
|
|
4240
4436
|
const rawParsed = parseFrontmatter(content);
|
|
4241
4437
|
const projectedAgent = parseProjectedAgentSkillFrontmatter(rawParsed.frontmatter, skillName);
|
|
4242
4438
|
if (projectedAgent) {
|
|
4243
|
-
const agentsDir = join31(projectRoot,
|
|
4439
|
+
const agentsDir = join31(projectRoot, GEMINI_CANONICAL_AGENTS_DIR);
|
|
4244
4440
|
await mkdirp(agentsDir);
|
|
4245
4441
|
const agentPath = join31(agentsDir, `${projectedAgent.name}.md`);
|
|
4246
4442
|
await writeFileAtomic(
|
|
@@ -4250,20 +4446,20 @@ async function importFromGemini(projectRoot) {
|
|
|
4250
4446
|
results.push({
|
|
4251
4447
|
fromTool: "gemini-cli",
|
|
4252
4448
|
fromPath: srcPath,
|
|
4253
|
-
toPath: `${
|
|
4449
|
+
toPath: `${GEMINI_CANONICAL_AGENTS_DIR}/${projectedAgent.name}.md`,
|
|
4254
4450
|
feature: "agents"
|
|
4255
4451
|
});
|
|
4256
4452
|
continue;
|
|
4257
4453
|
}
|
|
4258
|
-
const destPath = join31(projectRoot,
|
|
4454
|
+
const destPath = join31(projectRoot, GEMINI_CANONICAL_SKILLS_DIR, skillName, "SKILL.md");
|
|
4259
4455
|
const normalized = normalize(content, srcPath, destPath);
|
|
4260
|
-
const skillDir = join31(projectRoot,
|
|
4456
|
+
const skillDir = join31(projectRoot, GEMINI_CANONICAL_SKILLS_DIR, skillName);
|
|
4261
4457
|
await mkdirp(skillDir);
|
|
4262
4458
|
await writeFileAtomic(destPath, normalized);
|
|
4263
4459
|
results.push({
|
|
4264
4460
|
fromTool: "gemini-cli",
|
|
4265
4461
|
fromPath: srcPath,
|
|
4266
|
-
toPath: `${
|
|
4462
|
+
toPath: `${GEMINI_CANONICAL_SKILLS_DIR}/${skillName}/SKILL.md`,
|
|
4267
4463
|
feature: "skills"
|
|
4268
4464
|
});
|
|
4269
4465
|
const allSkillFiles = await readDirRecursive(dirname16(srcPath));
|
|
@@ -4278,7 +4474,7 @@ async function importFromGemini(projectRoot) {
|
|
|
4278
4474
|
results.push({
|
|
4279
4475
|
fromTool: "gemini-cli",
|
|
4280
4476
|
fromPath: absPath,
|
|
4281
|
-
toPath: `${
|
|
4477
|
+
toPath: `${GEMINI_CANONICAL_SKILLS_DIR}/${skillName}/${relPath}`,
|
|
4282
4478
|
feature: "skills"
|
|
4283
4479
|
});
|
|
4284
4480
|
}
|
|
@@ -4292,8 +4488,8 @@ async function importFromGemini(projectRoot) {
|
|
|
4292
4488
|
const content = await readFileSafe(srcPath);
|
|
4293
4489
|
if (!content) continue;
|
|
4294
4490
|
const { frontmatter, body } = parseFrontmatter(content);
|
|
4295
|
-
const name = typeof frontmatter.name === "string" ? frontmatter.name :
|
|
4296
|
-
const agentsDir = join31(projectRoot,
|
|
4491
|
+
const name = typeof frontmatter.name === "string" ? frontmatter.name : basename22(srcPath, ".md");
|
|
4492
|
+
const agentsDir = join31(projectRoot, GEMINI_CANONICAL_AGENTS_DIR);
|
|
4297
4493
|
await mkdirp(agentsDir);
|
|
4298
4494
|
const destPath = join31(agentsDir, `${name}.md`);
|
|
4299
4495
|
const normalizedBody = normalize(body, srcPath, destPath);
|
|
@@ -4312,7 +4508,7 @@ async function importFromGemini(projectRoot) {
|
|
|
4312
4508
|
results.push({
|
|
4313
4509
|
fromTool: "gemini-cli",
|
|
4314
4510
|
fromPath: srcPath,
|
|
4315
|
-
toPath: `${
|
|
4511
|
+
toPath: `${GEMINI_CANONICAL_AGENTS_DIR}/${name}.md`,
|
|
4316
4512
|
feature: "agents"
|
|
4317
4513
|
});
|
|
4318
4514
|
}
|
|
@@ -4444,24 +4640,21 @@ function validateRules(canonical, projectRoot, projectFiles) {
|
|
|
4444
4640
|
}
|
|
4445
4641
|
|
|
4446
4642
|
// src/targets/claude-code/linter.ts
|
|
4447
|
-
var TARGET = "claude-code";
|
|
4448
4643
|
function lintRules(canonical, _projectRoot, projectFiles) {
|
|
4449
4644
|
const diags = validateRules(canonical, _projectRoot, projectFiles);
|
|
4450
|
-
return diags.map((d) => ({ ...d, target:
|
|
4645
|
+
return diags.map((d) => ({ ...d, target: CLAUDE_CODE_TARGET }));
|
|
4451
4646
|
}
|
|
4452
4647
|
|
|
4453
4648
|
// src/targets/cursor/linter.ts
|
|
4454
|
-
var TARGET2 = "cursor";
|
|
4455
4649
|
function lintRules2(canonical, _projectRoot, projectFiles) {
|
|
4456
4650
|
const diags = validateRules(canonical, _projectRoot, projectFiles);
|
|
4457
|
-
return diags.map((d) => ({ ...d, target:
|
|
4651
|
+
return diags.map((d) => ({ ...d, target: CURSOR_TARGET }));
|
|
4458
4652
|
}
|
|
4459
4653
|
|
|
4460
4654
|
// src/targets/copilot/linter.ts
|
|
4461
|
-
var TARGET3 = "copilot";
|
|
4462
4655
|
function lintRules3(canonical, projectRoot, projectFiles) {
|
|
4463
4656
|
const diags = validateRules(canonical, projectRoot, projectFiles);
|
|
4464
|
-
const targetDiags = diags.map((d) => ({ ...d, target:
|
|
4657
|
+
const targetDiags = diags.map((d) => ({ ...d, target: COPILOT_TARGET }));
|
|
4465
4658
|
const nonRootWithoutGlobs = canonical.rules.filter(
|
|
4466
4659
|
(rule) => !rule.root && rule.globs.length === 0
|
|
4467
4660
|
);
|
|
@@ -4470,47 +4663,42 @@ function lintRules3(canonical, projectRoot, projectFiles) {
|
|
|
4470
4663
|
...nonRootWithoutGlobs.map((rule) => ({
|
|
4471
4664
|
level: "warning",
|
|
4472
4665
|
file: rule.source,
|
|
4473
|
-
target:
|
|
4666
|
+
target: COPILOT_TARGET,
|
|
4474
4667
|
message: "Copilot path-specific instructions require applyTo globs; non-root rules without globs are not generated."
|
|
4475
4668
|
}))
|
|
4476
4669
|
];
|
|
4477
4670
|
}
|
|
4478
4671
|
|
|
4479
4672
|
// src/targets/continue/linter.ts
|
|
4480
|
-
var TARGET4 = "continue";
|
|
4481
4673
|
function lintRules4(canonical, projectRoot, projectFiles) {
|
|
4482
4674
|
return validateRules(canonical, projectRoot, projectFiles).map((diagnostic) => ({
|
|
4483
4675
|
...diagnostic,
|
|
4484
|
-
target:
|
|
4676
|
+
target: CONTINUE_TARGET
|
|
4485
4677
|
}));
|
|
4486
4678
|
}
|
|
4487
4679
|
|
|
4488
4680
|
// src/targets/junie/linter.ts
|
|
4489
|
-
var TARGET5 = "junie";
|
|
4490
4681
|
function lintRules5(canonical, projectRoot, projectFiles) {
|
|
4491
4682
|
return validateRules(canonical, projectRoot, projectFiles).map((diagnostic) => ({
|
|
4492
4683
|
...diagnostic,
|
|
4493
|
-
target:
|
|
4684
|
+
target: JUNIE_TARGET
|
|
4494
4685
|
}));
|
|
4495
4686
|
}
|
|
4496
4687
|
|
|
4497
4688
|
// src/targets/gemini-cli/linter.ts
|
|
4498
|
-
var TARGET6 = "gemini-cli";
|
|
4499
4689
|
function lintRules6(canonical, projectRoot, projectFiles) {
|
|
4500
4690
|
const diags = validateRules(canonical, projectRoot, projectFiles);
|
|
4501
|
-
return diags.map((d) => ({ ...d, target:
|
|
4691
|
+
return diags.map((d) => ({ ...d, target: GEMINI_TARGET }));
|
|
4502
4692
|
}
|
|
4503
4693
|
|
|
4504
4694
|
// src/targets/cline/linter.ts
|
|
4505
|
-
var TARGET7 = "cline";
|
|
4506
4695
|
function lintRules7(canonical, projectRoot, projectFiles) {
|
|
4507
4696
|
const diags = validateRules(canonical, projectRoot, projectFiles);
|
|
4508
|
-
return diags.map((d) => ({ ...d, target:
|
|
4697
|
+
return diags.map((d) => ({ ...d, target: CLINE_TARGET }));
|
|
4509
4698
|
}
|
|
4510
4699
|
|
|
4511
4700
|
// src/targets/codex-cli/linter.ts
|
|
4512
4701
|
import { relative as relative11 } from "path";
|
|
4513
|
-
var TARGET8 = "codex-cli";
|
|
4514
4702
|
function lintRules8(canonical, projectRoot, _projectFiles) {
|
|
4515
4703
|
const { rules } = canonical;
|
|
4516
4704
|
if (rules.length === 0) return [];
|
|
@@ -4520,7 +4708,7 @@ function lintRules8(canonical, projectRoot, _projectFiles) {
|
|
|
4520
4708
|
{
|
|
4521
4709
|
level: "warning",
|
|
4522
4710
|
file: relative11(projectRoot, rules[0].source),
|
|
4523
|
-
target:
|
|
4711
|
+
target: CODEX_TARGET,
|
|
4524
4712
|
message: "Codex needs a root rule to generate AGENTS.md. Add root: true to a rule."
|
|
4525
4713
|
}
|
|
4526
4714
|
];
|
|
@@ -4530,7 +4718,6 @@ function lintRules8(canonical, projectRoot, _projectFiles) {
|
|
|
4530
4718
|
|
|
4531
4719
|
// src/targets/windsurf/linter.ts
|
|
4532
4720
|
import { relative as relative12 } from "path";
|
|
4533
|
-
var TARGET9 = "windsurf";
|
|
4534
4721
|
function lintRules9(canonical, projectRoot, _projectFiles) {
|
|
4535
4722
|
const diags = [];
|
|
4536
4723
|
const { rules } = canonical;
|
|
@@ -4540,7 +4727,7 @@ function lintRules9(canonical, projectRoot, _projectFiles) {
|
|
|
4540
4727
|
diags.push({
|
|
4541
4728
|
level: "warning",
|
|
4542
4729
|
file: relative12(projectRoot, rules[0].source),
|
|
4543
|
-
target:
|
|
4730
|
+
target: WINDSURF_TARGET,
|
|
4544
4731
|
message: "Windsurf needs a root rule to generate AGENTS.md. Add root: true to a rule."
|
|
4545
4732
|
});
|
|
4546
4733
|
}
|
|
@@ -4552,7 +4739,7 @@ function lintRules9(canonical, projectRoot, _projectFiles) {
|
|
|
4552
4739
|
diags.push({
|
|
4553
4740
|
level: "warning",
|
|
4554
4741
|
file: ".agentsmesh",
|
|
4555
|
-
target:
|
|
4742
|
+
target: WINDSURF_TARGET,
|
|
4556
4743
|
message: `Windsurf cannot project these features yet: ${unsupported.join(", ")}.`
|
|
4557
4744
|
});
|
|
4558
4745
|
}
|
|
@@ -5304,7 +5491,7 @@ async function resolveExtendPaths(config, configDir, options = {}) {
|
|
|
5304
5491
|
import { join as join38 } from "path";
|
|
5305
5492
|
|
|
5306
5493
|
// src/canonical/rules.ts
|
|
5307
|
-
import { basename as
|
|
5494
|
+
import { basename as basename23 } from "path";
|
|
5308
5495
|
init_markdown();
|
|
5309
5496
|
var VALID_TRIGGERS = ["always_on", "model_decision", "glob", "manual"];
|
|
5310
5497
|
function toStrArray(v) {
|
|
@@ -5320,7 +5507,7 @@ async function parseRules(rulesDir) {
|
|
|
5320
5507
|
const content = await readFileSafe(path);
|
|
5321
5508
|
if (!content) continue;
|
|
5322
5509
|
const { frontmatter, body } = parseFrontmatter(content);
|
|
5323
|
-
const name =
|
|
5510
|
+
const name = basename23(path, ".md");
|
|
5324
5511
|
const rootFromFilename = name === "_root";
|
|
5325
5512
|
const rootFromFm = frontmatter.root === true;
|
|
5326
5513
|
const triggerRaw = frontmatter.trigger;
|
|
@@ -5345,7 +5532,7 @@ async function parseRules(rulesDir) {
|
|
|
5345
5532
|
}
|
|
5346
5533
|
|
|
5347
5534
|
// src/canonical/commands.ts
|
|
5348
|
-
import { basename as
|
|
5535
|
+
import { basename as basename24 } from "path";
|
|
5349
5536
|
init_markdown();
|
|
5350
5537
|
function toToolsArray2(v) {
|
|
5351
5538
|
if (Array.isArray(v)) {
|
|
@@ -5364,7 +5551,7 @@ async function parseCommands(commandsDir) {
|
|
|
5364
5551
|
const content = await readFileSafe(path);
|
|
5365
5552
|
if (!content) continue;
|
|
5366
5553
|
const { frontmatter, body } = parseFrontmatter(content);
|
|
5367
|
-
const name =
|
|
5554
|
+
const name = basename24(path, ".md");
|
|
5368
5555
|
const fromCamel = toToolsArray2(frontmatter.allowedTools);
|
|
5369
5556
|
const fromKebab = toToolsArray2(frontmatter["allowed-tools"]);
|
|
5370
5557
|
const allowedTools = fromCamel.length > 0 ? fromCamel : fromKebab;
|
|
@@ -5380,7 +5567,7 @@ async function parseCommands(commandsDir) {
|
|
|
5380
5567
|
}
|
|
5381
5568
|
|
|
5382
5569
|
// src/canonical/agents.ts
|
|
5383
|
-
import { basename as
|
|
5570
|
+
import { basename as basename25 } from "path";
|
|
5384
5571
|
init_markdown();
|
|
5385
5572
|
function toStrArray2(v) {
|
|
5386
5573
|
if (Array.isArray(v)) {
|
|
@@ -5413,7 +5600,7 @@ async function parseAgents(agentsDir) {
|
|
|
5413
5600
|
const content = await readFileSafe(path);
|
|
5414
5601
|
if (!content) continue;
|
|
5415
5602
|
const { frontmatter, body } = parseFrontmatter(content);
|
|
5416
|
-
const name =
|
|
5603
|
+
const name = basename25(path, ".md");
|
|
5417
5604
|
const toolsCamel = toStrArray2(frontmatter.tools);
|
|
5418
5605
|
const toolsKebab = toStrArray2(frontmatter["tools"]);
|
|
5419
5606
|
const tools = toolsCamel.length > 0 ? toolsCamel : toolsKebab;
|
|
@@ -5447,7 +5634,7 @@ async function parseAgents(agentsDir) {
|
|
|
5447
5634
|
}
|
|
5448
5635
|
|
|
5449
5636
|
// src/canonical/skills.ts
|
|
5450
|
-
import { basename as
|
|
5637
|
+
import { basename as basename26, join as join37 } from "path";
|
|
5451
5638
|
import { readdir as readdir8 } from "fs/promises";
|
|
5452
5639
|
init_markdown();
|
|
5453
5640
|
async function readContent(path) {
|
|
@@ -5455,6 +5642,10 @@ async function readContent(path) {
|
|
|
5455
5642
|
return c2 ?? "";
|
|
5456
5643
|
}
|
|
5457
5644
|
var SKILL_FILE = "SKILL.md";
|
|
5645
|
+
var EXCLUDED_DIR_PREFIXES = [".git", "node_modules"];
|
|
5646
|
+
function sanitizeSkillName(raw) {
|
|
5647
|
+
return raw.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
5648
|
+
}
|
|
5458
5649
|
async function listSupportingFiles(skillDir) {
|
|
5459
5650
|
const files = await readDirRecursive(skillDir);
|
|
5460
5651
|
const result = [];
|
|
@@ -5462,6 +5653,9 @@ async function listSupportingFiles(skillDir) {
|
|
|
5462
5653
|
const raw = absPath.slice(skillDir.length + 1);
|
|
5463
5654
|
const name = raw.replace(/\\/g, "/");
|
|
5464
5655
|
if (name === SKILL_FILE || name.endsWith(`/${SKILL_FILE}`)) continue;
|
|
5656
|
+
const firstSegment = name.split("/")[0];
|
|
5657
|
+
if (EXCLUDED_DIR_PREFIXES.some((p) => firstSegment === p)) continue;
|
|
5658
|
+
if (name === ".DS_Store" || name.endsWith("/.DS_Store")) continue;
|
|
5465
5659
|
const content = await readContent(absPath);
|
|
5466
5660
|
result.push({ relativePath: name, absolutePath: absPath, content });
|
|
5467
5661
|
}
|
|
@@ -5473,9 +5667,10 @@ async function parseSkillDirectory(skillDir) {
|
|
|
5473
5667
|
if (!content) return null;
|
|
5474
5668
|
const { frontmatter, body } = parseFrontmatter(content);
|
|
5475
5669
|
const supportingFiles = await listSupportingFiles(skillDir);
|
|
5670
|
+
const fmName = typeof frontmatter.name === "string" ? sanitizeSkillName(frontmatter.name) : "";
|
|
5476
5671
|
return {
|
|
5477
5672
|
source: skillPath,
|
|
5478
|
-
name:
|
|
5673
|
+
name: fmName || basename26(skillDir),
|
|
5479
5674
|
description: typeof frontmatter.description === "string" ? frontmatter.description : "",
|
|
5480
5675
|
body,
|
|
5481
5676
|
supportingFiles
|
|
@@ -5672,14 +5867,14 @@ async function loadCanonicalFiles(projectRoot) {
|
|
|
5672
5867
|
}
|
|
5673
5868
|
|
|
5674
5869
|
// src/canonical/merge.ts
|
|
5675
|
-
import { basename as
|
|
5676
|
-
function
|
|
5677
|
-
return
|
|
5870
|
+
import { basename as basename27 } from "path";
|
|
5871
|
+
function ruleSlug2(r) {
|
|
5872
|
+
return basename27(r.source, ".md");
|
|
5678
5873
|
}
|
|
5679
5874
|
function mergeCanonicalFiles(base, overlay) {
|
|
5680
|
-
const baseRuleMap = new Map(base.rules.map((r) => [
|
|
5875
|
+
const baseRuleMap = new Map(base.rules.map((r) => [ruleSlug2(r), r]));
|
|
5681
5876
|
for (const r of overlay.rules) {
|
|
5682
|
-
baseRuleMap.set(
|
|
5877
|
+
baseRuleMap.set(ruleSlug2(r), r);
|
|
5683
5878
|
}
|
|
5684
5879
|
const baseCmdMap = new Map(base.commands.map((c2) => [c2.name, c2]));
|
|
5685
5880
|
for (const c2 of overlay.commands) {
|
|
@@ -5882,7 +6077,7 @@ async function loadSkillsAtExtendPath(skillsRoot) {
|
|
|
5882
6077
|
}
|
|
5883
6078
|
|
|
5884
6079
|
// src/canonical/load-canonical-slice.ts
|
|
5885
|
-
import { basename as
|
|
6080
|
+
import { basename as basename28, dirname as dirname18, join as join41 } from "path";
|
|
5886
6081
|
import { stat as stat4 } from "fs/promises";
|
|
5887
6082
|
function emptyCanonical() {
|
|
5888
6083
|
return {
|
|
@@ -5913,8 +6108,8 @@ async function normalizeSlicePath(absolutePath) {
|
|
|
5913
6108
|
);
|
|
5914
6109
|
}
|
|
5915
6110
|
const parent = dirname18(absolutePath);
|
|
5916
|
-
const parentBase =
|
|
5917
|
-
const fileBase =
|
|
6111
|
+
const parentBase = basename28(parent);
|
|
6112
|
+
const fileBase = basename28(absolutePath);
|
|
5918
6113
|
const slug = fileBase.replace(/\.md$/i, "");
|
|
5919
6114
|
if (parentBase === "rules") {
|
|
5920
6115
|
return { sliceRoot: parent, implicitPick: { rules: [slug] } };
|
|
@@ -5930,7 +6125,7 @@ async function normalizeSlicePath(absolutePath) {
|
|
|
5930
6125
|
);
|
|
5931
6126
|
}
|
|
5932
6127
|
async function parseRulesAt(sliceRoot) {
|
|
5933
|
-
const base =
|
|
6128
|
+
const base = basename28(sliceRoot);
|
|
5934
6129
|
if (base === "rules") {
|
|
5935
6130
|
return parseRules(sliceRoot);
|
|
5936
6131
|
}
|
|
@@ -5941,7 +6136,7 @@ async function parseRulesAt(sliceRoot) {
|
|
|
5941
6136
|
return [];
|
|
5942
6137
|
}
|
|
5943
6138
|
async function parseCommandsAt(sliceRoot) {
|
|
5944
|
-
const base =
|
|
6139
|
+
const base = basename28(sliceRoot);
|
|
5945
6140
|
if (base === "commands") {
|
|
5946
6141
|
return parseCommands(sliceRoot);
|
|
5947
6142
|
}
|
|
@@ -5952,7 +6147,7 @@ async function parseCommandsAt(sliceRoot) {
|
|
|
5952
6147
|
return [];
|
|
5953
6148
|
}
|
|
5954
6149
|
async function parseAgentsAt(sliceRoot) {
|
|
5955
|
-
const base =
|
|
6150
|
+
const base = basename28(sliceRoot);
|
|
5956
6151
|
if (base === "agents") {
|
|
5957
6152
|
return parseAgents(sliceRoot);
|
|
5958
6153
|
}
|
|
@@ -6052,7 +6247,7 @@ Expected one of: .agentsmesh/, ${KNOWN_NATIVE_PATHS.join(", ")}.`
|
|
|
6052
6247
|
}
|
|
6053
6248
|
|
|
6054
6249
|
// src/canonical/extend-pick.ts
|
|
6055
|
-
import { basename as
|
|
6250
|
+
import { basename as basename29 } from "path";
|
|
6056
6251
|
function applyExtendPick(canonical, features, pick, extendName) {
|
|
6057
6252
|
if (!pick) return canonical;
|
|
6058
6253
|
let next = { ...canonical };
|
|
@@ -6095,7 +6290,7 @@ function applyExtendPick(canonical, features, pick, extendName) {
|
|
|
6095
6290
|
if (pick.rules?.length && features.includes("rules")) {
|
|
6096
6291
|
const wanted = new Set(pick.rules);
|
|
6097
6292
|
const prev = next.rules;
|
|
6098
|
-
const stem = (src) =>
|
|
6293
|
+
const stem = (src) => basename29(src).replace(/\.md$/i, "");
|
|
6099
6294
|
next = {
|
|
6100
6295
|
...next,
|
|
6101
6296
|
rules: prev.filter((r) => wanted.has(stem(r.source)))
|
|
@@ -6487,7 +6682,7 @@ function generateRules(canonical) {
|
|
|
6487
6682
|
const root = canonical.rules.find((r) => r.root);
|
|
6488
6683
|
if (root) {
|
|
6489
6684
|
outputs.push({
|
|
6490
|
-
path:
|
|
6685
|
+
path: CLAUDE_ROOT,
|
|
6491
6686
|
content: root.body.trim() ? root.body : ""
|
|
6492
6687
|
});
|
|
6493
6688
|
}
|
|
@@ -6500,7 +6695,7 @@ function generateRules(canonical) {
|
|
|
6500
6695
|
if (rule.description) frontmatter.description = rule.description;
|
|
6501
6696
|
if (rule.globs.length > 0) frontmatter.globs = rule.globs;
|
|
6502
6697
|
const content = serializeFrontmatter(frontmatter, rule.body.trim() || "");
|
|
6503
|
-
outputs.push({ path:
|
|
6698
|
+
outputs.push({ path: `${CLAUDE_RULES_DIR}/${slug}.md`, content });
|
|
6504
6699
|
}
|
|
6505
6700
|
return outputs;
|
|
6506
6701
|
}
|
|
@@ -6512,7 +6707,7 @@ function generateCommands(canonical) {
|
|
|
6512
6707
|
};
|
|
6513
6708
|
if (frontmatter["allowed-tools"] === void 0) delete frontmatter["allowed-tools"];
|
|
6514
6709
|
const content = serializeFrontmatter(frontmatter, cmd.body.trim() || "");
|
|
6515
|
-
return { path:
|
|
6710
|
+
return { path: `${CLAUDE_COMMANDS_DIR}/${cmd.name}.md`, content };
|
|
6516
6711
|
});
|
|
6517
6712
|
}
|
|
6518
6713
|
function generateAgents(canonical) {
|
|
@@ -6534,13 +6729,13 @@ function generateAgents(canonical) {
|
|
|
6534
6729
|
if (frontmatter[k] === void 0) delete frontmatter[k];
|
|
6535
6730
|
});
|
|
6536
6731
|
const content = serializeFrontmatter(frontmatter, agent.body.trim() || "");
|
|
6537
|
-
return { path:
|
|
6732
|
+
return { path: `${CLAUDE_AGENTS_DIR}/${agent.name}.md`, content };
|
|
6538
6733
|
});
|
|
6539
6734
|
}
|
|
6540
6735
|
function generateMcp(canonical) {
|
|
6541
6736
|
if (!canonical.mcp || Object.keys(canonical.mcp.mcpServers).length === 0) return [];
|
|
6542
6737
|
const content = JSON.stringify({ mcpServers: canonical.mcp.mcpServers }, null, 2);
|
|
6543
|
-
return [{ path:
|
|
6738
|
+
return [{ path: CLAUDE_MCP_JSON, content }];
|
|
6544
6739
|
}
|
|
6545
6740
|
function generateSkills(canonical) {
|
|
6546
6741
|
const outputs = [];
|
|
@@ -6552,13 +6747,13 @@ function generateSkills(canonical) {
|
|
|
6552
6747
|
if (frontmatter.description === void 0) delete frontmatter.description;
|
|
6553
6748
|
const skillContent = serializeFrontmatter(frontmatter, skill.body.trim() || "");
|
|
6554
6749
|
outputs.push({
|
|
6555
|
-
path:
|
|
6750
|
+
path: `${CLAUDE_SKILLS_DIR}/${skill.name}/SKILL.md`,
|
|
6556
6751
|
content: skillContent
|
|
6557
6752
|
});
|
|
6558
6753
|
for (const file of skill.supportingFiles) {
|
|
6559
6754
|
const relPath = file.relativePath.replace(/\\/g, "/");
|
|
6560
6755
|
outputs.push({
|
|
6561
|
-
path:
|
|
6756
|
+
path: `${CLAUDE_SKILLS_DIR}/${skill.name}/${relPath}`,
|
|
6562
6757
|
content: file.content
|
|
6563
6758
|
});
|
|
6564
6759
|
}
|
|
@@ -6570,7 +6765,7 @@ function generatePermissions(canonical) {
|
|
|
6570
6765
|
const { allow, deny } = canonical.permissions;
|
|
6571
6766
|
if (allow.length === 0 && deny.length === 0) return [];
|
|
6572
6767
|
const content = JSON.stringify({ permissions: { allow, deny } }, null, 2);
|
|
6573
|
-
return [{ path:
|
|
6768
|
+
return [{ path: CLAUDE_SETTINGS, content }];
|
|
6574
6769
|
}
|
|
6575
6770
|
function toClaudeCodeHooks(hooks) {
|
|
6576
6771
|
const result = {};
|
|
@@ -6598,17 +6793,18 @@ function generateHooks(canonical) {
|
|
|
6598
6793
|
const claudeHooks = toClaudeCodeHooks(canonical.hooks);
|
|
6599
6794
|
if (Object.keys(claudeHooks).length === 0) return [];
|
|
6600
6795
|
const content = JSON.stringify({ hooks: claudeHooks }, null, 2);
|
|
6601
|
-
return [{ path:
|
|
6796
|
+
return [{ path: CLAUDE_SETTINGS, content }];
|
|
6602
6797
|
}
|
|
6603
6798
|
function generateIgnore(canonical) {
|
|
6604
6799
|
if (!canonical.ignore || canonical.ignore.length === 0) return [];
|
|
6605
6800
|
const content = canonical.ignore.join("\n");
|
|
6606
|
-
return [{ path:
|
|
6801
|
+
return [{ path: CLAUDE_IGNORE, content }];
|
|
6607
6802
|
}
|
|
6608
6803
|
|
|
6609
6804
|
// src/targets/claude-code/index.ts
|
|
6610
6805
|
var target = {
|
|
6611
6806
|
name: "claude-code",
|
|
6807
|
+
primaryRootInstructionPath: CLAUDE_ROOT,
|
|
6612
6808
|
generateRules,
|
|
6613
6809
|
generateCommands,
|
|
6614
6810
|
generateAgents,
|
|
@@ -6628,11 +6824,11 @@ function generateRules2(canonical) {
|
|
|
6628
6824
|
const root = canonical.rules.find((r) => r.root);
|
|
6629
6825
|
if (root) {
|
|
6630
6826
|
const body = root.body.trim() ? root.body : "";
|
|
6631
|
-
outputs.push({ path:
|
|
6827
|
+
outputs.push({ path: CURSOR_COMPAT_AGENTS, content: body });
|
|
6632
6828
|
const frontmatter = { alwaysApply: true };
|
|
6633
6829
|
if (root.description) frontmatter.description = root.description;
|
|
6634
6830
|
const content = serializeFrontmatter(frontmatter, body);
|
|
6635
|
-
outputs.push({ path:
|
|
6831
|
+
outputs.push({ path: CURSOR_GENERAL_RULE, content });
|
|
6636
6832
|
}
|
|
6637
6833
|
const nonRoot = canonical.rules.filter(
|
|
6638
6834
|
(r) => !r.root && (r.targets.length === 0 || r.targets.includes("cursor"))
|
|
@@ -6644,20 +6840,20 @@ function generateRules2(canonical) {
|
|
|
6644
6840
|
if (rule.description) frontmatter.description = rule.description;
|
|
6645
6841
|
if (rule.globs.length > 0) frontmatter.globs = rule.globs;
|
|
6646
6842
|
const content = serializeFrontmatter(frontmatter, rule.body.trim() || "");
|
|
6647
|
-
outputs.push({ path:
|
|
6843
|
+
outputs.push({ path: `${CURSOR_RULES_DIR}/${slug}.mdc`, content });
|
|
6648
6844
|
}
|
|
6649
6845
|
return outputs;
|
|
6650
6846
|
}
|
|
6651
6847
|
function generateCommands2(canonical) {
|
|
6652
6848
|
return canonical.commands.map((cmd) => ({
|
|
6653
|
-
path:
|
|
6849
|
+
path: `${CURSOR_COMMANDS_DIR}/${cmd.name}.md`,
|
|
6654
6850
|
content: cmd.body.trim() || ""
|
|
6655
6851
|
}));
|
|
6656
6852
|
}
|
|
6657
6853
|
function generateMcp2(canonical) {
|
|
6658
6854
|
if (!canonical.mcp || Object.keys(canonical.mcp.mcpServers).length === 0) return [];
|
|
6659
6855
|
const content = JSON.stringify({ mcpServers: canonical.mcp.mcpServers }, null, 2);
|
|
6660
|
-
return [{ path:
|
|
6856
|
+
return [{ path: CURSOR_MCP, content }];
|
|
6661
6857
|
}
|
|
6662
6858
|
function generateSkills2(canonical) {
|
|
6663
6859
|
const outputs = [];
|
|
@@ -6668,10 +6864,13 @@ function generateSkills2(canonical) {
|
|
|
6668
6864
|
};
|
|
6669
6865
|
if (frontmatter.description === void 0) delete frontmatter.description;
|
|
6670
6866
|
const content = serializeFrontmatter(frontmatter, skill.body.trim() || "");
|
|
6671
|
-
outputs.push({ path:
|
|
6867
|
+
outputs.push({ path: `${CURSOR_SKILLS_DIR}/${skill.name}/SKILL.md`, content });
|
|
6672
6868
|
for (const file of skill.supportingFiles) {
|
|
6673
6869
|
const relPath = file.relativePath.replace(/\\/g, "/");
|
|
6674
|
-
outputs.push({
|
|
6870
|
+
outputs.push({
|
|
6871
|
+
path: `${CURSOR_SKILLS_DIR}/${skill.name}/${relPath}`,
|
|
6872
|
+
content: file.content
|
|
6873
|
+
});
|
|
6675
6874
|
}
|
|
6676
6875
|
}
|
|
6677
6876
|
return outputs;
|
|
@@ -6695,7 +6894,7 @@ function generateAgents2(canonical) {
|
|
|
6695
6894
|
if (frontmatter[k] === void 0) delete frontmatter[k];
|
|
6696
6895
|
});
|
|
6697
6896
|
const content = serializeFrontmatter(frontmatter, agent.body.trim() || "");
|
|
6698
|
-
return { path:
|
|
6897
|
+
return { path: `${CURSOR_AGENTS_DIR}/${agent.name}.md`, content };
|
|
6699
6898
|
});
|
|
6700
6899
|
}
|
|
6701
6900
|
function generatePermissions2(_canonical) {
|
|
@@ -6727,17 +6926,18 @@ function generateHooks2(canonical) {
|
|
|
6727
6926
|
const cursorHooks = toCursorHooks(canonical.hooks);
|
|
6728
6927
|
if (Object.keys(cursorHooks).length === 0) return [];
|
|
6729
6928
|
const content = JSON.stringify({ version: 1, hooks: cursorHooks }, null, 2);
|
|
6730
|
-
return [{ path:
|
|
6929
|
+
return [{ path: CURSOR_HOOKS, content }];
|
|
6731
6930
|
}
|
|
6732
6931
|
function generateIgnore2(canonical) {
|
|
6733
6932
|
if (!canonical.ignore || canonical.ignore.length === 0) return [];
|
|
6734
6933
|
const content = canonical.ignore.join("\n");
|
|
6735
|
-
return [{ path:
|
|
6934
|
+
return [{ path: CURSOR_IGNORE, content }];
|
|
6736
6935
|
}
|
|
6737
6936
|
|
|
6738
6937
|
// src/targets/cursor/index.ts
|
|
6739
6938
|
var target2 = {
|
|
6740
6939
|
name: "cursor",
|
|
6940
|
+
primaryRootInstructionPath: CURSOR_GENERAL_RULE,
|
|
6741
6941
|
generateRules: generateRules2,
|
|
6742
6942
|
generateCommands: generateCommands2,
|
|
6743
6943
|
generateAgents: generateAgents2,
|
|
@@ -6752,7 +6952,7 @@ registerTarget(target2);
|
|
|
6752
6952
|
|
|
6753
6953
|
// src/targets/copilot/generator.ts
|
|
6754
6954
|
init_markdown();
|
|
6755
|
-
import { basename as
|
|
6955
|
+
import { basename as basename30 } from "path";
|
|
6756
6956
|
|
|
6757
6957
|
// src/targets/copilot/hook-entry.ts
|
|
6758
6958
|
function hasHookCommand2(entry) {
|
|
@@ -6760,8 +6960,8 @@ function hasHookCommand2(entry) {
|
|
|
6760
6960
|
}
|
|
6761
6961
|
|
|
6762
6962
|
// src/targets/copilot/generator.ts
|
|
6763
|
-
function
|
|
6764
|
-
const name =
|
|
6963
|
+
function ruleSlug3(source) {
|
|
6964
|
+
const name = basename30(source, ".md");
|
|
6765
6965
|
return name === "_root" ? "root" : name;
|
|
6766
6966
|
}
|
|
6767
6967
|
function mapHookEvent(event) {
|
|
@@ -6781,14 +6981,17 @@ function mapHookEvent(event) {
|
|
|
6781
6981
|
function generateRules3(canonical) {
|
|
6782
6982
|
const root = canonical.rules.find((r) => r.root);
|
|
6783
6983
|
const outputs = [];
|
|
6784
|
-
if (root
|
|
6785
|
-
outputs.push({
|
|
6984
|
+
if (root) {
|
|
6985
|
+
outputs.push({
|
|
6986
|
+
path: COPILOT_INSTRUCTIONS,
|
|
6987
|
+
content: root.body.trim() || ""
|
|
6988
|
+
});
|
|
6786
6989
|
}
|
|
6787
6990
|
for (const rule of canonical.rules) {
|
|
6788
6991
|
if (rule.root) continue;
|
|
6789
6992
|
if (rule.targets.length > 0 && !rule.targets.includes("copilot")) continue;
|
|
6790
6993
|
if (rule.globs.length === 0) continue;
|
|
6791
|
-
const slug =
|
|
6994
|
+
const slug = ruleSlug3(rule.source);
|
|
6792
6995
|
const frontmatter = {
|
|
6793
6996
|
description: rule.description || void 0,
|
|
6794
6997
|
applyTo: rule.globs.length === 1 ? rule.globs[0] : rule.globs
|
|
@@ -6880,6 +7083,7 @@ function generateHooks3(canonical) {
|
|
|
6880
7083
|
// src/targets/copilot/index.ts
|
|
6881
7084
|
var target3 = {
|
|
6882
7085
|
name: "copilot",
|
|
7086
|
+
primaryRootInstructionPath: COPILOT_INSTRUCTIONS,
|
|
6883
7087
|
generateRules: generateRules3,
|
|
6884
7088
|
generateCommands: generateCommands3,
|
|
6885
7089
|
generateAgents: generateAgents3,
|
|
@@ -6938,6 +7142,7 @@ function generateSkills4(canonical) {
|
|
|
6938
7142
|
// src/targets/continue/index.ts
|
|
6939
7143
|
var target4 = {
|
|
6940
7144
|
name: "continue",
|
|
7145
|
+
primaryRootInstructionPath: CONTINUE_ROOT_RULE,
|
|
6941
7146
|
generateRules: generateRules4,
|
|
6942
7147
|
generateCommands: generateCommands4,
|
|
6943
7148
|
generateSkills: generateSkills4,
|
|
@@ -6947,7 +7152,7 @@ var target4 = {
|
|
|
6947
7152
|
registerTarget(target4);
|
|
6948
7153
|
|
|
6949
7154
|
// src/targets/junie/generator.ts
|
|
6950
|
-
import { basename as
|
|
7155
|
+
import { basename as basename31 } from "path";
|
|
6951
7156
|
function generateRules5(canonical) {
|
|
6952
7157
|
const outputs = [];
|
|
6953
7158
|
const root = canonical.rules.find((rule) => rule.root);
|
|
@@ -6960,7 +7165,7 @@ function generateRules5(canonical) {
|
|
|
6960
7165
|
for (const rule of canonical.rules) {
|
|
6961
7166
|
if (rule.root) continue;
|
|
6962
7167
|
if (rule.targets.length > 0 && !rule.targets.includes("junie")) continue;
|
|
6963
|
-
const slug =
|
|
7168
|
+
const slug = basename31(rule.source, ".md");
|
|
6964
7169
|
outputs.push({
|
|
6965
7170
|
path: `${JUNIE_RULES_DIR}/${slug}.md`,
|
|
6966
7171
|
content: rule.body.trim() || ""
|
|
@@ -7002,6 +7207,7 @@ function generateSkills5(canonical) {
|
|
|
7002
7207
|
// src/targets/junie/index.ts
|
|
7003
7208
|
var target5 = {
|
|
7004
7209
|
name: "junie",
|
|
7210
|
+
primaryRootInstructionPath: JUNIE_DOT_AGENTS,
|
|
7005
7211
|
generateRules: generateRules5,
|
|
7006
7212
|
generateCommands: generateCommands5,
|
|
7007
7213
|
generateAgents: generateAgents4,
|
|
@@ -7258,6 +7464,7 @@ function generateGeminiPermissionsPolicies(canonical) {
|
|
|
7258
7464
|
// src/targets/gemini-cli/index.ts
|
|
7259
7465
|
var target6 = {
|
|
7260
7466
|
name: "gemini-cli",
|
|
7467
|
+
primaryRootInstructionPath: GEMINI_ROOT,
|
|
7261
7468
|
generateRules: generateRules6,
|
|
7262
7469
|
generateCommands: generateCommands6,
|
|
7263
7470
|
generateAgents: generateAgents5,
|
|
@@ -7270,10 +7477,10 @@ var target6 = {
|
|
|
7270
7477
|
registerTarget(target6);
|
|
7271
7478
|
|
|
7272
7479
|
// src/targets/cline/generator.ts
|
|
7273
|
-
import { basename as
|
|
7480
|
+
import { basename as basename32 } from "path";
|
|
7274
7481
|
init_markdown();
|
|
7275
|
-
function
|
|
7276
|
-
const name =
|
|
7482
|
+
function ruleSlug4(source) {
|
|
7483
|
+
const name = basename32(source, ".md");
|
|
7277
7484
|
return name === "_root" ? "root" : name;
|
|
7278
7485
|
}
|
|
7279
7486
|
function generateRules7(canonical) {
|
|
@@ -7286,7 +7493,7 @@ function generateRules7(canonical) {
|
|
|
7286
7493
|
for (const rule of canonical.rules) {
|
|
7287
7494
|
if (rule.root) continue;
|
|
7288
7495
|
if (rule.targets.length > 0 && !rule.targets.includes("cline")) continue;
|
|
7289
|
-
const slug =
|
|
7496
|
+
const slug = ruleSlug4(rule.source);
|
|
7290
7497
|
const frontmatter = {
|
|
7291
7498
|
description: rule.description || void 0,
|
|
7292
7499
|
paths: rule.globs.length > 0 ? rule.globs : void 0
|
|
@@ -7382,6 +7589,7 @@ function generateSkills7(canonical) {
|
|
|
7382
7589
|
// src/targets/cline/index.ts
|
|
7383
7590
|
var target7 = {
|
|
7384
7591
|
name: "cline",
|
|
7592
|
+
primaryRootInstructionPath: CLINE_AGENTS_MD,
|
|
7385
7593
|
generateRules: generateRules7,
|
|
7386
7594
|
generateWorkflows,
|
|
7387
7595
|
generateAgents: generateAgents6,
|
|
@@ -7414,47 +7622,6 @@ function usesCursorSensitiveInterpolation(server) {
|
|
|
7414
7622
|
// src/targets/codex-cli/generator.ts
|
|
7415
7623
|
init_markdown();
|
|
7416
7624
|
import { basename as basename33 } from "path";
|
|
7417
|
-
|
|
7418
|
-
// src/targets/codex-cli/codex-rule-paths.ts
|
|
7419
|
-
import { basename as basename32 } from "path";
|
|
7420
|
-
function sanitizeRelativeDir(rawPrefix) {
|
|
7421
|
-
const normalized = rawPrefix.replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
7422
|
-
const stripped = normalized.startsWith("./") ? normalized.slice(2) : normalized;
|
|
7423
|
-
if (stripped.length === 0 || stripped === "." || stripped === "..") return null;
|
|
7424
|
-
if (stripped.startsWith("/") || stripped.startsWith("../") || stripped.includes("/../"))
|
|
7425
|
-
return null;
|
|
7426
|
-
const segments = stripped.split("/");
|
|
7427
|
-
if (segments.some((segment) => segment.length === 0 || segment === "." || segment === "..")) {
|
|
7428
|
-
return null;
|
|
7429
|
-
}
|
|
7430
|
-
return stripped;
|
|
7431
|
-
}
|
|
7432
|
-
function directoryPrefixFromGlob(glob) {
|
|
7433
|
-
const normalized = glob.replace(/\\/g, "/");
|
|
7434
|
-
if (normalized.startsWith("{")) return null;
|
|
7435
|
-
const wildcardIndex = normalized.search(/[*{]/);
|
|
7436
|
-
if (wildcardIndex < 0) {
|
|
7437
|
-
const trimmed = normalized.replace(/\/+$/, "");
|
|
7438
|
-
return trimmed.length > 0 ? sanitizeRelativeDir(trimmed) : null;
|
|
7439
|
-
}
|
|
7440
|
-
if (wildcardIndex === 0) return null;
|
|
7441
|
-
const prefix = normalized.slice(0, wildcardIndex).replace(/\/+$/, "");
|
|
7442
|
-
return prefix.length > 0 ? sanitizeRelativeDir(prefix) : null;
|
|
7443
|
-
}
|
|
7444
|
-
function advisorySubdir(rule) {
|
|
7445
|
-
for (const glob of rule.globs) {
|
|
7446
|
-
const prefix = directoryPrefixFromGlob(glob);
|
|
7447
|
-
if (prefix !== null && !prefix.includes("**")) return prefix;
|
|
7448
|
-
}
|
|
7449
|
-
return basename32(rule.source, ".md");
|
|
7450
|
-
}
|
|
7451
|
-
function codexAdvisoryInstructionPath(rule) {
|
|
7452
|
-
const dir = advisorySubdir(rule);
|
|
7453
|
-
const file = rule.codexInstructionVariant === "override" ? "AGENTS.override.md" : "AGENTS.md";
|
|
7454
|
-
return `${dir}/${file}`;
|
|
7455
|
-
}
|
|
7456
|
-
|
|
7457
|
-
// src/targets/codex-cli/generator.ts
|
|
7458
7625
|
function looksLikeCodexRulesDsl(body) {
|
|
7459
7626
|
return /(^|\n)\s*[A-Za-z_][A-Za-z0-9_]*\s*\(/.test(body);
|
|
7460
7627
|
}
|
|
@@ -7487,22 +7654,21 @@ function generateRules8(canonical) {
|
|
|
7487
7654
|
const root = canonical.rules.find((r) => r.root);
|
|
7488
7655
|
const outputs = [];
|
|
7489
7656
|
if (root) {
|
|
7490
|
-
outputs.push({ path:
|
|
7657
|
+
outputs.push({ path: AGENTS_MD, content: appendCodexRuleIndex(root.body, canonical.rules) });
|
|
7491
7658
|
}
|
|
7492
7659
|
for (const rule of canonical.rules) {
|
|
7493
7660
|
if (rule.root) continue;
|
|
7494
|
-
if (rule.targets.length > 0 && !rule.targets.includes("codex-cli")) continue;
|
|
7495
7661
|
const slug = basename33(rule.source, ".md");
|
|
7662
|
+
if (rule.targets.length > 0 && !rule.targets.includes("codex-cli")) continue;
|
|
7496
7663
|
if (rule.codexEmit === "execution") {
|
|
7497
7664
|
outputs.push({
|
|
7498
7665
|
path: `${CODEX_RULES_DIR}/${slug}.rules`,
|
|
7499
7666
|
content: toSafeCodexRulesContent(rule.body)
|
|
7500
7667
|
});
|
|
7501
|
-
continue;
|
|
7502
7668
|
}
|
|
7503
7669
|
outputs.push({
|
|
7504
|
-
path:
|
|
7505
|
-
content: rule
|
|
7670
|
+
path: codexInstructionMirrorPath(rule),
|
|
7671
|
+
content: serializeCodexInstructionMirror(rule)
|
|
7506
7672
|
});
|
|
7507
7673
|
}
|
|
7508
7674
|
return outputs;
|
|
@@ -7608,6 +7774,7 @@ function needsTomlQuoting(key) {
|
|
|
7608
7774
|
// src/targets/codex-cli/index.ts
|
|
7609
7775
|
var target8 = {
|
|
7610
7776
|
name: "codex-cli",
|
|
7777
|
+
primaryRootInstructionPath: AGENTS_MD,
|
|
7611
7778
|
generateRules: generateRules8,
|
|
7612
7779
|
generateCommands: generateCommands7,
|
|
7613
7780
|
generateAgents: generateAgents7,
|
|
@@ -7620,7 +7787,7 @@ registerTarget(target8);
|
|
|
7620
7787
|
// src/targets/windsurf/generator.ts
|
|
7621
7788
|
import { basename as basename34 } from "path";
|
|
7622
7789
|
init_markdown();
|
|
7623
|
-
function
|
|
7790
|
+
function ruleSlug5(source) {
|
|
7624
7791
|
const name = basename34(source, ".md");
|
|
7625
7792
|
return name === "_root" ? "root" : name;
|
|
7626
7793
|
}
|
|
@@ -7641,7 +7808,7 @@ function generateRules9(canonical) {
|
|
|
7641
7808
|
for (const rule of canonical.rules) {
|
|
7642
7809
|
if (rule.root) continue;
|
|
7643
7810
|
if (rule.targets.length > 0 && !rule.targets.includes("windsurf")) continue;
|
|
7644
|
-
const slug =
|
|
7811
|
+
const slug = ruleSlug5(rule.source);
|
|
7645
7812
|
const normalizedTrigger = rule.trigger || (rule.globs.length > 0 ? "glob" : void 0);
|
|
7646
7813
|
const frontmatter = {
|
|
7647
7814
|
description: rule.description || void 0,
|
|
@@ -7754,6 +7921,7 @@ function generateSkills9(canonical) {
|
|
|
7754
7921
|
// src/targets/windsurf/index.ts
|
|
7755
7922
|
var target9 = {
|
|
7756
7923
|
name: "windsurf",
|
|
7924
|
+
primaryRootInstructionPath: WINDSURF_AGENTS_MD,
|
|
7757
7925
|
generateRules: generateRules9,
|
|
7758
7926
|
generateWorkflows: generateWorkflows2,
|
|
7759
7927
|
generateAgents: generateAgents8,
|
|
@@ -7786,6 +7954,13 @@ function addSkillDirectoryMappings(refs, canonicalPath, targetPath) {
|
|
|
7786
7954
|
|
|
7787
7955
|
// src/core/reference-map-targets.ts
|
|
7788
7956
|
import { basename as basename35 } from "path";
|
|
7957
|
+
|
|
7958
|
+
// src/targets/codex-cli/codex-rule-paths.ts
|
|
7959
|
+
function codexAdvisoryInstructionPath(rule) {
|
|
7960
|
+
return codexInstructionMirrorPath(rule);
|
|
7961
|
+
}
|
|
7962
|
+
|
|
7963
|
+
// src/core/reference-map-targets.ts
|
|
7789
7964
|
var ROOT_RULE_PATHS = {
|
|
7790
7965
|
"claude-code": ".claude/CLAUDE.md",
|
|
7791
7966
|
cursor: ".cursor/rules/general.mdc",
|
|
@@ -7794,7 +7969,7 @@ var ROOT_RULE_PATHS = {
|
|
|
7794
7969
|
junie: ".junie/AGENTS.md",
|
|
7795
7970
|
"gemini-cli": GEMINI_ROOT,
|
|
7796
7971
|
cline: CLINE_AGENTS_MD,
|
|
7797
|
-
"codex-cli":
|
|
7972
|
+
"codex-cli": AGENTS_MD,
|
|
7798
7973
|
windsurf: WINDSURF_AGENTS_MD
|
|
7799
7974
|
};
|
|
7800
7975
|
var SKILL_DIRS = {
|
|
@@ -7828,7 +8003,6 @@ function ruleTargetPath(target10, rule) {
|
|
|
7828
8003
|
case "cline":
|
|
7829
8004
|
return `${CLINE_RULES_DIR}/${slug}.md`;
|
|
7830
8005
|
case "codex-cli":
|
|
7831
|
-
if (rule.codexEmit === "execution") return `${CODEX_RULES_DIR}/${slug}.rules`;
|
|
7832
8006
|
return codexAdvisoryInstructionPath(rule);
|
|
7833
8007
|
case "windsurf":
|
|
7834
8008
|
return `${WINDSURF_RULES_DIR}/${slug}.md`;
|
|
@@ -7937,6 +8111,12 @@ function isClineAgents(result) {
|
|
|
7937
8111
|
function isCursorAgents(result) {
|
|
7938
8112
|
return result.target === "cursor" && result.path.endsWith(AGENTS_SUFFIX);
|
|
7939
8113
|
}
|
|
8114
|
+
function isGeminiAgents(result) {
|
|
8115
|
+
return result.target === "gemini-cli" && result.path.endsWith(AGENTS_SUFFIX);
|
|
8116
|
+
}
|
|
8117
|
+
function isCompatibilityAgents(result) {
|
|
8118
|
+
return isCursorAgents(result) || isGeminiAgents(result);
|
|
8119
|
+
}
|
|
7940
8120
|
function reverseReferenceMap(target10, canonical, config, cache) {
|
|
7941
8121
|
const cached = cache.get(target10);
|
|
7942
8122
|
if (cached) return cached;
|
|
@@ -7961,25 +8141,47 @@ function hasEquivalentCanonicalContent(left, right, canonical, config, cache) {
|
|
|
7961
8141
|
return normalizeContent(left.content, leftRefs) === normalizeContent(right.content, rightRefs);
|
|
7962
8142
|
}
|
|
7963
8143
|
function preferEquivalentCodexAgents(results, canonical, config) {
|
|
8144
|
+
const overlapTargetsByPath = /* @__PURE__ */ new Map();
|
|
8145
|
+
for (const result of results) {
|
|
8146
|
+
if (!result.path.endsWith(AGENTS_SUFFIX)) continue;
|
|
8147
|
+
const targets = overlapTargetsByPath.get(result.path) ?? /* @__PURE__ */ new Set();
|
|
8148
|
+
targets.add(result.target);
|
|
8149
|
+
overlapTargetsByPath.set(result.path, targets);
|
|
8150
|
+
}
|
|
7964
8151
|
const codexByPath = /* @__PURE__ */ new Map();
|
|
7965
8152
|
for (const result of results) {
|
|
7966
8153
|
if (isCodexAgents(result)) codexByPath.set(result.path, result);
|
|
7967
8154
|
}
|
|
7968
8155
|
const reverseCache = /* @__PURE__ */ new Map();
|
|
7969
8156
|
return results.filter((result) => {
|
|
7970
|
-
if (
|
|
8157
|
+
if (isCursorAgents(result)) {
|
|
8158
|
+
const targets = overlapTargetsByPath.get(result.path);
|
|
8159
|
+
if (targets && [...targets].some((target10) => target10 !== "cursor")) return false;
|
|
8160
|
+
}
|
|
8161
|
+
if (isGeminiAgents(result)) {
|
|
8162
|
+
const targets = overlapTargetsByPath.get(result.path);
|
|
8163
|
+
if (targets && [...targets].some((target10) => target10 !== "cursor" && target10 !== "gemini-cli")) {
|
|
8164
|
+
return false;
|
|
8165
|
+
}
|
|
8166
|
+
}
|
|
8167
|
+
if (!isWindsurfAgents(result) && !isClineAgents(result) && !isCursorAgents(result) && !isGeminiAgents(result)) {
|
|
8168
|
+
return true;
|
|
8169
|
+
}
|
|
7971
8170
|
const codexResult = codexByPath.get(result.path);
|
|
7972
8171
|
if (!codexResult) return true;
|
|
8172
|
+
if (isCompatibilityAgents(result) || isWindsurfAgents(result) || isClineAgents(result)) {
|
|
8173
|
+
return false;
|
|
8174
|
+
}
|
|
7973
8175
|
return !hasEquivalentCanonicalContent(codexResult, result, canonical, config, reverseCache);
|
|
7974
8176
|
});
|
|
7975
8177
|
}
|
|
7976
8178
|
|
|
7977
8179
|
// src/core/reference-rewriter.ts
|
|
7978
8180
|
import { existsSync as existsSync3 } from "fs";
|
|
7979
|
-
import { dirname as
|
|
8181
|
+
import { dirname as dirname20, join as join48 } from "path";
|
|
7980
8182
|
|
|
7981
8183
|
// src/core/output-source-map.ts
|
|
7982
|
-
import { join as join47, normalize as normalizePath2 } from "path";
|
|
8184
|
+
import { dirname as dirname19, join as join47, normalize as normalizePath2 } from "path";
|
|
7983
8185
|
function canonicalRulePath(rule) {
|
|
7984
8186
|
return `.agentsmesh/rules/${rule.source.split("/").pop()}`;
|
|
7985
8187
|
}
|
|
@@ -8023,8 +8225,30 @@ function ruleOutputPaths(target10, rule, refs) {
|
|
|
8023
8225
|
if (target10 === "gemini-cli") {
|
|
8024
8226
|
paths.push(GEMINI_COMPAT_AGENTS);
|
|
8025
8227
|
}
|
|
8228
|
+
if (target10 === "codex-cli") {
|
|
8229
|
+
if (!rule.root && rule.codexEmit === "execution") {
|
|
8230
|
+
const slug = rule.source.split("/").pop().replace(/\.md$/, "");
|
|
8231
|
+
paths.push(`${CODEX_RULES_DIR}/${slug}.rules`);
|
|
8232
|
+
}
|
|
8233
|
+
}
|
|
8026
8234
|
return paths;
|
|
8027
8235
|
}
|
|
8236
|
+
function addPackSkillPaths(refs, target10, canonical, projectRoot) {
|
|
8237
|
+
const skillDir = SKILL_DIRS[target10];
|
|
8238
|
+
if (!skillDir) return;
|
|
8239
|
+
const packsPrefix = join47(projectRoot, ".agentsmesh", "packs");
|
|
8240
|
+
for (const skill of canonical.skills) {
|
|
8241
|
+
const skillSourceDir = dirname19(skill.source);
|
|
8242
|
+
if (!skillSourceDir.startsWith(packsPrefix)) continue;
|
|
8243
|
+
const targetSkillDir = normalizePath2(join47(projectRoot, skillDir, skill.name));
|
|
8244
|
+
refs.set(normalizePath2(skillSourceDir), targetSkillDir);
|
|
8245
|
+
refs.set(normalizePath2(skill.source), normalizePath2(join47(targetSkillDir, "SKILL.md")));
|
|
8246
|
+
for (const file of skill.supportingFiles) {
|
|
8247
|
+
const targetFilePath = normalizePath2(join47(targetSkillDir, file.relativePath));
|
|
8248
|
+
refs.set(normalizePath2(file.absolutePath), targetFilePath);
|
|
8249
|
+
}
|
|
8250
|
+
}
|
|
8251
|
+
}
|
|
8028
8252
|
function buildArtifactPathMap(target10, canonical, config, projectRoot, destinationPath) {
|
|
8029
8253
|
const refs = new Map(
|
|
8030
8254
|
[...buildReferenceMap(target10, canonical, config)].map(([canonicalPath, targetPath]) => [
|
|
@@ -8041,6 +8265,7 @@ function buildArtifactPathMap(target10, canonical, config, projectRoot, destinat
|
|
|
8041
8265
|
);
|
|
8042
8266
|
}
|
|
8043
8267
|
}
|
|
8268
|
+
addPackSkillPaths(refs, target10, canonical, projectRoot);
|
|
8044
8269
|
return refs;
|
|
8045
8270
|
}
|
|
8046
8271
|
function buildOutputSourceMap(target10, canonical, config) {
|
|
@@ -8077,11 +8302,11 @@ function collectPlannedPaths(projectRoot, results) {
|
|
|
8077
8302
|
for (const result of results) {
|
|
8078
8303
|
const absolutePath = join48(projectRoot, result.path);
|
|
8079
8304
|
planned.add(absolutePath);
|
|
8080
|
-
let current =
|
|
8305
|
+
let current = dirname20(absolutePath);
|
|
8081
8306
|
while (current.startsWith(projectRoot) && !planned.has(current)) {
|
|
8082
8307
|
planned.add(current);
|
|
8083
8308
|
if (current === projectRoot) break;
|
|
8084
|
-
current =
|
|
8309
|
+
current = dirname20(current);
|
|
8085
8310
|
}
|
|
8086
8311
|
}
|
|
8087
8312
|
return planned;
|
|
@@ -8199,6 +8424,23 @@ async function generateFeature(results, targets, canonical, projectRoot, enabled
|
|
|
8199
8424
|
}
|
|
8200
8425
|
}
|
|
8201
8426
|
|
|
8427
|
+
// src/core/root-instruction-decorator.ts
|
|
8428
|
+
function decoratePrimaryRootInstructions(results) {
|
|
8429
|
+
return results.map((result) => {
|
|
8430
|
+
let primaryRootInstructionPath;
|
|
8431
|
+
try {
|
|
8432
|
+
primaryRootInstructionPath = getTarget(result.target).primaryRootInstructionPath;
|
|
8433
|
+
} catch {
|
|
8434
|
+
return result;
|
|
8435
|
+
}
|
|
8436
|
+
if (!primaryRootInstructionPath || result.path !== primaryRootInstructionPath) {
|
|
8437
|
+
return result;
|
|
8438
|
+
}
|
|
8439
|
+
const content = appendAgentsmeshRootInstructionParagraph(result.content);
|
|
8440
|
+
return content === result.content ? result : { ...result, content };
|
|
8441
|
+
});
|
|
8442
|
+
}
|
|
8443
|
+
|
|
8202
8444
|
// src/core/engine-optional-features.ts
|
|
8203
8445
|
import { join as join51 } from "path";
|
|
8204
8446
|
|
|
@@ -8452,10 +8694,9 @@ async function generate(ctx) {
|
|
|
8452
8694
|
if (hasMcp || hasIgnore || hasHooks || hasAgents) {
|
|
8453
8695
|
await generateGeminiSettingsFeature(results, targets, canonical, projectRoot);
|
|
8454
8696
|
}
|
|
8455
|
-
const rewrittenResults = rewriteGeneratedReferences(results, canonical, config, projectRoot)
|
|
8456
|
-
|
|
8457
|
-
);
|
|
8458
|
-
return resolveOutputCollisions(preferEquivalentCodexAgents(rewrittenResults, canonical, config));
|
|
8697
|
+
const rewrittenResults = rewriteGeneratedReferences(results, canonical, config, projectRoot);
|
|
8698
|
+
const decoratedResults = decoratePrimaryRootInstructions(rewrittenResults).map(refreshResultStatus);
|
|
8699
|
+
return resolveOutputCollisions(preferEquivalentCodexAgents(decoratedResults, canonical, config));
|
|
8459
8700
|
}
|
|
8460
8701
|
|
|
8461
8702
|
// src/core/matrix.ts
|
|
@@ -9580,7 +9821,7 @@ async function runCheck(flags, projectRoot) {
|
|
|
9580
9821
|
import { join as join58 } from "path";
|
|
9581
9822
|
|
|
9582
9823
|
// src/core/merger.ts
|
|
9583
|
-
import { dirname as
|
|
9824
|
+
import { dirname as dirname21, join as join57 } from "path";
|
|
9584
9825
|
var LOCK_FILENAME2 = ".lock";
|
|
9585
9826
|
var CONFLICT_MARKER = "<<<<<<<";
|
|
9586
9827
|
async function hasLockConflict(abDir) {
|
|
@@ -9595,7 +9836,7 @@ async function resolveLockConflict(abDir, libVersion, config) {
|
|
|
9595
9836
|
throw new Error("No conflict to resolve.");
|
|
9596
9837
|
}
|
|
9597
9838
|
const checksums = await buildChecksums(abDir);
|
|
9598
|
-
const configDir =
|
|
9839
|
+
const configDir = dirname21(abDir);
|
|
9599
9840
|
const resolvedExtends = config ? await resolveExtendPaths(config, configDir) : [];
|
|
9600
9841
|
const extendChecksums = resolvedExtends.length > 0 ? await buildExtendChecksums(resolvedExtends) : {};
|
|
9601
9842
|
const packChecksums = await buildPackChecksums(join57(abDir, "packs"));
|
|
@@ -9626,7 +9867,7 @@ async function runMerge(flags, projectRoot) {
|
|
|
9626
9867
|
}
|
|
9627
9868
|
|
|
9628
9869
|
// src/install/run-install.ts
|
|
9629
|
-
import { join as
|
|
9870
|
+
import { join as join72 } from "path";
|
|
9630
9871
|
|
|
9631
9872
|
// src/install/git-pin.ts
|
|
9632
9873
|
import { execFile as execFile2 } from "child_process";
|
|
@@ -9785,7 +10026,7 @@ function validateAgent(agent) {
|
|
|
9785
10026
|
}
|
|
9786
10027
|
return { agent, ok: true };
|
|
9787
10028
|
}
|
|
9788
|
-
function
|
|
10029
|
+
function ruleSlug6(rule) {
|
|
9789
10030
|
return basename38(rule.source).replace(/\.md$/i, "");
|
|
9790
10031
|
}
|
|
9791
10032
|
|
|
@@ -9822,7 +10063,7 @@ async function resolveRulePool(narrowed, force, dryRun, tty) {
|
|
|
9822
10063
|
if (!force && !dryRun && tty) {
|
|
9823
10064
|
for (const inv of invalid) {
|
|
9824
10065
|
const ok = await confirm(
|
|
9825
|
-
`Include invalid rule "${
|
|
10066
|
+
`Include invalid rule "${ruleSlug6(inv.rule)}" anyway? (${inv.reason}). You can fix it later.`
|
|
9826
10067
|
);
|
|
9827
10068
|
if (ok) pool.push(inv.rule);
|
|
9828
10069
|
}
|
|
@@ -9876,7 +10117,7 @@ async function resolveAgentPool(narrowed, force, dryRun, tty) {
|
|
|
9876
10117
|
// src/install/install-conflicts.ts
|
|
9877
10118
|
async function resolveInstallConflicts(merged, pools) {
|
|
9878
10119
|
let skillsSel = pools.skills.map((s) => s.name);
|
|
9879
|
-
let rulesSel = pools.rules.map((r) =>
|
|
10120
|
+
let rulesSel = pools.rules.map((r) => ruleSlug6(r));
|
|
9880
10121
|
let commandsSel = pools.commands.map((c2) => c2.name);
|
|
9881
10122
|
let agentsSel = pools.agents.map((a) => a.name);
|
|
9882
10123
|
for (const s of pools.skills) {
|
|
@@ -9888,8 +10129,8 @@ async function resolveInstallConflicts(merged, pools) {
|
|
|
9888
10129
|
}
|
|
9889
10130
|
}
|
|
9890
10131
|
for (const r of pools.rules) {
|
|
9891
|
-
const slug =
|
|
9892
|
-
if (merged.rules.some((x) =>
|
|
10132
|
+
const slug = ruleSlug6(r);
|
|
10133
|
+
if (merged.rules.some((x) => ruleSlug6(x) === slug)) {
|
|
9893
10134
|
const ok = await confirm(
|
|
9894
10135
|
`Rule "${slug}" already exists in merged config. Add extend anyway?`
|
|
9895
10136
|
);
|
|
@@ -10001,6 +10242,50 @@ function parseGitlabBlobUrl(urlStr) {
|
|
|
10001
10242
|
return null;
|
|
10002
10243
|
}
|
|
10003
10244
|
}
|
|
10245
|
+
var GITHUB_ROUTE_WORDS = /* @__PURE__ */ new Set([
|
|
10246
|
+
"tree",
|
|
10247
|
+
"blob",
|
|
10248
|
+
"commit",
|
|
10249
|
+
"releases",
|
|
10250
|
+
"actions",
|
|
10251
|
+
"issues",
|
|
10252
|
+
"pulls",
|
|
10253
|
+
"settings",
|
|
10254
|
+
"wiki",
|
|
10255
|
+
"discussions",
|
|
10256
|
+
"security",
|
|
10257
|
+
"projects",
|
|
10258
|
+
"packages"
|
|
10259
|
+
]);
|
|
10260
|
+
function parseGithubRepoUrl(urlStr) {
|
|
10261
|
+
try {
|
|
10262
|
+
const u = new URL3(urlStr);
|
|
10263
|
+
if (u.hostname !== "github.com") return null;
|
|
10264
|
+
const parts = u.pathname.split("/").filter(Boolean).map((s) => s.replace(/\.git$/i, ""));
|
|
10265
|
+
if (parts.length < 2) return null;
|
|
10266
|
+
if (parts.length > 2 || GITHUB_ROUTE_WORDS.has(parts[1])) return null;
|
|
10267
|
+
const org = parts[0];
|
|
10268
|
+
const repo = parts[1];
|
|
10269
|
+
return { org, repo };
|
|
10270
|
+
} catch {
|
|
10271
|
+
return null;
|
|
10272
|
+
}
|
|
10273
|
+
}
|
|
10274
|
+
function parseGitlabRepoUrl(urlStr) {
|
|
10275
|
+
try {
|
|
10276
|
+
const u = new URL3(urlStr);
|
|
10277
|
+
if (u.hostname !== "gitlab.com") return null;
|
|
10278
|
+
const parts = u.pathname.split("/").filter(Boolean).map((s) => s.replace(/\.git$/i, ""));
|
|
10279
|
+
if (parts.length < 2) return null;
|
|
10280
|
+
if (parts.includes("-")) return null;
|
|
10281
|
+
const project = parts[parts.length - 1];
|
|
10282
|
+
const namespace = parts.slice(0, -1).join("/");
|
|
10283
|
+
if (!namespace || !project) return null;
|
|
10284
|
+
return { namespace, project };
|
|
10285
|
+
} catch {
|
|
10286
|
+
return null;
|
|
10287
|
+
}
|
|
10288
|
+
}
|
|
10004
10289
|
function parseGitSshGithub(ssh) {
|
|
10005
10290
|
const m = ssh.match(/^git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/i);
|
|
10006
10291
|
if (!m) return null;
|
|
@@ -10038,26 +10323,48 @@ async function parseInstallSource(raw, configDir, explicitPath) {
|
|
|
10038
10323
|
};
|
|
10039
10324
|
}
|
|
10040
10325
|
if (trimmed.startsWith("https://") || trimmed.startsWith("http://")) {
|
|
10041
|
-
const
|
|
10042
|
-
if (
|
|
10326
|
+
const ghDetailed = parseGithubTreeUrl(trimmed) ?? parseGithubBlobUrl(trimmed);
|
|
10327
|
+
if (ghDetailed) {
|
|
10328
|
+
return {
|
|
10329
|
+
kind: "github",
|
|
10330
|
+
rawRef: ghDetailed.ref,
|
|
10331
|
+
org: ghDetailed.org,
|
|
10332
|
+
repo: ghDetailed.repo,
|
|
10333
|
+
gitRemoteUrl: `https://github.com/${ghDetailed.org}/${ghDetailed.repo}.git`,
|
|
10334
|
+
pathInRepo: pathFlag || ghDetailed.path
|
|
10335
|
+
};
|
|
10336
|
+
}
|
|
10337
|
+
const ghBare = parseGithubRepoUrl(trimmed);
|
|
10338
|
+
if (ghBare) {
|
|
10043
10339
|
return {
|
|
10044
10340
|
kind: "github",
|
|
10045
|
-
rawRef:
|
|
10046
|
-
org:
|
|
10047
|
-
repo:
|
|
10048
|
-
gitRemoteUrl: `https://github.com/${
|
|
10049
|
-
pathInRepo: pathFlag
|
|
10341
|
+
rawRef: "HEAD",
|
|
10342
|
+
org: ghBare.org,
|
|
10343
|
+
repo: ghBare.repo,
|
|
10344
|
+
gitRemoteUrl: `https://github.com/${ghBare.org}/${ghBare.repo}.git`,
|
|
10345
|
+
pathInRepo: pathFlag
|
|
10050
10346
|
};
|
|
10051
10347
|
}
|
|
10052
|
-
const
|
|
10053
|
-
if (
|
|
10348
|
+
const glDetailed = parseGitlabTreeUrl(trimmed) ?? parseGitlabBlobUrl(trimmed);
|
|
10349
|
+
if (glDetailed) {
|
|
10054
10350
|
return {
|
|
10055
10351
|
kind: "gitlab",
|
|
10056
|
-
rawRef:
|
|
10057
|
-
org:
|
|
10058
|
-
repo:
|
|
10059
|
-
gitRemoteUrl: `https://gitlab.com/${
|
|
10060
|
-
pathInRepo: pathFlag ||
|
|
10352
|
+
rawRef: glDetailed.ref,
|
|
10353
|
+
org: glDetailed.namespace,
|
|
10354
|
+
repo: glDetailed.project,
|
|
10355
|
+
gitRemoteUrl: `https://gitlab.com/${glDetailed.namespace}/${glDetailed.project}.git`,
|
|
10356
|
+
pathInRepo: pathFlag || glDetailed.path
|
|
10357
|
+
};
|
|
10358
|
+
}
|
|
10359
|
+
const glBare = parseGitlabRepoUrl(trimmed);
|
|
10360
|
+
if (glBare) {
|
|
10361
|
+
return {
|
|
10362
|
+
kind: "gitlab",
|
|
10363
|
+
rawRef: "HEAD",
|
|
10364
|
+
org: glBare.namespace,
|
|
10365
|
+
repo: glBare.project,
|
|
10366
|
+
gitRemoteUrl: `https://gitlab.com/${glBare.namespace}/${glBare.project}.git`,
|
|
10367
|
+
pathInRepo: pathFlag
|
|
10061
10368
|
};
|
|
10062
10369
|
}
|
|
10063
10370
|
}
|
|
@@ -10324,7 +10631,7 @@ import { join as join63 } from "path";
|
|
|
10324
10631
|
import { rename as rename4 } from "fs/promises";
|
|
10325
10632
|
|
|
10326
10633
|
// src/install/pack-writer.ts
|
|
10327
|
-
import { join as join60, basename as basename39, dirname as
|
|
10634
|
+
import { join as join60, basename as basename39, dirname as dirname22 } from "path";
|
|
10328
10635
|
import { rm as rm6, rename as rename3, mkdir as mkdir5, copyFile as copyFile2 } from "fs/promises";
|
|
10329
10636
|
import { stringify as yamlStringify6 } from "yaml";
|
|
10330
10637
|
|
|
@@ -10385,7 +10692,7 @@ async function writeSkills(canonical, packDir) {
|
|
|
10385
10692
|
await copyFile2(skill.source, join60(skillDestDir, "SKILL.md"));
|
|
10386
10693
|
for (const sf of skill.supportingFiles) {
|
|
10387
10694
|
const destPath = join60(skillDestDir, sf.relativePath);
|
|
10388
|
-
await mkdirp(
|
|
10695
|
+
await mkdirp(dirname22(destPath));
|
|
10389
10696
|
await copyFile2(sf.absolutePath, destPath);
|
|
10390
10697
|
}
|
|
10391
10698
|
}
|
|
@@ -10430,7 +10737,7 @@ async function materializePack(packsDir, packName, canonical, metadataInput) {
|
|
|
10430
10737
|
}
|
|
10431
10738
|
|
|
10432
10739
|
// src/install/pack-merge.ts
|
|
10433
|
-
import { join as join61, basename as basename40, dirname as
|
|
10740
|
+
import { join as join61, basename as basename40, dirname as dirname23 } from "path";
|
|
10434
10741
|
import { copyFile as copyFile3 } from "fs/promises";
|
|
10435
10742
|
import { stringify as yamlStringify7 } from "yaml";
|
|
10436
10743
|
function union(a, b) {
|
|
@@ -10493,7 +10800,7 @@ async function mergeSkills(canonical, packDir) {
|
|
|
10493
10800
|
await copyFile3(skill.source, join61(destDir, "SKILL.md"));
|
|
10494
10801
|
for (const sf of skill.supportingFiles) {
|
|
10495
10802
|
const destPath = join61(destDir, sf.relativePath);
|
|
10496
|
-
await mkdirp(
|
|
10803
|
+
await mkdirp(dirname23(destPath));
|
|
10497
10804
|
await copyFile3(sf.absolutePath, destPath);
|
|
10498
10805
|
}
|
|
10499
10806
|
}
|
|
@@ -10620,7 +10927,7 @@ function applySelection(canonical, selected) {
|
|
|
10620
10927
|
return {
|
|
10621
10928
|
...canonical,
|
|
10622
10929
|
skills: canonical.skills.filter((s) => skillSet.has(s.name)),
|
|
10623
|
-
rules: canonical.rules.filter((r) => ruleSlugSet.has(
|
|
10930
|
+
rules: canonical.rules.filter((r) => ruleSlugSet.has(ruleSlug6(r))),
|
|
10624
10931
|
commands: canonical.commands.filter((c2) => cmdSet.has(c2.name)),
|
|
10625
10932
|
agents: canonical.agents.filter((a) => agentSet.has(a.name))
|
|
10626
10933
|
};
|
|
@@ -10892,7 +11199,7 @@ function narrowDiscoveredForInstallScope(canonical, options) {
|
|
|
10892
11199
|
const w = new Set(implicitPick.rules);
|
|
10893
11200
|
next = {
|
|
10894
11201
|
...next,
|
|
10895
|
-
rules: implicitPick.rules.length === 0 ? [] : next.rules.filter((r) => w.has(
|
|
11202
|
+
rules: implicitPick.rules.length === 0 ? [] : next.rules.filter((r) => w.has(ruleSlug6(r)))
|
|
10896
11203
|
};
|
|
10897
11204
|
} else if (scopedFeatures && !allowed.has("rules")) {
|
|
10898
11205
|
next = { ...next, rules: [] };
|
|
@@ -10919,9 +11226,66 @@ function narrowDiscoveredForInstallScope(canonical, options) {
|
|
|
10919
11226
|
}
|
|
10920
11227
|
|
|
10921
11228
|
// src/install/manual-install-scope.ts
|
|
10922
|
-
import { basename as basename41, dirname as
|
|
10923
|
-
import { cp, mkdtemp, stat as stat5, rm as rm7 } from "fs/promises";
|
|
11229
|
+
import { basename as basename41, dirname as dirname24, join as join65, relative as relative22 } from "path";
|
|
11230
|
+
import { cp as cp2, mkdtemp, stat as stat5, rm as rm7 } from "fs/promises";
|
|
10924
11231
|
import { tmpdir } from "os";
|
|
11232
|
+
|
|
11233
|
+
// src/install/skill-repo-filter.ts
|
|
11234
|
+
import { relative as relative21 } from "path";
|
|
11235
|
+
import { cp } from "fs/promises";
|
|
11236
|
+
init_markdown();
|
|
11237
|
+
var REPO_BOILERPLATE_FILES = /* @__PURE__ */ new Set([
|
|
11238
|
+
"README.md",
|
|
11239
|
+
"README.rst",
|
|
11240
|
+
"README.txt",
|
|
11241
|
+
"README",
|
|
11242
|
+
"LICENSE",
|
|
11243
|
+
"LICENSE.md",
|
|
11244
|
+
"LICENSE.txt",
|
|
11245
|
+
"LICENSE-MIT",
|
|
11246
|
+
"LICENSE-APACHE",
|
|
11247
|
+
"CONTRIBUTING.md",
|
|
11248
|
+
"CHANGELOG.md",
|
|
11249
|
+
"CODE_OF_CONDUCT.md",
|
|
11250
|
+
"package.json",
|
|
11251
|
+
"package-lock.json",
|
|
11252
|
+
"pnpm-lock.yaml",
|
|
11253
|
+
"yarn.lock",
|
|
11254
|
+
".gitignore",
|
|
11255
|
+
".gitattributes",
|
|
11256
|
+
".editorconfig",
|
|
11257
|
+
".DS_Store"
|
|
11258
|
+
]);
|
|
11259
|
+
var REPO_BOILERPLATE_DIRS = /* @__PURE__ */ new Set([
|
|
11260
|
+
".git",
|
|
11261
|
+
".github",
|
|
11262
|
+
".gitlab",
|
|
11263
|
+
"node_modules",
|
|
11264
|
+
".vscode",
|
|
11265
|
+
".idea"
|
|
11266
|
+
]);
|
|
11267
|
+
async function readSkillFrontmatterName(skillMdPath) {
|
|
11268
|
+
const content = await readFileSafe(skillMdPath);
|
|
11269
|
+
if (!content) return "";
|
|
11270
|
+
const { frontmatter } = parseFrontmatter(content);
|
|
11271
|
+
if (typeof frontmatter.name !== "string") return "";
|
|
11272
|
+
return frontmatter.name.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
11273
|
+
}
|
|
11274
|
+
async function cpFilteredSkill(sourceRoot, destDir) {
|
|
11275
|
+
await cp(sourceRoot, destDir, {
|
|
11276
|
+
recursive: true,
|
|
11277
|
+
filter: (src) => {
|
|
11278
|
+
const rel2 = relative21(sourceRoot, src).replace(/\\/g, "/");
|
|
11279
|
+
if (rel2 === "") return true;
|
|
11280
|
+
const first = rel2.split("/")[0];
|
|
11281
|
+
if (REPO_BOILERPLATE_DIRS.has(first)) return false;
|
|
11282
|
+
if (!rel2.includes("/") && REPO_BOILERPLATE_FILES.has(rel2)) return false;
|
|
11283
|
+
return true;
|
|
11284
|
+
}
|
|
11285
|
+
});
|
|
11286
|
+
}
|
|
11287
|
+
|
|
11288
|
+
// src/install/manual-install-scope.ts
|
|
10925
11289
|
async function createStageRoot() {
|
|
10926
11290
|
const stageBase = await mkdtemp(join65(tmpdir(), "am-install-manual-"));
|
|
10927
11291
|
const discoveryRoot = join65(stageBase, "repo");
|
|
@@ -10940,7 +11304,7 @@ async function stageMarkdownCollection(sourceRoot, destinationDir) {
|
|
|
10940
11304
|
throw new Error(`Manual install only supports .md files for this collection: ${sourceRoot}`);
|
|
10941
11305
|
}
|
|
10942
11306
|
await mkdirp(destinationDir);
|
|
10943
|
-
await
|
|
11307
|
+
await cp2(sourceRoot, join65(destinationDir, basename41(sourceRoot)));
|
|
10944
11308
|
return;
|
|
10945
11309
|
}
|
|
10946
11310
|
const files = (await readDirRecursive(sourceRoot)).filter(
|
|
@@ -10960,7 +11324,7 @@ async function stageMarkdownCollection(sourceRoot, destinationDir) {
|
|
|
10960
11324
|
);
|
|
10961
11325
|
}
|
|
10962
11326
|
usedNames.set(name, file);
|
|
10963
|
-
await
|
|
11327
|
+
await cp2(file, join65(destinationDir, name));
|
|
10964
11328
|
}
|
|
10965
11329
|
}
|
|
10966
11330
|
async function stagePreferredSkills(sourceRoot, destinationDir, preferredSkillNames) {
|
|
@@ -10971,7 +11335,7 @@ async function stagePreferredSkills(sourceRoot, destinationDir, preferredSkillNa
|
|
|
10971
11335
|
const matches = /* @__PURE__ */ new Map();
|
|
10972
11336
|
for (const file of await readDirRecursive(sourceRoot)) {
|
|
10973
11337
|
if (!file.endsWith("/SKILL.md") && !file.endsWith("\\SKILL.md")) continue;
|
|
10974
|
-
const skillDir =
|
|
11338
|
+
const skillDir = dirname24(file);
|
|
10975
11339
|
const skillName = basename41(skillDir);
|
|
10976
11340
|
if (!wanted.has(skillName)) continue;
|
|
10977
11341
|
const previous = matches.get(skillName);
|
|
@@ -10985,7 +11349,7 @@ async function stagePreferredSkills(sourceRoot, destinationDir, preferredSkillNa
|
|
|
10985
11349
|
if (matches.size !== preferredSkillNames.length) return false;
|
|
10986
11350
|
await mkdirp(destinationDir);
|
|
10987
11351
|
for (const skillName of preferredSkillNames) {
|
|
10988
|
-
await
|
|
11352
|
+
await cp2(matches.get(skillName), join65(destinationDir, skillName), { recursive: true });
|
|
10989
11353
|
}
|
|
10990
11354
|
return true;
|
|
10991
11355
|
}
|
|
@@ -10995,10 +11359,10 @@ async function stageSkills(sourceRoot, destinationDir, options = {}) {
|
|
|
10995
11359
|
if (basename41(sourceRoot) !== "SKILL.md") {
|
|
10996
11360
|
throw new Error(`Manual skill install expects SKILL.md or a skill directory: ${sourceRoot}`);
|
|
10997
11361
|
}
|
|
10998
|
-
const skillName = basename41(
|
|
11362
|
+
const skillName = basename41(dirname24(sourceRoot));
|
|
10999
11363
|
const skillDir = join65(destinationDir, skillName);
|
|
11000
11364
|
await mkdirp(skillDir);
|
|
11001
|
-
await
|
|
11365
|
+
await cp2(dirname24(sourceRoot), skillDir, { recursive: true });
|
|
11002
11366
|
return;
|
|
11003
11367
|
}
|
|
11004
11368
|
if (await isSkillPackLayout(sourceRoot)) {
|
|
@@ -11006,9 +11370,11 @@ async function stageSkills(sourceRoot, destinationDir, options = {}) {
|
|
|
11006
11370
|
if (await stagePreferredSkills(sourceRoot, destinationDir, options.preferredSkillNames ?? [])) {
|
|
11007
11371
|
return;
|
|
11008
11372
|
}
|
|
11009
|
-
const
|
|
11373
|
+
const fmName = await readSkillFrontmatterName(join65(sourceRoot, "SKILL.md"));
|
|
11374
|
+
const skillName = fmName || basename41(sourceRoot);
|
|
11375
|
+
const skillDir = join65(destinationDir, skillName);
|
|
11010
11376
|
await mkdirp(destinationDir);
|
|
11011
|
-
await
|
|
11377
|
+
await cpFilteredSkill(sourceRoot, skillDir);
|
|
11012
11378
|
return;
|
|
11013
11379
|
}
|
|
11014
11380
|
if (await stagePreferredSkills(sourceRoot, destinationDir, options.preferredSkillNames ?? [])) {
|
|
@@ -11020,10 +11386,10 @@ async function stageSkills(sourceRoot, destinationDir, options = {}) {
|
|
|
11020
11386
|
for (const file of entries.filter(
|
|
11021
11387
|
(entry) => entry.endsWith("/SKILL.md") || entry.endsWith("\\SKILL.md")
|
|
11022
11388
|
)) {
|
|
11023
|
-
roots.add(
|
|
11389
|
+
roots.add(relative22(sourceRoot, dirname24(file)).split(/[\\/]/)[0]);
|
|
11024
11390
|
}
|
|
11025
11391
|
for (const root of roots) {
|
|
11026
|
-
await
|
|
11392
|
+
await cp2(join65(sourceRoot, root), join65(destinationDir, root), { recursive: true });
|
|
11027
11393
|
}
|
|
11028
11394
|
return;
|
|
11029
11395
|
}
|
|
@@ -11132,7 +11498,7 @@ function extendPickHasArrays(p) {
|
|
|
11132
11498
|
import { basename as basename44, join as join68 } from "path";
|
|
11133
11499
|
|
|
11134
11500
|
// src/install/gemini-install-commands.ts
|
|
11135
|
-
import { join as join66, relative as
|
|
11501
|
+
import { join as join66, relative as relative23 } from "path";
|
|
11136
11502
|
async function inferGeminiCommandNamesFromFiles(repoRoot, pathInRepoPosix) {
|
|
11137
11503
|
const commandsRoot = join66(repoRoot, ...GEMINI_COMMANDS_DIR.split("/"));
|
|
11138
11504
|
const scanDir = join66(repoRoot, ...pathInRepoPosix.split("/"));
|
|
@@ -11140,7 +11506,7 @@ async function inferGeminiCommandNamesFromFiles(repoRoot, pathInRepoPosix) {
|
|
|
11140
11506
|
const names = [];
|
|
11141
11507
|
for (const f of files) {
|
|
11142
11508
|
if (!/\.(toml|md)$/i.test(f)) continue;
|
|
11143
|
-
const rel2 =
|
|
11509
|
+
const rel2 = relative23(commandsRoot, f).replace(/\\/g, "/");
|
|
11144
11510
|
if (rel2.startsWith("..") || rel2 === "") continue;
|
|
11145
11511
|
const noExt = rel2.replace(/\.(toml|md)$/i, "");
|
|
11146
11512
|
const name = noExt.split("/").filter(Boolean).join(":");
|
|
@@ -11150,16 +11516,16 @@ async function inferGeminiCommandNamesFromFiles(repoRoot, pathInRepoPosix) {
|
|
|
11150
11516
|
}
|
|
11151
11517
|
|
|
11152
11518
|
// src/install/native-skill-scan.ts
|
|
11153
|
-
import { basename as basename42, dirname as
|
|
11519
|
+
import { basename as basename42, dirname as dirname25, relative as relative24 } from "path";
|
|
11154
11520
|
async function skillNamesFromNativeSkillDir(scanRoot) {
|
|
11155
11521
|
const files = await readDirRecursive(scanRoot);
|
|
11156
11522
|
const names = /* @__PURE__ */ new Set();
|
|
11157
11523
|
for (const f of files) {
|
|
11158
11524
|
if (basename42(f) === "SKILL.md") {
|
|
11159
|
-
names.add(basename42(
|
|
11525
|
+
names.add(basename42(dirname25(f)));
|
|
11160
11526
|
continue;
|
|
11161
11527
|
}
|
|
11162
|
-
const rel2 =
|
|
11528
|
+
const rel2 = relative24(scanRoot, f).replace(/\\/g, "/");
|
|
11163
11529
|
if (!rel2.includes("/") && f.toLowerCase().endsWith(".md")) {
|
|
11164
11530
|
names.add(basename42(f, ".md"));
|
|
11165
11531
|
}
|
|
@@ -11342,8 +11708,8 @@ function isImplicitPickEmpty(p) {
|
|
|
11342
11708
|
}
|
|
11343
11709
|
|
|
11344
11710
|
// src/install/native-install-scope.ts
|
|
11345
|
-
import { basename as basename45, join as join69, relative as
|
|
11346
|
-
import { cp as
|
|
11711
|
+
import { basename as basename45, join as join69, relative as relative25 } from "path";
|
|
11712
|
+
import { cp as cp3, mkdtemp as mkdtemp2, rm as rm8 } from "fs/promises";
|
|
11347
11713
|
import { tmpdir as tmpdir2 } from "os";
|
|
11348
11714
|
function normalizePath3(path) {
|
|
11349
11715
|
return path.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
@@ -11365,7 +11731,7 @@ async function makeStageRoot(repoRoot) {
|
|
|
11365
11731
|
await rm8(stageBase, { recursive: true, force: true });
|
|
11366
11732
|
};
|
|
11367
11733
|
try {
|
|
11368
|
-
await
|
|
11734
|
+
await cp3(repoRoot, stageRoot, { recursive: true });
|
|
11369
11735
|
return { stageRoot, cleanup };
|
|
11370
11736
|
} catch (error) {
|
|
11371
11737
|
await cleanup();
|
|
@@ -11398,7 +11764,7 @@ function buildPickFromResults(results, stageRoot) {
|
|
|
11398
11764
|
}
|
|
11399
11765
|
if (result.feature === "skills" && result.toPath.startsWith(".agentsmesh/skills/")) {
|
|
11400
11766
|
const rel2 = normalizePath3(
|
|
11401
|
-
|
|
11767
|
+
relative25(join69(stageRoot, ".agentsmesh", "skills"), join69(stageRoot, result.toPath))
|
|
11402
11768
|
);
|
|
11403
11769
|
const skillName = rel2.split("/")[0];
|
|
11404
11770
|
if (skillName) {
|
|
@@ -11586,7 +11952,7 @@ function applyReplayInstallScope(narrowed, discoveredFeatures, replay) {
|
|
|
11586
11952
|
}
|
|
11587
11953
|
|
|
11588
11954
|
// src/install/manual-install-persistence.ts
|
|
11589
|
-
import { basename as basename46, dirname as
|
|
11955
|
+
import { basename as basename46, dirname as dirname26, join as join71 } from "path";
|
|
11590
11956
|
import { stat as stat6 } from "fs/promises";
|
|
11591
11957
|
function trimDot(pathInRepo) {
|
|
11592
11958
|
return pathInRepo === "." || pathInRepo === "" ? void 0 : pathInRepo;
|
|
@@ -11605,27 +11971,28 @@ async function resolveManualInstallPersistence(args) {
|
|
|
11605
11971
|
const info = await stat6(args.contentRoot);
|
|
11606
11972
|
if (args.as !== "skills" && info.isFile() && args.contentRoot.toLowerCase().endsWith(".md")) {
|
|
11607
11973
|
return {
|
|
11608
|
-
pathInRepo: trimDot(
|
|
11974
|
+
pathInRepo: trimDot(dirname26(normalizedPath)),
|
|
11609
11975
|
pick: markdownPick(args.as, normalizedPath || args.contentRoot)
|
|
11610
11976
|
};
|
|
11611
11977
|
}
|
|
11612
11978
|
if (args.as === "skills") {
|
|
11613
11979
|
if (info.isFile() && basename46(args.contentRoot) === "SKILL.md") {
|
|
11614
|
-
const skillDir = normalizedPath ?
|
|
11980
|
+
const skillDir = normalizedPath ? dirname26(normalizedPath) : dirname26(args.contentRoot);
|
|
11615
11981
|
return {
|
|
11616
|
-
pathInRepo: trimDot(
|
|
11982
|
+
pathInRepo: trimDot(dirname26(skillDir)),
|
|
11617
11983
|
pick: { skills: [basename46(skillDir)] }
|
|
11618
11984
|
};
|
|
11619
11985
|
}
|
|
11620
11986
|
if (info.isDirectory()) {
|
|
11621
11987
|
const skillDir = normalizedPath || basename46(args.contentRoot);
|
|
11622
|
-
const skillFile =
|
|
11988
|
+
const skillFile = join71(args.contentRoot.replace(/\/+$/g, ""), "SKILL.md");
|
|
11623
11989
|
try {
|
|
11624
11990
|
const skillStat = await stat6(skillFile);
|
|
11625
11991
|
if (skillStat.isFile()) {
|
|
11992
|
+
const fmName = await readSkillFrontmatterName(skillFile);
|
|
11626
11993
|
return {
|
|
11627
|
-
pathInRepo: trimDot(
|
|
11628
|
-
pick: { skills: [basename46(skillDir)] }
|
|
11994
|
+
pathInRepo: trimDot(dirname26(skillDir)),
|
|
11995
|
+
pick: { skills: [fmName || basename46(skillDir)] }
|
|
11629
11996
|
};
|
|
11630
11997
|
}
|
|
11631
11998
|
} catch {
|
|
@@ -11693,7 +12060,7 @@ async function runInstall(flags, args, projectRoot, replay) {
|
|
|
11693
12060
|
sourceArg
|
|
11694
12061
|
);
|
|
11695
12062
|
const pathInRepo = parsed.pathInRepo.replace(/^\/+|\/+$/g, "");
|
|
11696
|
-
const contentRoot = pathInRepo ?
|
|
12063
|
+
const contentRoot = pathInRepo ? join72(resolvedPath, pathInRepo) : resolvedPath;
|
|
11697
12064
|
if (!await exists(contentRoot)) {
|
|
11698
12065
|
throw new Error(`Install path does not exist: ${contentRoot}`);
|
|
11699
12066
|
}
|
|
@@ -11735,7 +12102,7 @@ async function runInstall(flags, args, projectRoot, replay) {
|
|
|
11735
12102
|
agents: agentsPool
|
|
11736
12103
|
}) : {
|
|
11737
12104
|
skillNames: skillsPool.map((s) => s.name),
|
|
11738
|
-
ruleSlugs: rulesPool.map((r) =>
|
|
12105
|
+
ruleSlugs: rulesPool.map((r) => ruleSlug6(r)),
|
|
11739
12106
|
commandNames: commandsPool.map((c2) => c2.name),
|
|
11740
12107
|
agentNames: agentsPool.map((a) => a.name)
|
|
11741
12108
|
};
|