agentsmesh 0.2.8 → 0.2.9
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 +6 -0
- package/README.md +11 -11
- package/dist/cli.js +769 -410
- package/dist/cli.js.map +1 -1
- package/package.json +3 -2
package/dist/cli.js
CHANGED
|
@@ -247,7 +247,7 @@ function handleError(err, options) {
|
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
// src/cli/commands/generate.ts
|
|
250
|
-
import { join as
|
|
250
|
+
import { join as join55, resolve as resolve4, sep } from "path";
|
|
251
251
|
|
|
252
252
|
// src/config/core/loader.ts
|
|
253
253
|
import { parse as parseYaml } from "yaml";
|
|
@@ -359,7 +359,8 @@ var TARGET_IDS = [
|
|
|
359
359
|
"cline",
|
|
360
360
|
"codex-cli",
|
|
361
361
|
"windsurf",
|
|
362
|
-
"antigravity"
|
|
362
|
+
"antigravity",
|
|
363
|
+
"roo-code"
|
|
363
364
|
];
|
|
364
365
|
function isBuiltinTargetId(value) {
|
|
365
366
|
return TARGET_IDS.includes(value);
|
|
@@ -524,7 +525,7 @@ async function loadConfigFromDir(startDir) {
|
|
|
524
525
|
}
|
|
525
526
|
|
|
526
527
|
// src/canonical/extends/extends.ts
|
|
527
|
-
import { join as
|
|
528
|
+
import { join as join47 } from "path";
|
|
528
529
|
|
|
529
530
|
// src/config/resolve/resolver.ts
|
|
530
531
|
import { mkdir as mkdir4, rm as rm4 } from "fs/promises";
|
|
@@ -1464,7 +1465,7 @@ function mergeIgnore(base, overlay) {
|
|
|
1464
1465
|
}
|
|
1465
1466
|
|
|
1466
1467
|
// src/canonical/extends/extend-load.ts
|
|
1467
|
-
import { join as
|
|
1468
|
+
import { join as join44 } from "path";
|
|
1468
1469
|
|
|
1469
1470
|
// src/config/resolve/native-format-detector.ts
|
|
1470
1471
|
import { join as join10 } from "path";
|
|
@@ -1542,11 +1543,11 @@ var KNOWN_NATIVE_PATHS = TARGET_SIGNATURES.map((sig) => sig.paths[0]).filter(
|
|
|
1542
1543
|
);
|
|
1543
1544
|
|
|
1544
1545
|
// src/targets/claude-code/importer.ts
|
|
1545
|
-
import { join as
|
|
1546
|
+
import { join as join41, basename as basename26, relative as relative17, dirname as dirname18 } from "path";
|
|
1546
1547
|
|
|
1547
1548
|
// src/core/reference/import-rewriter.ts
|
|
1548
1549
|
import { existsSync as existsSync2, realpathSync as realpathSync3 } from "fs";
|
|
1549
|
-
import { join as
|
|
1550
|
+
import { join as join38 } from "path";
|
|
1550
1551
|
import { normalize as normalizePath } from "path";
|
|
1551
1552
|
|
|
1552
1553
|
// src/config/core/conversions.ts
|
|
@@ -1561,22 +1562,22 @@ var DEFAULT_AGENTS_TO_SKILLS = {
|
|
|
1561
1562
|
// native .codex/agents/*.toml per agent-structures
|
|
1562
1563
|
windsurf: true
|
|
1563
1564
|
};
|
|
1564
|
-
function hasOwnTarget(map,
|
|
1565
|
-
return Object.prototype.hasOwnProperty.call(map,
|
|
1565
|
+
function hasOwnTarget(map, target12) {
|
|
1566
|
+
return Object.prototype.hasOwnProperty.call(map, target12);
|
|
1566
1567
|
}
|
|
1567
|
-
function usesCommandSkillProjection(
|
|
1568
|
-
return hasOwnTarget(DEFAULT_COMMANDS_TO_SKILLS,
|
|
1568
|
+
function usesCommandSkillProjection(target12) {
|
|
1569
|
+
return hasOwnTarget(DEFAULT_COMMANDS_TO_SKILLS, target12);
|
|
1569
1570
|
}
|
|
1570
|
-
function usesAgentSkillProjection(
|
|
1571
|
-
return hasOwnTarget(DEFAULT_AGENTS_TO_SKILLS,
|
|
1571
|
+
function usesAgentSkillProjection(target12) {
|
|
1572
|
+
return hasOwnTarget(DEFAULT_AGENTS_TO_SKILLS, target12);
|
|
1572
1573
|
}
|
|
1573
|
-
function shouldConvertCommandsToSkills(config,
|
|
1574
|
-
if (!usesCommandSkillProjection(
|
|
1575
|
-
return config.conversions?.commands_to_skills?.[
|
|
1574
|
+
function shouldConvertCommandsToSkills(config, target12) {
|
|
1575
|
+
if (!usesCommandSkillProjection(target12)) return false;
|
|
1576
|
+
return config.conversions?.commands_to_skills?.[target12] ?? DEFAULT_COMMANDS_TO_SKILLS[target12];
|
|
1576
1577
|
}
|
|
1577
|
-
function shouldConvertAgentsToSkills(config,
|
|
1578
|
-
if (!usesAgentSkillProjection(
|
|
1579
|
-
return config.conversions?.agents_to_skills?.[
|
|
1578
|
+
function shouldConvertAgentsToSkills(config, target12) {
|
|
1579
|
+
if (!usesAgentSkillProjection(target12)) return false;
|
|
1580
|
+
return config.conversions?.agents_to_skills?.[target12] ?? DEFAULT_AGENTS_TO_SKILLS[target12];
|
|
1580
1581
|
}
|
|
1581
1582
|
|
|
1582
1583
|
// src/targets/claude-code/constants.ts
|
|
@@ -1873,6 +1874,22 @@ var JUNIE_CANONICAL_AGENTS_DIR = ".agentsmesh/agents";
|
|
|
1873
1874
|
var JUNIE_CANONICAL_MCP = ".agentsmesh/mcp.json";
|
|
1874
1875
|
var JUNIE_CANONICAL_IGNORE = ".agentsmesh/ignore";
|
|
1875
1876
|
|
|
1877
|
+
// src/targets/roo-code/constants.ts
|
|
1878
|
+
var ROO_CODE_TARGET = "roo-code";
|
|
1879
|
+
var ROO_CODE_DIR = ".roo";
|
|
1880
|
+
var ROO_CODE_ROOT_RULE = `${ROO_CODE_DIR}/rules/00-root.md`;
|
|
1881
|
+
var ROO_CODE_ROOT_RULE_FALLBACK = ".roorules";
|
|
1882
|
+
var ROO_CODE_RULES_DIR = `${ROO_CODE_DIR}/rules`;
|
|
1883
|
+
var ROO_CODE_COMMANDS_DIR = `${ROO_CODE_DIR}/commands`;
|
|
1884
|
+
var ROO_CODE_SKILLS_DIR = `${ROO_CODE_DIR}/skills`;
|
|
1885
|
+
var ROO_CODE_MCP_FILE = `${ROO_CODE_DIR}/mcp.json`;
|
|
1886
|
+
var ROO_CODE_IGNORE = ".rooignore";
|
|
1887
|
+
var ROO_CODE_CANONICAL_ROOT_RULE = ".agentsmesh/rules/_root.md";
|
|
1888
|
+
var ROO_CODE_CANONICAL_RULES_DIR = ".agentsmesh/rules";
|
|
1889
|
+
var ROO_CODE_CANONICAL_COMMANDS_DIR = ".agentsmesh/commands";
|
|
1890
|
+
var ROO_CODE_CANONICAL_MCP = ".agentsmesh/mcp.json";
|
|
1891
|
+
var ROO_CODE_CANONICAL_IGNORE = ".agentsmesh/ignore";
|
|
1892
|
+
|
|
1876
1893
|
// src/targets/antigravity/constants.ts
|
|
1877
1894
|
var ANTIGRAVITY_TARGET = "antigravity";
|
|
1878
1895
|
var ANTIGRAVITY_DIR = ".agents";
|
|
@@ -2107,7 +2124,8 @@ var SCOPED_AGENTS_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
|
2107
2124
|
".gemini",
|
|
2108
2125
|
".github",
|
|
2109
2126
|
".junie",
|
|
2110
|
-
".windsurf"
|
|
2127
|
+
".windsurf",
|
|
2128
|
+
".roo"
|
|
2111
2129
|
]);
|
|
2112
2130
|
async function addScopedAgentsMappings(refs, projectRoot) {
|
|
2113
2131
|
const files = await listFiles(projectRoot, ".");
|
|
@@ -2303,6 +2321,27 @@ async function buildAntigravityImportPaths(refs, projectRoot) {
|
|
|
2303
2321
|
addSkillLikeMapping(refs, rel(projectRoot, absPath), ANTIGRAVITY_SKILLS_DIR);
|
|
2304
2322
|
}
|
|
2305
2323
|
}
|
|
2324
|
+
async function buildRooCodeImportPaths(refs, projectRoot) {
|
|
2325
|
+
refs.set(ROO_CODE_ROOT_RULE, `${AB_RULES2}/_root.md`);
|
|
2326
|
+
refs.set(ROO_CODE_ROOT_RULE_FALLBACK, `${AB_RULES2}/_root.md`);
|
|
2327
|
+
for (const absPath of await listFiles(projectRoot, ROO_CODE_RULES_DIR)) {
|
|
2328
|
+
const relPath = rel(projectRoot, absPath);
|
|
2329
|
+
if (relPath === ROO_CODE_ROOT_RULE) continue;
|
|
2330
|
+
addSimpleFileMapping(refs, relPath, AB_RULES2, ".md");
|
|
2331
|
+
}
|
|
2332
|
+
for (const absPath of await listFiles(projectRoot, ".roo")) {
|
|
2333
|
+
const relPath = rel(projectRoot, absPath);
|
|
2334
|
+
if (/^\.roo\/rules-[^/]+\/.+\.md$/.test(relPath)) {
|
|
2335
|
+
addSimpleFileMapping(refs, relPath, AB_RULES2, ".md");
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
for (const absPath of await listFiles(projectRoot, ROO_CODE_COMMANDS_DIR)) {
|
|
2339
|
+
addSimpleFileMapping(refs, rel(projectRoot, absPath), AB_COMMANDS2, ".md");
|
|
2340
|
+
}
|
|
2341
|
+
for (const absPath of await listFiles(projectRoot, ROO_CODE_SKILLS_DIR)) {
|
|
2342
|
+
addSkillLikeMapping(refs, rel(projectRoot, absPath), ROO_CODE_SKILLS_DIR);
|
|
2343
|
+
}
|
|
2344
|
+
}
|
|
2306
2345
|
|
|
2307
2346
|
// src/targets/claude-code/index.ts
|
|
2308
2347
|
var target = {
|
|
@@ -5772,7 +5811,7 @@ function summarizeRule(rule) {
|
|
|
5772
5811
|
scopes.push(`Enforced in \`${CODEX_RULES_DIR}/${ruleSlug4(rule.source)}.rules\`.`);
|
|
5773
5812
|
}
|
|
5774
5813
|
if (rule.targets.length > 0) {
|
|
5775
|
-
scopes.push(`Targeted to ${rule.targets.map((
|
|
5814
|
+
scopes.push(`Targeted to ${rule.targets.map((target12) => `\`${target12}\``).join(", ")}.`);
|
|
5776
5815
|
}
|
|
5777
5816
|
return scopes.join(" ");
|
|
5778
5817
|
}
|
|
@@ -7221,6 +7260,323 @@ var descriptor10 = {
|
|
|
7221
7260
|
]
|
|
7222
7261
|
};
|
|
7223
7262
|
|
|
7263
|
+
// src/targets/roo-code/generator.ts
|
|
7264
|
+
import { basename as basename25 } from "path";
|
|
7265
|
+
function generateRules11(canonical) {
|
|
7266
|
+
const outputs = [];
|
|
7267
|
+
const root = canonical.rules.find((rule) => rule.root);
|
|
7268
|
+
if (root) {
|
|
7269
|
+
outputs.push({
|
|
7270
|
+
path: ROO_CODE_ROOT_RULE,
|
|
7271
|
+
content: root.body.trim() || ""
|
|
7272
|
+
});
|
|
7273
|
+
}
|
|
7274
|
+
for (const rule of canonical.rules) {
|
|
7275
|
+
if (rule.root) continue;
|
|
7276
|
+
if (rule.targets.length > 0 && !rule.targets.includes(ROO_CODE_TARGET)) continue;
|
|
7277
|
+
const slug = basename25(rule.source, ".md");
|
|
7278
|
+
outputs.push({
|
|
7279
|
+
path: `${ROO_CODE_RULES_DIR}/${slug}.md`,
|
|
7280
|
+
content: rule.body.trim() || ""
|
|
7281
|
+
});
|
|
7282
|
+
}
|
|
7283
|
+
return outputs;
|
|
7284
|
+
}
|
|
7285
|
+
function generateCommands8(canonical) {
|
|
7286
|
+
return canonical.commands.map((command) => {
|
|
7287
|
+
const frontmatter = {};
|
|
7288
|
+
if (command.description) frontmatter.description = command.description;
|
|
7289
|
+
return {
|
|
7290
|
+
path: `${ROO_CODE_COMMANDS_DIR}/${command.name}.md`,
|
|
7291
|
+
content: serializeFrontmatter(frontmatter, command.body.trim() || "")
|
|
7292
|
+
};
|
|
7293
|
+
});
|
|
7294
|
+
}
|
|
7295
|
+
function generateMcp8(canonical) {
|
|
7296
|
+
if (!canonical.mcp || Object.keys(canonical.mcp.mcpServers).length === 0) return [];
|
|
7297
|
+
return [
|
|
7298
|
+
{
|
|
7299
|
+
path: ROO_CODE_MCP_FILE,
|
|
7300
|
+
content: JSON.stringify({ mcpServers: canonical.mcp.mcpServers }, null, 2)
|
|
7301
|
+
}
|
|
7302
|
+
];
|
|
7303
|
+
}
|
|
7304
|
+
function generateIgnore7(canonical) {
|
|
7305
|
+
if (canonical.ignore.length === 0) return [];
|
|
7306
|
+
return [{ path: ROO_CODE_IGNORE, content: canonical.ignore.join("\n") }];
|
|
7307
|
+
}
|
|
7308
|
+
function generateSkills11(canonical) {
|
|
7309
|
+
return generateEmbeddedSkills(canonical, ROO_CODE_SKILLS_DIR);
|
|
7310
|
+
}
|
|
7311
|
+
|
|
7312
|
+
// src/targets/roo-code/importer.ts
|
|
7313
|
+
import { readdir as readdir9 } from "fs/promises";
|
|
7314
|
+
import { join as join37 } from "path";
|
|
7315
|
+
function readMcpServers3(content) {
|
|
7316
|
+
const parsed = JSON.parse(content);
|
|
7317
|
+
const rawServers = parsed.mcpServers;
|
|
7318
|
+
if (!rawServers || typeof rawServers !== "object" || Array.isArray(rawServers)) return {};
|
|
7319
|
+
const servers = {};
|
|
7320
|
+
for (const [name, value] of Object.entries(rawServers)) {
|
|
7321
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
7322
|
+
const server = value;
|
|
7323
|
+
if (typeof server.command === "string") {
|
|
7324
|
+
servers[name] = {
|
|
7325
|
+
type: typeof server.type === "string" ? server.type : "stdio",
|
|
7326
|
+
command: server.command,
|
|
7327
|
+
args: toStringArray4(server.args),
|
|
7328
|
+
env: toStringRecord(server.env),
|
|
7329
|
+
description: typeof server.description === "string" ? server.description : void 0
|
|
7330
|
+
};
|
|
7331
|
+
continue;
|
|
7332
|
+
}
|
|
7333
|
+
if (typeof server.url === "string") {
|
|
7334
|
+
servers[name] = {
|
|
7335
|
+
type: typeof server.type === "string" ? server.type : "http",
|
|
7336
|
+
url: server.url,
|
|
7337
|
+
headers: toStringRecord(server.headers),
|
|
7338
|
+
env: toStringRecord(server.env),
|
|
7339
|
+
description: typeof server.description === "string" ? server.description : void 0
|
|
7340
|
+
};
|
|
7341
|
+
}
|
|
7342
|
+
}
|
|
7343
|
+
return servers;
|
|
7344
|
+
}
|
|
7345
|
+
async function importRootRule2(projectRoot, results, normalize) {
|
|
7346
|
+
const destPath = join37(projectRoot, ROO_CODE_CANONICAL_ROOT_RULE);
|
|
7347
|
+
const sources = [ROO_CODE_ROOT_RULE, ROO_CODE_ROOT_RULE_FALLBACK];
|
|
7348
|
+
for (const relPath of sources) {
|
|
7349
|
+
const srcPath = join37(projectRoot, relPath);
|
|
7350
|
+
const content = await readFileSafe(srcPath);
|
|
7351
|
+
if (content === null) continue;
|
|
7352
|
+
const { frontmatter, body } = parseFrontmatter(normalize(content, srcPath, destPath));
|
|
7353
|
+
const output = await serializeImportedRuleWithFallback(
|
|
7354
|
+
destPath,
|
|
7355
|
+
{
|
|
7356
|
+
root: true,
|
|
7357
|
+
description: typeof frontmatter.description === "string" ? frontmatter.description : void 0,
|
|
7358
|
+
globs: Array.isArray(frontmatter.globs) ? frontmatter.globs : void 0
|
|
7359
|
+
},
|
|
7360
|
+
body
|
|
7361
|
+
);
|
|
7362
|
+
await writeFileAtomic(destPath, output);
|
|
7363
|
+
results.push({
|
|
7364
|
+
fromTool: ROO_CODE_TARGET,
|
|
7365
|
+
fromPath: srcPath,
|
|
7366
|
+
toPath: ROO_CODE_CANONICAL_ROOT_RULE,
|
|
7367
|
+
feature: "rules"
|
|
7368
|
+
});
|
|
7369
|
+
return;
|
|
7370
|
+
}
|
|
7371
|
+
}
|
|
7372
|
+
async function importNonRootRules3(projectRoot, results, normalize) {
|
|
7373
|
+
const srcDir = join37(projectRoot, ROO_CODE_RULES_DIR);
|
|
7374
|
+
const destDir = join37(projectRoot, ROO_CODE_CANONICAL_RULES_DIR);
|
|
7375
|
+
const rootRuleName = "00-root.md";
|
|
7376
|
+
results.push(
|
|
7377
|
+
...await importFileDirectory({
|
|
7378
|
+
srcDir,
|
|
7379
|
+
destDir,
|
|
7380
|
+
extensions: [".md"],
|
|
7381
|
+
fromTool: ROO_CODE_TARGET,
|
|
7382
|
+
normalize,
|
|
7383
|
+
mapEntry: async ({ relativePath, normalizeTo }) => {
|
|
7384
|
+
if (relativePath === rootRuleName) return null;
|
|
7385
|
+
const destPath = join37(destDir, relativePath);
|
|
7386
|
+
const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
|
|
7387
|
+
const output = await serializeImportedRuleWithFallback(
|
|
7388
|
+
destPath,
|
|
7389
|
+
{
|
|
7390
|
+
root: false,
|
|
7391
|
+
description: typeof frontmatter.description === "string" ? frontmatter.description : void 0,
|
|
7392
|
+
globs: Array.isArray(frontmatter.globs) ? frontmatter.globs : void 0
|
|
7393
|
+
},
|
|
7394
|
+
body
|
|
7395
|
+
);
|
|
7396
|
+
return {
|
|
7397
|
+
destPath,
|
|
7398
|
+
toPath: `${ROO_CODE_CANONICAL_RULES_DIR}/${relativePath}`,
|
|
7399
|
+
feature: "rules",
|
|
7400
|
+
content: output
|
|
7401
|
+
};
|
|
7402
|
+
}
|
|
7403
|
+
})
|
|
7404
|
+
);
|
|
7405
|
+
}
|
|
7406
|
+
async function importPerModeRules(projectRoot, results, normalize) {
|
|
7407
|
+
const rooDir = join37(projectRoot, ROO_CODE_DIR);
|
|
7408
|
+
let entries;
|
|
7409
|
+
try {
|
|
7410
|
+
entries = await readdir9(rooDir, { withFileTypes: true });
|
|
7411
|
+
} catch {
|
|
7412
|
+
return;
|
|
7413
|
+
}
|
|
7414
|
+
const modeRuleDirs = entries.filter((e) => e.isDirectory() && e.name.startsWith("rules-")).map((e) => e.name);
|
|
7415
|
+
for (const dirName of modeRuleDirs) {
|
|
7416
|
+
const srcDir = join37(rooDir, dirName);
|
|
7417
|
+
const destDir = join37(projectRoot, ROO_CODE_CANONICAL_RULES_DIR);
|
|
7418
|
+
results.push(
|
|
7419
|
+
...await importFileDirectory({
|
|
7420
|
+
srcDir,
|
|
7421
|
+
destDir,
|
|
7422
|
+
extensions: [".md"],
|
|
7423
|
+
fromTool: ROO_CODE_TARGET,
|
|
7424
|
+
normalize,
|
|
7425
|
+
mapEntry: async ({ relativePath, normalizeTo }) => {
|
|
7426
|
+
const destPath = join37(destDir, relativePath);
|
|
7427
|
+
const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
|
|
7428
|
+
const output = await serializeImportedRuleWithFallback(
|
|
7429
|
+
destPath,
|
|
7430
|
+
{
|
|
7431
|
+
root: false,
|
|
7432
|
+
description: typeof frontmatter.description === "string" ? frontmatter.description : void 0,
|
|
7433
|
+
globs: Array.isArray(frontmatter.globs) ? frontmatter.globs : void 0
|
|
7434
|
+
},
|
|
7435
|
+
body
|
|
7436
|
+
);
|
|
7437
|
+
return {
|
|
7438
|
+
destPath,
|
|
7439
|
+
toPath: `${ROO_CODE_CANONICAL_RULES_DIR}/${relativePath}`,
|
|
7440
|
+
feature: "rules",
|
|
7441
|
+
content: output
|
|
7442
|
+
};
|
|
7443
|
+
}
|
|
7444
|
+
})
|
|
7445
|
+
);
|
|
7446
|
+
}
|
|
7447
|
+
}
|
|
7448
|
+
async function importCommands5(projectRoot, results, normalize) {
|
|
7449
|
+
const srcDir = join37(projectRoot, ROO_CODE_COMMANDS_DIR);
|
|
7450
|
+
const destDir = join37(projectRoot, ROO_CODE_CANONICAL_COMMANDS_DIR);
|
|
7451
|
+
results.push(
|
|
7452
|
+
...await importFileDirectory({
|
|
7453
|
+
srcDir,
|
|
7454
|
+
destDir,
|
|
7455
|
+
extensions: [".md"],
|
|
7456
|
+
fromTool: ROO_CODE_TARGET,
|
|
7457
|
+
normalize,
|
|
7458
|
+
mapEntry: async ({ relativePath, normalizeTo }) => {
|
|
7459
|
+
const destPath = join37(destDir, relativePath);
|
|
7460
|
+
const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
|
|
7461
|
+
const output = await serializeImportedCommandWithFallback(
|
|
7462
|
+
destPath,
|
|
7463
|
+
{
|
|
7464
|
+
hasDescription: true,
|
|
7465
|
+
description: typeof frontmatter.description === "string" ? frontmatter.description : void 0,
|
|
7466
|
+
hasAllowedTools: false,
|
|
7467
|
+
allowedTools: []
|
|
7468
|
+
},
|
|
7469
|
+
body
|
|
7470
|
+
);
|
|
7471
|
+
return {
|
|
7472
|
+
destPath,
|
|
7473
|
+
toPath: `${ROO_CODE_CANONICAL_COMMANDS_DIR}/${relativePath}`,
|
|
7474
|
+
feature: "commands",
|
|
7475
|
+
content: output
|
|
7476
|
+
};
|
|
7477
|
+
}
|
|
7478
|
+
})
|
|
7479
|
+
);
|
|
7480
|
+
}
|
|
7481
|
+
async function importMcp6(projectRoot, results) {
|
|
7482
|
+
const srcPath = join37(projectRoot, ROO_CODE_MCP_FILE);
|
|
7483
|
+
const content = await readFileSafe(srcPath);
|
|
7484
|
+
if (content === null) return;
|
|
7485
|
+
const servers = readMcpServers3(content);
|
|
7486
|
+
if (Object.keys(servers).length === 0) return;
|
|
7487
|
+
await writeFileAtomic(
|
|
7488
|
+
join37(projectRoot, ROO_CODE_CANONICAL_MCP),
|
|
7489
|
+
JSON.stringify({ mcpServers: servers }, null, 2)
|
|
7490
|
+
);
|
|
7491
|
+
results.push({
|
|
7492
|
+
fromTool: ROO_CODE_TARGET,
|
|
7493
|
+
fromPath: srcPath,
|
|
7494
|
+
toPath: ROO_CODE_CANONICAL_MCP,
|
|
7495
|
+
feature: "mcp"
|
|
7496
|
+
});
|
|
7497
|
+
}
|
|
7498
|
+
async function importIgnore3(projectRoot, results) {
|
|
7499
|
+
const srcPath = join37(projectRoot, ROO_CODE_IGNORE);
|
|
7500
|
+
const content = await readFileSafe(srcPath);
|
|
7501
|
+
if (content === null) return;
|
|
7502
|
+
await writeFileAtomic(join37(projectRoot, ROO_CODE_CANONICAL_IGNORE), content.trimEnd());
|
|
7503
|
+
results.push({
|
|
7504
|
+
fromTool: ROO_CODE_TARGET,
|
|
7505
|
+
fromPath: srcPath,
|
|
7506
|
+
toPath: ROO_CODE_CANONICAL_IGNORE,
|
|
7507
|
+
feature: "ignore"
|
|
7508
|
+
});
|
|
7509
|
+
}
|
|
7510
|
+
async function importFromRooCode(projectRoot) {
|
|
7511
|
+
const results = [];
|
|
7512
|
+
const normalize = await createImportReferenceNormalizer(ROO_CODE_TARGET, projectRoot);
|
|
7513
|
+
await importRootRule2(projectRoot, results, normalize);
|
|
7514
|
+
await importNonRootRules3(projectRoot, results, normalize);
|
|
7515
|
+
await importPerModeRules(projectRoot, results, normalize);
|
|
7516
|
+
await importCommands5(projectRoot, results, normalize);
|
|
7517
|
+
await importEmbeddedSkills(projectRoot, ROO_CODE_SKILLS_DIR, ROO_CODE_TARGET, results, normalize);
|
|
7518
|
+
await importMcp6(projectRoot, results);
|
|
7519
|
+
await importIgnore3(projectRoot, results);
|
|
7520
|
+
return results;
|
|
7521
|
+
}
|
|
7522
|
+
|
|
7523
|
+
// src/targets/roo-code/linter.ts
|
|
7524
|
+
function lintRules11(canonical, projectRoot, projectFiles) {
|
|
7525
|
+
return validateRules(canonical, projectRoot, projectFiles).map((diagnostic) => ({
|
|
7526
|
+
...diagnostic,
|
|
7527
|
+
target: ROO_CODE_TARGET
|
|
7528
|
+
}));
|
|
7529
|
+
}
|
|
7530
|
+
|
|
7531
|
+
// src/targets/roo-code/index.ts
|
|
7532
|
+
var target11 = {
|
|
7533
|
+
name: "roo-code",
|
|
7534
|
+
primaryRootInstructionPath: ROO_CODE_ROOT_RULE,
|
|
7535
|
+
generateRules: generateRules11,
|
|
7536
|
+
generateCommands: generateCommands8,
|
|
7537
|
+
generateSkills: generateSkills11,
|
|
7538
|
+
generateMcp: generateMcp8,
|
|
7539
|
+
generateIgnore: generateIgnore7,
|
|
7540
|
+
importFrom: importFromRooCode
|
|
7541
|
+
};
|
|
7542
|
+
var descriptor11 = {
|
|
7543
|
+
id: "roo-code",
|
|
7544
|
+
generators: target11,
|
|
7545
|
+
capabilities: {
|
|
7546
|
+
rules: "native",
|
|
7547
|
+
commands: "native",
|
|
7548
|
+
agents: "none",
|
|
7549
|
+
skills: "native",
|
|
7550
|
+
mcp: "native",
|
|
7551
|
+
hooks: "none",
|
|
7552
|
+
ignore: "native",
|
|
7553
|
+
permissions: "none"
|
|
7554
|
+
},
|
|
7555
|
+
emptyImportMessage: "No Roo Code config found (.roo/rules, .roo/commands, .roo/skills, .roo/mcp.json, .rooignore, or .roorules).",
|
|
7556
|
+
lintRules: lintRules11,
|
|
7557
|
+
skillDir: ".roo/skills",
|
|
7558
|
+
paths: {
|
|
7559
|
+
rulePath(slug, _rule) {
|
|
7560
|
+
return `${ROO_CODE_RULES_DIR}/${slug}.md`;
|
|
7561
|
+
},
|
|
7562
|
+
commandPath(name, _config) {
|
|
7563
|
+
return `${ROO_CODE_COMMANDS_DIR}/${name}.md`;
|
|
7564
|
+
},
|
|
7565
|
+
agentPath(_name, _config) {
|
|
7566
|
+
return null;
|
|
7567
|
+
}
|
|
7568
|
+
},
|
|
7569
|
+
buildImportPaths: buildRooCodeImportPaths,
|
|
7570
|
+
detectionPaths: [
|
|
7571
|
+
".roo/rules",
|
|
7572
|
+
".roo/commands",
|
|
7573
|
+
".roo/skills",
|
|
7574
|
+
".roo/mcp.json",
|
|
7575
|
+
".rooignore",
|
|
7576
|
+
".roorules"
|
|
7577
|
+
]
|
|
7578
|
+
};
|
|
7579
|
+
|
|
7224
7580
|
// src/targets/catalog/builtin-targets.ts
|
|
7225
7581
|
var BUILTIN_TARGETS = [
|
|
7226
7582
|
descriptor,
|
|
@@ -7232,39 +7588,40 @@ var BUILTIN_TARGETS = [
|
|
|
7232
7588
|
descriptor7,
|
|
7233
7589
|
descriptor8,
|
|
7234
7590
|
descriptor9,
|
|
7235
|
-
descriptor10
|
|
7591
|
+
descriptor10,
|
|
7592
|
+
descriptor11
|
|
7236
7593
|
];
|
|
7237
|
-
function getBuiltinTargetDefinition(
|
|
7238
|
-
return BUILTIN_TARGETS.find((candidate) => candidate.id ===
|
|
7594
|
+
function getBuiltinTargetDefinition(target12) {
|
|
7595
|
+
return BUILTIN_TARGETS.find((candidate) => candidate.id === target12);
|
|
7239
7596
|
}
|
|
7240
|
-
function getTargetSkillDir(
|
|
7241
|
-
return getBuiltinTargetDefinition(
|
|
7597
|
+
function getTargetSkillDir(target12) {
|
|
7598
|
+
return getBuiltinTargetDefinition(target12)?.skillDir;
|
|
7242
7599
|
}
|
|
7243
|
-
function getEffectiveTargetSupportLevel(
|
|
7244
|
-
const definition = getBuiltinTargetDefinition(
|
|
7600
|
+
function getEffectiveTargetSupportLevel(target12, feature, config) {
|
|
7601
|
+
const definition = getBuiltinTargetDefinition(target12);
|
|
7245
7602
|
const baseLevel = definition?.capabilities[feature] ?? "none";
|
|
7246
7603
|
if (baseLevel !== "embedded") return baseLevel;
|
|
7247
|
-
if (feature === "commands" &&
|
|
7248
|
-
return shouldConvertCommandsToSkills(config,
|
|
7604
|
+
if (feature === "commands" && target12 === "codex-cli") {
|
|
7605
|
+
return shouldConvertCommandsToSkills(config, target12) ? "embedded" : "none";
|
|
7249
7606
|
}
|
|
7250
|
-
if (feature === "agents" && (
|
|
7251
|
-
return shouldConvertAgentsToSkills(config,
|
|
7607
|
+
if (feature === "agents" && (target12 === "cline" || target12 === "windsurf")) {
|
|
7608
|
+
return shouldConvertAgentsToSkills(config, target12) ? "embedded" : "none";
|
|
7252
7609
|
}
|
|
7253
7610
|
return baseLevel;
|
|
7254
7611
|
}
|
|
7255
|
-
function resolveTargetFeatureGenerator(
|
|
7256
|
-
const generators = getBuiltinTargetDefinition(
|
|
7612
|
+
function resolveTargetFeatureGenerator(target12, feature, config) {
|
|
7613
|
+
const generators = getBuiltinTargetDefinition(target12)?.generators;
|
|
7257
7614
|
if (!generators) return void 0;
|
|
7258
7615
|
switch (feature) {
|
|
7259
7616
|
case "rules":
|
|
7260
7617
|
return generators.generateRules;
|
|
7261
7618
|
case "commands":
|
|
7262
|
-
if (
|
|
7619
|
+
if (target12 === "codex-cli" && config && !shouldConvertCommandsToSkills(config, target12)) {
|
|
7263
7620
|
return void 0;
|
|
7264
7621
|
}
|
|
7265
7622
|
return generators.generateWorkflows ?? generators.generateCommands;
|
|
7266
7623
|
case "agents":
|
|
7267
|
-
if (config && (
|
|
7624
|
+
if (config && (target12 === "cline" || target12 === "windsurf") && !shouldConvertAgentsToSkills(config, target12)) {
|
|
7268
7625
|
return void 0;
|
|
7269
7626
|
}
|
|
7270
7627
|
return generators.generateAgents;
|
|
@@ -7284,9 +7641,9 @@ function resolveTargetFeatureGenerator(target11, feature, config) {
|
|
|
7284
7641
|
}
|
|
7285
7642
|
|
|
7286
7643
|
// src/core/reference/import-map.ts
|
|
7287
|
-
async function buildImportReferenceMap(
|
|
7644
|
+
async function buildImportReferenceMap(target12, projectRoot) {
|
|
7288
7645
|
const refs = /* @__PURE__ */ new Map();
|
|
7289
|
-
const def = getBuiltinTargetDefinition(
|
|
7646
|
+
const def = getBuiltinTargetDefinition(target12);
|
|
7290
7647
|
if (def) {
|
|
7291
7648
|
await def.buildImportPaths(refs, projectRoot);
|
|
7292
7649
|
}
|
|
@@ -7342,7 +7699,8 @@ var ROOT_RELATIVE_PREFIXES = [
|
|
|
7342
7699
|
".clinerules/",
|
|
7343
7700
|
".cline/",
|
|
7344
7701
|
".agents/",
|
|
7345
|
-
".windsurf/"
|
|
7702
|
+
".windsurf/",
|
|
7703
|
+
".roo/"
|
|
7346
7704
|
];
|
|
7347
7705
|
var NON_REWRITABLE_BARE_FILES = /* @__PURE__ */ new Set([
|
|
7348
7706
|
"AGENTS.md",
|
|
@@ -7359,7 +7717,7 @@ var EXTERNAL_REF_PATTERNS = [
|
|
|
7359
7717
|
/\/\/[A-Za-z0-9][\w.-]*\.[A-Za-z]{2,}[^\s<>()\]]*/g
|
|
7360
7718
|
];
|
|
7361
7719
|
var FENCED_CODE_BLOCK = /^(?:```|~~~)[^\n]*\n[\s\S]*?^(?:```|~~~)/gm;
|
|
7362
|
-
var PATH_TOKEN = /(?:\.\.[\\/]|\.\/|\.\\|\/[A-Za-z0-9._-]|[A-Za-z]:[\\/][A-Za-z0-9._-]|\.agentsmesh[\\/]|\.claude[\\/]|\.cursor[\\/]|\.github[\\/]|\.continue[\\/]|\.junie[\\/]|\.gemini[\\/]|\.clinerules[\\/]|\.cline[\\/]|\.agents[\\/]|\.windsurf[\\/]|(?:[A-Za-z0-9._-]+[\\/])+|[A-Za-z0-9._-]+\.[A-Za-z0-9._-]+)[A-Za-z0-9._@%+~:\\/-]*/g;
|
|
7720
|
+
var PATH_TOKEN = /(?:\.\.[\\/]|\.\/|\.\\|\/[A-Za-z0-9._-]|[A-Za-z]:[\\/][A-Za-z0-9._-]|\.agentsmesh[\\/]|\.claude[\\/]|\.cursor[\\/]|\.github[\\/]|\.continue[\\/]|\.junie[\\/]|\.gemini[\\/]|\.clinerules[\\/]|\.cline[\\/]|\.agents[\\/]|\.windsurf[\\/]|\.roo[\\/]|(?:[A-Za-z0-9._-]+[\\/])+|[A-Za-z0-9._-]+\.[A-Za-z0-9._-]+)[A-Za-z0-9._@%+~:\\/-]*/g;
|
|
7363
7721
|
var LINE_NUMBER_SUFFIX = /(?::(\d+)){1,2}$/;
|
|
7364
7722
|
function resolveProjectPath(token, projectRoot, sourceFile) {
|
|
7365
7723
|
const api = pathApi(projectRoot);
|
|
@@ -7506,7 +7864,8 @@ var IMPORT_REFERENCE_TARGETS = [
|
|
|
7506
7864
|
"gemini-cli",
|
|
7507
7865
|
"cline",
|
|
7508
7866
|
"codex-cli",
|
|
7509
|
-
"windsurf"
|
|
7867
|
+
"windsurf",
|
|
7868
|
+
"roo-code"
|
|
7510
7869
|
];
|
|
7511
7870
|
function pathVariants(path) {
|
|
7512
7871
|
const variants = [normalizePath(path)];
|
|
@@ -7521,9 +7880,9 @@ function pathVariants(path) {
|
|
|
7521
7880
|
}
|
|
7522
7881
|
return variants;
|
|
7523
7882
|
}
|
|
7524
|
-
async function createImportReferenceNormalizer(
|
|
7883
|
+
async function createImportReferenceNormalizer(target12, projectRoot) {
|
|
7525
7884
|
const refs = /* @__PURE__ */ new Map();
|
|
7526
|
-
const targets = Array.from(/* @__PURE__ */ new Set([
|
|
7885
|
+
const targets = Array.from(/* @__PURE__ */ new Set([target12, ...IMPORT_REFERENCE_TARGETS]));
|
|
7527
7886
|
for (const candidate of targets) {
|
|
7528
7887
|
const candidateRefs = await buildImportReferenceMap(candidate, projectRoot);
|
|
7529
7888
|
for (const [targetPath, canonicalPath] of candidateRefs.entries()) {
|
|
@@ -7532,8 +7891,8 @@ async function createImportReferenceNormalizer(target11, projectRoot) {
|
|
|
7532
7891
|
}
|
|
7533
7892
|
const artifactMap = /* @__PURE__ */ new Map();
|
|
7534
7893
|
for (const [targetPath, canonicalPath] of refs.entries()) {
|
|
7535
|
-
const canonicalAbsPath = normalizePath(
|
|
7536
|
-
for (const variant of pathVariants(
|
|
7894
|
+
const canonicalAbsPath = normalizePath(join38(projectRoot, canonicalPath));
|
|
7895
|
+
for (const variant of pathVariants(join38(projectRoot, targetPath))) {
|
|
7537
7896
|
artifactMap.set(variant, canonicalAbsPath);
|
|
7538
7897
|
}
|
|
7539
7898
|
}
|
|
@@ -7548,9 +7907,9 @@ async function createImportReferenceNormalizer(target11, projectRoot) {
|
|
|
7548
7907
|
}
|
|
7549
7908
|
|
|
7550
7909
|
// src/targets/claude-code/importer-mappers.ts
|
|
7551
|
-
import { join as
|
|
7910
|
+
import { join as join39 } from "path";
|
|
7552
7911
|
async function mapClaudeRuleFile(relativePath, destDir, normalizeTo) {
|
|
7553
|
-
const destPath =
|
|
7912
|
+
const destPath = join39(destDir, relativePath);
|
|
7554
7913
|
const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
|
|
7555
7914
|
return {
|
|
7556
7915
|
destPath,
|
|
@@ -7564,7 +7923,7 @@ async function mapClaudeRuleFile(relativePath, destDir, normalizeTo) {
|
|
|
7564
7923
|
};
|
|
7565
7924
|
}
|
|
7566
7925
|
async function mapClaudeMarkdownFile(relativePath, destDir, feature, normalizeTo) {
|
|
7567
|
-
const destPath =
|
|
7926
|
+
const destPath = join39(destDir, relativePath);
|
|
7568
7927
|
const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
|
|
7569
7928
|
const basePath = feature === "commands" ? CLAUDE_CANONICAL_COMMANDS_DIR : CLAUDE_CANONICAL_AGENTS_DIR;
|
|
7570
7929
|
return {
|
|
@@ -7588,7 +7947,7 @@ async function mapClaudeMarkdownFile(relativePath, destDir, feature, normalizeTo
|
|
|
7588
7947
|
}
|
|
7589
7948
|
|
|
7590
7949
|
// src/targets/claude-code/settings-helpers.ts
|
|
7591
|
-
import { join as
|
|
7950
|
+
import { join as join40, dirname as dirname17 } from "path";
|
|
7592
7951
|
import { stringify as yamlStringify5 } from "yaml";
|
|
7593
7952
|
function claudeHooksToCanonical(hooks) {
|
|
7594
7953
|
const result = {};
|
|
@@ -7615,7 +7974,7 @@ function claudeHooksToCanonical(hooks) {
|
|
|
7615
7974
|
return result;
|
|
7616
7975
|
}
|
|
7617
7976
|
async function importMcpJson(projectRoot, results) {
|
|
7618
|
-
const mcpPath =
|
|
7977
|
+
const mcpPath = join40(projectRoot, CLAUDE_MCP_JSON);
|
|
7619
7978
|
const content = await readFileSafe(mcpPath);
|
|
7620
7979
|
if (content === null) return;
|
|
7621
7980
|
let parsed;
|
|
@@ -7626,7 +7985,7 @@ async function importMcpJson(projectRoot, results) {
|
|
|
7626
7985
|
}
|
|
7627
7986
|
if (parsed.mcpServers && typeof parsed.mcpServers === "object") {
|
|
7628
7987
|
const mcpContent = JSON.stringify({ mcpServers: parsed.mcpServers }, null, 2);
|
|
7629
|
-
const destPath =
|
|
7988
|
+
const destPath = join40(projectRoot, CLAUDE_CANONICAL_MCP);
|
|
7630
7989
|
await mkdirp(dirname17(destPath));
|
|
7631
7990
|
await writeFileAtomic(destPath, mcpContent);
|
|
7632
7991
|
results.push({
|
|
@@ -7638,7 +7997,7 @@ async function importMcpJson(projectRoot, results) {
|
|
|
7638
7997
|
}
|
|
7639
7998
|
}
|
|
7640
7999
|
async function importSettings2(projectRoot, results) {
|
|
7641
|
-
const settingsPath =
|
|
8000
|
+
const settingsPath = join40(projectRoot, CLAUDE_SETTINGS);
|
|
7642
8001
|
const content = await readFileSafe(settingsPath);
|
|
7643
8002
|
if (!content) return;
|
|
7644
8003
|
let settings;
|
|
@@ -7650,7 +8009,7 @@ async function importSettings2(projectRoot, results) {
|
|
|
7650
8009
|
const alreadyImportedMcp = results.some((r) => r.feature === "mcp");
|
|
7651
8010
|
if (!alreadyImportedMcp && settings.mcpServers && typeof settings.mcpServers === "object") {
|
|
7652
8011
|
const mcpContent = JSON.stringify({ mcpServers: settings.mcpServers }, null, 2);
|
|
7653
|
-
const destPath =
|
|
8012
|
+
const destPath = join40(projectRoot, CLAUDE_CANONICAL_MCP);
|
|
7654
8013
|
await mkdirp(dirname17(destPath));
|
|
7655
8014
|
await writeFileAtomic(destPath, mcpContent);
|
|
7656
8015
|
results.push({
|
|
@@ -7667,7 +8026,7 @@ async function importSettings2(projectRoot, results) {
|
|
|
7667
8026
|
const deny = Array.isArray(perms.deny) ? perms.deny.filter((s) => typeof s === "string") : [];
|
|
7668
8027
|
if (allow.length > 0 || deny.length > 0) {
|
|
7669
8028
|
const permContent = yamlStringify5({ allow, deny });
|
|
7670
|
-
const destPath =
|
|
8029
|
+
const destPath = join40(projectRoot, CLAUDE_CANONICAL_PERMISSIONS);
|
|
7671
8030
|
await mkdirp(dirname17(destPath));
|
|
7672
8031
|
await writeFileAtomic(destPath, permContent);
|
|
7673
8032
|
results.push({
|
|
@@ -7683,7 +8042,7 @@ async function importSettings2(projectRoot, results) {
|
|
|
7683
8042
|
const canonicalHooks = claudeHooksToCanonical(rawHooks);
|
|
7684
8043
|
if (Object.keys(canonicalHooks).length > 0) {
|
|
7685
8044
|
const hooksContent = yamlStringify5(canonicalHooks);
|
|
7686
|
-
const destPath =
|
|
8045
|
+
const destPath = join40(projectRoot, CLAUDE_CANONICAL_HOOKS);
|
|
7687
8046
|
await mkdirp(dirname17(destPath));
|
|
7688
8047
|
await writeFileAtomic(destPath, hooksContent);
|
|
7689
8048
|
results.push({
|
|
@@ -7701,25 +8060,25 @@ async function importFromClaudeCode(projectRoot) {
|
|
|
7701
8060
|
const results = [];
|
|
7702
8061
|
const normalize = await createImportReferenceNormalizer("claude-code", projectRoot);
|
|
7703
8062
|
await importRules5(projectRoot, results, normalize);
|
|
7704
|
-
await
|
|
8063
|
+
await importCommands6(projectRoot, results, normalize);
|
|
7705
8064
|
await importAgents5(projectRoot, results, normalize);
|
|
7706
8065
|
await importSkills5(projectRoot, results, normalize);
|
|
7707
8066
|
await importMcpJson(projectRoot, results);
|
|
7708
8067
|
await importSettings2(projectRoot, results);
|
|
7709
|
-
await
|
|
8068
|
+
await importIgnore4(projectRoot, results);
|
|
7710
8069
|
return results;
|
|
7711
8070
|
}
|
|
7712
8071
|
async function importRules5(projectRoot, results, normalize) {
|
|
7713
|
-
const destDir =
|
|
7714
|
-
const primaryClaudePath =
|
|
8072
|
+
const destDir = join41(projectRoot, CLAUDE_CANONICAL_RULES_DIR);
|
|
8073
|
+
const primaryClaudePath = join41(projectRoot, CLAUDE_ROOT);
|
|
7715
8074
|
const primaryContent = await readFileSafe(primaryClaudePath);
|
|
7716
|
-
const legacyClaudePath =
|
|
8075
|
+
const legacyClaudePath = join41(projectRoot, CLAUDE_LEGACY_ROOT);
|
|
7717
8076
|
const legacyContent = primaryContent === null ? await readFileSafe(legacyClaudePath) : null;
|
|
7718
8077
|
const claudeContent = primaryContent ?? legacyContent;
|
|
7719
8078
|
const claudePath = primaryContent !== null ? primaryClaudePath : legacyClaudePath;
|
|
7720
8079
|
if (claudeContent !== null) {
|
|
7721
8080
|
await mkdirp(destDir);
|
|
7722
|
-
const destPath =
|
|
8081
|
+
const destPath = join41(destDir, "_root.md");
|
|
7723
8082
|
const { frontmatter, body } = parseFrontmatter(normalize(claudeContent, claudePath, destPath));
|
|
7724
8083
|
const hasRoot = frontmatter.root === true;
|
|
7725
8084
|
const outFm = hasRoot ? frontmatter : { ...frontmatter, root: true };
|
|
@@ -7732,7 +8091,7 @@ async function importRules5(projectRoot, results, normalize) {
|
|
|
7732
8091
|
feature: "rules"
|
|
7733
8092
|
});
|
|
7734
8093
|
}
|
|
7735
|
-
const rulesDir =
|
|
8094
|
+
const rulesDir = join41(projectRoot, CLAUDE_RULES_DIR);
|
|
7736
8095
|
results.push(
|
|
7737
8096
|
...await importFileDirectory({
|
|
7738
8097
|
srcDir: rulesDir,
|
|
@@ -7744,9 +8103,9 @@ async function importRules5(projectRoot, results, normalize) {
|
|
|
7744
8103
|
})
|
|
7745
8104
|
);
|
|
7746
8105
|
}
|
|
7747
|
-
async function
|
|
7748
|
-
const destDir =
|
|
7749
|
-
const commandsDir =
|
|
8106
|
+
async function importCommands6(projectRoot, results, normalize) {
|
|
8107
|
+
const destDir = join41(projectRoot, CLAUDE_CANONICAL_COMMANDS_DIR);
|
|
8108
|
+
const commandsDir = join41(projectRoot, CLAUDE_COMMANDS_DIR);
|
|
7750
8109
|
results.push(
|
|
7751
8110
|
...await importFileDirectory({
|
|
7752
8111
|
srcDir: commandsDir,
|
|
@@ -7759,8 +8118,8 @@ async function importCommands5(projectRoot, results, normalize) {
|
|
|
7759
8118
|
);
|
|
7760
8119
|
}
|
|
7761
8120
|
async function importAgents5(projectRoot, results, normalize) {
|
|
7762
|
-
const destDir =
|
|
7763
|
-
const agentsDir =
|
|
8121
|
+
const destDir = join41(projectRoot, CLAUDE_CANONICAL_AGENTS_DIR);
|
|
8122
|
+
const agentsDir = join41(projectRoot, CLAUDE_AGENTS_DIR);
|
|
7764
8123
|
results.push(
|
|
7765
8124
|
...await importFileDirectory({
|
|
7766
8125
|
srcDir: agentsDir,
|
|
@@ -7773,20 +8132,20 @@ async function importAgents5(projectRoot, results, normalize) {
|
|
|
7773
8132
|
);
|
|
7774
8133
|
}
|
|
7775
8134
|
async function importSkills5(projectRoot, results, normalize) {
|
|
7776
|
-
const skillsBaseDir =
|
|
7777
|
-
const destBase =
|
|
8135
|
+
const skillsBaseDir = join41(projectRoot, CLAUDE_SKILLS_DIR);
|
|
8136
|
+
const destBase = join41(projectRoot, CLAUDE_CANONICAL_SKILLS_DIR);
|
|
7778
8137
|
const allFiles = await readDirRecursive(skillsBaseDir);
|
|
7779
8138
|
const skillMdFiles = allFiles.filter((f) => f.endsWith("SKILL.md"));
|
|
7780
8139
|
for (const skillMdPath of skillMdFiles) {
|
|
7781
8140
|
const skillDir = dirname18(skillMdPath);
|
|
7782
|
-
const skillName =
|
|
7783
|
-
const destSkillDir =
|
|
8141
|
+
const skillName = basename26(skillDir);
|
|
8142
|
+
const destSkillDir = join41(destBase, skillName);
|
|
7784
8143
|
const skillFiles = await readDirRecursive(skillDir);
|
|
7785
8144
|
for (const filePath of skillFiles) {
|
|
7786
8145
|
const fileContent = await readFileSafe(filePath);
|
|
7787
8146
|
if (fileContent === null) continue;
|
|
7788
8147
|
const relPath = relative17(skillDir, filePath);
|
|
7789
|
-
const destPath =
|
|
8148
|
+
const destPath = join41(destSkillDir, relPath);
|
|
7790
8149
|
await mkdirp(dirname18(destPath));
|
|
7791
8150
|
const normalized = normalize(fileContent, filePath, destPath);
|
|
7792
8151
|
const parsed = relPath === "SKILL.md" ? parseFrontmatter(normalized) : null;
|
|
@@ -7808,11 +8167,11 @@ async function importSkills5(projectRoot, results, normalize) {
|
|
|
7808
8167
|
}
|
|
7809
8168
|
}
|
|
7810
8169
|
}
|
|
7811
|
-
async function
|
|
7812
|
-
const ignorePath =
|
|
8170
|
+
async function importIgnore4(projectRoot, results) {
|
|
8171
|
+
const ignorePath = join41(projectRoot, CLAUDE_IGNORE);
|
|
7813
8172
|
const content = await readFileSafe(ignorePath);
|
|
7814
8173
|
if (content === null) return;
|
|
7815
|
-
const destPath =
|
|
8174
|
+
const destPath = join41(projectRoot, CLAUDE_CANONICAL_IGNORE);
|
|
7816
8175
|
await mkdirp(dirname18(destPath));
|
|
7817
8176
|
await writeFileAtomic(destPath, content);
|
|
7818
8177
|
results.push({
|
|
@@ -7844,17 +8203,17 @@ async function importNativeToCanonical(repoPath, targetName) {
|
|
|
7844
8203
|
}
|
|
7845
8204
|
|
|
7846
8205
|
// src/canonical/load/skill-pack-load.ts
|
|
7847
|
-
import { join as
|
|
7848
|
-
import { readdir as
|
|
8206
|
+
import { join as join42 } from "path";
|
|
8207
|
+
import { readdir as readdir10 } from "fs/promises";
|
|
7849
8208
|
var SKILL = "SKILL.md";
|
|
7850
8209
|
async function isSkillPackLayout(root) {
|
|
7851
8210
|
if (!await exists(root)) return false;
|
|
7852
|
-
if (await exists(
|
|
8211
|
+
if (await exists(join42(root, SKILL))) return true;
|
|
7853
8212
|
try {
|
|
7854
|
-
const ents = await
|
|
8213
|
+
const ents = await readdir10(root, { withFileTypes: true });
|
|
7855
8214
|
for (const e of ents) {
|
|
7856
8215
|
if (!e.isDirectory() || e.name.startsWith(".")) continue;
|
|
7857
|
-
if (await exists(
|
|
8216
|
+
if (await exists(join42(root, e.name, SKILL))) return true;
|
|
7858
8217
|
}
|
|
7859
8218
|
} catch {
|
|
7860
8219
|
return false;
|
|
@@ -7863,7 +8222,7 @@ async function isSkillPackLayout(root) {
|
|
|
7863
8222
|
}
|
|
7864
8223
|
async function loadSkillsAtExtendPath(skillsRoot) {
|
|
7865
8224
|
if (!await exists(skillsRoot)) return [];
|
|
7866
|
-
if (await exists(
|
|
8225
|
+
if (await exists(join42(skillsRoot, SKILL))) {
|
|
7867
8226
|
const one = await parseSkillDirectory(skillsRoot);
|
|
7868
8227
|
return one ? [one] : [];
|
|
7869
8228
|
}
|
|
@@ -7871,7 +8230,7 @@ async function loadSkillsAtExtendPath(skillsRoot) {
|
|
|
7871
8230
|
}
|
|
7872
8231
|
|
|
7873
8232
|
// src/canonical/load/load-canonical-slice.ts
|
|
7874
|
-
import { basename as
|
|
8233
|
+
import { basename as basename27, dirname as dirname19, join as join43 } from "path";
|
|
7875
8234
|
import { stat as stat4 } from "fs/promises";
|
|
7876
8235
|
function emptyCanonical() {
|
|
7877
8236
|
return {
|
|
@@ -7902,8 +8261,8 @@ async function normalizeSlicePath(absolutePath) {
|
|
|
7902
8261
|
);
|
|
7903
8262
|
}
|
|
7904
8263
|
const parent = dirname19(absolutePath);
|
|
7905
|
-
const parentBase =
|
|
7906
|
-
const fileBase =
|
|
8264
|
+
const parentBase = basename27(parent);
|
|
8265
|
+
const fileBase = basename27(absolutePath);
|
|
7907
8266
|
const slug = fileBase.replace(/\.md$/i, "");
|
|
7908
8267
|
if (parentBase === "rules") {
|
|
7909
8268
|
return { sliceRoot: parent, implicitPick: { rules: [slug] } };
|
|
@@ -7919,33 +8278,33 @@ async function normalizeSlicePath(absolutePath) {
|
|
|
7919
8278
|
);
|
|
7920
8279
|
}
|
|
7921
8280
|
async function parseRulesAt(sliceRoot) {
|
|
7922
|
-
const base =
|
|
8281
|
+
const base = basename27(sliceRoot);
|
|
7923
8282
|
if (base === "rules") {
|
|
7924
8283
|
return parseRules(sliceRoot);
|
|
7925
8284
|
}
|
|
7926
|
-
const nested =
|
|
8285
|
+
const nested = join43(sliceRoot, "rules");
|
|
7927
8286
|
if (await exists(nested)) {
|
|
7928
8287
|
return parseRules(nested);
|
|
7929
8288
|
}
|
|
7930
8289
|
return [];
|
|
7931
8290
|
}
|
|
7932
8291
|
async function parseCommandsAt(sliceRoot) {
|
|
7933
|
-
const base =
|
|
8292
|
+
const base = basename27(sliceRoot);
|
|
7934
8293
|
if (base === "commands") {
|
|
7935
8294
|
return parseCommands(sliceRoot);
|
|
7936
8295
|
}
|
|
7937
|
-
const nested =
|
|
8296
|
+
const nested = join43(sliceRoot, "commands");
|
|
7938
8297
|
if (await exists(nested)) {
|
|
7939
8298
|
return parseCommands(nested);
|
|
7940
8299
|
}
|
|
7941
8300
|
return [];
|
|
7942
8301
|
}
|
|
7943
8302
|
async function parseAgentsAt(sliceRoot) {
|
|
7944
|
-
const base =
|
|
8303
|
+
const base = basename27(sliceRoot);
|
|
7945
8304
|
if (base === "agents") {
|
|
7946
8305
|
return parseAgents(sliceRoot);
|
|
7947
8306
|
}
|
|
7948
|
-
const nested =
|
|
8307
|
+
const nested = join43(sliceRoot, "agents");
|
|
7949
8308
|
if (await exists(nested)) {
|
|
7950
8309
|
return parseAgents(nested);
|
|
7951
8310
|
}
|
|
@@ -7955,14 +8314,14 @@ async function loadSkillsForPartialSlice(sliceRoot) {
|
|
|
7955
8314
|
if (await isSkillPackLayout(sliceRoot)) {
|
|
7956
8315
|
return loadSkillsAtExtendPath(sliceRoot);
|
|
7957
8316
|
}
|
|
7958
|
-
const nestedSkills =
|
|
8317
|
+
const nestedSkills = join43(sliceRoot, "skills");
|
|
7959
8318
|
if (await isSkillPackLayout(nestedSkills)) {
|
|
7960
8319
|
return loadSkillsAtExtendPath(nestedSkills);
|
|
7961
8320
|
}
|
|
7962
8321
|
return [];
|
|
7963
8322
|
}
|
|
7964
8323
|
async function loadCanonicalSliceAtPath(sliceRoot) {
|
|
7965
|
-
const ab =
|
|
8324
|
+
const ab = join43(sliceRoot, ".agentsmesh");
|
|
7966
8325
|
if (await exists(ab)) {
|
|
7967
8326
|
return loadCanonicalFiles(sliceRoot);
|
|
7968
8327
|
}
|
|
@@ -7995,7 +8354,7 @@ function emptyCanonical2() {
|
|
|
7995
8354
|
async function loadCanonicalForExtend(ext) {
|
|
7996
8355
|
const base = ext.resolvedPath;
|
|
7997
8356
|
if (!ext.path) {
|
|
7998
|
-
const agentsmeshDir =
|
|
8357
|
+
const agentsmeshDir = join44(base, ".agentsmesh");
|
|
7999
8358
|
if (!await exists(agentsmeshDir)) {
|
|
8000
8359
|
if (await isSkillPackLayout(base)) {
|
|
8001
8360
|
const skills = await loadSkillsAtExtendPath(base);
|
|
@@ -8015,12 +8374,12 @@ Expected one of: .agentsmesh/, ${KNOWN_NATIVE_PATHS.join(", ")}.`
|
|
|
8015
8374
|
}
|
|
8016
8375
|
return loadCanonicalFiles(base);
|
|
8017
8376
|
}
|
|
8018
|
-
const rawRoot =
|
|
8377
|
+
const rawRoot = join44(base, ext.path);
|
|
8019
8378
|
if (!await exists(rawRoot)) {
|
|
8020
8379
|
throw new Error(`Extend "${ext.name}": path does not exist: ${rawRoot}`);
|
|
8021
8380
|
}
|
|
8022
8381
|
if (ext.target) {
|
|
8023
|
-
const agentsmeshDir =
|
|
8382
|
+
const agentsmeshDir = join44(base, ".agentsmesh");
|
|
8024
8383
|
if (!await exists(agentsmeshDir)) {
|
|
8025
8384
|
logger.info(
|
|
8026
8385
|
`[agentsmesh] Extend "${ext.name}": path "${ext.path}" with target "${ext.target}" \u2014 importing at extend root, then loading canonical.`
|
|
@@ -8041,7 +8400,7 @@ Expected one of: .agentsmesh/, ${KNOWN_NATIVE_PATHS.join(", ")}.`
|
|
|
8041
8400
|
}
|
|
8042
8401
|
|
|
8043
8402
|
// src/canonical/extends/extend-pick.ts
|
|
8044
|
-
import { basename as
|
|
8403
|
+
import { basename as basename28 } from "path";
|
|
8045
8404
|
function applyExtendPick(canonical, features, pick, extendName) {
|
|
8046
8405
|
if (!pick) return canonical;
|
|
8047
8406
|
let next = { ...canonical };
|
|
@@ -8084,7 +8443,7 @@ function applyExtendPick(canonical, features, pick, extendName) {
|
|
|
8084
8443
|
if (pick.rules?.length && features.includes("rules")) {
|
|
8085
8444
|
const wanted = new Set(pick.rules);
|
|
8086
8445
|
const prev = next.rules;
|
|
8087
|
-
const stem = (src) =>
|
|
8446
|
+
const stem = (src) => basename28(src).replace(/\.md$/i, "");
|
|
8088
8447
|
next = {
|
|
8089
8448
|
...next,
|
|
8090
8449
|
rules: prev.filter((r) => wanted.has(stem(r.source)))
|
|
@@ -8101,11 +8460,11 @@ function applyExtendPick(canonical, features, pick, extendName) {
|
|
|
8101
8460
|
}
|
|
8102
8461
|
|
|
8103
8462
|
// src/canonical/load/pack-load.ts
|
|
8104
|
-
import { join as
|
|
8463
|
+
import { join as join46 } from "path";
|
|
8105
8464
|
|
|
8106
8465
|
// src/install/pack/pack-reader.ts
|
|
8107
|
-
import { join as
|
|
8108
|
-
import { readdir as
|
|
8466
|
+
import { join as join45 } from "path";
|
|
8467
|
+
import { readdir as readdir11 } from "fs/promises";
|
|
8109
8468
|
import { parse as parseYaml5 } from "yaml";
|
|
8110
8469
|
|
|
8111
8470
|
// src/install/pack/pack-schema.ts
|
|
@@ -8151,7 +8510,7 @@ function sameFeatures(a, b) {
|
|
|
8151
8510
|
return a.length === b.length && [...a].sort().every((feature, index) => feature === [...b].sort()[index]);
|
|
8152
8511
|
}
|
|
8153
8512
|
async function readPackMetadata(packDir) {
|
|
8154
|
-
const metaPath =
|
|
8513
|
+
const metaPath = join45(packDir, "pack.yaml");
|
|
8155
8514
|
const content = await readFileSafe(metaPath);
|
|
8156
8515
|
if (content === null) return null;
|
|
8157
8516
|
try {
|
|
@@ -8166,13 +8525,13 @@ async function findExistingPack(packsDir, source, scope) {
|
|
|
8166
8525
|
const requestedIdentity = sourceIdentity(source);
|
|
8167
8526
|
let entries;
|
|
8168
8527
|
try {
|
|
8169
|
-
entries = await
|
|
8528
|
+
entries = await readdir11(packsDir, { withFileTypes: true });
|
|
8170
8529
|
} catch {
|
|
8171
8530
|
return null;
|
|
8172
8531
|
}
|
|
8173
8532
|
for (const entry of entries) {
|
|
8174
8533
|
if (!entry.isDirectory()) continue;
|
|
8175
|
-
const packDir =
|
|
8534
|
+
const packDir = join45(packsDir, entry.name);
|
|
8176
8535
|
const meta = await readPackMetadata(packDir);
|
|
8177
8536
|
if (meta && sourceIdentity(meta.source) === requestedIdentity && meta.target === scope.target && meta.as === scope.as && sameFeatures(meta.features, scope.features)) {
|
|
8178
8537
|
return { meta, packDir, name: meta.name };
|
|
@@ -8184,14 +8543,14 @@ async function listPacks(packsDir) {
|
|
|
8184
8543
|
if (!await exists(packsDir)) return [];
|
|
8185
8544
|
let entries;
|
|
8186
8545
|
try {
|
|
8187
|
-
entries = await
|
|
8546
|
+
entries = await readdir11(packsDir, { withFileTypes: true });
|
|
8188
8547
|
} catch {
|
|
8189
8548
|
return [];
|
|
8190
8549
|
}
|
|
8191
8550
|
const result = [];
|
|
8192
8551
|
for (const entry of entries) {
|
|
8193
8552
|
if (!entry.isDirectory()) continue;
|
|
8194
|
-
const packDir =
|
|
8553
|
+
const packDir = join45(packsDir, entry.name);
|
|
8195
8554
|
const meta = await readPackMetadata(packDir);
|
|
8196
8555
|
if (meta) {
|
|
8197
8556
|
result.push({ meta, packDir, name: meta.name });
|
|
@@ -8215,19 +8574,19 @@ function emptyCanonical3() {
|
|
|
8215
8574
|
}
|
|
8216
8575
|
async function loadPackCanonical(packDir) {
|
|
8217
8576
|
const [rules, commands, agents, skills, mcp, permissions, hooks, ignore] = await Promise.all([
|
|
8218
|
-
parseRules(
|
|
8219
|
-
parseCommands(
|
|
8220
|
-
parseAgents(
|
|
8221
|
-
parseSkills(
|
|
8222
|
-
parseMcp(
|
|
8223
|
-
parsePermissions(
|
|
8224
|
-
parseHooks(
|
|
8225
|
-
parseIgnore(
|
|
8577
|
+
parseRules(join46(packDir, "rules")),
|
|
8578
|
+
parseCommands(join46(packDir, "commands")),
|
|
8579
|
+
parseAgents(join46(packDir, "agents")),
|
|
8580
|
+
parseSkills(join46(packDir, "skills")),
|
|
8581
|
+
parseMcp(join46(packDir, "mcp.json")),
|
|
8582
|
+
parsePermissions(join46(packDir, "permissions.yaml")),
|
|
8583
|
+
parseHooks(join46(packDir, "hooks.yaml")),
|
|
8584
|
+
parseIgnore(join46(packDir, "ignore"))
|
|
8226
8585
|
]);
|
|
8227
8586
|
return { ...emptyCanonical3(), rules, commands, agents, skills, mcp, permissions, hooks, ignore };
|
|
8228
8587
|
}
|
|
8229
8588
|
async function loadPacksCanonical(abDir) {
|
|
8230
|
-
const packsDir =
|
|
8589
|
+
const packsDir = join46(abDir, "packs");
|
|
8231
8590
|
const packs = await listPacks(packsDir);
|
|
8232
8591
|
let merged = emptyCanonical3();
|
|
8233
8592
|
for (const { meta, packDir } of packs) {
|
|
@@ -8289,7 +8648,7 @@ async function loadCanonicalWithExtends(config, configDir, options = {}) {
|
|
|
8289
8648
|
const picked = applyExtendPick(filtered, ext.features, ext.pick, ext.name);
|
|
8290
8649
|
merged = mergeCanonicalFiles(merged, picked);
|
|
8291
8650
|
}
|
|
8292
|
-
const packsCanonical = await loadPacksCanonical(
|
|
8651
|
+
const packsCanonical = await loadPacksCanonical(join47(configDir, ".agentsmesh"));
|
|
8293
8652
|
merged = mergeCanonicalFiles(merged, packsCanonical);
|
|
8294
8653
|
const localCanonical = await loadCanonicalFiles(configDir);
|
|
8295
8654
|
merged = mergeCanonicalFiles(merged, localCanonical);
|
|
@@ -8298,7 +8657,7 @@ async function loadCanonicalWithExtends(config, configDir, options = {}) {
|
|
|
8298
8657
|
|
|
8299
8658
|
// src/config/core/lock.ts
|
|
8300
8659
|
import { parse as parseYaml6, stringify as stringifyYaml3 } from "yaml";
|
|
8301
|
-
import { join as
|
|
8660
|
+
import { join as join48, relative as relative18 } from "path";
|
|
8302
8661
|
|
|
8303
8662
|
// src/utils/crypto/hash.ts
|
|
8304
8663
|
import { createHash } from "crypto";
|
|
@@ -8345,7 +8704,7 @@ var FEATURE_PATTERNS = {
|
|
|
8345
8704
|
ignore: (path) => path === "ignore"
|
|
8346
8705
|
};
|
|
8347
8706
|
async function readLock(abDir) {
|
|
8348
|
-
const lockPath =
|
|
8707
|
+
const lockPath = join48(abDir, LOCK_FILENAME);
|
|
8349
8708
|
const content = await readFileSafe(lockPath);
|
|
8350
8709
|
if (content === null) return null;
|
|
8351
8710
|
try {
|
|
@@ -8364,7 +8723,7 @@ async function readLock(abDir) {
|
|
|
8364
8723
|
}
|
|
8365
8724
|
}
|
|
8366
8725
|
async function writeLock(abDir, lock) {
|
|
8367
|
-
const lockPath =
|
|
8726
|
+
const lockPath = join48(abDir, LOCK_FILENAME);
|
|
8368
8727
|
const raw = {
|
|
8369
8728
|
generated_at: lock.generatedAt,
|
|
8370
8729
|
generated_by: lock.generatedBy,
|
|
@@ -8418,7 +8777,7 @@ async function buildExtendChecksums(resolvedExtends) {
|
|
|
8418
8777
|
result[ext.name] = ext.version;
|
|
8419
8778
|
continue;
|
|
8420
8779
|
}
|
|
8421
|
-
const abDir =
|
|
8780
|
+
const abDir = join48(ext.resolvedPath, ".agentsmesh");
|
|
8422
8781
|
const checksums = await buildChecksums(abDir);
|
|
8423
8782
|
const fingerprint = Object.keys(checksums).sort().map((p) => `${p}:${checksums[p]}`).join("\n");
|
|
8424
8783
|
const h = hashContent(fingerprint);
|
|
@@ -8429,7 +8788,7 @@ async function buildExtendChecksums(resolvedExtends) {
|
|
|
8429
8788
|
}
|
|
8430
8789
|
|
|
8431
8790
|
// src/core/reference/map.ts
|
|
8432
|
-
import { basename as
|
|
8791
|
+
import { basename as basename30 } from "path";
|
|
8433
8792
|
|
|
8434
8793
|
// src/core/reference/map-directories.ts
|
|
8435
8794
|
import { posix as posix2 } from "path";
|
|
@@ -8448,29 +8807,29 @@ function addSkillDirectoryMappings(refs, canonicalPath, targetPath) {
|
|
|
8448
8807
|
}
|
|
8449
8808
|
|
|
8450
8809
|
// src/core/reference/map-targets.ts
|
|
8451
|
-
import { basename as
|
|
8810
|
+
import { basename as basename29 } from "path";
|
|
8452
8811
|
var SKILL_DIRS = Object.fromEntries(
|
|
8453
|
-
TARGET_IDS.map((
|
|
8812
|
+
TARGET_IDS.map((target12) => [target12, getTargetSkillDir(target12)]).filter(
|
|
8454
8813
|
(entry) => typeof entry[1] === "string"
|
|
8455
8814
|
)
|
|
8456
8815
|
);
|
|
8457
|
-
function ruleTargetPath(
|
|
8458
|
-
const def = getBuiltinTargetDefinition(
|
|
8816
|
+
function ruleTargetPath(target12, rule) {
|
|
8817
|
+
const def = getBuiltinTargetDefinition(target12);
|
|
8459
8818
|
if (!def) return null;
|
|
8460
8819
|
if (rule.root) {
|
|
8461
8820
|
return def.generators.primaryRootInstructionPath ?? null;
|
|
8462
8821
|
}
|
|
8463
|
-
if (rule.targets.length > 0 && !rule.targets.includes(
|
|
8464
|
-
const slug =
|
|
8822
|
+
if (rule.targets.length > 0 && !rule.targets.includes(target12)) return null;
|
|
8823
|
+
const slug = basename29(rule.source, ".md");
|
|
8465
8824
|
return def.paths.rulePath(slug, rule);
|
|
8466
8825
|
}
|
|
8467
|
-
function commandTargetPath(
|
|
8468
|
-
const def = getBuiltinTargetDefinition(
|
|
8826
|
+
function commandTargetPath(target12, name, config) {
|
|
8827
|
+
const def = getBuiltinTargetDefinition(target12);
|
|
8469
8828
|
if (!def) return null;
|
|
8470
8829
|
return def.paths.commandPath(name, config);
|
|
8471
8830
|
}
|
|
8472
|
-
function agentTargetPath(
|
|
8473
|
-
const def = getBuiltinTargetDefinition(
|
|
8831
|
+
function agentTargetPath(target12, name, config) {
|
|
8832
|
+
const def = getBuiltinTargetDefinition(target12);
|
|
8474
8833
|
if (!def) return null;
|
|
8475
8834
|
return def.paths.agentPath(name, config);
|
|
8476
8835
|
}
|
|
@@ -8480,21 +8839,21 @@ function addDirectoryMapping3(refs, from, to) {
|
|
|
8480
8839
|
refs.set(from, to);
|
|
8481
8840
|
refs.set(`${from}/`, `${to}/`);
|
|
8482
8841
|
}
|
|
8483
|
-
function buildReferenceMap(
|
|
8842
|
+
function buildReferenceMap(target12, canonical, config) {
|
|
8484
8843
|
const refs = /* @__PURE__ */ new Map();
|
|
8485
8844
|
for (const rule of canonical.rules) {
|
|
8486
|
-
const path = ruleTargetPath(
|
|
8487
|
-
if (path) refs.set(`.agentsmesh/rules/${
|
|
8845
|
+
const path = ruleTargetPath(target12, rule);
|
|
8846
|
+
if (path) refs.set(`.agentsmesh/rules/${basename30(rule.source)}`, path);
|
|
8488
8847
|
}
|
|
8489
8848
|
for (const command of canonical.commands) {
|
|
8490
|
-
const path = commandTargetPath(
|
|
8849
|
+
const path = commandTargetPath(target12, command.name, config);
|
|
8491
8850
|
if (path) refs.set(`.agentsmesh/commands/${command.name}.md`, path);
|
|
8492
8851
|
}
|
|
8493
8852
|
for (const agent of canonical.agents) {
|
|
8494
|
-
const path = agentTargetPath(
|
|
8853
|
+
const path = agentTargetPath(target12, agent.name, config);
|
|
8495
8854
|
if (path) refs.set(`.agentsmesh/agents/${agent.name}.md`, path);
|
|
8496
8855
|
}
|
|
8497
|
-
const skillDir = SKILL_DIRS[
|
|
8856
|
+
const skillDir = SKILL_DIRS[target12];
|
|
8498
8857
|
if (!skillDir) return refs;
|
|
8499
8858
|
for (const skill of canonical.skills) {
|
|
8500
8859
|
addDirectoryMapping3(refs, `.agentsmesh/skills/${skill.name}`, `${skillDir}/${skill.name}`);
|
|
@@ -8530,14 +8889,14 @@ function isGeminiAgents(result) {
|
|
|
8530
8889
|
function isCompatibilityAgents(result) {
|
|
8531
8890
|
return isCursorAgents(result) || isGeminiAgents(result);
|
|
8532
8891
|
}
|
|
8533
|
-
function reverseReferenceMap(
|
|
8534
|
-
const cached = cache.get(
|
|
8892
|
+
function reverseReferenceMap(target12, canonical, config, cache) {
|
|
8893
|
+
const cached = cache.get(target12);
|
|
8535
8894
|
if (cached) return cached;
|
|
8536
8895
|
const reversed = /* @__PURE__ */ new Map();
|
|
8537
|
-
for (const [canonicalPath, targetPath] of buildReferenceMap(
|
|
8896
|
+
for (const [canonicalPath, targetPath] of buildReferenceMap(target12, canonical, config)) {
|
|
8538
8897
|
if (!reversed.has(targetPath)) reversed.set(targetPath, canonicalPath);
|
|
8539
8898
|
}
|
|
8540
|
-
cache.set(
|
|
8899
|
+
cache.set(target12, reversed);
|
|
8541
8900
|
return reversed;
|
|
8542
8901
|
}
|
|
8543
8902
|
function normalizeContent(content, refs) {
|
|
@@ -8569,11 +8928,11 @@ function preferEquivalentCodexAgents(results, canonical, config) {
|
|
|
8569
8928
|
return results.filter((result) => {
|
|
8570
8929
|
if (isCursorAgents(result)) {
|
|
8571
8930
|
const targets = overlapTargetsByPath.get(result.path);
|
|
8572
|
-
if (targets && [...targets].some((
|
|
8931
|
+
if (targets && [...targets].some((target12) => target12 !== "cursor")) return false;
|
|
8573
8932
|
}
|
|
8574
8933
|
if (isGeminiAgents(result)) {
|
|
8575
8934
|
const targets = overlapTargetsByPath.get(result.path);
|
|
8576
|
-
if (targets && [...targets].some((
|
|
8935
|
+
if (targets && [...targets].some((target12) => target12 !== "cursor" && target12 !== "gemini-cli")) {
|
|
8577
8936
|
return false;
|
|
8578
8937
|
}
|
|
8579
8938
|
}
|
|
@@ -8591,10 +8950,10 @@ function preferEquivalentCodexAgents(results, canonical, config) {
|
|
|
8591
8950
|
|
|
8592
8951
|
// src/core/reference/rewriter.ts
|
|
8593
8952
|
import { existsSync as existsSync3 } from "fs";
|
|
8594
|
-
import { dirname as dirname21, join as
|
|
8953
|
+
import { dirname as dirname21, join as join50 } from "path";
|
|
8595
8954
|
|
|
8596
8955
|
// src/core/reference/output-source-map.ts
|
|
8597
|
-
import { dirname as dirname20, join as
|
|
8956
|
+
import { dirname as dirname20, join as join49, normalize as normalizePath2 } from "path";
|
|
8598
8957
|
function canonicalRulePath(rule) {
|
|
8599
8958
|
return `.agentsmesh/rules/${rule.source.split("/").pop()}`;
|
|
8600
8959
|
}
|
|
@@ -8617,17 +8976,17 @@ function copilotInstructionsPath(rule) {
|
|
|
8617
8976
|
const slug = rule.source.split("/").pop().replace(/\.md$/, "");
|
|
8618
8977
|
return `.github/instructions/${slug}.instructions.md`;
|
|
8619
8978
|
}
|
|
8620
|
-
function ruleOutputPaths(
|
|
8979
|
+
function ruleOutputPaths(target12, rule, refs) {
|
|
8621
8980
|
const paths = [];
|
|
8622
8981
|
const targetPath = refs.get(canonicalRulePath(rule));
|
|
8623
8982
|
if (targetPath) paths.push(targetPath);
|
|
8624
|
-
if (
|
|
8983
|
+
if (target12 === "copilot" && !rule.root && rule.globs.length > 0) {
|
|
8625
8984
|
paths.push(copilotInstructionsPath(rule));
|
|
8626
8985
|
}
|
|
8627
|
-
if ((
|
|
8986
|
+
if ((target12 === "cline" || target12 === "cursor") && rule.root) {
|
|
8628
8987
|
paths.push("AGENTS.md");
|
|
8629
8988
|
}
|
|
8630
|
-
if (
|
|
8989
|
+
if (target12 === "windsurf") {
|
|
8631
8990
|
if (rule.root) {
|
|
8632
8991
|
paths.push("AGENTS.md");
|
|
8633
8992
|
} else {
|
|
@@ -8635,10 +8994,10 @@ function ruleOutputPaths(target11, rule, refs) {
|
|
|
8635
8994
|
if (dir) paths.push(`${dir}/AGENTS.md`);
|
|
8636
8995
|
}
|
|
8637
8996
|
}
|
|
8638
|
-
if (
|
|
8997
|
+
if (target12 === "gemini-cli") {
|
|
8639
8998
|
paths.push(GEMINI_COMPAT_AGENTS);
|
|
8640
8999
|
}
|
|
8641
|
-
if (
|
|
9000
|
+
if (target12 === "codex-cli") {
|
|
8642
9001
|
if (!rule.root && rule.codexEmit === "execution") {
|
|
8643
9002
|
const slug = rule.source.split("/").pop().replace(/\.md$/, "");
|
|
8644
9003
|
paths.push(`${CODEX_RULES_DIR}/${slug}.rules`);
|
|
@@ -8646,46 +9005,46 @@ function ruleOutputPaths(target11, rule, refs) {
|
|
|
8646
9005
|
}
|
|
8647
9006
|
return paths;
|
|
8648
9007
|
}
|
|
8649
|
-
function addPackSkillPaths(refs,
|
|
8650
|
-
const skillDir = SKILL_DIRS[
|
|
9008
|
+
function addPackSkillPaths(refs, target12, canonical, projectRoot) {
|
|
9009
|
+
const skillDir = SKILL_DIRS[target12];
|
|
8651
9010
|
if (!skillDir) return;
|
|
8652
|
-
const packsPrefix =
|
|
9011
|
+
const packsPrefix = join49(projectRoot, ".agentsmesh", "packs");
|
|
8653
9012
|
for (const skill of canonical.skills) {
|
|
8654
9013
|
const skillSourceDir = dirname20(skill.source);
|
|
8655
9014
|
if (!skillSourceDir.startsWith(packsPrefix)) continue;
|
|
8656
|
-
const targetSkillDir = normalizePath2(
|
|
9015
|
+
const targetSkillDir = normalizePath2(join49(projectRoot, skillDir, skill.name));
|
|
8657
9016
|
refs.set(normalizePath2(skillSourceDir), targetSkillDir);
|
|
8658
|
-
refs.set(normalizePath2(skill.source), normalizePath2(
|
|
9017
|
+
refs.set(normalizePath2(skill.source), normalizePath2(join49(targetSkillDir, "SKILL.md")));
|
|
8659
9018
|
for (const file of skill.supportingFiles) {
|
|
8660
|
-
const targetFilePath = normalizePath2(
|
|
9019
|
+
const targetFilePath = normalizePath2(join49(targetSkillDir, file.relativePath));
|
|
8661
9020
|
refs.set(normalizePath2(file.absolutePath), targetFilePath);
|
|
8662
9021
|
}
|
|
8663
9022
|
}
|
|
8664
9023
|
}
|
|
8665
|
-
function buildArtifactPathMap(
|
|
9024
|
+
function buildArtifactPathMap(target12, canonical, config, projectRoot, destinationPath) {
|
|
8666
9025
|
const refs = new Map(
|
|
8667
|
-
[...buildReferenceMap(
|
|
8668
|
-
normalizePath2(
|
|
8669
|
-
normalizePath2(
|
|
9026
|
+
[...buildReferenceMap(target12, canonical, config)].map(([canonicalPath, targetPath]) => [
|
|
9027
|
+
normalizePath2(join49(projectRoot, canonicalPath)),
|
|
9028
|
+
normalizePath2(join49(projectRoot, targetPath))
|
|
8670
9029
|
])
|
|
8671
9030
|
);
|
|
8672
|
-
if (
|
|
9031
|
+
if (target12 === "copilot" && destinationPath?.startsWith(".github/instructions/")) {
|
|
8673
9032
|
for (const rule of canonical.rules) {
|
|
8674
9033
|
if (rule.root || rule.globs.length === 0) continue;
|
|
8675
9034
|
refs.set(
|
|
8676
|
-
normalizePath2(
|
|
8677
|
-
normalizePath2(
|
|
9035
|
+
normalizePath2(join49(projectRoot, canonicalRulePath(rule))),
|
|
9036
|
+
normalizePath2(join49(projectRoot, copilotInstructionsPath(rule)))
|
|
8678
9037
|
);
|
|
8679
9038
|
}
|
|
8680
9039
|
}
|
|
8681
|
-
addPackSkillPaths(refs,
|
|
9040
|
+
addPackSkillPaths(refs, target12, canonical, projectRoot);
|
|
8682
9041
|
return refs;
|
|
8683
9042
|
}
|
|
8684
|
-
function buildOutputSourceMap(
|
|
8685
|
-
const refs = buildReferenceMap(
|
|
9043
|
+
function buildOutputSourceMap(target12, canonical, config) {
|
|
9044
|
+
const refs = buildReferenceMap(target12, canonical, config);
|
|
8686
9045
|
const sourceMap = /* @__PURE__ */ new Map();
|
|
8687
9046
|
for (const rule of canonical.rules) {
|
|
8688
|
-
for (const targetPath of ruleOutputPaths(
|
|
9047
|
+
for (const targetPath of ruleOutputPaths(target12, rule, refs)) {
|
|
8689
9048
|
sourceMap.set(targetPath, rule.source);
|
|
8690
9049
|
}
|
|
8691
9050
|
}
|
|
@@ -8713,7 +9072,7 @@ function buildOutputSourceMap(target11, canonical, config) {
|
|
|
8713
9072
|
function collectPlannedPaths(projectRoot, results) {
|
|
8714
9073
|
const planned = /* @__PURE__ */ new Set();
|
|
8715
9074
|
for (const result of results) {
|
|
8716
|
-
const absolutePath =
|
|
9075
|
+
const absolutePath = join50(projectRoot, result.path);
|
|
8717
9076
|
planned.add(absolutePath);
|
|
8718
9077
|
let current = dirname21(absolutePath);
|
|
8719
9078
|
while (current.startsWith(projectRoot) && !planned.has(current)) {
|
|
@@ -8755,7 +9114,7 @@ function rewriteGeneratedReferences(results, canonical, config, projectRoot) {
|
|
|
8755
9114
|
content: result.content,
|
|
8756
9115
|
projectRoot,
|
|
8757
9116
|
sourceFile,
|
|
8758
|
-
destinationFile:
|
|
9117
|
+
destinationFile: join50(projectRoot, result.path),
|
|
8759
9118
|
translatePath: (absolutePath) => artifactMap.get(absolutePath) ?? absolutePath,
|
|
8760
9119
|
pathExists: (absolutePath) => plannedPaths.has(absolutePath) || existsSync3(absolutePath)
|
|
8761
9120
|
});
|
|
@@ -8806,7 +9165,7 @@ function refreshResultStatus(result) {
|
|
|
8806
9165
|
}
|
|
8807
9166
|
|
|
8808
9167
|
// src/core/generate/feature-loop.ts
|
|
8809
|
-
import { join as
|
|
9168
|
+
import { join as join51 } from "path";
|
|
8810
9169
|
function computeStatus(existing, content) {
|
|
8811
9170
|
if (existing === null) return "created";
|
|
8812
9171
|
if (existing !== content) return "updated";
|
|
@@ -8814,13 +9173,13 @@ function computeStatus(existing, content) {
|
|
|
8814
9173
|
}
|
|
8815
9174
|
async function generateFeature(results, targets, canonical, projectRoot, enabled, getGen) {
|
|
8816
9175
|
if (!enabled) return;
|
|
8817
|
-
for (const
|
|
8818
|
-
const gen = getGen(
|
|
9176
|
+
for (const target12 of targets) {
|
|
9177
|
+
const gen = getGen(target12);
|
|
8819
9178
|
if (!gen) continue;
|
|
8820
9179
|
for (const out of gen(canonical)) {
|
|
8821
|
-
const existing = await readFileSafe(
|
|
9180
|
+
const existing = await readFileSafe(join51(projectRoot, out.path));
|
|
8822
9181
|
results.push({
|
|
8823
|
-
target:
|
|
9182
|
+
target: target12,
|
|
8824
9183
|
path: out.path,
|
|
8825
9184
|
content: out.content,
|
|
8826
9185
|
currentContent: existing ?? void 0,
|
|
@@ -8838,8 +9197,8 @@ function getDescriptor(name) {
|
|
|
8838
9197
|
return descriptorRegistry.get(name) ?? builtinDescriptors.get(name);
|
|
8839
9198
|
}
|
|
8840
9199
|
function getTarget(name) {
|
|
8841
|
-
const
|
|
8842
|
-
if (
|
|
9200
|
+
const descriptor12 = getDescriptor(name);
|
|
9201
|
+
if (descriptor12) return descriptor12.generators;
|
|
8843
9202
|
const legacy = legacyRegistry.get(name);
|
|
8844
9203
|
if (legacy) return legacy;
|
|
8845
9204
|
throw new Error(`Unknown target: ${name}`);
|
|
@@ -8863,10 +9222,10 @@ function decoratePrimaryRootInstructions(results) {
|
|
|
8863
9222
|
}
|
|
8864
9223
|
|
|
8865
9224
|
// src/core/generate/optional-features.ts
|
|
8866
|
-
import { join as
|
|
9225
|
+
import { join as join53 } from "path";
|
|
8867
9226
|
|
|
8868
9227
|
// src/targets/copilot/hook-assets.ts
|
|
8869
|
-
import { join as
|
|
9228
|
+
import { join as join52, relative as relative19 } from "path";
|
|
8870
9229
|
var SCRIPT_PREFIX_RE = /^(?<prefix>\s*(?:(?:bash|sh|zsh)\s+)?)["']?(?<path>(?:\.\.\/|\.\/|[^/\s"'`]+\/)[^\s"'`]+)["']?(?<suffix>(?:\s.*)?)$/;
|
|
8871
9230
|
function safePhaseName(phase) {
|
|
8872
9231
|
return phase.replace(/[^a-zA-Z0-9]/g, "-").toLowerCase();
|
|
@@ -8887,7 +9246,7 @@ async function buildAssetOutput(projectRoot, command) {
|
|
|
8887
9246
|
const match = command.match(SCRIPT_PREFIX_RE);
|
|
8888
9247
|
const sourceToken = match?.groups?.["path"];
|
|
8889
9248
|
if (!sourceToken) return null;
|
|
8890
|
-
const sourcePath =
|
|
9249
|
+
const sourcePath = join52(projectRoot, sourceToken);
|
|
8891
9250
|
const assetContent = await readFileSafe(sourcePath);
|
|
8892
9251
|
if (assetContent === null) return null;
|
|
8893
9252
|
const repoRelative = toRepoRelative(projectRoot, sourcePath);
|
|
@@ -8975,14 +9334,14 @@ function mergeGeminiSettingsJson(existing, newContent) {
|
|
|
8975
9334
|
|
|
8976
9335
|
// src/core/generate/optional-features.ts
|
|
8977
9336
|
async function generatePermissionsFeature(results, targets, canonical, projectRoot) {
|
|
8978
|
-
for (const
|
|
8979
|
-
const gen = resolveTargetFeatureGenerator(
|
|
9337
|
+
for (const target12 of targets) {
|
|
9338
|
+
const gen = resolveTargetFeatureGenerator(target12, "permissions");
|
|
8980
9339
|
if (!gen) continue;
|
|
8981
9340
|
for (const out of gen(canonical)) {
|
|
8982
|
-
const existing = await readFileSafe(
|
|
9341
|
+
const existing = await readFileSafe(join53(projectRoot, out.path));
|
|
8983
9342
|
const content = existing !== null && SETTINGS_JSON_PATHS.includes(out.path) ? mergeSettingsJson(existing, out.content) : out.content;
|
|
8984
9343
|
results.push({
|
|
8985
|
-
target:
|
|
9344
|
+
target: target12,
|
|
8986
9345
|
path: out.path,
|
|
8987
9346
|
content,
|
|
8988
9347
|
currentContent: existing ?? void 0,
|
|
@@ -8992,15 +9351,15 @@ async function generatePermissionsFeature(results, targets, canonical, projectRo
|
|
|
8992
9351
|
}
|
|
8993
9352
|
}
|
|
8994
9353
|
async function generateHooksFeature(results, targets, canonical, projectRoot) {
|
|
8995
|
-
for (const
|
|
8996
|
-
const gen = resolveTargetFeatureGenerator(
|
|
9354
|
+
for (const target12 of targets) {
|
|
9355
|
+
const gen = resolveTargetFeatureGenerator(target12, "hooks");
|
|
8997
9356
|
if (!gen) continue;
|
|
8998
|
-
const outputs =
|
|
9357
|
+
const outputs = target12 === "copilot" ? await addHookScriptAssets(projectRoot, canonical, gen(canonical)) : gen(canonical);
|
|
8999
9358
|
for (const out of outputs) {
|
|
9000
|
-
const existing = await readFileSafe(
|
|
9359
|
+
const existing = await readFileSafe(join53(projectRoot, out.path));
|
|
9001
9360
|
let content = out.content;
|
|
9002
9361
|
if (SETTINGS_JSON_PATHS.includes(out.path)) {
|
|
9003
|
-
const pendingIdx = results.findIndex((r) => r.path === out.path && r.target ===
|
|
9362
|
+
const pendingIdx = results.findIndex((r) => r.path === out.path && r.target === target12);
|
|
9004
9363
|
const pendingResult = pendingIdx >= 0 ? results[pendingIdx] : void 0;
|
|
9005
9364
|
const base = pendingResult?.content ?? existing;
|
|
9006
9365
|
if (base !== null) {
|
|
@@ -9011,7 +9370,7 @@ async function generateHooksFeature(results, targets, canonical, projectRoot) {
|
|
|
9011
9370
|
}
|
|
9012
9371
|
}
|
|
9013
9372
|
results.push({
|
|
9014
|
-
target:
|
|
9373
|
+
target: target12,
|
|
9015
9374
|
path: out.path,
|
|
9016
9375
|
content,
|
|
9017
9376
|
currentContent: existing ?? void 0,
|
|
@@ -9021,17 +9380,17 @@ async function generateHooksFeature(results, targets, canonical, projectRoot) {
|
|
|
9021
9380
|
}
|
|
9022
9381
|
}
|
|
9023
9382
|
async function generateGeminiSettingsFeature(results, targets, canonical, projectRoot) {
|
|
9024
|
-
for (const
|
|
9025
|
-
if (
|
|
9026
|
-
const gen = resolveTargetFeatureGenerator(
|
|
9383
|
+
for (const target12 of targets) {
|
|
9384
|
+
if (target12 !== "gemini-cli") continue;
|
|
9385
|
+
const gen = resolveTargetFeatureGenerator(target12, "settings");
|
|
9027
9386
|
if (!gen) continue;
|
|
9028
9387
|
const outputs = gen(canonical);
|
|
9029
9388
|
if (outputs.length === 0) continue;
|
|
9030
9389
|
for (const out of outputs) {
|
|
9031
|
-
const existing = await readFileSafe(
|
|
9390
|
+
const existing = await readFileSafe(join53(projectRoot, out.path));
|
|
9032
9391
|
const content = existing !== null && out.path === GEMINI_SETTINGS ? mergeGeminiSettingsJson(existing, out.content) : out.content;
|
|
9033
9392
|
results.push({
|
|
9034
|
-
target:
|
|
9393
|
+
target: target12,
|
|
9035
9394
|
path: out.path,
|
|
9036
9395
|
content,
|
|
9037
9396
|
currentContent: existing ?? void 0,
|
|
@@ -9060,7 +9419,7 @@ async function generate(ctx) {
|
|
|
9060
9419
|
canonical,
|
|
9061
9420
|
projectRoot,
|
|
9062
9421
|
hasRules,
|
|
9063
|
-
(
|
|
9422
|
+
(target12) => resolveTargetFeatureGenerator(target12, "rules", config)
|
|
9064
9423
|
);
|
|
9065
9424
|
await generateFeature(
|
|
9066
9425
|
results,
|
|
@@ -9068,7 +9427,7 @@ async function generate(ctx) {
|
|
|
9068
9427
|
canonical,
|
|
9069
9428
|
projectRoot,
|
|
9070
9429
|
hasCommands,
|
|
9071
|
-
(
|
|
9430
|
+
(target12) => resolveTargetFeatureGenerator(target12, "commands", config)
|
|
9072
9431
|
);
|
|
9073
9432
|
await generateFeature(
|
|
9074
9433
|
results,
|
|
@@ -9076,7 +9435,7 @@ async function generate(ctx) {
|
|
|
9076
9435
|
canonical,
|
|
9077
9436
|
projectRoot,
|
|
9078
9437
|
hasAgents,
|
|
9079
|
-
(
|
|
9438
|
+
(target12) => resolveTargetFeatureGenerator(target12, "agents", config)
|
|
9080
9439
|
);
|
|
9081
9440
|
await generateFeature(
|
|
9082
9441
|
results,
|
|
@@ -9084,7 +9443,7 @@ async function generate(ctx) {
|
|
|
9084
9443
|
canonical,
|
|
9085
9444
|
projectRoot,
|
|
9086
9445
|
hasSkills,
|
|
9087
|
-
(
|
|
9446
|
+
(target12) => resolveTargetFeatureGenerator(target12, "skills", config)
|
|
9088
9447
|
);
|
|
9089
9448
|
await generateFeature(
|
|
9090
9449
|
results,
|
|
@@ -9092,7 +9451,7 @@ async function generate(ctx) {
|
|
|
9092
9451
|
canonical,
|
|
9093
9452
|
projectRoot,
|
|
9094
9453
|
hasMcp,
|
|
9095
|
-
(
|
|
9454
|
+
(target12) => resolveTargetFeatureGenerator(target12, "mcp", config)
|
|
9096
9455
|
);
|
|
9097
9456
|
if (hasPermissions) await generatePermissionsFeature(results, targets, canonical, projectRoot);
|
|
9098
9457
|
if (hasHooks) await generateHooksFeature(results, targets, canonical, projectRoot);
|
|
@@ -9102,7 +9461,7 @@ async function generate(ctx) {
|
|
|
9102
9461
|
canonical,
|
|
9103
9462
|
projectRoot,
|
|
9104
9463
|
hasIgnore,
|
|
9105
|
-
(
|
|
9464
|
+
(target12) => resolveTargetFeatureGenerator(target12, "ignore", config)
|
|
9106
9465
|
);
|
|
9107
9466
|
if (hasMcp || hasIgnore || hasHooks || hasAgents) {
|
|
9108
9467
|
await generateGeminiSettingsFeature(results, targets, canonical, projectRoot);
|
|
@@ -9113,8 +9472,8 @@ async function generate(ctx) {
|
|
|
9113
9472
|
}
|
|
9114
9473
|
|
|
9115
9474
|
// src/core/generate/stale-cleanup.ts
|
|
9116
|
-
import { readdir as
|
|
9117
|
-
import { join as
|
|
9475
|
+
import { readdir as readdir12, rm as rm6 } from "fs/promises";
|
|
9476
|
+
import { join as join54, relative as relative20 } from "path";
|
|
9118
9477
|
var TARGET_MANAGED_OUTPUTS = {
|
|
9119
9478
|
"claude-code": {
|
|
9120
9479
|
dirs: [".claude/agents", ".claude/commands", ".claude/rules", ".claude/skills"],
|
|
@@ -9177,10 +9536,10 @@ var TARGET_MANAGED_OUTPUTS = {
|
|
|
9177
9536
|
}
|
|
9178
9537
|
};
|
|
9179
9538
|
async function listFiles2(root, base = root) {
|
|
9180
|
-
const entries = await
|
|
9539
|
+
const entries = await readdir12(root, { withFileTypes: true });
|
|
9181
9540
|
const files = [];
|
|
9182
9541
|
for (const entry of entries) {
|
|
9183
|
-
const abs =
|
|
9542
|
+
const abs = join54(root, entry.name);
|
|
9184
9543
|
if (entry.isDirectory()) {
|
|
9185
9544
|
files.push(...await listFiles2(abs, base));
|
|
9186
9545
|
continue;
|
|
@@ -9191,18 +9550,18 @@ async function listFiles2(root, base = root) {
|
|
|
9191
9550
|
}
|
|
9192
9551
|
async function removeIfStale(projectRoot, relPath, expected) {
|
|
9193
9552
|
if (expected.has(relPath)) return;
|
|
9194
|
-
const abs =
|
|
9553
|
+
const abs = join54(projectRoot, relPath);
|
|
9195
9554
|
if (await exists(abs)) await rm6(abs, { recursive: true, force: true });
|
|
9196
9555
|
}
|
|
9197
9556
|
async function cleanupStaleGeneratedOutputs(args) {
|
|
9198
9557
|
const expected = new Set(args.expectedPaths);
|
|
9199
9558
|
const stale = /* @__PURE__ */ new Set();
|
|
9200
|
-
for (const
|
|
9201
|
-
const managed = TARGET_MANAGED_OUTPUTS[
|
|
9559
|
+
for (const target12 of args.targets) {
|
|
9560
|
+
const managed = TARGET_MANAGED_OUTPUTS[target12];
|
|
9202
9561
|
if (!managed) continue;
|
|
9203
9562
|
for (const file of managed.files) stale.add(file);
|
|
9204
9563
|
for (const dir of managed.dirs) {
|
|
9205
|
-
const absDir =
|
|
9564
|
+
const absDir = join54(args.projectRoot, dir);
|
|
9206
9565
|
if (!await exists(absDir)) continue;
|
|
9207
9566
|
for (const file of await listFiles2(absDir)) {
|
|
9208
9567
|
stale.add(`${dir}/${file}`.replace(/\/+/g, "/"));
|
|
@@ -9215,17 +9574,17 @@ async function cleanupStaleGeneratedOutputs(args) {
|
|
|
9215
9574
|
}
|
|
9216
9575
|
|
|
9217
9576
|
// src/core/matrix/matrix.ts
|
|
9218
|
-
import { basename as
|
|
9577
|
+
import { basename as basename31 } from "path";
|
|
9219
9578
|
|
|
9220
9579
|
// src/targets/catalog/target-catalog.ts
|
|
9221
9580
|
var TARGET_CATALOG = Object.fromEntries(
|
|
9222
|
-
BUILTIN_TARGETS.map((
|
|
9223
|
-
|
|
9581
|
+
BUILTIN_TARGETS.map((target12) => [
|
|
9582
|
+
target12.id,
|
|
9224
9583
|
{
|
|
9225
|
-
importFrom:
|
|
9226
|
-
emptyImportMessage:
|
|
9227
|
-
lintRules:
|
|
9228
|
-
capabilities:
|
|
9584
|
+
importFrom: target12.generators.importFrom,
|
|
9585
|
+
emptyImportMessage: target12.emptyImportMessage,
|
|
9586
|
+
lintRules: target12.lintRules,
|
|
9587
|
+
capabilities: target12.capabilities
|
|
9229
9588
|
}
|
|
9230
9589
|
])
|
|
9231
9590
|
);
|
|
@@ -9252,7 +9611,7 @@ var SUPPORT_MATRIX = Object.fromEntries(
|
|
|
9252
9611
|
FEATURE_IDS.map((feature) => [
|
|
9253
9612
|
feature,
|
|
9254
9613
|
Object.fromEntries(
|
|
9255
|
-
TARGET_IDS.map((
|
|
9614
|
+
TARGET_IDS.map((target12) => [target12, TARGET_CATALOG[target12].capabilities[feature]])
|
|
9256
9615
|
)
|
|
9257
9616
|
])
|
|
9258
9617
|
);
|
|
@@ -9358,13 +9717,13 @@ function formatMatrix(rows, targets) {
|
|
|
9358
9717
|
function formatVerboseDetails(canonical) {
|
|
9359
9718
|
const lines = [];
|
|
9360
9719
|
if (canonical.rules.length > 0) {
|
|
9361
|
-
lines.push(`rules: ${canonical.rules.map((r) =>
|
|
9720
|
+
lines.push(`rules: ${canonical.rules.map((r) => basename31(r.source)).join(", ")}`);
|
|
9362
9721
|
}
|
|
9363
9722
|
if (canonical.commands.length > 0) {
|
|
9364
|
-
lines.push(`commands: ${canonical.commands.map((c2) =>
|
|
9723
|
+
lines.push(`commands: ${canonical.commands.map((c2) => basename31(c2.source)).join(", ")}`);
|
|
9365
9724
|
}
|
|
9366
9725
|
if (canonical.agents.length > 0) {
|
|
9367
|
-
lines.push(`agents: ${canonical.agents.map((a) =>
|
|
9726
|
+
lines.push(`agents: ${canonical.agents.map((a) => basename31(a.source)).join(", ")}`);
|
|
9368
9727
|
}
|
|
9369
9728
|
if (canonical.skills.length > 0) {
|
|
9370
9729
|
lines.push(`skills: ${canonical.skills.map((s) => s.name).join(", ")}`);
|
|
@@ -9416,11 +9775,11 @@ async function runMatrix(flags, projectRoot) {
|
|
|
9416
9775
|
}
|
|
9417
9776
|
|
|
9418
9777
|
// src/cli/commands/generate.ts
|
|
9419
|
-
function ensurePathInsideRoot(rootDir, relativePath,
|
|
9778
|
+
function ensurePathInsideRoot(rootDir, relativePath, target12) {
|
|
9420
9779
|
const rootAbs = resolve4(rootDir);
|
|
9421
9780
|
const outputAbs = resolve4(rootDir, relativePath);
|
|
9422
9781
|
if (outputAbs === rootAbs || outputAbs.startsWith(`${rootAbs}${sep}`)) return outputAbs;
|
|
9423
|
-
throw new Error(`Unsafe generated output path for ${
|
|
9782
|
+
throw new Error(`Unsafe generated output path for ${target12}: ${relativePath}`);
|
|
9424
9783
|
}
|
|
9425
9784
|
async function runGenerate(flags, projectRoot, options = {}) {
|
|
9426
9785
|
if (flags.features !== void 0) {
|
|
@@ -9436,7 +9795,7 @@ async function runGenerate(flags, projectRoot, options = {}) {
|
|
|
9436
9795
|
const { config, configDir } = await loadConfigFromDir(root);
|
|
9437
9796
|
const lockFeatures = config.collaboration?.lock_features ?? [];
|
|
9438
9797
|
if (config.collaboration?.strategy === "lock" && !force && lockFeatures.length > 0) {
|
|
9439
|
-
const abDir =
|
|
9798
|
+
const abDir = join55(configDir, ".agentsmesh");
|
|
9440
9799
|
const existingLock = await readLock(abDir);
|
|
9441
9800
|
if (existingLock !== null) {
|
|
9442
9801
|
const currentChecksums = await buildChecksums(abDir);
|
|
@@ -9472,10 +9831,10 @@ async function runGenerate(flags, projectRoot, options = {}) {
|
|
|
9472
9831
|
return 0;
|
|
9473
9832
|
}
|
|
9474
9833
|
if (!dryRun) {
|
|
9475
|
-
const abDir =
|
|
9834
|
+
const abDir = join55(configDir, ".agentsmesh");
|
|
9476
9835
|
const checksums = await buildChecksums(abDir);
|
|
9477
9836
|
const extendChecksums = resolvedExtends.length > 0 ? await buildExtendChecksums(resolvedExtends) : {};
|
|
9478
|
-
const packChecksums = await buildPackChecksums(
|
|
9837
|
+
const packChecksums = await buildPackChecksums(join55(abDir, "packs"));
|
|
9479
9838
|
const generatedBy = process.env["USER"] ?? process.env["USERNAME"] ?? "unknown";
|
|
9480
9839
|
await writeLock(abDir, {
|
|
9481
9840
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -9486,7 +9845,7 @@ async function runGenerate(flags, projectRoot, options = {}) {
|
|
|
9486
9845
|
packs: packChecksums
|
|
9487
9846
|
});
|
|
9488
9847
|
try {
|
|
9489
|
-
await ensureCacheSymlink(getCacheDir(),
|
|
9848
|
+
await ensureCacheSymlink(getCacheDir(), join55(configDir, ".agentsmeshcache"));
|
|
9490
9849
|
} catch (err) {
|
|
9491
9850
|
logger.warn(
|
|
9492
9851
|
`Could not create .agentsmeshcache symlink: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -9533,10 +9892,10 @@ async function runGenerate(flags, projectRoot, options = {}) {
|
|
|
9533
9892
|
} else {
|
|
9534
9893
|
logger.info(`Nothing changed. (${unchanged} unchanged)`);
|
|
9535
9894
|
}
|
|
9536
|
-
const abDir =
|
|
9895
|
+
const abDir = join55(configDir, ".agentsmesh");
|
|
9537
9896
|
const checksums = await buildChecksums(abDir);
|
|
9538
9897
|
const extendChecksums = resolvedExtends.length > 0 ? await buildExtendChecksums(resolvedExtends) : {};
|
|
9539
|
-
const packChecksums = await buildPackChecksums(
|
|
9898
|
+
const packChecksums = await buildPackChecksums(join55(abDir, "packs"));
|
|
9540
9899
|
const generatedBy = process.env["USER"] ?? process.env["USERNAME"] ?? "unknown";
|
|
9541
9900
|
await writeLock(abDir, {
|
|
9542
9901
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -9547,7 +9906,7 @@ async function runGenerate(flags, projectRoot, options = {}) {
|
|
|
9547
9906
|
packs: packChecksums
|
|
9548
9907
|
});
|
|
9549
9908
|
try {
|
|
9550
|
-
await ensureCacheSymlink(getCacheDir(),
|
|
9909
|
+
await ensureCacheSymlink(getCacheDir(), join55(configDir, ".agentsmeshcache"));
|
|
9551
9910
|
} catch (err) {
|
|
9552
9911
|
logger.warn(
|
|
9553
9912
|
`Could not create .agentsmeshcache symlink: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -9561,7 +9920,7 @@ async function runGenerate(flags, projectRoot, options = {}) {
|
|
|
9561
9920
|
}
|
|
9562
9921
|
|
|
9563
9922
|
// src/cli/commands/init.ts
|
|
9564
|
-
import { join as
|
|
9923
|
+
import { join as join57 } from "path";
|
|
9565
9924
|
|
|
9566
9925
|
// src/cli/commands/init-templates.ts
|
|
9567
9926
|
var ALL_TARGETS = [
|
|
@@ -9717,7 +10076,7 @@ var LOCAL_TEMPLATE = `# Personal overrides \u2014 NOT committed to git
|
|
|
9717
10076
|
`;
|
|
9718
10077
|
|
|
9719
10078
|
// src/cli/commands/init-detect.ts
|
|
9720
|
-
import { join as
|
|
10079
|
+
import { join as join56 } from "path";
|
|
9721
10080
|
var TOOL_INDICATORS = BUILTIN_TARGETS.map((d) => ({
|
|
9722
10081
|
id: d.id,
|
|
9723
10082
|
paths: [...d.detectionPaths]
|
|
@@ -9726,7 +10085,7 @@ async function detectExistingConfigs(projectRoot) {
|
|
|
9726
10085
|
const found = [];
|
|
9727
10086
|
for (const { id, paths } of TOOL_INDICATORS) {
|
|
9728
10087
|
for (const p of paths) {
|
|
9729
|
-
const full =
|
|
10088
|
+
const full = join56(projectRoot, p);
|
|
9730
10089
|
if (await exists(full)) {
|
|
9731
10090
|
found.push(id);
|
|
9732
10091
|
break;
|
|
@@ -9744,7 +10103,7 @@ var IMPORTERS = Object.fromEntries(
|
|
|
9744
10103
|
BUILTIN_TARGETS.map((d) => [d.id, (root) => d.generators.importFrom(root)])
|
|
9745
10104
|
);
|
|
9746
10105
|
async function appendToGitignore(projectRoot) {
|
|
9747
|
-
const gitignorePath =
|
|
10106
|
+
const gitignorePath = join57(projectRoot, ".gitignore");
|
|
9748
10107
|
const current = await readFileSafe(gitignorePath) ?? "";
|
|
9749
10108
|
const lines = new Set(current.split("\n").map((s) => s.trim()));
|
|
9750
10109
|
const toAdd = GITIGNORE_ENTRIES.filter((e) => !lines.has(e));
|
|
@@ -9753,7 +10112,7 @@ async function appendToGitignore(projectRoot) {
|
|
|
9753
10112
|
await writeFileAtomic(gitignorePath, current + suffix + toAdd.join("\n") + "\n");
|
|
9754
10113
|
}
|
|
9755
10114
|
async function writeScaffold(projectRoot) {
|
|
9756
|
-
const ab = (rel2) =>
|
|
10115
|
+
const ab = (rel2) => join57(projectRoot, ".agentsmesh", rel2);
|
|
9757
10116
|
await mkdirp(ab("rules"));
|
|
9758
10117
|
await writeFileAtomic(ab("rules/_root.md"), TEMPLATE_ROOT_RULE);
|
|
9759
10118
|
logger.success("Created .agentsmesh/rules/_root.md");
|
|
@@ -9778,7 +10137,7 @@ async function writeScaffold(projectRoot) {
|
|
|
9778
10137
|
logger.success("Created .agentsmesh/ignore");
|
|
9779
10138
|
}
|
|
9780
10139
|
async function runInit(projectRoot, options = {}) {
|
|
9781
|
-
const configPath =
|
|
10140
|
+
const configPath = join57(projectRoot, CONFIG_FILENAME2);
|
|
9782
10141
|
if (await exists(configPath)) {
|
|
9783
10142
|
throw new Error(`Already initialized. ${CONFIG_FILENAME2} exists. Remove it first to re-init.`);
|
|
9784
10143
|
}
|
|
@@ -9815,7 +10174,7 @@ async function runInit(projectRoot, options = {}) {
|
|
|
9815
10174
|
await writeFileAtomic(configPath, buildConfig([]));
|
|
9816
10175
|
logger.success(`Created ${CONFIG_FILENAME2}`);
|
|
9817
10176
|
}
|
|
9818
|
-
const localPath =
|
|
10177
|
+
const localPath = join57(projectRoot, LOCAL_CONFIG_FILENAME2);
|
|
9819
10178
|
await writeFileAtomic(localPath, LOCAL_TEMPLATE);
|
|
9820
10179
|
logger.success(`Created ${LOCAL_CONFIG_FILENAME2}`);
|
|
9821
10180
|
await appendToGitignore(projectRoot);
|
|
@@ -9834,10 +10193,10 @@ async function runImport(flags, projectRoot) {
|
|
|
9834
10193
|
if (!isBuiltinTargetId(normalized)) {
|
|
9835
10194
|
throw new Error(`Unknown --from "${from}". Supported: ${TARGET_IDS.join(", ")}.`);
|
|
9836
10195
|
}
|
|
9837
|
-
const
|
|
9838
|
-
const results = await
|
|
10196
|
+
const target12 = getTargetCatalogEntry(normalized);
|
|
10197
|
+
const results = await target12.importFrom(root);
|
|
9839
10198
|
if (results.length === 0) {
|
|
9840
|
-
logger.info(
|
|
10199
|
+
logger.info(target12.emptyImportMessage);
|
|
9841
10200
|
return;
|
|
9842
10201
|
}
|
|
9843
10202
|
for (const r of results) {
|
|
@@ -9922,56 +10281,56 @@ async function runDiff(flags, projectRoot) {
|
|
|
9922
10281
|
import { relative as relative22 } from "path";
|
|
9923
10282
|
|
|
9924
10283
|
// src/core/lint/commands.ts
|
|
9925
|
-
function lintCommands(canonical,
|
|
10284
|
+
function lintCommands(canonical, target12) {
|
|
9926
10285
|
if (canonical.commands.length === 0) return [];
|
|
9927
10286
|
return canonical.commands.flatMap((command) => {
|
|
9928
|
-
if (
|
|
10287
|
+
if (target12 === "copilot" && command.allowedTools.length > 0) {
|
|
9929
10288
|
return [
|
|
9930
10289
|
{
|
|
9931
10290
|
level: "warning",
|
|
9932
10291
|
file: command.source,
|
|
9933
|
-
target:
|
|
10292
|
+
target: target12,
|
|
9934
10293
|
message: "Copilot prompt files do not enforce canonical allowed-tools natively."
|
|
9935
10294
|
}
|
|
9936
10295
|
];
|
|
9937
10296
|
}
|
|
9938
|
-
if (
|
|
10297
|
+
if (target12 === "cursor" && (command.description.length > 0 || command.allowedTools.length > 0)) {
|
|
9939
10298
|
return [
|
|
9940
10299
|
{
|
|
9941
10300
|
level: "warning",
|
|
9942
10301
|
file: command.source,
|
|
9943
|
-
target:
|
|
10302
|
+
target: target12,
|
|
9944
10303
|
message: "Cursor command files are plain Markdown; command description and allowed-tools metadata are not projected."
|
|
9945
10304
|
}
|
|
9946
10305
|
];
|
|
9947
10306
|
}
|
|
9948
|
-
if (
|
|
10307
|
+
if (target12 === "gemini-cli" && command.allowedTools.length > 0) {
|
|
9949
10308
|
return [
|
|
9950
10309
|
{
|
|
9951
10310
|
level: "warning",
|
|
9952
10311
|
file: command.source,
|
|
9953
|
-
target:
|
|
10312
|
+
target: target12,
|
|
9954
10313
|
message: "Gemini TOML command files do not project canonical allowed-tools metadata."
|
|
9955
10314
|
}
|
|
9956
10315
|
];
|
|
9957
10316
|
}
|
|
9958
|
-
if (
|
|
10317
|
+
if (target12 === "continue" && command.allowedTools.length > 0) {
|
|
9959
10318
|
return [
|
|
9960
10319
|
{
|
|
9961
10320
|
level: "warning",
|
|
9962
10321
|
file: command.source,
|
|
9963
|
-
target:
|
|
10322
|
+
target: target12,
|
|
9964
10323
|
message: "Continue invokable prompt rules do not natively enforce canonical allowed-tools metadata."
|
|
9965
10324
|
}
|
|
9966
10325
|
];
|
|
9967
10326
|
}
|
|
9968
|
-
if (["cline", "windsurf"].includes(
|
|
10327
|
+
if (["cline", "windsurf"].includes(target12) && (command.description.length > 0 || command.allowedTools.length > 0)) {
|
|
9969
10328
|
return [
|
|
9970
10329
|
{
|
|
9971
10330
|
level: "warning",
|
|
9972
10331
|
file: command.source,
|
|
9973
|
-
target:
|
|
9974
|
-
message: `${
|
|
10332
|
+
target: target12,
|
|
10333
|
+
message: `${target12} workflow files are plain Markdown; command description and allowed-tools metadata are not projected.`
|
|
9975
10334
|
}
|
|
9976
10335
|
];
|
|
9977
10336
|
}
|
|
@@ -9980,48 +10339,48 @@ function lintCommands(canonical, target11) {
|
|
|
9980
10339
|
}
|
|
9981
10340
|
|
|
9982
10341
|
// src/core/lint/mcp.ts
|
|
9983
|
-
function lintMcp(canonical,
|
|
10342
|
+
function lintMcp(canonical, target12) {
|
|
9984
10343
|
if (!canonical.mcp || Object.keys(canonical.mcp.mcpServers).length === 0) return [];
|
|
9985
10344
|
const diagnostics = [];
|
|
9986
10345
|
for (const [name, server] of Object.entries(canonical.mcp.mcpServers)) {
|
|
9987
|
-
if (
|
|
10346
|
+
if (target12 === "cursor" && usesCursorSensitiveInterpolation(server)) {
|
|
9988
10347
|
diagnostics.push({
|
|
9989
10348
|
level: "warning",
|
|
9990
10349
|
file: ".agentsmesh/mcp.json",
|
|
9991
|
-
target:
|
|
10350
|
+
target: target12,
|
|
9992
10351
|
message: `MCP server "${name}" uses env vars or URL/header interpolation; Cursor handling may differ from canonical MCP.`
|
|
9993
10352
|
});
|
|
9994
10353
|
}
|
|
9995
|
-
if (
|
|
10354
|
+
if (target12 === "codex-cli" && typeof server.description === "string" && server.description) {
|
|
9996
10355
|
diagnostics.push({
|
|
9997
10356
|
level: "warning",
|
|
9998
10357
|
file: ".agentsmesh/mcp.json",
|
|
9999
|
-
target:
|
|
10358
|
+
target: target12,
|
|
10000
10359
|
message: `MCP server "${name}" has a description, but codex-cli does not project MCP descriptions into .codex/config.toml.`
|
|
10001
10360
|
});
|
|
10002
10361
|
}
|
|
10003
|
-
if (
|
|
10362
|
+
if (target12 === "codex-cli" && isUrlMcpServer(server)) {
|
|
10004
10363
|
diagnostics.push({
|
|
10005
10364
|
level: "warning",
|
|
10006
10365
|
file: ".agentsmesh/mcp.json",
|
|
10007
|
-
target:
|
|
10366
|
+
target: target12,
|
|
10008
10367
|
message: `MCP server "${name}" uses ${server.type} transport; codex-cli only generates stdio MCP servers.`
|
|
10009
10368
|
});
|
|
10010
10369
|
}
|
|
10011
|
-
if (
|
|
10370
|
+
if (target12 === "junie" && isUrlMcpServer(server)) {
|
|
10012
10371
|
diagnostics.push({
|
|
10013
10372
|
level: "warning",
|
|
10014
10373
|
file: ".agentsmesh/mcp.json",
|
|
10015
|
-
target:
|
|
10374
|
+
target: target12,
|
|
10016
10375
|
message: `MCP server "${name}" uses ${server.type} transport; Junie project mcp.json currently documents stdio MCP servers only.`
|
|
10017
10376
|
});
|
|
10018
10377
|
}
|
|
10019
10378
|
}
|
|
10020
|
-
if (
|
|
10379
|
+
if (target12 === "windsurf") {
|
|
10021
10380
|
diagnostics.push({
|
|
10022
10381
|
level: "warning",
|
|
10023
10382
|
file: ".agentsmesh/mcp.json",
|
|
10024
|
-
target:
|
|
10383
|
+
target: target12,
|
|
10025
10384
|
message: "Windsurf MCP is partial; generated .windsurf/mcp_config.example.json is a reference artifact and may require manual setup."
|
|
10026
10385
|
});
|
|
10027
10386
|
}
|
|
@@ -10029,39 +10388,39 @@ function lintMcp(canonical, target11) {
|
|
|
10029
10388
|
}
|
|
10030
10389
|
|
|
10031
10390
|
// src/core/lint/permissions.ts
|
|
10032
|
-
function lintPermissions(canonical,
|
|
10391
|
+
function lintPermissions(canonical, target12) {
|
|
10033
10392
|
if (!canonical.permissions) return [];
|
|
10034
|
-
if (
|
|
10393
|
+
if (target12 !== "cursor") return [];
|
|
10035
10394
|
const hasEntries = canonical.permissions.allow.length > 0 || canonical.permissions.deny.length > 0;
|
|
10036
10395
|
if (!hasEntries) return [];
|
|
10037
10396
|
return [
|
|
10038
10397
|
{
|
|
10039
10398
|
level: "warning",
|
|
10040
10399
|
file: ".agentsmesh/permissions.yaml",
|
|
10041
|
-
target:
|
|
10400
|
+
target: target12,
|
|
10042
10401
|
message: "Cursor permissions are partial; tool-level allow/deny may lose fidelity."
|
|
10043
10402
|
}
|
|
10044
10403
|
];
|
|
10045
10404
|
}
|
|
10046
10405
|
|
|
10047
10406
|
// src/core/lint/hooks.ts
|
|
10048
|
-
function lintHooks(canonical,
|
|
10407
|
+
function lintHooks(canonical, target12) {
|
|
10049
10408
|
if (!canonical.hooks || Object.keys(canonical.hooks).length === 0) return [];
|
|
10050
|
-
if (
|
|
10409
|
+
if (target12 === "gemini-cli") {
|
|
10051
10410
|
const supported = /* @__PURE__ */ new Set(["PreToolUse", "PostToolUse", "Notification"]);
|
|
10052
10411
|
return Object.keys(canonical.hooks).filter((event) => !supported.has(event)).map((event) => ({
|
|
10053
10412
|
level: "warning",
|
|
10054
10413
|
file: ".agentsmesh/hooks.yaml",
|
|
10055
|
-
target:
|
|
10414
|
+
target: target12,
|
|
10056
10415
|
message: `${event} is not supported by gemini-cli; only PreToolUse, PostToolUse, and Notification are projected.`
|
|
10057
10416
|
}));
|
|
10058
10417
|
}
|
|
10059
|
-
if (
|
|
10418
|
+
if (target12 === "copilot") {
|
|
10060
10419
|
const supported = /* @__PURE__ */ new Set(["PreToolUse", "PostToolUse", "Notification", "UserPromptSubmit"]);
|
|
10061
10420
|
return Object.keys(canonical.hooks).filter((event) => !supported.has(event)).map((event) => ({
|
|
10062
10421
|
level: "warning",
|
|
10063
10422
|
file: ".agentsmesh/hooks.yaml",
|
|
10064
|
-
target:
|
|
10423
|
+
target: target12,
|
|
10065
10424
|
message: `${event} is not supported by Copilot hooks; only PreToolUse, PostToolUse, Notification, and UserPromptSubmit are projected.`
|
|
10066
10425
|
}));
|
|
10067
10426
|
}
|
|
@@ -10087,22 +10446,22 @@ async function runLint(config, canonical, projectRoot, targetFilter) {
|
|
|
10087
10446
|
const hasHooks = config.features.includes("hooks");
|
|
10088
10447
|
const diagnostics = [];
|
|
10089
10448
|
const projectFiles = await getProjectFiles(projectRoot);
|
|
10090
|
-
for (const
|
|
10091
|
-
const linter = isBuiltinTargetId(
|
|
10449
|
+
for (const target12 of targets) {
|
|
10450
|
+
const linter = isBuiltinTargetId(target12) ? getTargetCatalogEntry(target12).lintRules : null;
|
|
10092
10451
|
if (hasRules && linter) {
|
|
10093
10452
|
diagnostics.push(...linter(canonical, projectRoot, projectFiles));
|
|
10094
10453
|
}
|
|
10095
10454
|
if (hasCommands) {
|
|
10096
|
-
diagnostics.push(...lintCommands(canonical,
|
|
10455
|
+
diagnostics.push(...lintCommands(canonical, target12));
|
|
10097
10456
|
}
|
|
10098
10457
|
if (hasMcp) {
|
|
10099
|
-
diagnostics.push(...lintMcp(canonical,
|
|
10458
|
+
diagnostics.push(...lintMcp(canonical, target12));
|
|
10100
10459
|
}
|
|
10101
10460
|
if (hasPermissions) {
|
|
10102
|
-
diagnostics.push(...lintPermissions(canonical,
|
|
10461
|
+
diagnostics.push(...lintPermissions(canonical, target12));
|
|
10103
10462
|
}
|
|
10104
10463
|
if (hasHooks) {
|
|
10105
|
-
diagnostics.push(...lintHooks(canonical,
|
|
10464
|
+
diagnostics.push(...lintHooks(canonical, target12));
|
|
10106
10465
|
}
|
|
10107
10466
|
}
|
|
10108
10467
|
const hasErrors = diagnostics.some((d) => d.level === "error");
|
|
@@ -10142,7 +10501,7 @@ async function runLintCmd(flags, projectRoot) {
|
|
|
10142
10501
|
}
|
|
10143
10502
|
|
|
10144
10503
|
// src/cli/commands/watch.ts
|
|
10145
|
-
import { join as
|
|
10504
|
+
import { join as join58, relative as relative23 } from "path";
|
|
10146
10505
|
import chokidar from "chokidar";
|
|
10147
10506
|
var DEBOUNCE_MS = 300;
|
|
10148
10507
|
function normalizeWatchPath(path) {
|
|
@@ -10169,9 +10528,9 @@ async function runWatch(flags, projectRoot) {
|
|
|
10169
10528
|
const root = projectRoot ?? process.cwd();
|
|
10170
10529
|
const { configDir } = await loadConfigFromDir(root);
|
|
10171
10530
|
const paths = [
|
|
10172
|
-
|
|
10173
|
-
|
|
10174
|
-
|
|
10531
|
+
join58(configDir, ".agentsmesh"),
|
|
10532
|
+
join58(configDir, "agentsmesh.yaml"),
|
|
10533
|
+
join58(configDir, "agentsmesh.local.yaml")
|
|
10175
10534
|
];
|
|
10176
10535
|
let debounceTimer = null;
|
|
10177
10536
|
let lastFingerprint = null;
|
|
@@ -10257,12 +10616,12 @@ async function runWatch(flags, projectRoot) {
|
|
|
10257
10616
|
}
|
|
10258
10617
|
|
|
10259
10618
|
// src/cli/commands/check.ts
|
|
10260
|
-
import { join as
|
|
10619
|
+
import { join as join59 } from "path";
|
|
10261
10620
|
async function runCheck(flags, projectRoot) {
|
|
10262
10621
|
void flags;
|
|
10263
10622
|
const root = projectRoot ?? process.cwd();
|
|
10264
10623
|
const { config, configDir } = await loadConfigFromDir(root);
|
|
10265
|
-
const abDir =
|
|
10624
|
+
const abDir = join59(configDir, ".agentsmesh");
|
|
10266
10625
|
const lock = await readLock(abDir);
|
|
10267
10626
|
if (lock === null) {
|
|
10268
10627
|
logger.error("Not initialized for collaboration. Run 'agentsmesh generate' first.");
|
|
@@ -10332,14 +10691,14 @@ async function runCheck(flags, projectRoot) {
|
|
|
10332
10691
|
}
|
|
10333
10692
|
|
|
10334
10693
|
// src/cli/commands/merge.ts
|
|
10335
|
-
import { join as
|
|
10694
|
+
import { join as join61 } from "path";
|
|
10336
10695
|
|
|
10337
10696
|
// src/core/merger.ts
|
|
10338
|
-
import { dirname as dirname22, join as
|
|
10697
|
+
import { dirname as dirname22, join as join60 } from "path";
|
|
10339
10698
|
var LOCK_FILENAME2 = ".lock";
|
|
10340
10699
|
var CONFLICT_MARKER = "<<<<<<<";
|
|
10341
10700
|
async function hasLockConflict(abDir) {
|
|
10342
|
-
const lockPath =
|
|
10701
|
+
const lockPath = join60(abDir, LOCK_FILENAME2);
|
|
10343
10702
|
const content = await readFileSafe(lockPath);
|
|
10344
10703
|
if (content === null) return false;
|
|
10345
10704
|
return content.includes(CONFLICT_MARKER);
|
|
@@ -10353,7 +10712,7 @@ async function resolveLockConflict(abDir, libVersion, config) {
|
|
|
10353
10712
|
const configDir = dirname22(abDir);
|
|
10354
10713
|
const resolvedExtends = config ? await resolveExtendPaths(config, configDir) : [];
|
|
10355
10714
|
const extendChecksums = resolvedExtends.length > 0 ? await buildExtendChecksums(resolvedExtends) : {};
|
|
10356
|
-
const packChecksums = await buildPackChecksums(
|
|
10715
|
+
const packChecksums = await buildPackChecksums(join60(abDir, "packs"));
|
|
10357
10716
|
const generatedBy = process.env["USER"] ?? process.env["USERNAME"] ?? "unknown";
|
|
10358
10717
|
await writeLock(abDir, {
|
|
10359
10718
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -10370,7 +10729,7 @@ async function runMerge(flags, projectRoot) {
|
|
|
10370
10729
|
void flags;
|
|
10371
10730
|
const root = projectRoot ?? process.cwd();
|
|
10372
10731
|
const { config, configDir } = await loadConfigFromDir(root);
|
|
10373
|
-
const abDir =
|
|
10732
|
+
const abDir = join61(configDir, ".agentsmesh");
|
|
10374
10733
|
const hasConflict = await hasLockConflict(abDir);
|
|
10375
10734
|
if (!hasConflict) {
|
|
10376
10735
|
logger.info("No conflicts to resolve.");
|
|
@@ -10381,7 +10740,7 @@ async function runMerge(flags, projectRoot) {
|
|
|
10381
10740
|
}
|
|
10382
10741
|
|
|
10383
10742
|
// src/install/run/run-install.ts
|
|
10384
|
-
import { join as
|
|
10743
|
+
import { join as join75 } from "path";
|
|
10385
10744
|
|
|
10386
10745
|
// src/install/source/git-pin.ts
|
|
10387
10746
|
import { execFile as execFile2 } from "child_process";
|
|
@@ -10515,7 +10874,7 @@ async function confirm(message) {
|
|
|
10515
10874
|
}
|
|
10516
10875
|
|
|
10517
10876
|
// src/install/core/validate-resources.ts
|
|
10518
|
-
import { basename as
|
|
10877
|
+
import { basename as basename32 } from "path";
|
|
10519
10878
|
function validateSkill(skill) {
|
|
10520
10879
|
if (!skill.description.trim()) {
|
|
10521
10880
|
return { skill, ok: false, reason: "missing description in frontmatter" };
|
|
@@ -10541,7 +10900,7 @@ function validateAgent(agent) {
|
|
|
10541
10900
|
return { agent, ok: true };
|
|
10542
10901
|
}
|
|
10543
10902
|
function ruleSlug6(rule) {
|
|
10544
|
-
return
|
|
10903
|
+
return basename32(rule.source).replace(/\.md$/i, "");
|
|
10545
10904
|
}
|
|
10546
10905
|
|
|
10547
10906
|
// src/install/core/pool-resolution.ts
|
|
@@ -11035,7 +11394,7 @@ function ensureInstallSelection(args) {
|
|
|
11035
11394
|
}
|
|
11036
11395
|
|
|
11037
11396
|
// src/install/core/install-extend-entry.ts
|
|
11038
|
-
import { join as
|
|
11397
|
+
import { join as join62 } from "path";
|
|
11039
11398
|
|
|
11040
11399
|
// src/install/core/merge-extend-entry.ts
|
|
11041
11400
|
function assertExtendNameAvailable(extendsList, entry) {
|
|
@@ -11124,7 +11483,7 @@ async function writeInstallAsExtend(args) {
|
|
|
11124
11483
|
${JSON.stringify(entry, null, 2)}`);
|
|
11125
11484
|
return;
|
|
11126
11485
|
}
|
|
11127
|
-
const configPath =
|
|
11486
|
+
const configPath = join62(configDir, "agentsmesh.yaml");
|
|
11128
11487
|
await writeAgentsmeshWithNewExtend(configPath, config, entry);
|
|
11129
11488
|
logger.success(`Wrote extends entry "${entry.name}" to agentsmesh.yaml.`);
|
|
11130
11489
|
}
|
|
@@ -11141,11 +11500,11 @@ function toNewExtendEntry(args) {
|
|
|
11141
11500
|
}
|
|
11142
11501
|
|
|
11143
11502
|
// src/install/run/run-install-pack.ts
|
|
11144
|
-
import { join as
|
|
11503
|
+
import { join as join66 } from "path";
|
|
11145
11504
|
import { rename as rename4 } from "fs/promises";
|
|
11146
11505
|
|
|
11147
11506
|
// src/install/pack/pack-writer.ts
|
|
11148
|
-
import { join as
|
|
11507
|
+
import { join as join63, basename as basename33, dirname as dirname23 } from "path";
|
|
11149
11508
|
import { rm as rm7, rename as rename3, mkdir as mkdir5, copyFile as copyFile2 } from "fs/promises";
|
|
11150
11509
|
import { stringify as yamlStringify6 } from "yaml";
|
|
11151
11510
|
|
|
@@ -11171,41 +11530,41 @@ async function hashPackContent(packDir) {
|
|
|
11171
11530
|
// src/install/pack/pack-writer.ts
|
|
11172
11531
|
async function writeRules(canonical, packDir) {
|
|
11173
11532
|
if (canonical.rules.length === 0) return;
|
|
11174
|
-
const rulesDir =
|
|
11533
|
+
const rulesDir = join63(packDir, "rules");
|
|
11175
11534
|
await mkdirp(rulesDir);
|
|
11176
11535
|
for (const rule of canonical.rules) {
|
|
11177
|
-
const dest =
|
|
11536
|
+
const dest = join63(rulesDir, basename33(rule.source));
|
|
11178
11537
|
await copyFile2(rule.source, dest);
|
|
11179
11538
|
}
|
|
11180
11539
|
}
|
|
11181
11540
|
async function writeCommands(canonical, packDir) {
|
|
11182
11541
|
if (canonical.commands.length === 0) return;
|
|
11183
|
-
const dir =
|
|
11542
|
+
const dir = join63(packDir, "commands");
|
|
11184
11543
|
await mkdirp(dir);
|
|
11185
11544
|
for (const cmd of canonical.commands) {
|
|
11186
|
-
const dest =
|
|
11545
|
+
const dest = join63(dir, basename33(cmd.source));
|
|
11187
11546
|
await copyFile2(cmd.source, dest);
|
|
11188
11547
|
}
|
|
11189
11548
|
}
|
|
11190
11549
|
async function writeAgents(canonical, packDir) {
|
|
11191
11550
|
if (canonical.agents.length === 0) return;
|
|
11192
|
-
const dir =
|
|
11551
|
+
const dir = join63(packDir, "agents");
|
|
11193
11552
|
await mkdirp(dir);
|
|
11194
11553
|
for (const agent of canonical.agents) {
|
|
11195
|
-
const dest =
|
|
11554
|
+
const dest = join63(dir, basename33(agent.source));
|
|
11196
11555
|
await copyFile2(agent.source, dest);
|
|
11197
11556
|
}
|
|
11198
11557
|
}
|
|
11199
11558
|
async function writeSkills(canonical, packDir) {
|
|
11200
11559
|
if (canonical.skills.length === 0) return;
|
|
11201
|
-
const skillsDir =
|
|
11560
|
+
const skillsDir = join63(packDir, "skills");
|
|
11202
11561
|
await mkdirp(skillsDir);
|
|
11203
11562
|
for (const skill of canonical.skills) {
|
|
11204
|
-
const skillDestDir =
|
|
11563
|
+
const skillDestDir = join63(skillsDir, skill.name);
|
|
11205
11564
|
await mkdirp(skillDestDir);
|
|
11206
|
-
await copyFile2(skill.source,
|
|
11565
|
+
await copyFile2(skill.source, join63(skillDestDir, "SKILL.md"));
|
|
11207
11566
|
for (const sf of skill.supportingFiles) {
|
|
11208
|
-
const destPath =
|
|
11567
|
+
const destPath = join63(skillDestDir, sf.relativePath);
|
|
11209
11568
|
await mkdirp(dirname23(destPath));
|
|
11210
11569
|
await copyFile2(sf.absolutePath, destPath);
|
|
11211
11570
|
}
|
|
@@ -11213,23 +11572,23 @@ async function writeSkills(canonical, packDir) {
|
|
|
11213
11572
|
}
|
|
11214
11573
|
async function writeSettings(canonical, packDir) {
|
|
11215
11574
|
if (canonical.mcp !== null) {
|
|
11216
|
-
await writeFileAtomic(
|
|
11575
|
+
await writeFileAtomic(join63(packDir, "mcp.json"), `${JSON.stringify(canonical.mcp, null, 2)}
|
|
11217
11576
|
`);
|
|
11218
11577
|
}
|
|
11219
11578
|
if (canonical.permissions !== null) {
|
|
11220
|
-
await writeFileAtomic(
|
|
11579
|
+
await writeFileAtomic(join63(packDir, "permissions.yaml"), yamlStringify6(canonical.permissions));
|
|
11221
11580
|
}
|
|
11222
11581
|
if (canonical.hooks !== null) {
|
|
11223
|
-
await writeFileAtomic(
|
|
11582
|
+
await writeFileAtomic(join63(packDir, "hooks.yaml"), yamlStringify6(canonical.hooks));
|
|
11224
11583
|
}
|
|
11225
11584
|
if (canonical.ignore.length > 0) {
|
|
11226
|
-
await writeFileAtomic(
|
|
11585
|
+
await writeFileAtomic(join63(packDir, "ignore"), `${canonical.ignore.join("\n")}
|
|
11227
11586
|
`);
|
|
11228
11587
|
}
|
|
11229
11588
|
}
|
|
11230
11589
|
async function materializePack(packsDir, packName, canonical, metadataInput) {
|
|
11231
|
-
const tmpDir =
|
|
11232
|
-
const finalDir =
|
|
11590
|
+
const tmpDir = join63(packsDir, `${packName}.tmp`);
|
|
11591
|
+
const finalDir = join63(packsDir, packName);
|
|
11233
11592
|
if (await exists(tmpDir)) {
|
|
11234
11593
|
await rm7(tmpDir, { recursive: true, force: true });
|
|
11235
11594
|
}
|
|
@@ -11241,7 +11600,7 @@ async function materializePack(packsDir, packName, canonical, metadataInput) {
|
|
|
11241
11600
|
await writeSettings(canonical, tmpDir);
|
|
11242
11601
|
const contentHash = await hashPackContent(tmpDir);
|
|
11243
11602
|
const metadata = { ...metadataInput, content_hash: contentHash };
|
|
11244
|
-
await writeFileAtomic(
|
|
11603
|
+
await writeFileAtomic(join63(tmpDir, "pack.yaml"), yamlStringify6(metadata));
|
|
11245
11604
|
if (await exists(finalDir)) {
|
|
11246
11605
|
await rm7(finalDir, { recursive: true, force: true });
|
|
11247
11606
|
}
|
|
@@ -11251,7 +11610,7 @@ async function materializePack(packsDir, packName, canonical, metadataInput) {
|
|
|
11251
11610
|
}
|
|
11252
11611
|
|
|
11253
11612
|
// src/install/pack/pack-merge.ts
|
|
11254
|
-
import { join as
|
|
11613
|
+
import { join as join64, basename as basename34, dirname as dirname24 } from "path";
|
|
11255
11614
|
import { copyFile as copyFile3 } from "fs/promises";
|
|
11256
11615
|
import { stringify as yamlStringify7 } from "yaml";
|
|
11257
11616
|
function union(a, b) {
|
|
@@ -11282,38 +11641,38 @@ function mergePick2(existing, newFeatures, newPick) {
|
|
|
11282
11641
|
}
|
|
11283
11642
|
async function mergeRules(canonical, packDir) {
|
|
11284
11643
|
if (canonical.rules.length === 0) return;
|
|
11285
|
-
const dir =
|
|
11644
|
+
const dir = join64(packDir, "rules");
|
|
11286
11645
|
await mkdirp(dir);
|
|
11287
11646
|
for (const rule of canonical.rules) {
|
|
11288
|
-
await copyFile3(rule.source,
|
|
11647
|
+
await copyFile3(rule.source, join64(dir, basename34(rule.source)));
|
|
11289
11648
|
}
|
|
11290
11649
|
}
|
|
11291
11650
|
async function mergeCommands(canonical, packDir) {
|
|
11292
11651
|
if (canonical.commands.length === 0) return;
|
|
11293
|
-
const dir =
|
|
11652
|
+
const dir = join64(packDir, "commands");
|
|
11294
11653
|
await mkdirp(dir);
|
|
11295
11654
|
for (const cmd of canonical.commands) {
|
|
11296
|
-
await copyFile3(cmd.source,
|
|
11655
|
+
await copyFile3(cmd.source, join64(dir, basename34(cmd.source)));
|
|
11297
11656
|
}
|
|
11298
11657
|
}
|
|
11299
11658
|
async function mergeAgents(canonical, packDir) {
|
|
11300
11659
|
if (canonical.agents.length === 0) return;
|
|
11301
|
-
const dir =
|
|
11660
|
+
const dir = join64(packDir, "agents");
|
|
11302
11661
|
await mkdirp(dir);
|
|
11303
11662
|
for (const agent of canonical.agents) {
|
|
11304
|
-
await copyFile3(agent.source,
|
|
11663
|
+
await copyFile3(agent.source, join64(dir, basename34(agent.source)));
|
|
11305
11664
|
}
|
|
11306
11665
|
}
|
|
11307
11666
|
async function mergeSkills(canonical, packDir) {
|
|
11308
11667
|
if (canonical.skills.length === 0) return;
|
|
11309
|
-
const skillsDir =
|
|
11668
|
+
const skillsDir = join64(packDir, "skills");
|
|
11310
11669
|
await mkdirp(skillsDir);
|
|
11311
11670
|
for (const skill of canonical.skills) {
|
|
11312
|
-
const destDir =
|
|
11671
|
+
const destDir = join64(skillsDir, skill.name);
|
|
11313
11672
|
await mkdirp(destDir);
|
|
11314
|
-
await copyFile3(skill.source,
|
|
11673
|
+
await copyFile3(skill.source, join64(destDir, "SKILL.md"));
|
|
11315
11674
|
for (const sf of skill.supportingFiles) {
|
|
11316
|
-
const destPath =
|
|
11675
|
+
const destPath = join64(destDir, sf.relativePath);
|
|
11317
11676
|
await mkdirp(dirname24(destPath));
|
|
11318
11677
|
await copyFile3(sf.absolutePath, destPath);
|
|
11319
11678
|
}
|
|
@@ -11321,17 +11680,17 @@ async function mergeSkills(canonical, packDir) {
|
|
|
11321
11680
|
}
|
|
11322
11681
|
async function mergeSettings(canonical, packDir) {
|
|
11323
11682
|
if (canonical.mcp !== null) {
|
|
11324
|
-
await writeFileAtomic(
|
|
11683
|
+
await writeFileAtomic(join64(packDir, "mcp.json"), `${JSON.stringify(canonical.mcp, null, 2)}
|
|
11325
11684
|
`);
|
|
11326
11685
|
}
|
|
11327
11686
|
if (canonical.permissions !== null) {
|
|
11328
|
-
await writeFileAtomic(
|
|
11687
|
+
await writeFileAtomic(join64(packDir, "permissions.yaml"), yamlStringify7(canonical.permissions));
|
|
11329
11688
|
}
|
|
11330
11689
|
if (canonical.hooks !== null) {
|
|
11331
|
-
await writeFileAtomic(
|
|
11690
|
+
await writeFileAtomic(join64(packDir, "hooks.yaml"), yamlStringify7(canonical.hooks));
|
|
11332
11691
|
}
|
|
11333
11692
|
if (canonical.ignore.length > 0) {
|
|
11334
|
-
await writeFileAtomic(
|
|
11693
|
+
await writeFileAtomic(join64(packDir, "ignore"), `${canonical.ignore.join("\n")}
|
|
11335
11694
|
`);
|
|
11336
11695
|
}
|
|
11337
11696
|
}
|
|
@@ -11358,12 +11717,12 @@ async function mergeIntoPack(packDir, existingMeta, newCanonical, newFeatures, n
|
|
|
11358
11717
|
updated_at: updatedAt,
|
|
11359
11718
|
content_hash: contentHash
|
|
11360
11719
|
};
|
|
11361
|
-
await writeFileAtomic(
|
|
11720
|
+
await writeFileAtomic(join64(packDir, "pack.yaml"), yamlStringify7(updatedMeta));
|
|
11362
11721
|
return updatedMeta;
|
|
11363
11722
|
}
|
|
11364
11723
|
|
|
11365
11724
|
// src/install/core/install-manifest.ts
|
|
11366
|
-
import { join as
|
|
11725
|
+
import { join as join65 } from "path";
|
|
11367
11726
|
import { parse as parseYaml8, stringify as yamlStringify8 } from "yaml";
|
|
11368
11727
|
import { z as z4 } from "zod";
|
|
11369
11728
|
var installManifestEntrySchema = z4.object({
|
|
@@ -11389,7 +11748,7 @@ function sameInstallIdentity(a, b) {
|
|
|
11389
11748
|
return a.source === b.source && a.target === b.target && a.as === b.as && sameFeatures2(a.features, b.features);
|
|
11390
11749
|
}
|
|
11391
11750
|
function manifestPath(configDir) {
|
|
11392
|
-
return
|
|
11751
|
+
return join65(configDir, ".agentsmesh", "installs.yaml");
|
|
11393
11752
|
}
|
|
11394
11753
|
async function readInstallManifest(configDir) {
|
|
11395
11754
|
const content = await readFileSafe(manifestPath(configDir));
|
|
@@ -11462,7 +11821,7 @@ async function installAsPack(args) {
|
|
|
11462
11821
|
manualAs,
|
|
11463
11822
|
renameExistingPack
|
|
11464
11823
|
} = args;
|
|
11465
|
-
const packsDir =
|
|
11824
|
+
const packsDir = join66(configDir, ".agentsmesh", "packs");
|
|
11466
11825
|
const selectedCanonical = applySelection(narrowed, selected);
|
|
11467
11826
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
11468
11827
|
const parsedTarget = yamlTarget !== void 0 ? targetSchema.parse(yamlTarget) : void 0;
|
|
@@ -11480,7 +11839,7 @@ async function installAsPack(args) {
|
|
|
11480
11839
|
let packDir = existingPack.packDir;
|
|
11481
11840
|
let packMeta = existingPack.meta;
|
|
11482
11841
|
if (renameExistingPack && existingPack.name !== packName) {
|
|
11483
|
-
const nextDir =
|
|
11842
|
+
const nextDir = join66(packsDir, packName);
|
|
11484
11843
|
if (await exists(nextDir)) {
|
|
11485
11844
|
throw new Error(
|
|
11486
11845
|
`Auto-generated pack name "${packName}" collides with an existing incompatible pack. Use --name to choose a different pack name.`
|
|
@@ -11511,7 +11870,7 @@ async function installAsPack(args) {
|
|
|
11511
11870
|
persistedPaths = mergedMeta.paths;
|
|
11512
11871
|
logger.success(`Updated pack "${mergedMeta.name}" in .agentsmesh/packs/.`);
|
|
11513
11872
|
} else {
|
|
11514
|
-
const collidingMeta = await readPackMetadata(
|
|
11873
|
+
const collidingMeta = await readPackMetadata(join66(packsDir, packName));
|
|
11515
11874
|
if (collidingMeta) {
|
|
11516
11875
|
throw new Error(
|
|
11517
11876
|
`Auto-generated pack name "${packName}" collides with an existing incompatible pack. Use --name to choose a different pack name.`
|
|
@@ -11553,7 +11912,7 @@ async function installAsPack(args) {
|
|
|
11553
11912
|
}
|
|
11554
11913
|
|
|
11555
11914
|
// src/install/run/install-sync.ts
|
|
11556
|
-
import { join as
|
|
11915
|
+
import { join as join67 } from "path";
|
|
11557
11916
|
async function syncInstalledPacks(args) {
|
|
11558
11917
|
const installs = await readInstallManifest(args.configDir);
|
|
11559
11918
|
if (installs.length === 0) {
|
|
@@ -11562,7 +11921,7 @@ async function syncInstalledPacks(args) {
|
|
|
11562
11921
|
}
|
|
11563
11922
|
const missing = [];
|
|
11564
11923
|
for (const entry of installs) {
|
|
11565
|
-
const packDir =
|
|
11924
|
+
const packDir = join67(args.configDir, ".agentsmesh", "packs", entry.name);
|
|
11566
11925
|
if (!await exists(packDir)) {
|
|
11567
11926
|
missing.push(entry);
|
|
11568
11927
|
}
|
|
@@ -11740,7 +12099,7 @@ function narrowDiscoveredForInstallScope(canonical, options) {
|
|
|
11740
12099
|
}
|
|
11741
12100
|
|
|
11742
12101
|
// src/install/manual/manual-install-scope.ts
|
|
11743
|
-
import { basename as
|
|
12102
|
+
import { basename as basename35, dirname as dirname25, join as join68, relative as relative27 } from "path";
|
|
11744
12103
|
import { cp as cp2, mkdtemp, stat as stat5, rm as rm8 } from "fs/promises";
|
|
11745
12104
|
import { tmpdir } from "os";
|
|
11746
12105
|
|
|
@@ -11800,9 +12159,9 @@ async function cpFilteredSkill(sourceRoot, destDir) {
|
|
|
11800
12159
|
|
|
11801
12160
|
// src/install/manual/manual-install-scope.ts
|
|
11802
12161
|
async function createStageRoot() {
|
|
11803
|
-
const stageBase = await mkdtemp(
|
|
11804
|
-
const discoveryRoot =
|
|
11805
|
-
await mkdirp(
|
|
12162
|
+
const stageBase = await mkdtemp(join68(tmpdir(), "am-install-manual-"));
|
|
12163
|
+
const discoveryRoot = join68(stageBase, "repo");
|
|
12164
|
+
await mkdirp(join68(discoveryRoot, ".agentsmesh"));
|
|
11806
12165
|
return {
|
|
11807
12166
|
discoveryRoot,
|
|
11808
12167
|
cleanup: async () => {
|
|
@@ -11817,7 +12176,7 @@ async function stageMarkdownCollection(sourceRoot, destinationDir) {
|
|
|
11817
12176
|
throw new Error(`Manual install only supports .md files for this collection: ${sourceRoot}`);
|
|
11818
12177
|
}
|
|
11819
12178
|
await mkdirp(destinationDir);
|
|
11820
|
-
await cp2(sourceRoot,
|
|
12179
|
+
await cp2(sourceRoot, join68(destinationDir, basename35(sourceRoot)));
|
|
11821
12180
|
return;
|
|
11822
12181
|
}
|
|
11823
12182
|
const files = (await readDirRecursive(sourceRoot)).filter(
|
|
@@ -11829,7 +12188,7 @@ async function stageMarkdownCollection(sourceRoot, destinationDir) {
|
|
|
11829
12188
|
const usedNames = /* @__PURE__ */ new Map();
|
|
11830
12189
|
await mkdirp(destinationDir);
|
|
11831
12190
|
for (const file of files) {
|
|
11832
|
-
const name =
|
|
12191
|
+
const name = basename35(file);
|
|
11833
12192
|
const previous = usedNames.get(name);
|
|
11834
12193
|
if (previous) {
|
|
11835
12194
|
throw new Error(
|
|
@@ -11837,7 +12196,7 @@ async function stageMarkdownCollection(sourceRoot, destinationDir) {
|
|
|
11837
12196
|
);
|
|
11838
12197
|
}
|
|
11839
12198
|
usedNames.set(name, file);
|
|
11840
|
-
await cp2(file,
|
|
12199
|
+
await cp2(file, join68(destinationDir, name));
|
|
11841
12200
|
}
|
|
11842
12201
|
}
|
|
11843
12202
|
async function stagePreferredSkills(sourceRoot, destinationDir, preferredSkillNames) {
|
|
@@ -11849,7 +12208,7 @@ async function stagePreferredSkills(sourceRoot, destinationDir, preferredSkillNa
|
|
|
11849
12208
|
for (const file of await readDirRecursive(sourceRoot)) {
|
|
11850
12209
|
if (!file.endsWith("/SKILL.md") && !file.endsWith("\\SKILL.md")) continue;
|
|
11851
12210
|
const skillDir = dirname25(file);
|
|
11852
|
-
const skillName =
|
|
12211
|
+
const skillName = basename35(skillDir);
|
|
11853
12212
|
if (!wanted.has(skillName)) continue;
|
|
11854
12213
|
const previous = matches.get(skillName);
|
|
11855
12214
|
if (previous && previous !== skillDir) {
|
|
@@ -11862,30 +12221,30 @@ async function stagePreferredSkills(sourceRoot, destinationDir, preferredSkillNa
|
|
|
11862
12221
|
if (matches.size !== preferredSkillNames.length) return false;
|
|
11863
12222
|
await mkdirp(destinationDir);
|
|
11864
12223
|
for (const skillName of preferredSkillNames) {
|
|
11865
|
-
await cp2(matches.get(skillName),
|
|
12224
|
+
await cp2(matches.get(skillName), join68(destinationDir, skillName), { recursive: true });
|
|
11866
12225
|
}
|
|
11867
12226
|
return true;
|
|
11868
12227
|
}
|
|
11869
12228
|
async function stageSkills(sourceRoot, destinationDir, options = {}) {
|
|
11870
12229
|
const info = await stat5(sourceRoot);
|
|
11871
12230
|
if (info.isFile()) {
|
|
11872
|
-
if (
|
|
12231
|
+
if (basename35(sourceRoot) !== "SKILL.md") {
|
|
11873
12232
|
throw new Error(`Manual skill install expects SKILL.md or a skill directory: ${sourceRoot}`);
|
|
11874
12233
|
}
|
|
11875
|
-
const skillName =
|
|
11876
|
-
const skillDir =
|
|
12234
|
+
const skillName = basename35(dirname25(sourceRoot));
|
|
12235
|
+
const skillDir = join68(destinationDir, skillName);
|
|
11877
12236
|
await mkdirp(skillDir);
|
|
11878
12237
|
await cp2(dirname25(sourceRoot), skillDir, { recursive: true });
|
|
11879
12238
|
return;
|
|
11880
12239
|
}
|
|
11881
12240
|
if (await isSkillPackLayout(sourceRoot)) {
|
|
11882
|
-
if ((await stat5(
|
|
12241
|
+
if ((await stat5(join68(sourceRoot, "SKILL.md")).catch(() => null))?.isFile()) {
|
|
11883
12242
|
if (await stagePreferredSkills(sourceRoot, destinationDir, options.preferredSkillNames ?? [])) {
|
|
11884
12243
|
return;
|
|
11885
12244
|
}
|
|
11886
|
-
const fmName = await readSkillFrontmatterName(
|
|
11887
|
-
const skillName = fmName ||
|
|
11888
|
-
const skillDir =
|
|
12245
|
+
const fmName = await readSkillFrontmatterName(join68(sourceRoot, "SKILL.md"));
|
|
12246
|
+
const skillName = fmName || basename35(sourceRoot);
|
|
12247
|
+
const skillDir = join68(destinationDir, skillName);
|
|
11889
12248
|
await mkdirp(destinationDir);
|
|
11890
12249
|
await cpFilteredSkill(sourceRoot, skillDir);
|
|
11891
12250
|
return;
|
|
@@ -11902,7 +12261,7 @@ async function stageSkills(sourceRoot, destinationDir, options = {}) {
|
|
|
11902
12261
|
roots.add(relative27(sourceRoot, dirname25(file)).split(/[\\/]/)[0]);
|
|
11903
12262
|
}
|
|
11904
12263
|
for (const root of roots) {
|
|
11905
|
-
await cp2(
|
|
12264
|
+
await cp2(join68(sourceRoot, root), join68(destinationDir, root), { recursive: true });
|
|
11906
12265
|
}
|
|
11907
12266
|
return;
|
|
11908
12267
|
}
|
|
@@ -11913,7 +12272,7 @@ async function stageSkills(sourceRoot, destinationDir, options = {}) {
|
|
|
11913
12272
|
async function stageManualInstallScope(sourceRoot, as, options = {}) {
|
|
11914
12273
|
const staged = await createStageRoot();
|
|
11915
12274
|
try {
|
|
11916
|
-
const destDir =
|
|
12275
|
+
const destDir = join68(staged.discoveryRoot, ".agentsmesh", as);
|
|
11917
12276
|
if (as === "skills") {
|
|
11918
12277
|
await stageSkills(sourceRoot, destDir, options);
|
|
11919
12278
|
} else {
|
|
@@ -11947,7 +12306,7 @@ async function resolveManualDiscoveredForInstall(sourceRoot, explicitAs, explici
|
|
|
11947
12306
|
}
|
|
11948
12307
|
|
|
11949
12308
|
// src/install/core/prepare-install-discovery.ts
|
|
11950
|
-
import { join as
|
|
12309
|
+
import { join as join73 } from "path";
|
|
11951
12310
|
|
|
11952
12311
|
// src/install/native/native-path-pick.ts
|
|
11953
12312
|
var PATH_PREFIX_TO_TARGET = [
|
|
@@ -11985,14 +12344,14 @@ function norm(p) {
|
|
|
11985
12344
|
function targetHintFromNativePath(pathInRepoPosix) {
|
|
11986
12345
|
const p = norm(pathInRepoPosix);
|
|
11987
12346
|
const sorted = [...PATH_PREFIX_TO_TARGET].sort((a, b) => b.prefix.length - a.prefix.length);
|
|
11988
|
-
for (const { prefix, target:
|
|
11989
|
-
if (p === prefix || p.startsWith(`${prefix}/`)) return
|
|
12347
|
+
for (const { prefix, target: target12 } of sorted) {
|
|
12348
|
+
if (p === prefix || p.startsWith(`${prefix}/`)) return target12;
|
|
11990
12349
|
}
|
|
11991
12350
|
return void 0;
|
|
11992
12351
|
}
|
|
11993
|
-
function pathSupportsNativePick(pathInRepoPosix,
|
|
12352
|
+
function pathSupportsNativePick(pathInRepoPosix, target12) {
|
|
11994
12353
|
const hint = targetHintFromNativePath(pathInRepoPosix);
|
|
11995
|
-
return hint ===
|
|
12354
|
+
return hint === target12;
|
|
11996
12355
|
}
|
|
11997
12356
|
function validateTargetMatchesPath(explicitTarget, pathInRepoPosix) {
|
|
11998
12357
|
if (!explicitTarget || !pathInRepoPosix) return;
|
|
@@ -12008,13 +12367,13 @@ function extendPickHasArrays(p) {
|
|
|
12008
12367
|
}
|
|
12009
12368
|
|
|
12010
12369
|
// src/install/native/native-path-pick-infer.ts
|
|
12011
|
-
import { basename as
|
|
12370
|
+
import { basename as basename38, join as join71 } from "path";
|
|
12012
12371
|
|
|
12013
12372
|
// src/install/native/gemini-install-commands.ts
|
|
12014
|
-
import { join as
|
|
12373
|
+
import { join as join69, relative as relative28 } from "path";
|
|
12015
12374
|
async function inferGeminiCommandNamesFromFiles(repoRoot, pathInRepoPosix) {
|
|
12016
|
-
const commandsRoot =
|
|
12017
|
-
const scanDir =
|
|
12375
|
+
const commandsRoot = join69(repoRoot, ...GEMINI_COMMANDS_DIR.split("/"));
|
|
12376
|
+
const scanDir = join69(repoRoot, ...pathInRepoPosix.split("/"));
|
|
12018
12377
|
const files = await readDirRecursive(scanDir);
|
|
12019
12378
|
const names = [];
|
|
12020
12379
|
for (const f of files) {
|
|
@@ -12029,32 +12388,32 @@ async function inferGeminiCommandNamesFromFiles(repoRoot, pathInRepoPosix) {
|
|
|
12029
12388
|
}
|
|
12030
12389
|
|
|
12031
12390
|
// src/install/native/native-skill-scan.ts
|
|
12032
|
-
import { basename as
|
|
12391
|
+
import { basename as basename36, dirname as dirname26, relative as relative29 } from "path";
|
|
12033
12392
|
async function skillNamesFromNativeSkillDir(scanRoot) {
|
|
12034
12393
|
const files = await readDirRecursive(scanRoot);
|
|
12035
12394
|
const names = /* @__PURE__ */ new Set();
|
|
12036
12395
|
for (const f of files) {
|
|
12037
|
-
if (
|
|
12038
|
-
names.add(
|
|
12396
|
+
if (basename36(f) === "SKILL.md") {
|
|
12397
|
+
names.add(basename36(dirname26(f)));
|
|
12039
12398
|
continue;
|
|
12040
12399
|
}
|
|
12041
12400
|
const rel2 = relative29(scanRoot, f).replace(/\\/g, "/");
|
|
12042
12401
|
if (!rel2.includes("/") && f.toLowerCase().endsWith(".md")) {
|
|
12043
|
-
names.add(
|
|
12402
|
+
names.add(basename36(f, ".md"));
|
|
12044
12403
|
}
|
|
12045
12404
|
}
|
|
12046
12405
|
return [...names].filter(Boolean).sort();
|
|
12047
12406
|
}
|
|
12048
12407
|
|
|
12049
12408
|
// src/install/native/native-path-pick-infer-copilot.ts
|
|
12050
|
-
import { basename as
|
|
12409
|
+
import { basename as basename37, join as join70 } from "path";
|
|
12051
12410
|
async function inferCopilotPickFromPath(repoRoot, posixPath) {
|
|
12052
|
-
const scan =
|
|
12411
|
+
const scan = join70(repoRoot, ...posixPath.split("/"));
|
|
12053
12412
|
if (posixPath.startsWith(COPILOT_PROMPTS_DIR)) {
|
|
12054
12413
|
const files = await readDirRecursive(scan);
|
|
12055
12414
|
const commands = [
|
|
12056
12415
|
...new Set(
|
|
12057
|
-
files.filter((f) => f.toLowerCase().endsWith(".prompt.md")).map((f) =>
|
|
12416
|
+
files.filter((f) => f.toLowerCase().endsWith(".prompt.md")).map((f) => basename37(f, ".prompt.md"))
|
|
12058
12417
|
)
|
|
12059
12418
|
].sort();
|
|
12060
12419
|
return commands.length ? { commands } : {};
|
|
@@ -12063,7 +12422,7 @@ async function inferCopilotPickFromPath(repoRoot, posixPath) {
|
|
|
12063
12422
|
const files = await readDirRecursive(scan);
|
|
12064
12423
|
const rules = [
|
|
12065
12424
|
...new Set(
|
|
12066
|
-
files.filter((f) => f.includes(".instructions.md")).map((f) =>
|
|
12425
|
+
files.filter((f) => f.includes(".instructions.md")).map((f) => basename37(f).replace(/\.instructions\.md$/i, ""))
|
|
12067
12426
|
)
|
|
12068
12427
|
].sort();
|
|
12069
12428
|
return rules.length ? { rules } : {};
|
|
@@ -12072,10 +12431,10 @@ async function inferCopilotPickFromPath(repoRoot, posixPath) {
|
|
|
12072
12431
|
const files = await readDirRecursive(scan);
|
|
12073
12432
|
const names = /* @__PURE__ */ new Set();
|
|
12074
12433
|
for (const f of files) {
|
|
12075
|
-
const b =
|
|
12434
|
+
const b = basename37(f);
|
|
12076
12435
|
if (b.toLowerCase().endsWith(".instructions.md"))
|
|
12077
12436
|
names.add(b.replace(/\.instructions\.md$/i, ""));
|
|
12078
|
-
else if (b.toLowerCase().endsWith(".md")) names.add(
|
|
12437
|
+
else if (b.toLowerCase().endsWith(".md")) names.add(basename37(f, ".md"));
|
|
12079
12438
|
}
|
|
12080
12439
|
const rules = [...names].sort();
|
|
12081
12440
|
return rules.length ? { rules } : {};
|
|
@@ -12088,7 +12447,7 @@ async function inferCopilotPickFromPath(repoRoot, posixPath) {
|
|
|
12088
12447
|
const files = await readDirRecursive(scan);
|
|
12089
12448
|
const agents = [
|
|
12090
12449
|
...new Set(
|
|
12091
|
-
files.filter((f) => f.toLowerCase().endsWith(".agent.md")).map((f) =>
|
|
12450
|
+
files.filter((f) => f.toLowerCase().endsWith(".agent.md")).map((f) => basename37(f, ".agent.md"))
|
|
12092
12451
|
)
|
|
12093
12452
|
].sort();
|
|
12094
12453
|
return agents.length ? { agents } : {};
|
|
@@ -12101,20 +12460,20 @@ async function mdNames(dir, ext) {
|
|
|
12101
12460
|
const files = await readDirRecursive(dir);
|
|
12102
12461
|
const e = ext.toLowerCase();
|
|
12103
12462
|
return [
|
|
12104
|
-
...new Set(files.filter((f) => f.toLowerCase().endsWith(e)).map((f) =>
|
|
12463
|
+
...new Set(files.filter((f) => f.toLowerCase().endsWith(e)).map((f) => basename38(f, ext)))
|
|
12105
12464
|
].sort();
|
|
12106
12465
|
}
|
|
12107
|
-
async function inferImplicitPickFromNativePath(repoRoot, pathInRepoPosix,
|
|
12466
|
+
async function inferImplicitPickFromNativePath(repoRoot, pathInRepoPosix, target12) {
|
|
12108
12467
|
const posixPath = pathInRepoPosix.replace(/\\/g, "/").replace(/^\/+|\/+$/g, "");
|
|
12109
|
-
const scan =
|
|
12110
|
-
if (
|
|
12468
|
+
const scan = join71(repoRoot, ...posixPath.split("/"));
|
|
12469
|
+
if (target12 === "gemini-cli") {
|
|
12111
12470
|
if (posixPath === GEMINI_COMMANDS_DIR || posixPath.startsWith(`${GEMINI_COMMANDS_DIR}/`)) {
|
|
12112
12471
|
const commands = await inferGeminiCommandNamesFromFiles(repoRoot, posixPath);
|
|
12113
12472
|
return commands.length ? { commands } : {};
|
|
12114
12473
|
}
|
|
12115
12474
|
return {};
|
|
12116
12475
|
}
|
|
12117
|
-
if (
|
|
12476
|
+
if (target12 === "claude-code") {
|
|
12118
12477
|
if (posixPath.startsWith(".claude/commands")) {
|
|
12119
12478
|
const commands = await mdNames(scan, ".md");
|
|
12120
12479
|
return commands.length ? { commands } : {};
|
|
@@ -12134,7 +12493,7 @@ async function inferImplicitPickFromNativePath(repoRoot, pathInRepoPosix, target
|
|
|
12134
12493
|
}
|
|
12135
12494
|
return {};
|
|
12136
12495
|
}
|
|
12137
|
-
if (
|
|
12496
|
+
if (target12 === "cursor") {
|
|
12138
12497
|
if (posixPath.startsWith(".cursor/rules")) {
|
|
12139
12498
|
const rules = await mdNames(scan, ".mdc");
|
|
12140
12499
|
return rules.length ? { rules } : {};
|
|
@@ -12153,14 +12512,14 @@ async function inferImplicitPickFromNativePath(repoRoot, pathInRepoPosix, target
|
|
|
12153
12512
|
}
|
|
12154
12513
|
return {};
|
|
12155
12514
|
}
|
|
12156
|
-
if (
|
|
12515
|
+
if (target12 === "copilot") {
|
|
12157
12516
|
return inferCopilotPickFromPath(repoRoot, posixPath);
|
|
12158
12517
|
}
|
|
12159
|
-
if (
|
|
12518
|
+
if (target12 === "windsurf" && posixPath.startsWith(".windsurf/rules")) {
|
|
12160
12519
|
const rules = await mdNames(scan, ".md");
|
|
12161
12520
|
return rules.length ? { rules } : {};
|
|
12162
12521
|
}
|
|
12163
|
-
if (
|
|
12522
|
+
if (target12 === "cline") {
|
|
12164
12523
|
if (posixPath.startsWith(CLINE_SKILLS_DIR)) {
|
|
12165
12524
|
const skills = await skillNamesFromNativeSkillDir(scan);
|
|
12166
12525
|
return skills.length ? { skills } : {};
|
|
@@ -12171,7 +12530,7 @@ async function inferImplicitPickFromNativePath(repoRoot, pathInRepoPosix, target
|
|
|
12171
12530
|
}
|
|
12172
12531
|
return {};
|
|
12173
12532
|
}
|
|
12174
|
-
if (
|
|
12533
|
+
if (target12 === "continue") {
|
|
12175
12534
|
if (posixPath.startsWith(".continue/rules")) {
|
|
12176
12535
|
const rules = await mdNames(scan, ".md");
|
|
12177
12536
|
return rules.length ? { rules } : {};
|
|
@@ -12186,7 +12545,7 @@ async function inferImplicitPickFromNativePath(repoRoot, pathInRepoPosix, target
|
|
|
12186
12545
|
}
|
|
12187
12546
|
return {};
|
|
12188
12547
|
}
|
|
12189
|
-
if (
|
|
12548
|
+
if (target12 === "junie") {
|
|
12190
12549
|
if (posixPath.startsWith(".junie/commands")) {
|
|
12191
12550
|
const commands = await mdNames(scan, ".md");
|
|
12192
12551
|
return commands.length ? { commands } : {};
|
|
@@ -12205,11 +12564,11 @@ async function inferImplicitPickFromNativePath(repoRoot, pathInRepoPosix, target
|
|
|
12205
12564
|
}
|
|
12206
12565
|
return {};
|
|
12207
12566
|
}
|
|
12208
|
-
if (
|
|
12567
|
+
if (target12 === "codex-cli" && posixPath.startsWith(".codex")) {
|
|
12209
12568
|
const files = await readDirRecursive(scan);
|
|
12210
12569
|
const rules = [
|
|
12211
12570
|
...new Set(
|
|
12212
|
-
files.filter((f) => f.toLowerCase().endsWith(".md")).map((f) =>
|
|
12571
|
+
files.filter((f) => f.toLowerCase().endsWith(".md")).map((f) => basename38(f, ".md"))
|
|
12213
12572
|
)
|
|
12214
12573
|
].sort();
|
|
12215
12574
|
return rules.length ? { rules } : {};
|
|
@@ -12221,7 +12580,7 @@ function isImplicitPickEmpty(p) {
|
|
|
12221
12580
|
}
|
|
12222
12581
|
|
|
12223
12582
|
// src/install/native/native-install-scope.ts
|
|
12224
|
-
import { basename as
|
|
12583
|
+
import { basename as basename39, join as join72, relative as relative30 } from "path";
|
|
12225
12584
|
import { cp as cp3, mkdtemp as mkdtemp2, rm as rm9 } from "fs/promises";
|
|
12226
12585
|
import { tmpdir as tmpdir2 } from "os";
|
|
12227
12586
|
function normalizePath3(path) {
|
|
@@ -12232,14 +12591,14 @@ function overlapsPath(requested, imported) {
|
|
|
12232
12591
|
const b = normalizePath3(imported);
|
|
12233
12592
|
return a === b || a.startsWith(`${b}/`) || b.startsWith(`${a}/`);
|
|
12234
12593
|
}
|
|
12235
|
-
function addUnique(
|
|
12236
|
-
const next =
|
|
12594
|
+
function addUnique(target12, value) {
|
|
12595
|
+
const next = target12 ?? [];
|
|
12237
12596
|
if (!next.includes(value)) next.push(value);
|
|
12238
12597
|
return next;
|
|
12239
12598
|
}
|
|
12240
12599
|
async function makeStageRoot(repoRoot) {
|
|
12241
|
-
const stageBase = await mkdtemp2(
|
|
12242
|
-
const stageRoot =
|
|
12600
|
+
const stageBase = await mkdtemp2(join72(tmpdir2(), "am-install-native-"));
|
|
12601
|
+
const stageRoot = join72(stageBase, "repo");
|
|
12243
12602
|
const cleanup = async () => {
|
|
12244
12603
|
await rm9(stageBase, { recursive: true, force: true });
|
|
12245
12604
|
};
|
|
@@ -12257,13 +12616,13 @@ function buildPickFromResults(results, stageRoot) {
|
|
|
12257
12616
|
if (result.feature === "rules" && result.toPath.startsWith(".agentsmesh/rules/")) {
|
|
12258
12617
|
pick = {
|
|
12259
12618
|
...pick,
|
|
12260
|
-
rules: addUnique(pick?.rules,
|
|
12619
|
+
rules: addUnique(pick?.rules, basename39(result.toPath, ".md"))
|
|
12261
12620
|
};
|
|
12262
12621
|
continue;
|
|
12263
12622
|
}
|
|
12264
12623
|
if (result.feature === "commands" && result.toPath.startsWith(".agentsmesh/commands/")) {
|
|
12265
12624
|
const rel2 = normalizePath3(
|
|
12266
|
-
relative30(
|
|
12625
|
+
relative30(join72(stageRoot, ".agentsmesh", "commands"), join72(stageRoot, result.toPath))
|
|
12267
12626
|
);
|
|
12268
12627
|
pick = {
|
|
12269
12628
|
...pick,
|
|
@@ -12277,13 +12636,13 @@ function buildPickFromResults(results, stageRoot) {
|
|
|
12277
12636
|
if (result.feature === "agents" && result.toPath.startsWith(".agentsmesh/agents/")) {
|
|
12278
12637
|
pick = {
|
|
12279
12638
|
...pick,
|
|
12280
|
-
agents: addUnique(pick?.agents,
|
|
12639
|
+
agents: addUnique(pick?.agents, basename39(result.toPath, ".md"))
|
|
12281
12640
|
};
|
|
12282
12641
|
continue;
|
|
12283
12642
|
}
|
|
12284
12643
|
if (result.feature === "skills" && result.toPath.startsWith(".agentsmesh/skills/")) {
|
|
12285
12644
|
const rel2 = normalizePath3(
|
|
12286
|
-
relative30(
|
|
12645
|
+
relative30(join72(stageRoot, ".agentsmesh", "skills"), join72(stageRoot, result.toPath))
|
|
12287
12646
|
);
|
|
12288
12647
|
const skillName = rel2.split("/")[0];
|
|
12289
12648
|
if (skillName) {
|
|
@@ -12298,12 +12657,12 @@ function buildPickFromResults(results, stageRoot) {
|
|
|
12298
12657
|
const hasAny = (pick.rules?.length ?? 0) + (pick.commands?.length ?? 0) + (pick.agents?.length ?? 0) + (pick.skills?.length ?? 0) > 0;
|
|
12299
12658
|
return hasAny ? pick : void 0;
|
|
12300
12659
|
}
|
|
12301
|
-
function scopeImportedResults(pathInRepoPosix, stageRoot, results,
|
|
12302
|
-
const requestedPath =
|
|
12660
|
+
function scopeImportedResults(pathInRepoPosix, stageRoot, results, target12) {
|
|
12661
|
+
const requestedPath = join72(stageRoot, ...normalizePath3(pathInRepoPosix).split("/"));
|
|
12303
12662
|
const filtered = results.filter((result) => overlapsPath(requestedPath, result.fromPath));
|
|
12304
12663
|
if (filtered.length === 0) {
|
|
12305
12664
|
throw new Error(
|
|
12306
|
-
`No installable native resources found under "${pathInRepoPosix}" for target "${
|
|
12665
|
+
`No installable native resources found under "${pathInRepoPosix}" for target "${target12}".`
|
|
12307
12666
|
);
|
|
12308
12667
|
}
|
|
12309
12668
|
return {
|
|
@@ -12311,23 +12670,23 @@ function scopeImportedResults(pathInRepoPosix, stageRoot, results, target11) {
|
|
|
12311
12670
|
pick: buildPickFromResults(filtered, stageRoot)
|
|
12312
12671
|
};
|
|
12313
12672
|
}
|
|
12314
|
-
async function stageImportedNativeRepo(repoRoot,
|
|
12673
|
+
async function stageImportedNativeRepo(repoRoot, target12) {
|
|
12315
12674
|
const { stageRoot, cleanup } = await makeStageRoot(repoRoot);
|
|
12316
12675
|
try {
|
|
12317
|
-
const results = await importNativeToCanonical(stageRoot,
|
|
12676
|
+
const results = await importNativeToCanonical(stageRoot, target12);
|
|
12318
12677
|
return { stageRoot, results, cleanup };
|
|
12319
12678
|
} catch (error) {
|
|
12320
12679
|
await cleanup();
|
|
12321
12680
|
throw error;
|
|
12322
12681
|
}
|
|
12323
12682
|
}
|
|
12324
|
-
async function stageNativeInstallScope(repoRoot, pathInRepoPosix,
|
|
12325
|
-
const staged = await stageImportedNativeRepo(repoRoot,
|
|
12683
|
+
async function stageNativeInstallScope(repoRoot, pathInRepoPosix, target12) {
|
|
12684
|
+
const staged = await stageImportedNativeRepo(repoRoot, target12);
|
|
12326
12685
|
try {
|
|
12327
12686
|
return {
|
|
12328
12687
|
stageRoot: staged.stageRoot,
|
|
12329
12688
|
cleanup: staged.cleanup,
|
|
12330
|
-
...scopeImportedResults(pathInRepoPosix, staged.stageRoot, staged.results,
|
|
12689
|
+
...scopeImportedResults(pathInRepoPosix, staged.stageRoot, staged.results, target12)
|
|
12331
12690
|
};
|
|
12332
12691
|
} catch (error) {
|
|
12333
12692
|
await staged.cleanup();
|
|
@@ -12343,7 +12702,7 @@ async function prepareInstallDiscovery(repoRoot, contentRoot, pathInRepo, option
|
|
|
12343
12702
|
}
|
|
12344
12703
|
const posixPath = pathInRepo.replace(/\\/g, "/").replace(/^\/+|\/+$/g, "");
|
|
12345
12704
|
validateTargetMatchesPath(explicitTarget, posixPath);
|
|
12346
|
-
const agentsmeshAtRoot =
|
|
12705
|
+
const agentsmeshAtRoot = join73(repoRoot, ".agentsmesh");
|
|
12347
12706
|
const hasAbRoot = await exists(agentsmeshAtRoot);
|
|
12348
12707
|
const pathHint = posixPath ? targetHintFromNativePath(posixPath) : void 0;
|
|
12349
12708
|
const detectedTarget = !hasAbRoot && !explicitTarget ? await detectNativeFormat(repoRoot) ?? void 0 : void 0;
|
|
@@ -12368,7 +12727,7 @@ async function prepareInstallDiscovery(repoRoot, contentRoot, pathInRepo, option
|
|
|
12368
12727
|
}
|
|
12369
12728
|
const staged = await stageImportedNativeRepo(repoRoot, effectiveTarget);
|
|
12370
12729
|
return {
|
|
12371
|
-
discoveryRoot: posixPath ?
|
|
12730
|
+
discoveryRoot: posixPath ? join73(staged.stageRoot, posixPath) : staged.stageRoot,
|
|
12372
12731
|
yamlTarget: effectiveTarget,
|
|
12373
12732
|
importHappened: true,
|
|
12374
12733
|
cleanup: staged.cleanup
|
|
@@ -12471,13 +12830,13 @@ function applyReplayInstallScope(narrowed, discoveredFeatures, replay) {
|
|
|
12471
12830
|
}
|
|
12472
12831
|
|
|
12473
12832
|
// src/install/manual/manual-install-persistence.ts
|
|
12474
|
-
import { basename as
|
|
12833
|
+
import { basename as basename40, dirname as dirname27, join as join74 } from "path";
|
|
12475
12834
|
import { stat as stat6 } from "fs/promises";
|
|
12476
12835
|
function trimDot(pathInRepo) {
|
|
12477
12836
|
return pathInRepo === "." || pathInRepo === "" ? void 0 : pathInRepo;
|
|
12478
12837
|
}
|
|
12479
12838
|
function markdownPick(as, pathValue) {
|
|
12480
|
-
const name =
|
|
12839
|
+
const name = basename40(pathValue).replace(/\.md$/i, "");
|
|
12481
12840
|
if (as === "agents") return { agents: [name] };
|
|
12482
12841
|
if (as === "commands") return { commands: [name] };
|
|
12483
12842
|
return { rules: [name] };
|
|
@@ -12495,23 +12854,23 @@ async function resolveManualInstallPersistence(args) {
|
|
|
12495
12854
|
};
|
|
12496
12855
|
}
|
|
12497
12856
|
if (args.as === "skills") {
|
|
12498
|
-
if (info.isFile() &&
|
|
12857
|
+
if (info.isFile() && basename40(args.contentRoot) === "SKILL.md") {
|
|
12499
12858
|
const skillDir = normalizedPath ? dirname27(normalizedPath) : dirname27(args.contentRoot);
|
|
12500
12859
|
return {
|
|
12501
12860
|
pathInRepo: trimDot(dirname27(skillDir)),
|
|
12502
|
-
pick: { skills: [
|
|
12861
|
+
pick: { skills: [basename40(skillDir)] }
|
|
12503
12862
|
};
|
|
12504
12863
|
}
|
|
12505
12864
|
if (info.isDirectory()) {
|
|
12506
|
-
const skillDir = normalizedPath ||
|
|
12507
|
-
const skillFile =
|
|
12865
|
+
const skillDir = normalizedPath || basename40(args.contentRoot);
|
|
12866
|
+
const skillFile = join74(args.contentRoot.replace(/\/+$/g, ""), "SKILL.md");
|
|
12508
12867
|
try {
|
|
12509
12868
|
const skillStat = await stat6(skillFile);
|
|
12510
12869
|
if (skillStat.isFile()) {
|
|
12511
12870
|
const fmName = await readSkillFrontmatterName(skillFile);
|
|
12512
12871
|
return {
|
|
12513
12872
|
pathInRepo: trimDot(dirname27(skillDir)),
|
|
12514
|
-
pick: { skills: [fmName ||
|
|
12873
|
+
pick: { skills: [fmName || basename40(skillDir)] }
|
|
12515
12874
|
};
|
|
12516
12875
|
}
|
|
12517
12876
|
} catch {
|
|
@@ -12579,7 +12938,7 @@ async function runInstall(flags, args, projectRoot, replay) {
|
|
|
12579
12938
|
sourceArg
|
|
12580
12939
|
);
|
|
12581
12940
|
const pathInRepo = parsed.pathInRepo.replace(/^\/+|\/+$/g, "");
|
|
12582
|
-
const contentRoot = pathInRepo ?
|
|
12941
|
+
const contentRoot = pathInRepo ? join75(resolvedPath, pathInRepo) : resolvedPath;
|
|
12583
12942
|
if (!await exists(contentRoot)) {
|
|
12584
12943
|
throw new Error(`Install path does not exist: ${contentRoot}`);
|
|
12585
12944
|
}
|