agentsmesh 0.41.0 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/targets.js CHANGED
@@ -1282,12 +1282,6 @@ var init_no_outputs = __esm({
1282
1282
  function escapeRegExp(value) {
1283
1283
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1284
1284
  }
1285
- function managedBlockPattern(start, end) {
1286
- return new RegExp(`${escapeRegExp(start)}[\\s\\S]*?${escapeRegExp(end)}`, "g");
1287
- }
1288
- function stripManagedBlock(content, start, end) {
1289
- return content.replace(managedBlockPattern(start, end), "").trim();
1290
- }
1291
1285
  function ruleSource(source) {
1292
1286
  const normalized = source.replace(/\\/g, "/");
1293
1287
  const meshIndex = normalized.lastIndexOf(".agentsmesh/");
@@ -1295,36 +1289,22 @@ function ruleSource(source) {
1295
1289
  if (normalized.startsWith("rules/")) return normalized;
1296
1290
  return join("rules", basename(normalized)).replace(/\\/g, "/");
1297
1291
  }
1298
- function markerForRule(rule) {
1299
- return {
1292
+ function renderEmbeddedRule(rule) {
1293
+ const marker = {
1300
1294
  source: ruleSource(rule.source),
1301
1295
  description: rule.description,
1302
1296
  globs: rule.globs,
1303
1297
  targets: rule.targets
1304
1298
  };
1305
- }
1306
- function embeddedRuleStart(rule) {
1307
- return `${EMBEDDED_RULE_START_PREFIX}${JSON.stringify(markerForRule(rule))}${EMBEDDED_RULE_START_SUFFIX}`;
1308
- }
1309
- function renderRule(rule) {
1310
- const parts = [embeddedRuleStart(rule)];
1299
+ const parts = [`${START_PREFIX}${JSON.stringify(marker)}${START_SUFFIX}`];
1311
1300
  if (rule.description.trim()) {
1312
1301
  parts.push(`## ${rule.description.trim()}`, "");
1313
1302
  }
1314
1303
  parts.push(rule.body.trim(), EMBEDDED_RULE_END);
1315
1304
  return parts.filter((part) => part.length > 0).join("\n");
1316
1305
  }
1317
- function renderEmbeddedRulesBlock(rules) {
1318
- if (rules.length === 0) return "";
1319
- return [EMBEDDED_RULES_START, ...rules.map(renderRule), EMBEDDED_RULES_END].join("\n");
1320
- }
1321
- function appendEmbeddedRulesBlock(content, rules) {
1322
- const block = renderEmbeddedRulesBlock(rules);
1323
- const withoutExisting = stripManagedBlock(content, EMBEDDED_RULES_START, EMBEDDED_RULES_END);
1324
- if (!block) return withoutExisting;
1325
- return withoutExisting ? `${withoutExisting}
1326
-
1327
- ${block}` : block;
1306
+ function renderEmbeddedRuleEntries(rules) {
1307
+ return rules.map(renderEmbeddedRule).join("\n\n");
1328
1308
  }
1329
1309
  function toStringArray2(value) {
1330
1310
  return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
@@ -1351,26 +1331,54 @@ function stripGeneratedHeading(body, description) {
1351
1331
  const heading = `## ${description.trim()}`;
1352
1332
  return trimmed.startsWith(heading) ? trimmed.slice(heading.length).trim() : trimmed;
1353
1333
  }
1334
+ function takeEmbeddedRuleEntries(text) {
1335
+ const rules = [];
1336
+ const entry = new RegExp(
1337
+ `${escapeRegExp(START_PREFIX)}([\\s\\S]*?)${escapeRegExp(START_SUFFIX)}([\\s\\S]*?)${escapeRegExp(EMBEDDED_RULE_END)}`,
1338
+ "g"
1339
+ );
1340
+ const rest = text.replace(entry, (whole, markerText, body) => {
1341
+ const marker = parseMarker(markerText);
1342
+ if (!marker) return whole;
1343
+ rules.push({ ...marker, body: stripGeneratedHeading(body, marker.description) });
1344
+ return "";
1345
+ });
1346
+ return { rest: rest.trim(), rules };
1347
+ }
1348
+ var EMBEDDED_RULE_END, START_PREFIX, START_SUFFIX;
1349
+ var init_embedded_rule_entries = __esm({
1350
+ "src/targets/projection/embedded-rule-entries.ts"() {
1351
+ EMBEDDED_RULE_END = "<!-- agentsmesh:embedded-rule:end -->";
1352
+ START_PREFIX = "<!-- agentsmesh:embedded-rule:start ";
1353
+ START_SUFFIX = " -->";
1354
+ }
1355
+ });
1356
+
1357
+ // src/targets/projection/managed-blocks.ts
1358
+ function managedBlockPattern(start, end) {
1359
+ return new RegExp(`${escapeRegExp(start)}[\\s\\S]*?${escapeRegExp(end)}`, "g");
1360
+ }
1361
+ function stripManagedBlock(content, start, end) {
1362
+ return content.replace(managedBlockPattern(start, end), "").trim();
1363
+ }
1364
+ function renderEmbeddedRulesBlock(rules) {
1365
+ if (rules.length === 0) return "";
1366
+ return [EMBEDDED_RULES_START, ...rules.map(renderEmbeddedRule), EMBEDDED_RULES_END].join("\n");
1367
+ }
1368
+ function appendEmbeddedRulesBlock(content, rules) {
1369
+ const block = renderEmbeddedRulesBlock(rules);
1370
+ const withoutExisting = stripManagedBlock(content, EMBEDDED_RULES_START, EMBEDDED_RULES_END);
1371
+ if (!block) return withoutExisting;
1372
+ return withoutExisting ? `${withoutExisting}
1373
+
1374
+ ${block}` : block;
1375
+ }
1354
1376
  function extractEmbeddedRules(content) {
1355
1377
  const rules = [];
1356
1378
  const outerPattern = managedBlockPattern(EMBEDDED_RULES_START, EMBEDDED_RULES_END);
1357
1379
  const rootContent = content.replace(outerPattern, (block) => {
1358
- const inner = block.replace(EMBEDDED_RULES_START, "").replace(EMBEDDED_RULES_END, "").trim();
1359
- const entryPattern = new RegExp(
1360
- `${escapeRegExp(EMBEDDED_RULE_START_PREFIX)}([\\s\\S]*?)${escapeRegExp(EMBEDDED_RULE_START_SUFFIX)}([\\s\\S]*?)${escapeRegExp(EMBEDDED_RULE_END)}`,
1361
- "g"
1362
- );
1363
- for (const match of inner.matchAll(entryPattern)) {
1364
- const markerText = match[1];
1365
- const body = match[2];
1366
- if (markerText === void 0 || body === void 0) continue;
1367
- const marker = parseMarker(markerText);
1368
- if (!marker) continue;
1369
- rules.push({
1370
- ...marker,
1371
- body: stripGeneratedHeading(body, marker.description)
1372
- });
1373
- }
1380
+ const inner = block.replace(EMBEDDED_RULES_START, "").replace(EMBEDDED_RULES_END, "");
1381
+ rules.push(...takeEmbeddedRuleEntries(inner).rules);
1374
1382
  return "";
1375
1383
  });
1376
1384
  return { rootContent: rootContent.trim(), rules };
@@ -1383,17 +1391,16 @@ function embeddedRootRule(canonical, target34, rootFile) {
1383
1391
  const content = appendEmbeddedRulesBlock(rootBody, nonRootRules);
1384
1392
  return content ? [{ path: rootFile, content }] : [];
1385
1393
  }
1386
- var ROOT_CONTRACT_START, ROOT_CONTRACT_END, EMBEDDED_RULES_START, EMBEDDED_RULES_END, EMBEDDED_RULE_END, EMBEDDED_RULE_START_PREFIX, EMBEDDED_RULE_START_SUFFIX;
1394
+ var ROOT_CONTRACT_START, ROOT_CONTRACT_END, EMBEDDED_RULES_START, EMBEDDED_RULES_END;
1387
1395
  var init_managed_blocks = __esm({
1388
1396
  "src/targets/projection/managed-blocks.ts"() {
1389
1397
  init_markdown();
1398
+ init_embedded_rule_entries();
1399
+ init_embedded_rule_entries();
1390
1400
  ROOT_CONTRACT_START = "<!-- agentsmesh:root-generation-contract:start -->";
1391
1401
  ROOT_CONTRACT_END = "<!-- agentsmesh:root-generation-contract:end -->";
1392
1402
  EMBEDDED_RULES_START = "<!-- agentsmesh:embedded-rules:start -->";
1393
1403
  EMBEDDED_RULES_END = "<!-- agentsmesh:embedded-rules:end -->";
1394
- EMBEDDED_RULE_END = "<!-- agentsmesh:embedded-rule:end -->";
1395
- EMBEDDED_RULE_START_PREFIX = "<!-- agentsmesh:embedded-rule:start ";
1396
- EMBEDDED_RULE_START_SUFFIX = " -->";
1397
1404
  }
1398
1405
  });
1399
1406
 
@@ -2059,12 +2066,12 @@ function topLevelDotfilePrefixes(descriptor34) {
2059
2066
  ...descriptor34.detectionPaths,
2060
2067
  ...layouts.flatMap((layout) => managedOutputPaths(layout))
2061
2068
  ];
2062
- const out = /* @__PURE__ */ new Set();
2069
+ const out2 = /* @__PURE__ */ new Set();
2063
2070
  for (const candidate of candidates) {
2064
2071
  const top = candidate.split("/")[0];
2065
- if (top && top.startsWith(".") && top.length > 1) out.add(`${top}/`);
2072
+ if (top && top.startsWith(".") && top.length > 1) out2.add(`${top}/`);
2066
2073
  }
2067
- return out;
2074
+ return out2;
2068
2075
  }
2069
2076
  function buildDefaultRootRelativePrefixes() {
2070
2077
  const set = /* @__PURE__ */ new Set([".agentsmesh/"]);
@@ -2563,9 +2570,9 @@ function markdownBracketLabelDuplicatesDestination(fullContent, labelPathStart,
2563
2570
  let j = closeBracket + 2;
2564
2571
  let dest = "";
2565
2572
  while (j < fullContent.length) {
2566
- const c = fullContent[j];
2567
- if (c === ")" || c === "#" || c === "?" || c === " " || c === " " || c === "\n") break;
2568
- dest += c;
2573
+ const c2 = fullContent[j];
2574
+ if (c2 === ")" || c2 === "#" || c2 === "?" || c2 === " " || c2 === " " || c2 === "\n") break;
2575
+ dest += c2;
2569
2576
  j++;
2570
2577
  }
2571
2578
  return dest === labelPathText;
@@ -2661,6 +2668,8 @@ function rewriteFileLinks(input) {
2661
2668
  const lineNumSuffix = lineNumMatch ? lineNumMatch[0] : "";
2662
2669
  if (!rawCandidate) return match;
2663
2670
  const tokenContext = getTokenContext(fullContent, offset, offset + rawCandidate.length);
2671
+ if (input.markdownLinksOnly === true && tokenContext.role !== "markdown-link-dest")
2672
+ return match;
2664
2673
  const candidate = decodeLinkPath(rawCandidate, tokenContext.role);
2665
2674
  if (tokenContext.role !== "markdown-link-dest" && WINDOWS_ABSOLUTE_PATH.test(candidate)) {
2666
2675
  return match;
@@ -2835,13 +2844,12 @@ var init_import_rewriter = __esm({
2835
2844
  });
2836
2845
  async function writeMcpWithMerge(projectRoot, canonicalPath, imported) {
2837
2846
  const destPath = join(projectRoot, canonicalPath);
2838
- const existing = await readExistingServers(destPath);
2847
+ const existing = parseMcpServers(await readFileSafe(destPath));
2839
2848
  const merged = { ...existing, ...imported };
2840
2849
  await mkdirp(dirname(destPath));
2841
2850
  await writeFileAtomic(destPath, JSON.stringify({ mcpServers: merged }, null, 2));
2842
2851
  }
2843
- async function readExistingServers(path) {
2844
- const content = await readFileSafe(path);
2852
+ function parseMcpServers(content) {
2845
2853
  if (content === null) return {};
2846
2854
  let parsed;
2847
2855
  try {
@@ -2852,12 +2860,12 @@ async function readExistingServers(path) {
2852
2860
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
2853
2861
  const raw = parsed.mcpServers;
2854
2862
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
2855
- const out = {};
2863
+ const out2 = {};
2856
2864
  for (const [name, value] of Object.entries(raw)) {
2857
2865
  if (!value || typeof value !== "object" || Array.isArray(value)) continue;
2858
- out[name] = value;
2866
+ out2[name] = value;
2859
2867
  }
2860
- return out;
2868
+ return out2;
2861
2869
  }
2862
2870
  var init_mcp_merge = __esm({
2863
2871
  "src/targets/import/mcp-merge.ts"() {
@@ -3176,13 +3184,13 @@ function parseMcpJson(content, serversKey = "mcpServers") {
3176
3184
  if (!parsed || typeof parsed !== "object") return {};
3177
3185
  const raw = parsed[serversKey];
3178
3186
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
3179
- const out = {};
3187
+ const out2 = {};
3180
3188
  for (const [name, value] of Object.entries(raw)) {
3181
3189
  if (!value || typeof value !== "object" || Array.isArray(value)) continue;
3182
3190
  const server = value;
3183
3191
  const description = typeof server.description === "string" ? server.description : void 0;
3184
3192
  if (typeof server.command === "string") {
3185
- out[name] = {
3193
+ out2[name] = {
3186
3194
  type: typeof server.type === "string" ? server.type : "stdio",
3187
3195
  command: server.command,
3188
3196
  args: toStringArray(server.args),
@@ -3192,7 +3200,7 @@ function parseMcpJson(content, serversKey = "mcpServers") {
3192
3200
  continue;
3193
3201
  }
3194
3202
  if (typeof server.url === "string") {
3195
- out[name] = {
3203
+ out2[name] = {
3196
3204
  type: typeof server.type === "string" ? server.type : "http",
3197
3205
  url: server.url,
3198
3206
  headers: toStringRecord(server.headers),
@@ -3201,7 +3209,7 @@ function parseMcpJson(content, serversKey = "mcpServers") {
3201
3209
  };
3202
3210
  }
3203
3211
  }
3204
- return out;
3212
+ return out2;
3205
3213
  }
3206
3214
  async function runMcpJson(spec, sources, projectRoot, fromTool) {
3207
3215
  if (!spec.canonicalFilename) {
@@ -3540,14 +3548,14 @@ var init_capability_gap = __esm({
3540
3548
  permissions: AB_PERMISSIONS
3541
3549
  };
3542
3550
  HAS_CONTENT = {
3543
- commands: (c) => c.commands.length > 0,
3544
- ignore: (c) => c.ignore.length > 0,
3545
- mcp: (c) => Object.keys(c.mcp?.mcpServers ?? {}).length > 0,
3546
- hooks: (c) => Object.values(c.hooks ?? {}).some((entries) => Array.isArray(entries) && entries.length > 0),
3547
- permissions: (c) => {
3548
- if (!c.permissions) return false;
3549
- const { allow, deny } = c.permissions;
3550
- const ask = c.permissions.ask ?? [];
3551
+ commands: (c2) => c2.commands.length > 0,
3552
+ ignore: (c2) => c2.ignore.length > 0,
3553
+ mcp: (c2) => Object.keys(c2.mcp?.mcpServers ?? {}).length > 0,
3554
+ hooks: (c2) => Object.values(c2.hooks ?? {}).some((entries) => Array.isArray(entries) && entries.length > 0),
3555
+ permissions: (c2) => {
3556
+ if (!c2.permissions) return false;
3557
+ const { allow, deny } = c2.permissions;
3558
+ const ask = c2.permissions.ask ?? [];
3551
3559
  return allow.length > 0 || deny.length > 0 || ask.length > 0;
3552
3560
  }
3553
3561
  };
@@ -5879,12 +5887,12 @@ function parseJson(content) {
5879
5887
  function serverObjects(root) {
5880
5888
  const raw = asObject2(root?.mcpServers);
5881
5889
  if (!raw) return {};
5882
- const out = {};
5890
+ const out2 = {};
5883
5891
  for (const [name, value] of Object.entries(raw)) {
5884
5892
  const entry = asObject2(value);
5885
- if (entry) out[name] = entry;
5893
+ if (entry) out2[name] = entry;
5886
5894
  }
5887
- return out;
5895
+ return out2;
5888
5896
  }
5889
5897
  function mergeMcpServersJson(base, newContent, ownedServerKeys) {
5890
5898
  if (base !== null) {
@@ -6849,12 +6857,14 @@ function canonicalRulePath(source) {
6849
6857
  }
6850
6858
  async function splitEmbeddedRulesToCanonical(input) {
6851
6859
  const extracted = extractEmbeddedRules(input.content);
6860
+ const results = await writeEmbeddedRules(extracted.rules, input);
6861
+ return { rootContent: extracted.rootContent, results };
6862
+ }
6863
+ async function writeEmbeddedRules(rules, input) {
6852
6864
  const results = [];
6853
- if (extracted.rules.length === 0) {
6854
- return { rootContent: extracted.rootContent, results };
6855
- }
6865
+ if (rules.length === 0) return results;
6856
6866
  await mkdirp(join(input.projectRoot, input.rulesDir));
6857
- for (const rule of extracted.rules) {
6867
+ for (const rule of rules) {
6858
6868
  const canonicalSource = canonicalRulePath(rule.source);
6859
6869
  if (canonicalSource === null || canonicalSource === "rules/_root.md") continue;
6860
6870
  const destPath = join(input.projectRoot, ".agentsmesh", canonicalSource);
@@ -6864,6 +6874,7 @@ async function splitEmbeddedRulesToCanonical(input) {
6864
6874
  destPath,
6865
6875
  {
6866
6876
  ...frontmatter,
6877
+ ...input.frontmatter,
6867
6878
  root: false,
6868
6879
  description: rule.description || void 0,
6869
6880
  globs: rule.globs.length > 0 ? rule.globs : void 0,
@@ -6879,13 +6890,19 @@ async function splitEmbeddedRulesToCanonical(input) {
6879
6890
  feature: "rules"
6880
6891
  });
6881
6892
  }
6882
- return { rootContent: extracted.rootContent, results };
6893
+ return results;
6894
+ }
6895
+ async function splitNestedAgentsFile(input, into) {
6896
+ const { rest, rules } = takeEmbeddedRuleEntries(input.content);
6897
+ into.push(...await writeEmbeddedRules(rules, input));
6898
+ return rest.length > 0 ? rest : null;
6883
6899
  }
6884
6900
  var init_embedded_rules = __esm({
6885
6901
  "src/targets/import/embedded-rules.ts"() {
6886
6902
  init_fs();
6887
6903
  init_markdown();
6888
6904
  init_managed_blocks();
6905
+ init_embedded_rule_entries();
6889
6906
  init_import_metadata();
6890
6907
  }
6891
6908
  });
@@ -7076,12 +7093,12 @@ function parseAntigravityMcpServers(content) {
7076
7093
  if (!parsed || typeof parsed !== "object") return {};
7077
7094
  const raw = parsed.mcpServers;
7078
7095
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
7079
- const out = {};
7096
+ const out2 = {};
7080
7097
  for (const [name, value] of Object.entries(raw)) {
7081
7098
  const server = parseServer2(value);
7082
- if (server) out[name] = server;
7099
+ if (server) out2[name] = server;
7083
7100
  }
7084
- return out;
7101
+ return out2;
7085
7102
  }
7086
7103
  var ANTIGRAVITY_OWNED_SERVER_KEYS;
7087
7104
  var init_mcp_format = __esm({
@@ -8309,7 +8326,7 @@ function generateRules6(canonical) {
8309
8326
  const slug = basename(rule.source, ".md");
8310
8327
  const frontmatter = {};
8311
8328
  if (rule.description) frontmatter.description = rule.description;
8312
- if (rule.globs.length > 0) frontmatter.globs = rule.globs;
8329
+ if (rule.globs.length > 0) frontmatter.paths = rule.globs;
8313
8330
  const content = serializeFrontmatter(frontmatter, rule.body.trim() || "");
8314
8331
  outputs.push({ path: `${CLAUDE_RULES_DIR}/${slug}.md`, content });
8315
8332
  }
@@ -8691,12 +8708,14 @@ var init_import_mappers2 = __esm({
8691
8708
  }) => {
8692
8709
  const destPath = join(destDir, relativePath);
8693
8710
  const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
8711
+ const { paths: paths2, ...rest } = frontmatter;
8712
+ const scoped = paths2 === void 0 ? {} : { globs: toToolsArray(paths2) };
8694
8713
  return {
8695
8714
  destPath,
8696
8715
  toPath: `${AB_RULES}/${relativePath}`,
8697
8716
  content: await serializeImportedRuleWithFallback(
8698
8717
  destPath,
8699
- { ...frontmatter, root: false },
8718
+ { ...rest, ...scoped, root: false },
8700
8719
  body
8701
8720
  )
8702
8721
  };
@@ -10201,7 +10220,7 @@ function generateRules8(canonical) {
10201
10220
  const rootBody = canonical.rules.find((rule) => rule.root)?.body.trim() ?? "";
10202
10221
  if (rootBody) outputs.push({ path: CODEBUFF_ROOT_FILE, content: rootBody });
10203
10222
  for (const [path, rules] of groupByNestedPath(eligibleRules(canonical))) {
10204
- const content = rules.map((rule) => rule.body.trim()).filter((body) => body.length > 0).join("\n\n");
10223
+ const content = renderEmbeddedRuleEntries(rules.filter((rule) => rule.body.trim().length > 0));
10205
10224
  if (content) outputs.push({ path, content });
10206
10225
  }
10207
10226
  return outputs;
@@ -10229,6 +10248,7 @@ var init_generator8 = __esm({
10229
10248
  init_no_outputs();
10230
10249
  init_embedded_skill();
10231
10250
  init_managed_blocks();
10251
+ init_embedded_rule_entries();
10232
10252
  init_command_skill();
10233
10253
  init_nested_rules();
10234
10254
  init_mcp_format2();
@@ -10278,33 +10298,47 @@ function isVendored(relDir) {
10278
10298
  }
10279
10299
  async function importNestedRules(projectRoot, normalize) {
10280
10300
  const destDir = join(projectRoot, AB_RULES);
10281
- return importFileDirectory({
10301
+ const embedded = [];
10302
+ const results = await importFileDirectory({
10282
10303
  srcDir: projectRoot,
10283
10304
  destDir,
10284
10305
  extensions: [CODEBUFF_ROOT_FILE],
10285
10306
  fromTool: CODEBUFF_TARGET,
10286
10307
  normalize,
10287
- mapEntry: ({ srcPath, normalizeTo }) => {
10308
+ mapEntry: async ({ srcPath, content, normalizeTo }) => {
10288
10309
  if (basename(srcPath) !== CODEBUFF_ROOT_FILE) return null;
10289
10310
  const relDir = relative(projectRoot, dirname(srcPath)).replace(/\\/g, "/");
10290
10311
  if (!relDir || relDir === ".") return null;
10291
10312
  if (!shouldImportScopedAgentsRule(relDir)) return null;
10292
10313
  if (isVendored(relDir)) return null;
10314
+ const ownText = await splitNestedAgentsFile(
10315
+ {
10316
+ content,
10317
+ projectRoot,
10318
+ rulesDir: AB_RULES,
10319
+ sourcePath: srcPath,
10320
+ fromTool: CODEBUFF_TARGET,
10321
+ normalize
10322
+ },
10323
+ embedded
10324
+ );
10325
+ if (ownText === null) return null;
10293
10326
  const ruleName2 = relDir.replace(/\//g, "-");
10294
10327
  const destPath = join(destDir, `${ruleName2}.md`);
10295
- const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
10296
- return serializeImportedRuleWithFallback(
10297
- destPath,
10298
- { ...frontmatter, root: false, globs: [`${relDir}/**`] },
10299
- body
10300
- ).then((content) => ({
10328
+ const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath, ownText));
10329
+ return {
10301
10330
  destPath,
10302
10331
  toPath: `${AB_RULES}/${ruleName2}.md`,
10303
10332
  feature: "rules",
10304
- content
10305
- }));
10333
+ content: await serializeImportedRuleWithFallback(
10334
+ destPath,
10335
+ { ...frontmatter, root: false, globs: [`${relDir}/**`] },
10336
+ body
10337
+ )
10338
+ };
10306
10339
  }
10307
10340
  });
10341
+ return [...results, ...embedded];
10308
10342
  }
10309
10343
  async function importCodebuffRules(projectRoot, scope, normalize) {
10310
10344
  const results = await importRootRule2(projectRoot, scope, normalize);
@@ -10737,7 +10771,7 @@ function generateRules9(canonical) {
10737
10771
  }
10738
10772
  const nested = advisory.filter((rule) => !isRootEmbedded(rule));
10739
10773
  for (const [path, rules] of groupByNestedPath2(nested)) {
10740
- const content = rules.map((rule) => rule.body.trim()).filter((body) => body.length > 0).join("\n\n");
10774
+ const content = renderEmbeddedRuleEntries(rules.filter((rule) => rule.body.trim().length > 0));
10741
10775
  outputs.push({ path, content });
10742
10776
  }
10743
10777
  return outputs;
@@ -10750,6 +10784,7 @@ function renderCodexGlobalInstructions(canonical) {
10750
10784
  var init_rules = __esm({
10751
10785
  "src/targets/codex-cli/generator/rules.ts"() {
10752
10786
  init_managed_blocks();
10787
+ init_embedded_rule_entries();
10753
10788
  init_constants10();
10754
10789
  init_codex_rule_paths();
10755
10790
  }
@@ -11379,6 +11414,7 @@ async function importCodexRules(projectRoot, results, normalize, normalizeWindsu
11379
11414
  await importInstructionMirrors(projectRoot, destDir, results, normalize);
11380
11415
  results.push(...await importCodexNonRootRuleFiles(projectRoot, destDir, normalize));
11381
11416
  if (layoutScope !== "global") {
11417
+ const embedded = [];
11382
11418
  results.push(
11383
11419
  ...await importFileDirectory({
11384
11420
  srcDir: projectRoot,
@@ -11386,7 +11422,7 @@ async function importCodexRules(projectRoot, results, normalize, normalizeWindsu
11386
11422
  extensions: ["AGENTS.md", "AGENTS.override.md"],
11387
11423
  fromTool: "codex-cli",
11388
11424
  normalize,
11389
- mapEntry: async ({ srcPath, normalizeTo }) => {
11425
+ mapEntry: async ({ srcPath, content: content2, normalizeTo }) => {
11390
11426
  const relDir = relative(projectRoot, dirname(srcPath)).replace(/\\/g, "/");
11391
11427
  const fileName = basename(srcPath);
11392
11428
  const isOverride = fileName === "AGENTS.override.md";
@@ -11397,26 +11433,36 @@ async function importCodexRules(projectRoot, results, normalize, normalizeWindsu
11397
11433
  await removePathIfExists(join(destDir, `${ruleName2}.md`));
11398
11434
  return null;
11399
11435
  }
11436
+ const variant = isOverride ? { codex_instruction: "override" } : {};
11437
+ const ownText = await splitNestedAgentsFile(
11438
+ {
11439
+ content: content2,
11440
+ projectRoot,
11441
+ rulesDir: AB_RULES,
11442
+ sourcePath: srcPath,
11443
+ fromTool: "codex-cli",
11444
+ normalize,
11445
+ frontmatter: variant
11446
+ },
11447
+ embedded
11448
+ );
11449
+ if (ownText === null) return null;
11400
11450
  const destPath = join(destDir, `${ruleName2}.md`);
11401
- const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
11451
+ const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath, ownText));
11402
11452
  return {
11403
11453
  destPath,
11404
11454
  toPath: `${AB_RULES}/${ruleName2}.md`,
11405
11455
  feature: "rules",
11406
11456
  content: await serializeImportedRuleWithFallback(
11407
11457
  destPath,
11408
- {
11409
- ...frontmatter,
11410
- root: false,
11411
- globs: [`${relDir}/**`],
11412
- ...isOverride ? { codex_instruction: "override" } : {}
11413
- },
11458
+ { ...frontmatter, root: false, globs: [`${relDir}/**`], ...variant },
11414
11459
  body
11415
11460
  )
11416
11461
  };
11417
11462
  }
11418
11463
  })
11419
11464
  );
11465
+ results.push(...embedded);
11420
11466
  }
11421
11467
  }
11422
11468
  async function importInstructionMirrors(projectRoot, destDir, results, normalize) {
@@ -12162,11 +12208,11 @@ function serializeContinuePermissions(permissions) {
12162
12208
  const ask = permissions.ask ?? [];
12163
12209
  const exclude = permissions.deny ?? [];
12164
12210
  if (allow.length === 0 && ask.length === 0 && exclude.length === 0) return null;
12165
- const out = {};
12166
- if (allow.length > 0) out.allow = allow;
12167
- if (ask.length > 0) out.ask = ask;
12168
- if (exclude.length > 0) out.exclude = exclude;
12169
- return stringify(out).trimEnd() + "\n";
12211
+ const out2 = {};
12212
+ if (allow.length > 0) out2.allow = allow;
12213
+ if (ask.length > 0) out2.ask = ask;
12214
+ if (exclude.length > 0) out2.exclude = exclude;
12215
+ return stringify(out2).trimEnd() + "\n";
12170
12216
  }
12171
12217
  function parseContinuePermissions(content) {
12172
12218
  let parsed;
@@ -13365,14 +13411,14 @@ async function generateCopilotGlobalHooks(canonical, projectRoot) {
13365
13411
  COPILOT_GLOBAL_HOOKS_DIR
13366
13412
  );
13367
13413
  const results = [];
13368
- for (const out of outputs) {
13369
- const existing = await readFileSafe(join(projectRoot, out.path));
13414
+ for (const out2 of outputs) {
13415
+ const existing = await readFileSafe(join(projectRoot, out2.path));
13370
13416
  results.push({
13371
13417
  target: COPILOT_TARGET,
13372
- path: out.path,
13373
- content: out.content,
13418
+ path: out2.path,
13419
+ content: out2.content,
13374
13420
  currentContent: existing ?? void 0,
13375
- status: computeStatus6(existing, out.content)
13421
+ status: computeStatus6(existing, out2.content)
13376
13422
  });
13377
13423
  }
13378
13424
  return results;
@@ -13979,13 +14025,13 @@ function parseCrushPermissions(rawPermissions, rawOptions) {
13979
14025
  }
13980
14026
  function parseCrushMcpServers(raw) {
13981
14027
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
13982
- const out = {};
14028
+ const out2 = {};
13983
14029
  for (const [name, value] of Object.entries(raw)) {
13984
14030
  if (!value || typeof value !== "object" || Array.isArray(value)) continue;
13985
14031
  const server = value;
13986
14032
  const description = typeof server["description"] === "string" ? server["description"] : void 0;
13987
14033
  if (typeof server["command"] === "string") {
13988
- out[name] = {
14034
+ out2[name] = {
13989
14035
  type: typeof server["type"] === "string" ? server["type"] : "stdio",
13990
14036
  command: server["command"],
13991
14037
  args: toStringArray(server["args"]),
@@ -13995,7 +14041,7 @@ function parseCrushMcpServers(raw) {
13995
14041
  continue;
13996
14042
  }
13997
14043
  if (typeof server["url"] === "string") {
13998
- out[name] = {
14044
+ out2[name] = {
13999
14045
  type: typeof server["type"] === "string" ? server["type"] : "http",
14000
14046
  url: server["url"],
14001
14047
  headers: toStringRecord(server["headers"]),
@@ -14004,11 +14050,11 @@ function parseCrushMcpServers(raw) {
14004
14050
  };
14005
14051
  }
14006
14052
  }
14007
- return out;
14053
+ return out2;
14008
14054
  }
14009
14055
  function parseCrushHooks(raw) {
14010
14056
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
14011
- const out = {};
14057
+ const out2 = {};
14012
14058
  for (const [event, entries] of Object.entries(raw)) {
14013
14059
  if (!Array.isArray(entries)) continue;
14014
14060
  const items = [];
@@ -14022,9 +14068,9 @@ function parseCrushHooks(raw) {
14022
14068
  if (typeof e["timeout"] === "number") item.timeout = e["timeout"];
14023
14069
  items.push(item);
14024
14070
  }
14025
- if (items.length > 0) out[event] = items;
14071
+ if (items.length > 0) out2[event] = items;
14026
14072
  }
14027
- return Object.keys(out).length > 0 ? out : null;
14073
+ return Object.keys(out2).length > 0 ? out2 : null;
14028
14074
  }
14029
14075
  function serializeHooksYaml(hooks) {
14030
14076
  const lines = [];
@@ -15488,7 +15534,7 @@ function deepagentsHooksToCanonical(hooksArray) {
15488
15534
  for (const raw of hooksArray) {
15489
15535
  if (!raw || typeof raw !== "object") continue;
15490
15536
  const hook = raw;
15491
- const commandArr = Array.isArray(hook.command) ? hook.command.filter((c) => typeof c === "string") : [];
15537
+ const commandArr = Array.isArray(hook.command) ? hook.command.filter((c2) => typeof c2 === "string") : [];
15492
15538
  if (commandArr.length === 0) continue;
15493
15539
  const command = commandArr.length === 3 && commandArr[0] === "bash" && commandArr[1] === "-c" ? commandArr[2] : commandArr.join(" ");
15494
15540
  const events = Array.isArray(hook.events) ? hook.events.filter((e) => typeof e === "string") : [];
@@ -18014,13 +18060,13 @@ function parsePluginMcpJson(content) {
18014
18060
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
18015
18061
  const servers = parsed.mcpServers;
18016
18062
  if (!servers || typeof servers !== "object" || Array.isArray(servers)) return {};
18017
- const out = {};
18063
+ const out2 = {};
18018
18064
  for (const [name, value] of Object.entries(servers)) {
18019
18065
  if (!value || typeof value !== "object" || Array.isArray(value)) continue;
18020
18066
  const server = pluginEntryToMcpServer(value);
18021
- if (server) out[name] = server;
18067
+ if (server) out2[name] = server;
18022
18068
  }
18023
- return out;
18069
+ return out2;
18024
18070
  }
18025
18071
  function parseExtensions(content) {
18026
18072
  let parsed;
@@ -18032,15 +18078,15 @@ function parseExtensions(content) {
18032
18078
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
18033
18079
  const extensions = parsed.extensions;
18034
18080
  if (!extensions || typeof extensions !== "object" || Array.isArray(extensions)) return {};
18035
- const out = {};
18081
+ const out2 = {};
18036
18082
  for (const [name, value] of Object.entries(extensions)) {
18037
18083
  if (!value || typeof value !== "object" || Array.isArray(value)) continue;
18038
18084
  const server = extensionToMcpServer(value);
18039
- if (server) out[name] = server;
18085
+ if (server) out2[name] = server;
18040
18086
  }
18041
- return out;
18087
+ return out2;
18042
18088
  }
18043
- async function readExistingServers2(destPath) {
18089
+ async function readExistingServers(destPath) {
18044
18090
  const content = await readFileSafe(destPath);
18045
18091
  if (content === null) return {};
18046
18092
  let parsed;
@@ -18052,18 +18098,18 @@ async function readExistingServers2(destPath) {
18052
18098
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
18053
18099
  const raw = parsed.mcpServers;
18054
18100
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
18055
- const out = {};
18101
+ const out2 = {};
18056
18102
  for (const [name, value] of Object.entries(raw)) {
18057
18103
  if (!value || typeof value !== "object" || Array.isArray(value)) continue;
18058
- out[name] = value;
18104
+ out2[name] = value;
18059
18105
  }
18060
- return out;
18106
+ return out2;
18061
18107
  }
18062
18108
  async function gooseMcpMap(ctx) {
18063
18109
  const imported = ctx.relativePath.endsWith(".mcp.json") ? parsePluginMcpJson(ctx.content) : parseExtensions(ctx.content);
18064
18110
  if (Object.keys(imported).length === 0) return null;
18065
18111
  const destPath = join(ctx.destDir, "mcp.json");
18066
- const existing = await readExistingServers2(destPath);
18112
+ const existing = await readExistingServers(destPath);
18067
18113
  const merged = { ...existing, ...imported };
18068
18114
  return {
18069
18115
  destPath,
@@ -18145,19 +18191,19 @@ function asObject3(value) {
18145
18191
  function unownedExtensions(existing) {
18146
18192
  const block = asObject3(existing);
18147
18193
  if (!block) return {};
18148
- const out = {};
18194
+ const out2 = {};
18149
18195
  for (const [name, value] of Object.entries(block)) {
18150
18196
  const entry = asObject3(value);
18151
- if (entry && extensionToMcpServer(entry) === null) out[name] = entry;
18197
+ if (entry && extensionToMcpServer(entry) === null) out2[name] = entry;
18152
18198
  }
18153
- return out;
18199
+ return out2;
18154
18200
  }
18155
18201
  function buildExtensions(servers) {
18156
- const out = {};
18202
+ const out2 = {};
18157
18203
  for (const [name, server] of Object.entries(servers)) {
18158
- out[name] = mcpServerToExtension(name, server);
18204
+ out2[name] = mcpServerToExtension(name, server);
18159
18205
  }
18160
- return out;
18206
+ return out2;
18161
18207
  }
18162
18208
  function result(content, existing) {
18163
18209
  return {
@@ -18673,18 +18719,18 @@ function generateRules19(canonical) {
18673
18719
  return outputs;
18674
18720
  }
18675
18721
  function toJunieMcpServer(server) {
18676
- const out = {};
18677
- if (server.description) out.description = server.description;
18678
- if (server.type !== "stdio") out.type = server.type;
18722
+ const out2 = {};
18723
+ if (server.description) out2.description = server.description;
18724
+ if (server.type !== "stdio") out2.type = server.type;
18679
18725
  if (isStdioMcpServer(server)) {
18680
- out.command = server.command;
18681
- out.args = server.args;
18726
+ out2.command = server.command;
18727
+ out2.args = server.args;
18682
18728
  } else {
18683
- out.url = server.url;
18684
- if (Object.keys(server.headers).length > 0) out.headers = server.headers;
18729
+ out2.url = server.url;
18730
+ if (Object.keys(server.headers).length > 0) out2.headers = server.headers;
18685
18731
  }
18686
- if (Object.keys(server.env).length > 0) out.env = server.env;
18687
- return out;
18732
+ if (Object.keys(server.env).length > 0) out2.env = server.env;
18733
+ return out2;
18688
18734
  }
18689
18735
  function generateMcp14(canonical) {
18690
18736
  if (!canonical.mcp || Object.keys(canonical.mcp.mcpServers).length === 0) return [];
@@ -19251,11 +19297,11 @@ var init_import_mappers7 = __esm({
19251
19297
  });
19252
19298
  function toStringRecord3(value) {
19253
19299
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
19254
- const out = {};
19300
+ const out2 = {};
19255
19301
  for (const [key, v] of Object.entries(value)) {
19256
- if (typeof v === "string") out[key] = v;
19302
+ if (typeof v === "string") out2[key] = v;
19257
19303
  }
19258
- return out;
19304
+ return out2;
19259
19305
  }
19260
19306
  function parseKiloGlobalMcp(content) {
19261
19307
  let parsed;
@@ -19267,13 +19313,13 @@ function parseKiloGlobalMcp(content) {
19267
19313
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
19268
19314
  const raw = parsed.mcp;
19269
19315
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
19270
- const out = {};
19316
+ const out2 = {};
19271
19317
  for (const [name, value] of Object.entries(raw)) {
19272
19318
  if (!value || typeof value !== "object" || Array.isArray(value)) continue;
19273
19319
  const entry = value;
19274
19320
  const description = typeof entry.description === "string" ? entry.description : void 0;
19275
19321
  if (typeof entry.url === "string") {
19276
- out[name] = {
19322
+ out2[name] = {
19277
19323
  type: "url",
19278
19324
  url: entry.url,
19279
19325
  headers: toStringRecord3(entry.headers),
@@ -19285,7 +19331,7 @@ function parseKiloGlobalMcp(content) {
19285
19331
  if (Array.isArray(entry.command) && entry.command.length > 0) {
19286
19332
  const [command, ...args] = entry.command;
19287
19333
  if (typeof command !== "string") continue;
19288
- out[name] = {
19334
+ out2[name] = {
19289
19335
  type: "stdio",
19290
19336
  command,
19291
19337
  args: args.filter((a) => typeof a === "string"),
@@ -19294,7 +19340,7 @@ function parseKiloGlobalMcp(content) {
19294
19340
  };
19295
19341
  }
19296
19342
  }
19297
- return out;
19343
+ return out2;
19298
19344
  }
19299
19345
  async function importGlobalKiloMcp(projectRoot, results) {
19300
19346
  const srcPath = join(projectRoot, KILO_GLOBAL_CONFIG_FILE);
@@ -21162,16 +21208,16 @@ function mergeImportedEntries(existing, imported, effect) {
21162
21208
  const key = kiroRuleKey(rule);
21163
21209
  byKey.set(key, [...byKey.get(key) ?? [], entry]);
21164
21210
  }
21165
- const out = [];
21211
+ const out2 = [];
21166
21212
  const push2 = (entry) => {
21167
- if (!out.includes(entry)) out.push(entry);
21213
+ if (!out2.includes(entry)) out2.push(entry);
21168
21214
  };
21169
21215
  for (const rule of imported) {
21170
21216
  if (rule.effect !== effect) continue;
21171
21217
  for (const entry of byKey.get(kiroRuleKey(rule)) ?? ruleToCanonicalEntries(rule)) push2(entry);
21172
21218
  }
21173
21219
  for (const entry of unrepresentable) push2(entry);
21174
- return out;
21220
+ return out2;
21175
21221
  }
21176
21222
  var OWNED_RULE_KEYS;
21177
21223
  var init_permissions_lists = __esm({
@@ -21867,11 +21913,11 @@ var init_generator26 = __esm({
21867
21913
  });
21868
21914
  function toStringRecord4(value) {
21869
21915
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
21870
- const out = {};
21916
+ const out2 = {};
21871
21917
  for (const [k, v] of Object.entries(value)) {
21872
- if (typeof v === "string") out[k] = v;
21918
+ if (typeof v === "string") out2[k] = v;
21873
21919
  }
21874
- return out;
21920
+ return out2;
21875
21921
  }
21876
21922
  function parseOpenCodeMcp(content) {
21877
21923
  let parsed;
@@ -21883,12 +21929,12 @@ function parseOpenCodeMcp(content) {
21883
21929
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
21884
21930
  const raw = parsed.mcp;
21885
21931
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
21886
- const out = {};
21932
+ const out2 = {};
21887
21933
  for (const [name, value] of Object.entries(raw)) {
21888
21934
  if (!value || typeof value !== "object" || Array.isArray(value)) continue;
21889
21935
  const entry = value;
21890
21936
  if (typeof entry.url === "string") {
21891
- out[name] = {
21937
+ out2[name] = {
21892
21938
  type: "url",
21893
21939
  url: entry.url,
21894
21940
  headers: toStringRecord4(entry.headers),
@@ -21902,7 +21948,7 @@ function parseOpenCodeMcp(content) {
21902
21948
  const command = cmdArr[0];
21903
21949
  if (command === void 0) continue;
21904
21950
  const args = cmdArr.slice(1);
21905
- out[name] = {
21951
+ out2[name] = {
21906
21952
  type: "stdio",
21907
21953
  command,
21908
21954
  args,
@@ -21911,7 +21957,7 @@ function parseOpenCodeMcp(content) {
21911
21957
  };
21912
21958
  }
21913
21959
  }
21914
- return out;
21960
+ return out2;
21915
21961
  }
21916
21962
  async function importMcp5(projectRoot, scope, results) {
21917
21963
  const configFile = scope === "global" ? OPENCODE_GLOBAL_CONFIG_FILE : OPENCODE_CONFIG_FILE;
@@ -23093,12 +23139,12 @@ function unmappedPermissionEntries3(permissions) {
23093
23139
  };
23094
23140
  }
23095
23141
  function defaultToolsToCanonicalAllow(tools) {
23096
- const out = [];
23142
+ const out2 = [];
23097
23143
  for (const tool of tools) {
23098
23144
  const name = CANONICAL_BY_PI_TOOL.get(tool);
23099
- if (name !== void 0 && !out.includes(name)) out.push(name);
23145
+ if (name !== void 0 && !out2.includes(name)) out2.push(name);
23100
23146
  }
23101
- return out;
23147
+ return out2;
23102
23148
  }
23103
23149
  function parseObject(content) {
23104
23150
  try {
@@ -23134,11 +23180,11 @@ function withDefaultTools(settings, tools, keepEmptyKey) {
23134
23180
  return JSON.stringify(settings, null, 2) + "\n";
23135
23181
  }
23136
23182
  function mergeImportedAllow(existing, tools) {
23137
- const out = defaultToolsToCanonicalAllow(tools);
23183
+ const out2 = defaultToolsToCanonicalAllow(tools);
23138
23184
  for (const entry of existing) {
23139
- if (piToolFor(entry) === null && !out.includes(entry)) out.push(entry);
23185
+ if (piToolFor(entry) === null && !out2.includes(entry)) out2.push(entry);
23140
23186
  }
23141
- return out;
23187
+ return out2;
23142
23188
  }
23143
23189
  var PI_BUILTIN_TOOLS, PI_TOOL_BY_CANONICAL, CANONICAL_BY_PI_TOOL, OWNED_PI_TOOLS;
23144
23190
  var init_permissions_format4 = __esm({
@@ -25390,18 +25436,18 @@ function approvalOf(value) {
25390
25436
  const approval = value.approval;
25391
25437
  return approval === "allow" || approval === "ask" || approval === "deny" ? approval : null;
25392
25438
  }
25393
- function collectRules(bucket, suffix, out) {
25439
+ function collectRules(bucket, suffix, out2) {
25394
25440
  if (!isRecord(bucket)) return;
25395
25441
  for (const [command, rule] of Object.entries(bucket)) {
25396
25442
  const approval = approvalOf(rule);
25397
25443
  if (approval === null || command.trim() === "") continue;
25398
- out[approval].push(`Bash(${command}${suffix})`);
25444
+ out2[approval].push(`Bash(${command}${suffix})`);
25399
25445
  }
25400
25446
  }
25401
- function collectPaths(value, tool, out) {
25447
+ function collectPaths(value, tool, out2) {
25402
25448
  if (!Array.isArray(value)) return;
25403
25449
  for (const path of value) {
25404
- if (typeof path === "string" && path.trim() !== "") out.push(`${tool}(${path})`);
25450
+ if (typeof path === "string" && path.trim() !== "") out2.push(`${tool}(${path})`);
25405
25451
  }
25406
25452
  }
25407
25453
  function traeToPermissions(root) {
@@ -25448,11 +25494,11 @@ function branch(parent, key) {
25448
25494
  return isRecord6(value) ? { ...value } : {};
25449
25495
  }
25450
25496
  function unionPaths(existing, projected) {
25451
- const out = stringList(existing);
25497
+ const out2 = stringList(existing);
25452
25498
  for (const path of projected) {
25453
- if (!out.includes(path)) out.push(path);
25499
+ if (!out2.includes(path)) out2.push(path);
25454
25500
  }
25455
- return out;
25501
+ return out2;
25456
25502
  }
25457
25503
  function applyBucket(rules, bucket, projected) {
25458
25504
  if (Object.keys(projected).length === 0) return;
@@ -26178,12 +26224,12 @@ function mapsToWarpKey(pattern, list) {
26178
26224
  return pattern.trim() === "Read" || readTarget(pattern) !== null;
26179
26225
  }
26180
26226
  function uniqueRegexes(patterns, list) {
26181
- const out = [];
26227
+ const out2 = [];
26182
26228
  for (const pattern of patterns) {
26183
26229
  const regex = commandRegex(pattern, list);
26184
- if (regex !== null && !out.includes(regex)) out.push(regex);
26230
+ if (regex !== null && !out2.includes(regex)) out2.push(regex);
26185
26231
  }
26186
- return out;
26232
+ return out2;
26187
26233
  }
26188
26234
  function filterLists(permissions, keep) {
26189
26235
  return {
@@ -26223,10 +26269,10 @@ function stringEntries(value) {
26223
26269
  if (!Array.isArray(value)) return [];
26224
26270
  return value.filter((entry) => typeof entry === "string");
26225
26271
  }
26226
- function collectCommands(value, list, out) {
26272
+ function collectCommands(value, list, out2) {
26227
26273
  for (const regex of stringEntries(value)) {
26228
26274
  const pattern = commandPattern(regex, list);
26229
- if (pattern !== null && !out.includes(pattern)) out.push(pattern);
26275
+ if (pattern !== null && !out2.includes(pattern)) out2.push(pattern);
26230
26276
  }
26231
26277
  }
26232
26278
  function profileToPermissions(profiles) {
@@ -26618,12 +26664,6 @@ function ruleSlug3(source) {
26618
26664
  const name = basename(source, ".md");
26619
26665
  return name === "_root" ? "root" : name;
26620
26666
  }
26621
- function directoryScopedRuleDir(globs) {
26622
- if (globs.length === 0) return null;
26623
- const dirs = globs.map((glob) => glob.split("/")[0] ?? "").filter((segment) => /^[A-Za-z0-9._-]+$/.test(segment));
26624
- if (dirs.length !== globs.length) return null;
26625
- return dirs.every((dir) => dir === dirs[0]) ? dirs[0] : null;
26626
- }
26627
26667
  function generateRules32(canonical) {
26628
26668
  const outputs = [];
26629
26669
  const root = canonical.rules.find((r) => r.root);
@@ -26640,21 +26680,14 @@ function generateRules32(canonical) {
26640
26680
  const frontmatter = {
26641
26681
  description: rule.description || void 0,
26642
26682
  trigger: normalizedTrigger,
26643
- glob: rule.globs.length === 1 ? rule.globs[0] : void 0,
26644
- globs: rule.globs.length > 1 ? rule.globs : void 0
26683
+ // Windsurf reads `globs` as one comma-joined string; it ignores `glob`.
26684
+ globs: rule.globs.length > 0 ? rule.globs.join(",") : void 0
26645
26685
  };
26646
26686
  Object.keys(frontmatter).forEach((k) => {
26647
26687
  if (frontmatter[k] === void 0) delete frontmatter[k];
26648
26688
  });
26649
26689
  const content = Object.keys(frontmatter).length > 0 ? serializeFrontmatter(frontmatter, rule.body.trim() || "") : rule.body.trim() || "";
26650
26690
  outputs.push({ path: `${WINDSURF_RULES_DIR}/${slug}.md`, content });
26651
- const dir = directoryScopedRuleDir(rule.globs);
26652
- if (dir) {
26653
- if (dir !== slug) {
26654
- outputs.push({ path: `${WINDSURF_RULES_DIR}/${dir}.md`, content });
26655
- }
26656
- outputs.push({ path: `${dir}/AGENTS.md`, content: rule.body.trim() || "" });
26657
- }
26658
26691
  }
26659
26692
  return outputs;
26660
26693
  }
@@ -26854,6 +26887,185 @@ var init_generator36 = __esm({
26854
26887
  init_generator35();
26855
26888
  }
26856
26889
  });
26890
+
26891
+ // src/utils/output/color.ts
26892
+ function noColorRequested() {
26893
+ const value = process.env.NO_COLOR;
26894
+ return value !== void 0 && value !== "";
26895
+ }
26896
+ function forceColorRequested() {
26897
+ const value = process.env.FORCE_COLOR;
26898
+ if (value === void 0) return void 0;
26899
+ return value !== "0" && value !== "false";
26900
+ }
26901
+ function colorEnabled(stream = process.stdout) {
26902
+ const forced = forceColorRequested();
26903
+ if (forced !== void 0) return forced;
26904
+ if (noColorRequested()) return false;
26905
+ return stream.isTTY === true;
26906
+ }
26907
+ var init_color = __esm({
26908
+ "src/utils/output/color.ts"() {
26909
+ }
26910
+ });
26911
+
26912
+ // src/utils/output/logger.ts
26913
+ function outStream() {
26914
+ return stdoutRedirectedToStderr ? process.stderr : process.stdout;
26915
+ }
26916
+ function out(text) {
26917
+ outStream().write(text);
26918
+ }
26919
+ function c(code, text, stream) {
26920
+ return colorEnabled(stream) ? `${code}${text}${C.reset}` : text;
26921
+ }
26922
+ var C, muted, stdoutRedirectedToStderr, logger;
26923
+ var init_logger = __esm({
26924
+ "src/utils/output/logger.ts"() {
26925
+ init_color();
26926
+ C = {
26927
+ green: "\x1B[32m",
26928
+ red: "\x1B[31m",
26929
+ yellow: "\x1B[33m",
26930
+ cyan: "\x1B[36m",
26931
+ reset: "\x1B[0m"
26932
+ };
26933
+ muted = false;
26934
+ stdoutRedirectedToStderr = false;
26935
+ logger = {
26936
+ info(msg) {
26937
+ if (muted) return;
26938
+ out(c(C.cyan, msg, outStream()) + "\n");
26939
+ },
26940
+ warn(msg) {
26941
+ if (muted) return;
26942
+ process.stderr.write(c(C.yellow, "\u26A0 ", process.stderr) + msg + "\n");
26943
+ },
26944
+ error(msg) {
26945
+ if (muted) return;
26946
+ process.stderr.write(c(C.red, "\u2717 ", process.stderr) + msg + "\n");
26947
+ },
26948
+ success(msg) {
26949
+ if (muted) return;
26950
+ out(c(C.green, "\u2713 ", outStream()) + msg + "\n");
26951
+ },
26952
+ debug(msg) {
26953
+ if (muted) return;
26954
+ if (process.env.AGENTSMESH_DEBUG === "1") {
26955
+ out(c(C.cyan, "[debug] ", outStream()) + msg + "\n");
26956
+ }
26957
+ }
26958
+ };
26959
+ }
26960
+ });
26961
+
26962
+ // src/targets/windsurf/rule-globs.ts
26963
+ function splitTopLevelCommas(value) {
26964
+ const parts = [];
26965
+ let depth = 0;
26966
+ let current = "";
26967
+ for (const char of value) {
26968
+ if (char === "{") depth++;
26969
+ else if (char === "}") depth = Math.max(0, depth - 1);
26970
+ if (char === "," && depth === 0) {
26971
+ parts.push(current);
26972
+ current = "";
26973
+ } else {
26974
+ current += char;
26975
+ }
26976
+ }
26977
+ parts.push(current);
26978
+ return parts.map((part) => part.trim()).filter(Boolean);
26979
+ }
26980
+ function parseWindsurfGlobs(value) {
26981
+ if (typeof value === "string") return splitTopLevelCommas(value);
26982
+ return Array.isArray(value) ? toToolsArray(value) : [];
26983
+ }
26984
+ function quoteWindsurfGlobValues(content) {
26985
+ const lines = content.split("\n");
26986
+ if (lines[0]?.trim() !== "---") return content;
26987
+ for (let i = 1; i < lines.length; i++) {
26988
+ if (lines[i].trim() === "---") break;
26989
+ const match = UNQUOTED_GLOBS_LINE.exec(lines[i]);
26990
+ if (match !== null) lines[i] = `${match[1]}${JSON.stringify(match[2])}${match[3]}`;
26991
+ }
26992
+ return lines.join("\n");
26993
+ }
26994
+ var UNQUOTED_GLOBS_LINE;
26995
+ var init_rule_globs = __esm({
26996
+ "src/targets/windsurf/rule-globs.ts"() {
26997
+ init_shared_import_helpers();
26998
+ UNQUOTED_GLOBS_LINE = /^(\s*globs?\s*:[ \t]*)([^\s"'[{|>#][^\r\n]*?)[ \t]*(\r?)$/;
26999
+ }
27000
+ });
27001
+ async function windsurfRuleBodies(projectRoot) {
27002
+ const files = await readDirRecursiveNoSymlinks(join(projectRoot, WINDSURF_RULES_DIR));
27003
+ const bodies = /* @__PURE__ */ new Set();
27004
+ for (const file of files.filter((path) => path.endsWith(".md"))) {
27005
+ const content = await readFileSafe(file);
27006
+ if (content !== null) bodies.add(bodyKey(splitFrontmatter(content)?.body ?? content));
27007
+ }
27008
+ return bodies;
27009
+ }
27010
+ async function importWindsurfNestedAgents(projectRoot, normalize) {
27011
+ const destRulesDir = join(projectRoot, AB_RULES);
27012
+ const embedded = [];
27013
+ const ruleBodies = await windsurfRuleBodies(projectRoot);
27014
+ const results = await importFileDirectory({
27015
+ srcDir: projectRoot,
27016
+ destDir: destRulesDir,
27017
+ extensions: ["AGENTS.md"],
27018
+ fromTool: "windsurf",
27019
+ normalize,
27020
+ mapEntry: async ({ srcPath, content, normalizeTo }) => {
27021
+ const relDir = relative(projectRoot, dirname(srcPath)).replace(/\\/g, "/");
27022
+ if (!relDir || relDir === "." || basename(srcPath) !== "AGENTS.md") return null;
27023
+ const ruleName2 = relDir.replace(/\//g, "-");
27024
+ if (!shouldImportScopedAgentsRule(relDir)) {
27025
+ await removePathIfExists(join(destRulesDir, `${ruleName2}.md`));
27026
+ return null;
27027
+ }
27028
+ const ownText = await splitNestedAgentsFile(
27029
+ {
27030
+ content,
27031
+ projectRoot,
27032
+ rulesDir: AB_RULES,
27033
+ sourcePath: srcPath,
27034
+ fromTool: "windsurf",
27035
+ normalize
27036
+ },
27037
+ embedded
27038
+ );
27039
+ if (ownText === null || ruleBodies.has(bodyKey(ownText))) return null;
27040
+ const destPath = join(destRulesDir, `${ruleName2}.md`);
27041
+ return {
27042
+ destPath,
27043
+ toPath: `${AB_RULES}/${ruleName2}.md`,
27044
+ feature: "rules",
27045
+ content: await serializeImportedRuleWithFallback(
27046
+ destPath,
27047
+ { root: false, globs: [`${relDir}/**`] },
27048
+ normalizeTo(destPath, ownText)
27049
+ )
27050
+ };
27051
+ }
27052
+ });
27053
+ return [...results, ...embedded];
27054
+ }
27055
+ var bodyKey;
27056
+ var init_import_nested_agents = __esm({
27057
+ "src/targets/windsurf/import-nested-agents.ts"() {
27058
+ init_canonical_paths();
27059
+ init_embedded_rules();
27060
+ init_import_metadata();
27061
+ init_import_orchestrator();
27062
+ init_scoped_agents_import();
27063
+ init_fs();
27064
+ init_markdown();
27065
+ init_constants34();
27066
+ bodyKey = (text) => text.replace(/\r\n?/g, "\n").trim();
27067
+ }
27068
+ });
26857
27069
  function toStringArray3(value) {
26858
27070
  if (Array.isArray(value)) {
26859
27071
  return value.filter((entry) => typeof entry === "string").map((entry) => entry.trim()).filter(Boolean);
@@ -26998,7 +27210,7 @@ function preservedMatcher(existing, event, command) {
26998
27210
  function legacyEntries(entry) {
26999
27211
  const matcher = typeof entry.matcher === "string" && entry.matcher.trim() ? entry.matcher : WILDCARD_MATCHER;
27000
27212
  const hooksList = Array.isArray(entry.hooks) ? entry.hooks : [];
27001
- const out = [];
27213
+ const out2 = [];
27002
27214
  for (const item of hooksList) {
27003
27215
  if (!item || typeof item !== "object") continue;
27004
27216
  const hook = item;
@@ -27010,9 +27222,9 @@ function legacyEntries(entry) {
27010
27222
  command
27011
27223
  };
27012
27224
  if (typeof hook.timeout === "number") canonical.timeout = hook.timeout;
27013
- out.push(canonical);
27225
+ out2.push(canonical);
27014
27226
  }
27015
- return out;
27227
+ return out2;
27016
27228
  }
27017
27229
  function windsurfHooksToCanonical(hooks, existing) {
27018
27230
  const result2 = {};
@@ -27122,35 +27334,7 @@ async function importFromWindsurf(projectRoot, options) {
27122
27334
  }
27123
27335
  }
27124
27336
  if (layoutScope !== "global") {
27125
- results.push(
27126
- ...await importFileDirectory({
27127
- srcDir: projectRoot,
27128
- destDir: destRulesDir,
27129
- extensions: ["AGENTS.md"],
27130
- fromTool: "windsurf",
27131
- normalize,
27132
- mapEntry: async ({ srcPath, normalizeTo }) => {
27133
- const relDir = relative(projectRoot, dirname(srcPath)).replace(/\\/g, "/");
27134
- if (!relDir || relDir === "." || basename(srcPath) !== "AGENTS.md") return null;
27135
- const ruleName2 = relDir.replace(/\//g, "-");
27136
- if (!shouldImportScopedAgentsRule(relDir)) {
27137
- await removePathIfExists(join(destRulesDir, `${ruleName2}.md`));
27138
- return null;
27139
- }
27140
- const destPath = join(destRulesDir, `${ruleName2}.md`);
27141
- return {
27142
- destPath,
27143
- toPath: `${AB_RULES}/${ruleName2}.md`,
27144
- feature: "rules",
27145
- content: await serializeImportedRuleWithFallback(
27146
- destPath,
27147
- { root: false, globs: [`${relDir}/**`] },
27148
- normalizeTo(destPath)
27149
- )
27150
- };
27151
- }
27152
- })
27153
- );
27337
+ results.push(...await importWindsurfNestedAgents(projectRoot, normalize));
27154
27338
  }
27155
27339
  const rulesDir = join(projectRoot, WINDSURF_RULES_DIR);
27156
27340
  results.push(
@@ -27160,15 +27344,22 @@ async function importFromWindsurf(projectRoot, options) {
27160
27344
  extensions: [".md"],
27161
27345
  fromTool: "windsurf",
27162
27346
  normalize,
27163
- mapEntry: async ({ relativePath, normalizeTo }) => {
27347
+ mapEntry: async ({ relativePath, content, normalizeTo }) => {
27164
27348
  if (relativePath === "_root.md" && rootContent !== null) return null;
27165
27349
  const destPath = join(destRulesDir, relativePath);
27166
- const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
27167
- const normalizedFrontmatter = { ...frontmatter };
27168
- if (typeof normalizedFrontmatter.glob === "string" && normalizedFrontmatter.glob.trim()) {
27169
- normalizedFrontmatter.globs = [normalizedFrontmatter.glob];
27170
- delete normalizedFrontmatter.glob;
27350
+ const sourceLabel = `${WINDSURF_RULES_DIR}/${relativePath}`;
27351
+ const parsed = tryParseFrontmatter(
27352
+ normalizeTo(destPath, quoteWindsurfGlobValues(content)),
27353
+ sourceLabel
27354
+ );
27355
+ if (!parsed.ok) {
27356
+ logger.warn(`Skipping ${sourceLabel}: ${parsed.error.message}`);
27357
+ return null;
27171
27358
  }
27359
+ const { frontmatter, body } = parsed.value;
27360
+ const { glob, ...normalizedFrontmatter } = frontmatter;
27361
+ const globs = parseWindsurfGlobs(frontmatter.globs ?? glob);
27362
+ if (globs.length > 0) normalizedFrontmatter.globs = globs;
27172
27363
  return {
27173
27364
  destPath,
27174
27365
  toPath: `${AB_RULES}/${relativePath}`,
@@ -27219,9 +27410,11 @@ var init_importer32 = __esm({
27219
27410
  init_import_rewriter();
27220
27411
  init_fs();
27221
27412
  init_markdown();
27413
+ init_logger();
27414
+ init_rule_globs();
27222
27415
  init_import_metadata();
27223
27416
  init_import_orchestrator();
27224
- init_scoped_agents_import();
27417
+ init_import_nested_agents();
27225
27418
  init_constants34();
27226
27419
  init_importer_workflows();
27227
27420
  init_skills_adapter5();
@@ -27326,12 +27519,6 @@ var init_lint31 = __esm({
27326
27519
  });
27327
27520
 
27328
27521
  // src/targets/windsurf/index.ts
27329
- function directoryScopedRuleDir2(globs) {
27330
- if (globs.length === 0) return null;
27331
- const dirs = globs.map((glob) => glob.split("/")[0] ?? "").filter((segment) => /^[A-Za-z0-9._-]+$/.test(segment));
27332
- if (dirs.length !== globs.length) return null;
27333
- return dirs.every((dir) => dir === dirs[0]) ? dirs[0] : null;
27334
- }
27335
27522
  var target32, project24, globalLayout30, globalCapabilities25, descriptor32;
27336
27523
  var init_windsurf2 = __esm({
27337
27524
  "src/targets/windsurf/index.ts"() {
@@ -27363,9 +27550,7 @@ var init_windsurf2 = __esm({
27363
27550
  project24 = {
27364
27551
  rootInstructionPath: WINDSURF_AGENTS_MD,
27365
27552
  extraRuleOutputPaths(rule) {
27366
- if (rule.root) return [WINDSURF_AGENTS_MD];
27367
- const dir = directoryScopedRuleDir2(rule.globs);
27368
- return dir !== null ? [`${dir}/AGENTS.md`] : [];
27553
+ return rule.root ? [WINDSURF_AGENTS_MD] : [];
27369
27554
  },
27370
27555
  skillDir: WINDSURF_SKILLS_DIR,
27371
27556
  managedOutputs: {
@@ -28042,23 +28227,23 @@ function buildZedOwnedOverlay(canonical, scope, enabledFeatures) {
28042
28227
  if (enabledFeatures.has("permissions") && scope === "global") addPermissions(canonical, overlay);
28043
28228
  return overlay;
28044
28229
  }
28045
- function applyZedOwnedSettingsKey(out, key, desired) {
28230
+ function applyZedOwnedSettingsKey(out2, key, desired) {
28046
28231
  if (key === ZED_AGENT_KEY) {
28047
- const merged = mergeZedAgent(out[ZED_AGENT_KEY], desired ?? {});
28048
- if (merged === void 0) delete out[ZED_AGENT_KEY];
28049
- else out[ZED_AGENT_KEY] = merged;
28232
+ const merged = mergeZedAgent(out2[ZED_AGENT_KEY], desired ?? {});
28233
+ if (merged === void 0) delete out2[ZED_AGENT_KEY];
28234
+ else out2[ZED_AGENT_KEY] = merged;
28050
28235
  return;
28051
28236
  }
28052
28237
  if (key === ZED_FILE_SCAN_EXCLUSIONS_KEY || key === ZED_PRIVATE_FILES_KEY) {
28053
28238
  const merged = mergeZedIgnoreList(
28054
- out[key],
28239
+ out2[key],
28055
28240
  Array.isArray(desired) ? desired : []
28056
28241
  );
28057
- if (merged !== null) out[key] = merged;
28242
+ if (merged !== null) out2[key] = merged;
28058
28243
  return;
28059
28244
  }
28060
- if (desired !== void 0) out[key] = desired;
28061
- else delete out[key];
28245
+ if (desired !== void 0) out2[key] = desired;
28246
+ else delete out2[key];
28062
28247
  }
28063
28248
  function parseZedSettings(raw) {
28064
28249
  if (raw === null) return null;