agentsmesh 0.18.0 → 0.19.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/engine.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { z } from 'zod';
2
2
  import { stringify, parse } from 'yaml';
3
- import { join, basename, dirname, relative, win32, posix, resolve, extname } from 'path';
4
- import { readFile, rm, mkdir, readdir, stat, lstat, unlink, writeFile, rename, chmod, access, realpath } from 'fs/promises';
3
+ import { basename, join, dirname, relative, win32, posix, sep, resolve, extname } from 'path';
4
+ import { readFile, rm, mkdir, readdir, stat, lstat, unlink, writeFile, rename, chmod, access, realpath, mkdtemp, cp } from 'fs/promises';
5
5
  import { constants, existsSync, realpathSync, statSync, readFileSync } from 'fs';
6
6
  import { parse as parse$1 } from 'smol-toml';
7
7
  import { Buffer } from 'buffer';
8
- import { homedir } from 'os';
8
+ import { homedir, tmpdir } from 'os';
9
9
  import { createHash } from 'crypto';
10
10
  import { execFile } from 'child_process';
11
11
  import { fileURLToPath, pathToFileURL, URL } from 'url';
@@ -22,86 +22,6 @@ var __export = (target31, all) => {
22
22
  for (var name in all)
23
23
  __defProp(target31, name, { get: all[name], enumerable: true });
24
24
  };
25
-
26
- // src/config/core/conversions.ts
27
- function usesCommandSkillProjection(target31) {
28
- return Object.prototype.hasOwnProperty.call(DEFAULT_COMMANDS_TO_SKILLS, target31);
29
- }
30
- function usesAgentSkillProjection(target31) {
31
- return Object.prototype.hasOwnProperty.call(DEFAULT_AGENTS_TO_SKILLS, target31);
32
- }
33
- function resolveConversionValue(value, scope) {
34
- if (value === void 0) return void 0;
35
- if (typeof value === "boolean") return value;
36
- return value[scope];
37
- }
38
- function shouldConvertCommandsToSkills(config, target31, defaultEnabled, scope = "project") {
39
- const raw = config.conversions?.commands_to_skills?.[target31];
40
- const configVal = resolveConversionValue(raw, scope);
41
- if (configVal !== void 0) return configVal;
42
- if (usesCommandSkillProjection(target31)) return DEFAULT_COMMANDS_TO_SKILLS[target31];
43
- return defaultEnabled ?? false;
44
- }
45
- function shouldConvertAgentsToSkills(config, target31, defaultEnabled, scope = "project") {
46
- const raw = config.conversions?.agents_to_skills?.[target31];
47
- const configVal = resolveConversionValue(raw, scope);
48
- if (configVal !== void 0) return configVal;
49
- if (usesAgentSkillProjection(target31)) return DEFAULT_AGENTS_TO_SKILLS[target31];
50
- return defaultEnabled ?? false;
51
- }
52
- var DEFAULT_COMMANDS_TO_SKILLS, DEFAULT_AGENTS_TO_SKILLS;
53
- var init_conversions = __esm({
54
- "src/config/core/conversions.ts"() {
55
- DEFAULT_COMMANDS_TO_SKILLS = {
56
- amp: true,
57
- "codex-cli": true,
58
- goose: true,
59
- kiro: true,
60
- warp: true
61
- };
62
- DEFAULT_AGENTS_TO_SKILLS = {
63
- amp: true,
64
- "gemini-cli": false,
65
- // native .gemini/agents/*.md per agent-structures
66
- cline: true,
67
- "codex-cli": false,
68
- // native .codex/agents/*.toml per agent-structures
69
- windsurf: true,
70
- goose: true,
71
- antigravity: true,
72
- continue: true,
73
- warp: true
74
- };
75
- }
76
- });
77
-
78
- // src/targets/catalog/capabilities.ts
79
- function cap(level, flavor) {
80
- return flavor !== void 0 ? { level, flavor } : { level };
81
- }
82
- function normalizeCapabilityValue(input) {
83
- if (typeof input === "string") {
84
- return { level: input };
85
- }
86
- return input;
87
- }
88
- function normalizeTargetCapabilities(caps) {
89
- return {
90
- rules: normalizeCapabilityValue(caps.rules),
91
- additionalRules: normalizeCapabilityValue(caps.additionalRules),
92
- commands: normalizeCapabilityValue(caps.commands),
93
- agents: normalizeCapabilityValue(caps.agents),
94
- skills: normalizeCapabilityValue(caps.skills),
95
- mcp: normalizeCapabilityValue(caps.mcp),
96
- hooks: normalizeCapabilityValue(caps.hooks),
97
- ignore: normalizeCapabilityValue(caps.ignore),
98
- permissions: normalizeCapabilityValue(caps.permissions)
99
- };
100
- }
101
- var init_capabilities = __esm({
102
- "src/targets/catalog/capabilities.ts"() {
103
- }
104
- });
105
25
  function capabilityLevel(capability) {
106
26
  return typeof capability === "string" ? capability : capability.level;
107
27
  }
@@ -125,7 +45,7 @@ function validateCapabilityImplementations(descriptor31, capabilities17, ctx, pa
125
45
  function validateDescriptor(value) {
126
46
  return targetDescriptorSchema.parse(value);
127
47
  }
128
- var capabilityLevelSchema, capabilitiesSchema, generatorsSchema, pathResolversSchema, layoutSchema, globalSupportSchema, legacyGlobalKeys, generatorRequirements, settingsBackedFeatures, targetDescriptorSchemaBase, targetDescriptorSchema;
48
+ var capabilityLevelSchema, capabilitiesSchema, generatorsSchema, pathResolversSchema, layoutSchema, globalSupportSchema, legacyGlobalKeys, generatorRequirements, settingsBackedFeatures, conversionDefaultsSchema, metadataSchema, targetDescriptorSchemaBase, targetDescriptorSchema;
129
49
  var init_target_descriptor_schema = __esm({
130
50
  "src/targets/catalog/target-descriptor.schema.ts"() {
131
51
  capabilityLevelSchema = z.union([
@@ -189,8 +109,19 @@ var init_target_descriptor_schema = __esm({
189
109
  { feature: "permissions", generator: "generatePermissions" }
190
110
  ];
191
111
  settingsBackedFeatures = ["mcp", "hooks", "ignore", "permissions"];
112
+ conversionDefaultsSchema = z.object({
113
+ commandsToSkills: z.boolean().optional(),
114
+ agentsToSkills: z.boolean().optional()
115
+ }).strict();
116
+ metadataSchema = z.object({
117
+ displayName: z.string().min(1),
118
+ category: z.enum(["cli", "ide", "agent-platform"]),
119
+ officialUrl: z.string().min(1),
120
+ shortDescription: z.string().min(1)
121
+ }).passthrough();
192
122
  targetDescriptorSchemaBase = z.object({
193
123
  id: z.string().regex(/^[a-z][a-z0-9-]*$/, "Target id must be lowercase with hyphens"),
124
+ metadata: metadataSchema,
194
125
  generators: generatorsSchema,
195
126
  capabilities: capabilitiesSchema,
196
127
  emptyImportMessage: z.string(),
@@ -198,7 +129,13 @@ var init_target_descriptor_schema = __esm({
198
129
  project: layoutSchema,
199
130
  globalSupport: globalSupportSchema.optional(),
200
131
  buildImportPaths: z.function(),
201
- detectionPaths: z.array(z.string())
132
+ detectionPaths: z.array(z.string()),
133
+ excludeFromStarterInit: z.boolean().optional(),
134
+ conversionDefaults: conversionDefaultsSchema.optional(),
135
+ emitScopedSettings: z.function().optional(),
136
+ mergeGeneratedOutputContent: z.function().optional(),
137
+ postProcessHookOutputs: z.function().optional(),
138
+ preservesManualActivation: z.boolean().optional()
202
139
  }).passthrough();
203
140
  targetDescriptorSchema = targetDescriptorSchemaBase.superRefine((value, ctx) => {
204
141
  for (const key of legacyGlobalKeys) {
@@ -223,10 +160,15 @@ var init_target_descriptor_schema = __esm({
223
160
 
224
161
  // src/targets/catalog/registry.ts
225
162
  function builtinDescriptors() {
226
- if (!_builtinDescriptors) {
227
- _builtinDescriptors = new Map(BUILTIN_TARGETS.map((d) => [d.id, d]));
163
+ if (_builtinDescriptors) return _builtinDescriptors;
164
+ const defined = BUILTIN_TARGETS.filter(
165
+ (d) => d !== void 0 && typeof d.id === "string"
166
+ );
167
+ const map = new Map(defined.map((d) => [d.id, d]));
168
+ if (defined.length === BUILTIN_TARGETS.length) {
169
+ _builtinDescriptors = map;
228
170
  }
229
- return _builtinDescriptors;
171
+ return map;
230
172
  }
231
173
  function registerTargetDescriptor(descriptor31) {
232
174
  const validated = validateDescriptor(descriptor31);
@@ -238,6 +180,10 @@ function getDescriptor(name) {
238
180
  function getAllDescriptors() {
239
181
  return [...descriptorRegistry.values()];
240
182
  }
183
+ function getAllRegisteredDescriptorIds() {
184
+ const ids = /* @__PURE__ */ new Set([...builtinDescriptors().keys(), ...descriptorRegistry.keys()]);
185
+ return [...ids];
186
+ }
241
187
  var descriptorRegistry, _builtinDescriptors;
242
188
  var init_registry = __esm({
243
189
  "src/targets/catalog/registry.ts"() {
@@ -247,6 +193,65 @@ var init_registry = __esm({
247
193
  }
248
194
  });
249
195
 
196
+ // src/config/core/conversions.ts
197
+ function builtinDefault(target31, key) {
198
+ return getDescriptor(target31)?.conversionDefaults?.[key];
199
+ }
200
+ function resolveConversionValue(value, scope) {
201
+ if (value === void 0) return void 0;
202
+ if (typeof value === "boolean") return value;
203
+ return value[scope];
204
+ }
205
+ function shouldConvertCommandsToSkills(config, target31, defaultEnabled, scope = "project") {
206
+ const raw = config.conversions?.commands_to_skills?.[target31];
207
+ const configVal = resolveConversionValue(raw, scope);
208
+ if (configVal !== void 0) return configVal;
209
+ const builtin = builtinDefault(target31, "commandsToSkills");
210
+ if (builtin !== void 0) return builtin;
211
+ return defaultEnabled ?? false;
212
+ }
213
+ function shouldConvertAgentsToSkills(config, target31, defaultEnabled, scope = "project") {
214
+ const raw = config.conversions?.agents_to_skills?.[target31];
215
+ const configVal = resolveConversionValue(raw, scope);
216
+ if (configVal !== void 0) return configVal;
217
+ const builtin = builtinDefault(target31, "agentsToSkills");
218
+ if (builtin !== void 0) return builtin;
219
+ return defaultEnabled ?? false;
220
+ }
221
+ var init_conversions = __esm({
222
+ "src/config/core/conversions.ts"() {
223
+ init_registry();
224
+ }
225
+ });
226
+
227
+ // src/targets/catalog/capabilities.ts
228
+ function cap(level, flavor) {
229
+ return flavor !== void 0 ? { level, flavor } : { level };
230
+ }
231
+ function normalizeCapabilityValue(input) {
232
+ if (typeof input === "string") {
233
+ return { level: input };
234
+ }
235
+ return input;
236
+ }
237
+ function normalizeTargetCapabilities(caps) {
238
+ return {
239
+ rules: normalizeCapabilityValue(caps.rules),
240
+ additionalRules: normalizeCapabilityValue(caps.additionalRules),
241
+ commands: normalizeCapabilityValue(caps.commands),
242
+ agents: normalizeCapabilityValue(caps.agents),
243
+ skills: normalizeCapabilityValue(caps.skills),
244
+ mcp: normalizeCapabilityValue(caps.mcp),
245
+ hooks: normalizeCapabilityValue(caps.hooks),
246
+ ignore: normalizeCapabilityValue(caps.ignore),
247
+ permissions: normalizeCapabilityValue(caps.permissions)
248
+ };
249
+ }
250
+ var init_capabilities = __esm({
251
+ "src/targets/catalog/capabilities.ts"() {
252
+ }
253
+ });
254
+
250
255
  // src/targets/catalog/shared-artifact-owner.ts
251
256
  function ownerTargetIdForSharedPath(path) {
252
257
  for (const descriptor31 of BUILTIN_TARGETS) {
@@ -364,6 +369,32 @@ function parseFrontmatter(content) {
364
369
  const frontmatter = yamlStr === "" ? {} : parse(yamlStr) ?? {};
365
370
  return { frontmatter, body };
366
371
  }
372
+ function extractBody(content) {
373
+ if (content.indexOf("---") !== 0) return content.trim();
374
+ const close = content.indexOf("---", 3);
375
+ if (close === -1) return content.trim();
376
+ return content.slice(close + 3).trim();
377
+ }
378
+ function tryParseFrontmatter(content, filePath) {
379
+ try {
380
+ return { ok: true, value: parseFrontmatter(content) };
381
+ } catch (err) {
382
+ const message = err instanceof Error ? err.message : String(err);
383
+ const wrapped = new Error(`Failed to parse frontmatter in ${filePath}: ${message}`, {
384
+ cause: err
385
+ });
386
+ return { ok: false, error: wrapped, bodyFallback: extractBody(content) };
387
+ }
388
+ }
389
+ function parseOrSkipFrontmatter(content, filePath, onParseError) {
390
+ const result = tryParseFrontmatter(content, filePath);
391
+ if (result.ok) return result.value;
392
+ if (onParseError) {
393
+ onParseError(result.error, filePath);
394
+ return null;
395
+ }
396
+ throw result.error;
397
+ }
367
398
  function serializeFrontmatter(frontmatter, body) {
368
399
  const keys = Object.keys(frontmatter);
369
400
  if (keys.length === 0) return body;
@@ -682,7 +713,18 @@ var init_fs_text_encoding = __esm({
682
713
  EXECUTABLE_SCRIPT_EXTENSIONS = /* @__PURE__ */ new Set([".sh", ".bash", ".zsh"]);
683
714
  }
684
715
  });
685
- async function readDirRecursive(dir, visited) {
716
+ function shouldSkipRecursiveBranch(segments) {
717
+ if (segments.length > MAX_RECURSIVE_DEPTH) return true;
718
+ const counts = /* @__PURE__ */ new Map();
719
+ for (const segment of segments) {
720
+ const count = (counts.get(segment) ?? 0) + 1;
721
+ if (count >= MAX_SEGMENT_REPETITIONS) return true;
722
+ counts.set(segment, count);
723
+ }
724
+ return false;
725
+ }
726
+ async function readDirRecursive(dir, visited, branchSegments) {
727
+ const currentBranchSegments = branchSegments ?? [basename(dir)];
686
728
  let canonicalDir;
687
729
  try {
688
730
  canonicalDir = await realpath(dir);
@@ -708,7 +750,9 @@ async function readDirRecursive(dir, visited) {
708
750
  () => false
709
751
  );
710
752
  if (walkChild) {
711
- files.push(...await readDirRecursive(full, seen));
753
+ const nextSegments = [...currentBranchSegments, ent.name];
754
+ if (shouldSkipRecursiveBranch(nextSegments)) continue;
755
+ files.push(...await readDirRecursive(full, seen, nextSegments));
712
756
  } else {
713
757
  files.push(full);
714
758
  }
@@ -724,9 +768,12 @@ async function readDirRecursive(dir, visited) {
724
768
  );
725
769
  }
726
770
  }
771
+ var MAX_RECURSIVE_DEPTH, MAX_SEGMENT_REPETITIONS;
727
772
  var init_fs_traverse = __esm({
728
773
  "src/utils/filesystem/fs-traverse.ts"() {
729
774
  init_errors();
775
+ MAX_RECURSIVE_DEPTH = 32;
776
+ MAX_SEGMENT_REPETITIONS = 3;
730
777
  }
731
778
  });
732
779
  async function readFileSafe(path) {
@@ -1932,7 +1979,9 @@ function shouldRewritePathToken(fullContent, start, end, matchText, rewriteBareP
1932
1979
  }
1933
1980
  if (before === "@") return true;
1934
1981
  if (before === "(") {
1935
- return after === ")" || after === "#" || after === "?" || after === " " || after === " ";
1982
+ if (fullContent[start - 2] === "]") {
1983
+ return after === ")" || after === "#" || after === "?" || after === " " || after === " ";
1984
+ }
1936
1985
  }
1937
1986
  if (!rewriteBarePathTokens) return false;
1938
1987
  if (isRootRelativePathToken(normalizedCandidate)) return true;
@@ -2326,6 +2375,85 @@ var init_descriptor_default_mappers = __esm({
2326
2375
  }
2327
2376
  });
2328
2377
 
2378
+ // src/install/importers/boilerplate-filter.ts
2379
+ function boilerplateKind(filename) {
2380
+ const lower = filename.toLowerCase();
2381
+ const dotIdx = lower.lastIndexOf(".");
2382
+ const stem = dotIdx > 0 ? lower.slice(0, dotIdx) : lower;
2383
+ return BOILERPLATE_STEMS.get(stem);
2384
+ }
2385
+ function isBoilerplate(filename) {
2386
+ return boilerplateKind(filename) !== void 0;
2387
+ }
2388
+ function isPreservedBoilerplate(filename) {
2389
+ return boilerplateKind(filename) === "preserved";
2390
+ }
2391
+ function isNoiseBoilerplate(filename) {
2392
+ return boilerplateKind(filename) === "noise";
2393
+ }
2394
+ function isRepoNonContentDir(name) {
2395
+ return NON_CONTENT_DIRS.has(name);
2396
+ }
2397
+ function isRepoNonContentFile(name) {
2398
+ return NON_CONTENT_FILES.has(name);
2399
+ }
2400
+ var BOILERPLATE_STEMS, NON_CONTENT_DIRS, NON_CONTENT_FILES;
2401
+ var init_boilerplate_filter = __esm({
2402
+ "src/install/importers/boilerplate-filter.ts"() {
2403
+ BOILERPLATE_STEMS = /* @__PURE__ */ new Map([
2404
+ // Noise — upstream-repo housekeeping with no downstream value.
2405
+ ["contributing", "noise"],
2406
+ ["changelog", "noise"],
2407
+ ["changes", "noise"],
2408
+ ["history", "noise"],
2409
+ ["code_of_conduct", "noise"],
2410
+ ["security", "noise"],
2411
+ ["support", "noise"],
2412
+ ["maintainers", "noise"],
2413
+ ["governance", "noise"],
2414
+ ["authors", "noise"],
2415
+ ["contributors", "noise"],
2416
+ ["codeowners", "noise"],
2417
+ ["citation", "noise"],
2418
+ ["acknowledgments", "noise"],
2419
+ ["acknowledgements", "noise"],
2420
+ // Preserved — installed alongside content but never treated as an entity.
2421
+ // LICENSE family: legal attribution required by MIT/Apache/BSD/GPL.
2422
+ ["license", "preserved"],
2423
+ ["license-mit", "preserved"],
2424
+ ["license-apache", "preserved"],
2425
+ ["license-bsd", "preserved"],
2426
+ ["license-gpl", "preserved"],
2427
+ ["notice", "preserved"],
2428
+ ["copying", "preserved"],
2429
+ ["copyright", "preserved"],
2430
+ // README: skill-specific context (overview, usage, prerequisites) that
2431
+ // explains the skill to the downstream consumer. Filtered from entity
2432
+ // discovery so it can never become a phantom rule/command/agent named
2433
+ // "README", but kept as a supporting file so the docs travel with the install.
2434
+ ["readme", "preserved"]
2435
+ ]);
2436
+ NON_CONTENT_DIRS = /* @__PURE__ */ new Set([
2437
+ ".git",
2438
+ ".github",
2439
+ ".gitlab",
2440
+ "node_modules",
2441
+ ".vscode",
2442
+ ".idea"
2443
+ ]);
2444
+ NON_CONTENT_FILES = /* @__PURE__ */ new Set([
2445
+ "package.json",
2446
+ "package-lock.json",
2447
+ "pnpm-lock.yaml",
2448
+ "yarn.lock",
2449
+ ".gitignore",
2450
+ ".gitattributes",
2451
+ ".editorconfig",
2452
+ ".DS_Store"
2453
+ ]);
2454
+ }
2455
+ });
2456
+
2329
2457
  // src/targets/catalog/import-descriptor.ts
2330
2458
  function resolveScopedSources(paths, scope) {
2331
2459
  if (!paths) return [];
@@ -2359,18 +2487,32 @@ async function runSingleFile(spec, sources, projectRoot, fromTool, normalize) {
2359
2487
  const destPath = join(destDir, spec.canonicalRootFilename);
2360
2488
  const normalizeTo = (destinationFile) => normalize(content, srcPath, destinationFile);
2361
2489
  if (spec.map) {
2362
- const mapping = await spec.map({
2363
- absolutePath: srcPath,
2364
- relativePath: rel2,
2365
- content,
2366
- destDir,
2367
- normalizeTo
2368
- });
2490
+ let mapping;
2491
+ try {
2492
+ mapping = await spec.map({
2493
+ absolutePath: srcPath,
2494
+ relativePath: rel2,
2495
+ content,
2496
+ destDir,
2497
+ normalizeTo
2498
+ });
2499
+ } catch (err) {
2500
+ const msg = err instanceof Error ? err.message : String(err);
2501
+ process.stderr.write(`\u26A0 skipping ${srcPath}: ${msg}
2502
+ `);
2503
+ continue;
2504
+ }
2369
2505
  if (!mapping) continue;
2370
2506
  await writeFileAtomic(mapping.destPath, mapping.content);
2371
2507
  return [{ fromTool, fromPath: srcPath, toPath: mapping.toPath, feature: spec.feature }];
2372
2508
  }
2373
- const { frontmatter, body } = parseFrontmatter(normalizeTo(destPath));
2509
+ const result = tryParseFrontmatter(normalizeTo(destPath), srcPath);
2510
+ if (!result.ok) {
2511
+ process.stderr.write(`\u26A0 skipping ${srcPath}: ${result.error.message}
2512
+ `);
2513
+ continue;
2514
+ }
2515
+ const { frontmatter, body } = result.value;
2374
2516
  const remapped = spec.frontmatterRemap ? spec.frontmatterRemap(frontmatter) : frontmatter;
2375
2517
  const outFm = spec.markAsRoot ? { ...remapped, root: true } : remapped;
2376
2518
  const outContent = await serializeImportedRuleWithFallback(destPath, outFm, body);
@@ -2399,13 +2541,22 @@ async function runDirectory(spec, sources, projectRoot, fromTool, normalize) {
2399
2541
  fromTool,
2400
2542
  normalize,
2401
2543
  mapEntry: async ({ srcPath, relativePath, content, normalizeTo }) => {
2402
- const mapping = await mapper({
2403
- absolutePath: srcPath,
2404
- relativePath,
2405
- content,
2406
- destDir,
2407
- normalizeTo: (destinationFile) => normalizeTo(destinationFile)
2408
- });
2544
+ if (isPreservedBoilerplate(basename(srcPath))) return null;
2545
+ let mapping;
2546
+ try {
2547
+ mapping = await mapper({
2548
+ absolutePath: srcPath,
2549
+ relativePath,
2550
+ content,
2551
+ destDir,
2552
+ normalizeTo: (destinationFile) => normalizeTo(destinationFile)
2553
+ });
2554
+ } catch (err) {
2555
+ const msg = err instanceof Error ? err.message : String(err);
2556
+ process.stderr.write(`\u26A0 skipping ${srcPath}: ${msg}
2557
+ `);
2558
+ return null;
2559
+ }
2409
2560
  if (!mapping) return null;
2410
2561
  return {
2411
2562
  destPath: mapping.destPath,
@@ -2546,6 +2697,7 @@ var init_descriptor_import_runner = __esm({
2546
2697
  init_import_metadata();
2547
2698
  init_import_orchestrator();
2548
2699
  init_descriptor_default_mappers();
2700
+ init_boilerplate_filter();
2549
2701
  init_import_descriptor();
2550
2702
  }
2551
2703
  });
@@ -3423,7 +3575,7 @@ var init_crush = __esm({
3423
3575
  });
3424
3576
 
3425
3577
  // src/targets/cursor/constants.ts
3426
- var CURSOR_TARGET, CURSOR_COMPAT_AGENTS, CURSOR_LEGACY_RULES, CURSOR_RULES_DIR, CURSOR_GENERAL_RULE, CURSOR_COMMANDS_DIR, CURSOR_AGENTS_DIR, CURSOR_SKILLS_DIR, CURSOR_MCP, CURSOR_HOOKS, CURSOR_SETTINGS, CURSOR_IGNORE, CURSOR_INDEXING_IGNORE, CURSOR_GLOBAL_EXPORT_DIR, CURSOR_GLOBAL_USER_RULES, CURSOR_DOT_CURSOR_AGENTS, CURSOR_GLOBAL_MCP_EXPORT, CURSOR_GLOBAL_SKILLS_DIR, CURSOR_GLOBAL_AGENTS_DIR, CURSOR_CANONICAL_RULES_DIR, CURSOR_CANONICAL_COMMANDS_DIR, CURSOR_CANONICAL_AGENTS_DIR, CURSOR_CANONICAL_SKILLS_DIR, CURSOR_CANONICAL_MCP, CURSOR_CANONICAL_PERMISSIONS, CURSOR_CANONICAL_HOOKS, CURSOR_CANONICAL_IGNORE;
3578
+ var CURSOR_TARGET, CURSOR_COMPAT_AGENTS, CURSOR_LEGACY_RULES, CURSOR_RULES_DIR, CURSOR_GENERAL_RULE, CURSOR_COMMANDS_DIR, CURSOR_AGENTS_DIR, CURSOR_SKILLS_DIR, CURSOR_MCP, CURSOR_HOOKS, CURSOR_SETTINGS, CURSOR_IGNORE, CURSOR_INDEXING_IGNORE, CURSOR_GLOBAL_EXPORT_DIR, CURSOR_GLOBAL_USER_RULES, CURSOR_DOT_CURSOR_AGENTS, CURSOR_CANONICAL_RULES_DIR, CURSOR_CANONICAL_COMMANDS_DIR, CURSOR_CANONICAL_AGENTS_DIR, CURSOR_CANONICAL_SKILLS_DIR, CURSOR_CANONICAL_MCP, CURSOR_CANONICAL_PERMISSIONS, CURSOR_CANONICAL_HOOKS, CURSOR_CANONICAL_IGNORE;
3427
3579
  var init_constants11 = __esm({
3428
3580
  "src/targets/cursor/constants.ts"() {
3429
3581
  CURSOR_TARGET = "cursor";
@@ -3442,9 +3594,6 @@ var init_constants11 = __esm({
3442
3594
  CURSOR_GLOBAL_EXPORT_DIR = ".agentsmesh-exports/cursor";
3443
3595
  CURSOR_GLOBAL_USER_RULES = `${CURSOR_GLOBAL_EXPORT_DIR}/user-rules.md`;
3444
3596
  CURSOR_DOT_CURSOR_AGENTS = ".cursor/AGENTS.md";
3445
- CURSOR_GLOBAL_MCP_EXPORT = CURSOR_MCP;
3446
- CURSOR_GLOBAL_SKILLS_DIR = CURSOR_SKILLS_DIR;
3447
- CURSOR_GLOBAL_AGENTS_DIR = CURSOR_AGENTS_DIR;
3448
3597
  CURSOR_CANONICAL_RULES_DIR = ".agentsmesh/rules";
3449
3598
  CURSOR_CANONICAL_COMMANDS_DIR = ".agentsmesh/commands";
3450
3599
  CURSOR_CANONICAL_AGENTS_DIR = ".agentsmesh/agents";
@@ -4575,7 +4724,7 @@ var init_linter2 = __esm({
4575
4724
  });
4576
4725
 
4577
4726
  // src/targets/amazon-q/index.ts
4578
- var target2, project2, global, globalCapabilities, descriptor2;
4727
+ var target2, project2, globalLayout2, globalCapabilities, descriptor2;
4579
4728
  var init_amazon_q2 = __esm({
4580
4729
  "src/targets/amazon-q/index.ts"() {
4581
4730
  init_generator2();
@@ -4606,7 +4755,7 @@ var init_amazon_q2 = __esm({
4606
4755
  }
4607
4756
  }
4608
4757
  };
4609
- global = {
4758
+ globalLayout2 = {
4610
4759
  managedOutputs: {
4611
4760
  dirs: [AMAZON_Q_GLOBAL_RULES_DIR],
4612
4761
  files: [AMAZON_Q_GLOBAL_MCP_FILE]
@@ -4669,7 +4818,7 @@ var init_amazon_q2 = __esm({
4669
4818
  globalSupport: {
4670
4819
  capabilities: globalCapabilities,
4671
4820
  detectionPaths: [AMAZON_Q_GLOBAL_RULES_DIR, AMAZON_Q_GLOBAL_MCP_FILE],
4672
- layout: global
4821
+ layout: globalLayout2
4673
4822
  },
4674
4823
  importer: {
4675
4824
  rules: {
@@ -4739,13 +4888,22 @@ var init_generator3 = __esm({
4739
4888
 
4740
4889
  // src/targets/catalog/skill-mirror.ts
4741
4890
  function mirrorSkillsToAgents(path, skillsDir, activeTargets) {
4742
- if (path.startsWith(`${skillsDir}/`) && !activeTargets.includes("codex-cli")) {
4891
+ const hasNativeWriter = activeTargets.some((id) => NATIVE_AGENTS_SKILL_WRITERS.includes(id));
4892
+ if (path.startsWith(`${skillsDir}/`) && !hasNativeWriter) {
4743
4893
  return `.agents/skills/${path.slice(skillsDir.length + 1)}`;
4744
4894
  }
4745
4895
  return null;
4746
4896
  }
4897
+ var NATIVE_AGENTS_SKILL_WRITERS;
4747
4898
  var init_skill_mirror = __esm({
4748
4899
  "src/targets/catalog/skill-mirror.ts"() {
4900
+ NATIVE_AGENTS_SKILL_WRITERS = [
4901
+ "amp",
4902
+ "antigravity",
4903
+ "codex-cli",
4904
+ "goose",
4905
+ "replit-agent"
4906
+ ];
4749
4907
  }
4750
4908
  });
4751
4909
  async function importAmpMcp(projectRoot, settingsPath, results) {
@@ -4887,7 +5045,7 @@ function mergeAmpSettings(existing, newContent) {
4887
5045
  }
4888
5046
  return JSON.stringify(base, null, 2);
4889
5047
  }
4890
- var target3, project3, globalLayout2, capabilities2, descriptor3;
5048
+ var target3, project3, globalLayout3, capabilities2, descriptor3;
4891
5049
  var init_amp2 = __esm({
4892
5050
  "src/targets/amp/index.ts"() {
4893
5051
  init_command_skill();
@@ -4927,7 +5085,7 @@ var init_amp2 = __esm({
4927
5085
  }
4928
5086
  }
4929
5087
  };
4930
- globalLayout2 = {
5088
+ globalLayout3 = {
4931
5089
  rootInstructionPath: AMP_GLOBAL_ROOT_FILE,
4932
5090
  skillDir: AMP_GLOBAL_SKILLS_DIR,
4933
5091
  managedOutputs: {
@@ -4990,7 +5148,7 @@ var init_amp2 = __esm({
4990
5148
  globalSupport: {
4991
5149
  capabilities: capabilities2,
4992
5150
  detectionPaths: [AMP_GLOBAL_ROOT_FILE, AMP_GLOBAL_MCP_FILE],
4993
- layout: globalLayout2
5151
+ layout: globalLayout3
4994
5152
  },
4995
5153
  importer: {
4996
5154
  rules: {
@@ -5024,7 +5182,8 @@ var init_amp2 = __esm({
5024
5182
  ".agents/skills/": "consumer"
5025
5183
  },
5026
5184
  buildImportPaths: buildAmpImportPaths,
5027
- detectionPaths: [AMP_ROOT_FILE, AMP_MCP_FILE]
5185
+ detectionPaths: [AMP_ROOT_FILE, AMP_MCP_FILE],
5186
+ conversionDefaults: { commandsToSkills: true, agentsToSkills: true }
5028
5187
  };
5029
5188
  }
5030
5189
  });
@@ -5264,7 +5423,7 @@ var init_linter4 = __esm({
5264
5423
  });
5265
5424
 
5266
5425
  // src/targets/antigravity/index.ts
5267
- var target4, project4, global2, globalCapabilities2, descriptor4;
5426
+ var target4, project4, globalLayout4, globalCapabilities2, descriptor4;
5268
5427
  var init_antigravity2 = __esm({
5269
5428
  "src/targets/antigravity/index.ts"() {
5270
5429
  init_capabilities();
@@ -5288,6 +5447,20 @@ var init_antigravity2 = __esm({
5288
5447
  project4 = {
5289
5448
  rootInstructionPath: ANTIGRAVITY_RULES_ROOT,
5290
5449
  skillDir: ".agents/skills",
5450
+ // managedOutputs is the sole signal `cleanupStaleGeneratedOutputs` uses to
5451
+ // decide which dirs/files to scan when reconciling post-uninstall state.
5452
+ // Antigravity emits across three dirs:
5453
+ // - `.agents/rules` (rules)
5454
+ // - `.agents/workflows` (commands → workflows projection)
5455
+ // - `.agents/skills` (agents → skills projection + native skills)
5456
+ // Without all three here, projected outputs from an uninstalled pack would
5457
+ // linger in the user's project. The root rule file and (suppressed) MCP
5458
+ // config are listed under `files` so a flip from one root style to another
5459
+ // doesn't leave both behind.
5460
+ managedOutputs: {
5461
+ dirs: [ANTIGRAVITY_RULES_DIR, ANTIGRAVITY_WORKFLOWS_DIR, ANTIGRAVITY_SKILLS_DIR],
5462
+ files: [ANTIGRAVITY_RULES_ROOT]
5463
+ },
5291
5464
  rewriteGeneratedPath(path) {
5292
5465
  if (path === ANTIGRAVITY_MCP_CONFIG) return null;
5293
5466
  return path;
@@ -5304,7 +5477,7 @@ var init_antigravity2 = __esm({
5304
5477
  }
5305
5478
  }
5306
5479
  };
5307
- global2 = {
5480
+ globalLayout4 = {
5308
5481
  rootInstructionPath: ANTIGRAVITY_GLOBAL_ROOT,
5309
5482
  renderPrimaryRootInstruction: renderAntigravityGlobalInstructions,
5310
5483
  skillDir: ANTIGRAVITY_GLOBAL_SKILLS_DIR,
@@ -5332,7 +5505,7 @@ var init_antigravity2 = __esm({
5332
5505
  return `${ANTIGRAVITY_GLOBAL_WORKFLOWS_DIR}/${name}.md`;
5333
5506
  },
5334
5507
  agentPath(name) {
5335
- return `${ANTIGRAVITY_SKILLS_DIR}/${projectedAgentSkillDirName(name)}/SKILL.md`;
5508
+ return `${ANTIGRAVITY_GLOBAL_SKILLS_DIR}/${projectedAgentSkillDirName(name)}/SKILL.md`;
5336
5509
  }
5337
5510
  }
5338
5511
  };
@@ -5379,7 +5552,7 @@ var init_antigravity2 = __esm({
5379
5552
  ".gemini/antigravity/workflows",
5380
5553
  ".gemini/antigravity/mcp_config.json"
5381
5554
  ],
5382
- layout: global2
5555
+ layout: globalLayout4
5383
5556
  },
5384
5557
  importer: {
5385
5558
  rules: {
@@ -5420,7 +5593,8 @@ var init_antigravity2 = __esm({
5420
5593
  ".agents/rules/",
5421
5594
  ".agents/skills/",
5422
5595
  ".agents/workflows/"
5423
- ]
5596
+ ],
5597
+ conversionDefaults: { agentsToSkills: true }
5424
5598
  };
5425
5599
  }
5426
5600
  });
@@ -5752,7 +5926,7 @@ function buildSettingsContent(canonical) {
5752
5926
  if (Object.keys(settings).length === 0) return null;
5753
5927
  return JSON.stringify(settings, null, 2);
5754
5928
  }
5755
- var target5, project5, globalLayout3, capabilities3, globalCapabilities3, descriptor5;
5929
+ var target5, project5, globalLayout5, capabilities3, globalCapabilities3, descriptor5;
5756
5930
  var init_augment_code2 = __esm({
5757
5931
  "src/targets/augment-code/index.ts"() {
5758
5932
  init_generator5();
@@ -5787,7 +5961,7 @@ var init_augment_code2 = __esm({
5787
5961
  }
5788
5962
  }
5789
5963
  };
5790
- globalLayout3 = {
5964
+ globalLayout5 = {
5791
5965
  skillDir: AUGMENT_CODE_GLOBAL_SKILLS_DIR,
5792
5966
  managedOutputs: {
5793
5967
  dirs: [
@@ -5873,7 +6047,7 @@ var init_augment_code2 = __esm({
5873
6047
  AUGMENT_CODE_GLOBAL_SKILLS_DIR,
5874
6048
  AUGMENT_CODE_GLOBAL_SETTINGS_FILE
5875
6049
  ],
5876
- layout: globalLayout3
6050
+ layout: globalLayout5
5877
6051
  },
5878
6052
  emitScopedSettings(canonical) {
5879
6053
  const content = buildSettingsContent(canonical);
@@ -6273,6 +6447,19 @@ async function importClaudeSkills(projectRoot, results, normalize) {
6273
6447
  const skillDir = dirname(skillMdPath);
6274
6448
  const skillName = basename(skillDir);
6275
6449
  const destSkillDir = join(destBase, skillName);
6450
+ const skillMdContent = await readFileSafe(skillMdPath);
6451
+ if (skillMdContent === null) continue;
6452
+ const normalizedSkillMd = normalize(
6453
+ skillMdContent,
6454
+ skillMdPath,
6455
+ join(destSkillDir, "SKILL.md")
6456
+ );
6457
+ const skillMdParsed = tryParseFrontmatter(normalizedSkillMd, skillMdPath);
6458
+ if (!skillMdParsed.ok) {
6459
+ process.stderr.write(`\u26A0 skipping ${skillMdPath}: ${skillMdParsed.error.message}
6460
+ `);
6461
+ continue;
6462
+ }
6276
6463
  const skillFiles = await readDirRecursive(skillDir);
6277
6464
  for (const filePath of skillFiles) {
6278
6465
  const fileContent = await readFileSafe(filePath);
@@ -6281,13 +6468,12 @@ async function importClaudeSkills(projectRoot, results, normalize) {
6281
6468
  const destPath = join(destSkillDir, relPath);
6282
6469
  await mkdirp(dirname(destPath));
6283
6470
  const normalized = normalize(fileContent, filePath, destPath);
6284
- const parsed = relPath === "SKILL.md" ? parseFrontmatter(normalized) : null;
6285
6471
  await writeFileAtomic(
6286
6472
  destPath,
6287
6473
  relPath === "SKILL.md" ? await serializeImportedSkillWithFallback(
6288
6474
  destPath,
6289
- parsed?.frontmatter ?? {},
6290
- parsed?.body ?? ""
6475
+ skillMdParsed.value.frontmatter,
6476
+ skillMdParsed.value.body
6291
6477
  ) : normalized
6292
6478
  );
6293
6479
  const toPath = `${CLAUDE_CANONICAL_SKILLS_DIR}/${skillName}/${relPath}`;
@@ -6408,7 +6594,7 @@ var init_linter6 = __esm({
6408
6594
  });
6409
6595
 
6410
6596
  // src/targets/claude-code/index.ts
6411
- var target6, project6, global3, globalCapabilities4, descriptor6;
6597
+ var target6, project6, globalLayout6, globalCapabilities4, descriptor6;
6412
6598
  var init_claude_code2 = __esm({
6413
6599
  "src/targets/claude-code/index.ts"() {
6414
6600
  init_generator6();
@@ -6452,7 +6638,7 @@ var init_claude_code2 = __esm({
6452
6638
  }
6453
6639
  }
6454
6640
  };
6455
- global3 = {
6641
+ globalLayout6 = {
6456
6642
  rootInstructionPath: CLAUDE_ROOT,
6457
6643
  skillDir: ".claude/skills",
6458
6644
  renderPrimaryRootInstruction: renderClaudeGlobalPrimaryInstructions,
@@ -6531,7 +6717,7 @@ var init_claude_code2 = __esm({
6531
6717
  ".claude.json",
6532
6718
  ".agents/skills"
6533
6719
  ],
6534
- layout: global3,
6720
+ layout: globalLayout6,
6535
6721
  scopeExtras: generateClaudeGlobalExtras
6536
6722
  },
6537
6723
  importer: {
@@ -7065,55 +7251,117 @@ async function findDirectorySkills(skillsDir) {
7065
7251
  }
7066
7252
  return skills;
7067
7253
  }
7254
+ async function importSkillsDirectory(sourceSkillsDirs, options, recognizers = []) {
7255
+ for (const sourceDir of sourceSkillsDirs) {
7256
+ const absSkillsDir = join(options.projectRoot, sourceDir);
7257
+ const directorySkills = await findDirectorySkills(absSkillsDir);
7258
+ if (directorySkills.size === 0) continue;
7259
+ let importedAny = false;
7260
+ for (const [skillName, skillDir] of directorySkills) {
7261
+ const skillMdPath = join(skillDir, "SKILL.md");
7262
+ const rawContent = await readFileSafe(skillMdPath);
7263
+ if (rawContent === null) continue;
7264
+ importedAny = true;
7265
+ const { frontmatter, body: rawBody } = parseFrontmatter(rawContent);
7266
+ const ctx = {
7267
+ skillName,
7268
+ skillDir,
7269
+ skillMdPath,
7270
+ rawContent,
7271
+ frontmatter,
7272
+ rawBody,
7273
+ options
7274
+ };
7275
+ let handled = false;
7276
+ for (const recognizer of recognizers) {
7277
+ const claimed = await recognizer.recognize(ctx);
7278
+ if (claimed) {
7279
+ handled = true;
7280
+ break;
7281
+ }
7282
+ }
7283
+ if (!handled) {
7284
+ await importDirectorySkill(skillName, skillDir, options);
7285
+ }
7286
+ }
7287
+ if (importedAny) return;
7288
+ }
7289
+ }
7290
+ function projectedAgentRecognizer(config) {
7291
+ return {
7292
+ async recognize(ctx) {
7293
+ const projectedAgent = parseProjectedAgentSkillFrontmatter(ctx.frontmatter, ctx.skillName);
7294
+ if (!projectedAgent) return false;
7295
+ const { options } = ctx;
7296
+ await removePathIfExists(
7297
+ join(options.projectRoot, options.destCanonicalSkillsDir, ctx.skillName)
7298
+ );
7299
+ const destAgentsDir = join(options.projectRoot, config.canonicalAgentsDir);
7300
+ await mkdirp(destAgentsDir);
7301
+ const agentPath = join(destAgentsDir, `${projectedAgent.name}.md`);
7302
+ const normalizedBody = options.normalize(ctx.rawBody, ctx.skillMdPath, agentPath);
7303
+ await writeFileAtomic(agentPath, serializeImportedAgent(projectedAgent, normalizedBody));
7304
+ options.results.push({
7305
+ fromTool: options.targetName,
7306
+ fromPath: ctx.skillMdPath,
7307
+ toPath: `${config.canonicalAgentsDir}/${projectedAgent.name}.md`,
7308
+ feature: "agents"
7309
+ });
7310
+ return true;
7311
+ }
7312
+ };
7313
+ }
7314
+ function commandSkillRecognizer(config) {
7315
+ return {
7316
+ async recognize(ctx) {
7317
+ const command = parseCommandSkillFrontmatter(ctx.frontmatter, ctx.skillName);
7318
+ if (!command) return false;
7319
+ const { options } = ctx;
7320
+ await removePathIfExists(
7321
+ join(options.projectRoot, options.destCanonicalSkillsDir, ctx.skillName)
7322
+ );
7323
+ const destCommandsDir = join(options.projectRoot, config.canonicalCommandsDir);
7324
+ await mkdirp(destCommandsDir);
7325
+ const commandPath = join(destCommandsDir, `${command.name}.md`);
7326
+ const normalizedBody = options.normalize(ctx.rawBody, ctx.skillMdPath, commandPath);
7327
+ await writeFileAtomic(commandPath, serializeImportedCommand(command, normalizedBody));
7328
+ options.results.push({
7329
+ fromTool: options.targetName,
7330
+ fromPath: ctx.skillMdPath,
7331
+ toPath: `${config.canonicalCommandsDir}/${command.name}.md`,
7332
+ feature: "commands"
7333
+ });
7334
+ return true;
7335
+ }
7336
+ };
7337
+ }
7068
7338
  var init_skill_import_pipeline = __esm({
7069
7339
  "src/targets/import/shared/skill-import-pipeline.ts"() {
7070
7340
  init_fs();
7071
7341
  init_markdown();
7072
7342
  init_import_metadata();
7073
7343
  init_reserved();
7344
+ init_projected_agent_skill();
7345
+ init_command_skill();
7346
+ init_scoped_agents_import();
7074
7347
  }
7075
7348
  });
7349
+
7350
+ // src/targets/cline/skills-adapter.ts
7076
7351
  async function importClineSkills(projectRoot, results, normalize, skillsRelDir = CLINE_SKILLS_DIR) {
7077
- const skillsDir = join(projectRoot, skillsRelDir);
7078
- const directorySkills = await findDirectorySkills(skillsDir);
7079
7352
  const options = {
7080
7353
  projectRoot,
7081
- sourceSkillsDir: skillsRelDir,
7082
7354
  destCanonicalSkillsDir: CLINE_CANONICAL_SKILLS_DIR,
7083
7355
  targetName: "cline",
7084
7356
  normalize,
7085
7357
  results
7086
7358
  };
7087
- for (const [skillName, skillDir] of directorySkills) {
7088
- const skillMdPath = join(skillDir, "SKILL.md");
7089
- const content = await readFileSafe(skillMdPath);
7090
- if (!content) continue;
7091
- const rawParsed = parseFrontmatter(content);
7092
- const projectedAgent = parseProjectedAgentSkillFrontmatter(rawParsed.frontmatter, skillName);
7093
- if (projectedAgent) {
7094
- const destAgentsDir = join(projectRoot, CLINE_CANONICAL_AGENTS_DIR);
7095
- await mkdirp(destAgentsDir);
7096
- const agentPath = join(destAgentsDir, `${projectedAgent.name}.md`);
7097
- await writeFileAtomic(
7098
- agentPath,
7099
- serializeImportedAgent(projectedAgent, normalize(rawParsed.body, skillMdPath, agentPath))
7100
- );
7101
- results.push({
7102
- fromTool: "cline",
7103
- fromPath: skillMdPath,
7104
- toPath: `${CLINE_CANONICAL_AGENTS_DIR}/${projectedAgent.name}.md`,
7105
- feature: "agents"
7106
- });
7107
- continue;
7108
- }
7109
- await importDirectorySkill(skillName, skillDir, options);
7110
- }
7359
+ await importSkillsDirectory([skillsRelDir], options, [
7360
+ projectedAgentRecognizer({ canonicalAgentsDir: CLINE_CANONICAL_AGENTS_DIR })
7361
+ ]);
7111
7362
  }
7112
7363
  var init_skills_adapter = __esm({
7113
7364
  "src/targets/cline/skills-adapter.ts"() {
7114
- init_fs();
7115
- init_markdown();
7116
- init_projected_agent_skill();
7117
7365
  init_skill_import_pipeline();
7118
7366
  init_constants8();
7119
7367
  }
@@ -7259,7 +7507,7 @@ var init_lint4 = __esm({
7259
7507
  });
7260
7508
 
7261
7509
  // src/targets/cline/index.ts
7262
- var target7, project7, globalLayout4, globalCapabilities5, descriptor7;
7510
+ var target7, project7, globalLayout7, globalCapabilities5, descriptor7;
7263
7511
  var init_cline2 = __esm({
7264
7512
  "src/targets/cline/index.ts"() {
7265
7513
  init_generator7();
@@ -7307,7 +7555,7 @@ var init_cline2 = __esm({
7307
7555
  }
7308
7556
  }
7309
7557
  };
7310
- globalLayout4 = {
7558
+ globalLayout7 = {
7311
7559
  skillDir: CLINE_SKILLS_DIR,
7312
7560
  managedOutputs: {
7313
7561
  dirs: [
@@ -7399,10 +7647,11 @@ var init_cline2 = __esm({
7399
7647
  CLINE_MCP_SETTINGS,
7400
7648
  CLINE_IGNORE
7401
7649
  ],
7402
- layout: globalLayout4
7650
+ layout: globalLayout7
7403
7651
  },
7404
7652
  buildImportPaths: buildClineImportPaths,
7405
- detectionPaths: [".clinerules", ".cline"]
7653
+ detectionPaths: [".clinerules", ".cline"],
7654
+ conversionDefaults: { agentsToSkills: true }
7406
7655
  };
7407
7656
  }
7408
7657
  });
@@ -7776,82 +8025,23 @@ var init_mcp_helpers = __esm({
7776
8025
  init_constants28();
7777
8026
  }
7778
8027
  });
8028
+
8029
+ // src/targets/codex-cli/skills-adapter.ts
7779
8030
  async function importSkills(projectRoot, results, normalize) {
7780
8031
  const options = {
7781
8032
  projectRoot,
7782
- sourceSkillsDir: CODEX_SKILLS_DIR,
7783
8033
  destCanonicalSkillsDir: CODEX_CANONICAL_SKILLS_DIR,
7784
8034
  targetName: CODEX_TARGET,
7785
8035
  normalize,
7786
8036
  results
7787
8037
  };
7788
- for (const skillsRoot of [CODEX_SKILLS_DIR, CODEX_SKILLS_FALLBACK_DIR]) {
7789
- const skillsDir = join(projectRoot, skillsRoot);
7790
- const entries = await readdir(skillsDir, {
7791
- encoding: "utf8",
7792
- withFileTypes: true
7793
- }).catch(() => null);
7794
- if (entries === null) continue;
7795
- let importedAny = false;
7796
- for (const ent of entries) {
7797
- if (!ent.isDirectory() && !ent.isSymbolicLink()) continue;
7798
- const skillPath = join(skillsDir, ent.name);
7799
- const skillMdPath = join(skillPath, "SKILL.md");
7800
- const skillMdContent = await readFileSafe(skillMdPath);
7801
- if (!skillMdContent) continue;
7802
- importedAny = true;
7803
- const skillName = ent.name;
7804
- const destSkillPath = join(projectRoot, CODEX_CANONICAL_SKILLS_DIR, skillName, "SKILL.md");
7805
- const normalized = normalize(skillMdContent, skillMdPath, destSkillPath);
7806
- const { frontmatter, body } = parseFrontmatter(normalized);
7807
- const command = parseCommandSkillFrontmatter(frontmatter, ent.name);
7808
- if (command) {
7809
- await removePathIfExists(join(projectRoot, CODEX_CANONICAL_SKILLS_DIR, skillName));
7810
- const destCommandsDir = join(projectRoot, CODEX_CANONICAL_COMMANDS_DIR);
7811
- await mkdirp(destCommandsDir);
7812
- const commandPath = join(destCommandsDir, `${command.name}.md`);
7813
- await writeFileAtomic(
7814
- commandPath,
7815
- serializeImportedCommand(command, normalize(body, skillMdPath, commandPath))
7816
- );
7817
- results.push({
7818
- fromTool: CODEX_TARGET,
7819
- fromPath: skillMdPath,
7820
- toPath: `${CODEX_CANONICAL_COMMANDS_DIR}/${command.name}.md`,
7821
- feature: "commands"
7822
- });
7823
- continue;
7824
- }
7825
- const projectedAgent = parseProjectedAgentSkillFrontmatter(frontmatter, ent.name);
7826
- if (projectedAgent) {
7827
- await removePathIfExists(join(projectRoot, CODEX_CANONICAL_SKILLS_DIR, skillName));
7828
- const destAgentsDir = join(projectRoot, CODEX_CANONICAL_AGENTS_DIR);
7829
- await mkdirp(destAgentsDir);
7830
- const agentPath = join(destAgentsDir, `${projectedAgent.name}.md`);
7831
- await writeFileAtomic(
7832
- agentPath,
7833
- serializeImportedAgent(projectedAgent, normalize(body, skillMdPath, agentPath))
7834
- );
7835
- results.push({
7836
- fromTool: CODEX_TARGET,
7837
- fromPath: skillMdPath,
7838
- toPath: `${CODEX_CANONICAL_AGENTS_DIR}/${projectedAgent.name}.md`,
7839
- feature: "agents"
7840
- });
7841
- continue;
7842
- }
7843
- await importDirectorySkill(skillName, skillPath, options);
7844
- }
7845
- if (importedAny) return;
7846
- }
8038
+ await importSkillsDirectory([CODEX_SKILLS_DIR, CODEX_SKILLS_FALLBACK_DIR], options, [
8039
+ commandSkillRecognizer({ canonicalCommandsDir: CODEX_CANONICAL_COMMANDS_DIR }),
8040
+ projectedAgentRecognizer({ canonicalAgentsDir: CODEX_CANONICAL_AGENTS_DIR })
8041
+ ]);
7847
8042
  }
7848
8043
  var init_skills_adapter2 = __esm({
7849
8044
  "src/targets/codex-cli/skills-adapter.ts"() {
7850
- init_fs();
7851
- init_markdown();
7852
- init_command_skill();
7853
- init_projected_agent_skill();
7854
- init_scoped_agents_import();
7855
8045
  init_skill_import_pipeline();
7856
8046
  init_constants28();
7857
8047
  }
@@ -8241,7 +8431,7 @@ var init_codex_rule_paths = __esm({
8241
8431
  init_instruction_mirror();
8242
8432
  }
8243
8433
  });
8244
- var target8, project8, global4, globalCapabilities6, descriptor8;
8434
+ var target8, project8, globalLayout8, globalCapabilities6, descriptor8;
8245
8435
  var init_codex_cli2 = __esm({
8246
8436
  "src/targets/codex-cli/index.ts"() {
8247
8437
  init_generator9();
@@ -8287,7 +8477,7 @@ var init_codex_cli2 = __esm({
8287
8477
  }
8288
8478
  }
8289
8479
  };
8290
- global4 = {
8480
+ globalLayout8 = {
8291
8481
  rootInstructionPath: CODEX_GLOBAL_AGENTS_MD,
8292
8482
  renderPrimaryRootInstruction: renderCodexGlobalInstructions,
8293
8483
  extraRuleOutputPaths(rule) {
@@ -8365,7 +8555,7 @@ var init_codex_cli2 = __esm({
8365
8555
  ".codex/rules",
8366
8556
  ".agents/skills"
8367
8557
  ],
8368
- layout: global4
8558
+ layout: globalLayout8
8369
8559
  },
8370
8560
  buildImportPaths: buildCodexCliImportPaths,
8371
8561
  sharedArtifacts: {
@@ -8378,7 +8568,9 @@ var init_codex_cli2 = __esm({
8378
8568
  ".codex/config.toml",
8379
8569
  ".codex/agents",
8380
8570
  ".codex/rules"
8381
- ]
8571
+ ],
8572
+ excludeFromStarterInit: true,
8573
+ conversionDefaults: { commandsToSkills: true, agentsToSkills: false }
8382
8574
  };
8383
8575
  }
8384
8576
  });
@@ -8741,7 +8933,7 @@ var init_scope_extras = __esm({
8741
8933
  });
8742
8934
 
8743
8935
  // src/targets/continue/index.ts
8744
- var target9, project9, globalLayout5, globalCapabilities7, descriptor9;
8936
+ var target9, project9, globalLayout9, globalCapabilities7, descriptor9;
8745
8937
  var init_continue2 = __esm({
8746
8938
  "src/targets/continue/index.ts"() {
8747
8939
  init_projected_agent_skill();
@@ -8783,7 +8975,7 @@ var init_continue2 = __esm({
8783
8975
  }
8784
8976
  }
8785
8977
  };
8786
- globalLayout5 = {
8978
+ globalLayout9 = {
8787
8979
  rootInstructionPath: CONTINUE_ROOT_RULE,
8788
8980
  outputFamilies: [
8789
8981
  { id: "compat-agents", kind: "additional", explicitPaths: [CONTINUE_GLOBAL_AGENTS_MD] }
@@ -8857,7 +9049,7 @@ var init_continue2 = __esm({
8857
9049
  ".continue/mcpServers",
8858
9050
  CONTINUE_SKILLS_DIR
8859
9051
  ],
8860
- layout: globalLayout5,
9052
+ layout: globalLayout9,
8861
9053
  scopeExtras: generateContinueScopeExtras
8862
9054
  },
8863
9055
  importer: {
@@ -8879,7 +9071,8 @@ var init_continue2 = __esm({
8879
9071
  }
8880
9072
  },
8881
9073
  buildImportPaths: buildContinueImportPaths,
8882
- detectionPaths: [".continue/rules", ".continue/skills", ".continue/mcpServers"]
9074
+ detectionPaths: [".continue/rules", ".continue/skills", ".continue/mcpServers"],
9075
+ conversionDefaults: { agentsToSkills: true }
8883
9076
  };
8884
9077
  }
8885
9078
  });
@@ -9205,7 +9398,6 @@ async function importSkills2(projectRoot, results, normalize, skillsDirRel = COP
9205
9398
  const directorySkills = await findDirectorySkills(skillsDir);
9206
9399
  const options = {
9207
9400
  projectRoot,
9208
- sourceSkillsDir: skillsDirRel,
9209
9401
  destCanonicalSkillsDir: COPILOT_CANONICAL_SKILLS_DIR,
9210
9402
  targetName: COPILOT_TARGET,
9211
9403
  normalize,
@@ -9530,7 +9722,7 @@ var init_scope_extras2 = __esm({
9530
9722
  };
9531
9723
  }
9532
9724
  });
9533
- var target10, project10, global5, globalCapabilities8, descriptor10;
9725
+ var target10, project10, globalLayout10, globalCapabilities8, descriptor10;
9534
9726
  var init_copilot2 = __esm({
9535
9727
  "src/targets/copilot/index.ts"() {
9536
9728
  init_generator11();
@@ -9584,7 +9776,7 @@ var init_copilot2 = __esm({
9584
9776
  }
9585
9777
  }
9586
9778
  };
9587
- global5 = {
9779
+ globalLayout10 = {
9588
9780
  rootInstructionPath: COPILOT_GLOBAL_INSTRUCTIONS,
9589
9781
  renderPrimaryRootInstruction: renderCopilotGlobalInstructions,
9590
9782
  outputFamilies: [
@@ -9690,7 +9882,7 @@ var init_copilot2 = __esm({
9690
9882
  COPILOT_GLOBAL_PROMPTS_DIR,
9691
9883
  COPILOT_GLOBAL_AGENTS_SKILLS_DIR
9692
9884
  ],
9693
- layout: global5,
9885
+ layout: globalLayout10,
9694
9886
  scopeExtras: generateCopilotGlobalExtras
9695
9887
  },
9696
9888
  importer: {
@@ -10072,7 +10264,7 @@ var init_settings = __esm({
10072
10264
  });
10073
10265
 
10074
10266
  // src/targets/crush/index.ts
10075
- var target11, project11, globalLayout6, capabilities4, globalCapabilities9, descriptor11;
10267
+ var target11, project11, globalLayout11, capabilities4, globalCapabilities9, descriptor11;
10076
10268
  var init_crush2 = __esm({
10077
10269
  "src/targets/crush/index.ts"() {
10078
10270
  init_command_skill();
@@ -10117,7 +10309,7 @@ var init_crush2 = __esm({
10117
10309
  }
10118
10310
  }
10119
10311
  };
10120
- globalLayout6 = {
10312
+ globalLayout11 = {
10121
10313
  rootInstructionPath: CRUSH_GLOBAL_ROOT_FILE,
10122
10314
  skillDir: CRUSH_GLOBAL_SKILLS_DIR,
10123
10315
  managedOutputs: {
@@ -10190,7 +10382,7 @@ var init_crush2 = __esm({
10190
10382
  globalSupport: {
10191
10383
  capabilities: globalCapabilities9,
10192
10384
  detectionPaths: [CRUSH_GLOBAL_ROOT_FILE, CRUSH_GLOBAL_CONFIG_FILE, CRUSH_GLOBAL_SKILLS_DIR],
10193
- layout: globalLayout6
10385
+ layout: globalLayout11
10194
10386
  },
10195
10387
  mergeGeneratedOutputContent(existing, pending, newContent, resolvedPath) {
10196
10388
  const base = pending?.content ?? existing;
@@ -10737,7 +10929,6 @@ async function importSkills3(projectRoot, results, normalize, skillsRelDir = CUR
10737
10929
  const directorySkills = await findDirectorySkills(skillsDir);
10738
10930
  const options = {
10739
10931
  projectRoot,
10740
- sourceSkillsDir: skillsRelDir,
10741
10932
  destCanonicalSkillsDir: CURSOR_CANONICAL_SKILLS_DIR,
10742
10933
  targetName: "cursor",
10743
10934
  normalize,
@@ -10773,20 +10964,20 @@ async function hasGlobalCursorArtifacts(projectRoot) {
10773
10964
  const candidates = [
10774
10965
  join(projectRoot, CURSOR_DOT_CURSOR_AGENTS),
10775
10966
  join(projectRoot, CURSOR_GLOBAL_USER_RULES),
10776
- join(projectRoot, CURSOR_GLOBAL_MCP_EXPORT),
10967
+ join(projectRoot, CURSOR_MCP),
10777
10968
  join(projectRoot, CURSOR_HOOKS),
10778
10969
  join(projectRoot, CURSOR_IGNORE),
10779
- join(projectRoot, CURSOR_GLOBAL_SKILLS_DIR),
10780
- join(projectRoot, CURSOR_GLOBAL_AGENTS_DIR),
10970
+ join(projectRoot, CURSOR_SKILLS_DIR),
10971
+ join(projectRoot, CURSOR_AGENTS_DIR),
10781
10972
  join(projectRoot, CURSOR_COMMANDS_DIR)
10782
10973
  ];
10783
10974
  for (const p of candidates) {
10784
- const stat7 = await readFileSafe(p);
10785
- if (stat7 !== null && stat7.trim() !== "") return true;
10975
+ const stat8 = await readFileSafe(p);
10976
+ if (stat8 !== null && stat8.trim() !== "") return true;
10786
10977
  }
10787
- const skillFiles = await readDirRecursive(join(projectRoot, CURSOR_GLOBAL_SKILLS_DIR));
10978
+ const skillFiles = await readDirRecursive(join(projectRoot, CURSOR_SKILLS_DIR));
10788
10979
  if (skillFiles.some((f) => f.endsWith(".md"))) return true;
10789
- const agentFiles = await readDirRecursive(join(projectRoot, CURSOR_GLOBAL_AGENTS_DIR));
10980
+ const agentFiles = await readDirRecursive(join(projectRoot, CURSOR_AGENTS_DIR));
10790
10981
  if (agentFiles.some((f) => f.endsWith(".md"))) return true;
10791
10982
  const commandFiles = await readDirRecursive(join(projectRoot, CURSOR_COMMANDS_DIR));
10792
10983
  if (commandFiles.some((f) => f.endsWith(".md"))) return true;
@@ -10843,7 +11034,7 @@ async function importGlobalDotCursorAgents(projectRoot, results, normalize) {
10843
11034
  });
10844
11035
  }
10845
11036
  async function importGlobalMcp(projectRoot, results) {
10846
- const mcpPath = join(projectRoot, CURSOR_GLOBAL_MCP_EXPORT);
11037
+ const mcpPath = join(projectRoot, CURSOR_MCP);
10847
11038
  const content = await readFileSafe(mcpPath);
10848
11039
  if (content === null || content.trim() === "") return;
10849
11040
  let parsed;
@@ -10864,7 +11055,7 @@ async function importGlobalMcp(projectRoot, results) {
10864
11055
  });
10865
11056
  }
10866
11057
  async function importGlobalAgents(projectRoot, results, normalize) {
10867
- const agentsDir = join(projectRoot, CURSOR_GLOBAL_AGENTS_DIR);
11058
+ const agentsDir = join(projectRoot, CURSOR_AGENTS_DIR);
10868
11059
  const destDir = join(projectRoot, CURSOR_CANONICAL_AGENTS_DIR);
10869
11060
  results.push(
10870
11061
  ...await importFileDirectory({
@@ -10913,7 +11104,7 @@ async function importFromCursorGlobalExports(projectRoot) {
10913
11104
  if (!rootWritten) rootWritten = await importGlobalUserRules(projectRoot, results, normalize);
10914
11105
  if (!rootWritten) await importGlobalDotCursorAgents(projectRoot, results, normalize);
10915
11106
  await importGlobalMcp(projectRoot, results);
10916
- await importSkills3(projectRoot, results, normalize, CURSOR_GLOBAL_SKILLS_DIR);
11107
+ await importSkills3(projectRoot, results, normalize, CURSOR_SKILLS_DIR);
10917
11108
  await importGlobalAgents(projectRoot, results, normalize);
10918
11109
  await importGlobalCommands(projectRoot, results, normalize);
10919
11110
  await importSettings2(projectRoot, results);
@@ -11087,7 +11278,7 @@ var init_lint9 = __esm({
11087
11278
  });
11088
11279
 
11089
11280
  // src/targets/cursor/index.ts
11090
- var target12, project12, global6, globalCapabilities10, descriptor12;
11281
+ var target12, project12, globalLayout12, globalCapabilities10, descriptor12;
11091
11282
  var init_cursor2 = __esm({
11092
11283
  "src/targets/cursor/index.ts"() {
11093
11284
  init_generator14();
@@ -11137,7 +11328,7 @@ var init_cursor2 = __esm({
11137
11328
  }
11138
11329
  }
11139
11330
  };
11140
- global6 = {
11331
+ globalLayout12 = {
11141
11332
  rootInstructionPath: CURSOR_GENERAL_RULE,
11142
11333
  outputFamilies: [
11143
11334
  {
@@ -11146,18 +11337,13 @@ var init_cursor2 = __esm({
11146
11337
  explicitPaths: [CURSOR_COMPAT_AGENTS, CURSOR_DOT_CURSOR_AGENTS]
11147
11338
  }
11148
11339
  ],
11149
- skillDir: CURSOR_GLOBAL_SKILLS_DIR,
11340
+ skillDir: CURSOR_SKILLS_DIR,
11150
11341
  managedOutputs: {
11151
- dirs: [
11152
- CURSOR_RULES_DIR,
11153
- CURSOR_COMMANDS_DIR,
11154
- CURSOR_GLOBAL_AGENTS_DIR,
11155
- CURSOR_GLOBAL_SKILLS_DIR
11156
- ],
11342
+ dirs: [CURSOR_RULES_DIR, CURSOR_COMMANDS_DIR, CURSOR_AGENTS_DIR, CURSOR_SKILLS_DIR],
11157
11343
  files: [
11158
11344
  CURSOR_GENERAL_RULE,
11159
11345
  CURSOR_DOT_CURSOR_AGENTS,
11160
- CURSOR_GLOBAL_MCP_EXPORT,
11346
+ CURSOR_MCP,
11161
11347
  CURSOR_HOOKS,
11162
11348
  CURSOR_IGNORE,
11163
11349
  CURSOR_GLOBAL_USER_RULES
@@ -11186,7 +11372,7 @@ var init_cursor2 = __esm({
11186
11372
  return `${CURSOR_COMMANDS_DIR}/${name}.md`;
11187
11373
  },
11188
11374
  agentPath(name, _config) {
11189
- return `${CURSOR_GLOBAL_AGENTS_DIR}/${name}.md`;
11375
+ return `${CURSOR_AGENTS_DIR}/${name}.md`;
11190
11376
  }
11191
11377
  }
11192
11378
  };
@@ -11238,11 +11424,11 @@ var init_cursor2 = __esm({
11238
11424
  CURSOR_HOOKS,
11239
11425
  CURSOR_IGNORE,
11240
11426
  CURSOR_SKILLS_DIR,
11241
- CURSOR_GLOBAL_AGENTS_DIR,
11427
+ CURSOR_AGENTS_DIR,
11242
11428
  CURSOR_COMMANDS_DIR,
11243
11429
  CURSOR_GLOBAL_USER_RULES
11244
11430
  ],
11245
- layout: global6
11431
+ layout: globalLayout12
11246
11432
  },
11247
11433
  importer: {
11248
11434
  // Project-only declarable features. Rules/mcp/skills/settings/ignore stay
@@ -11401,7 +11587,7 @@ var init_lint10 = __esm({
11401
11587
  });
11402
11588
 
11403
11589
  // src/targets/deepagents-cli/index.ts
11404
- var target13, project13, globalLayout7, capabilities5, globalCapabilities11, descriptor13;
11590
+ var target13, project13, globalLayout13, capabilities5, globalCapabilities11, descriptor13;
11405
11591
  var init_deepagents_cli2 = __esm({
11406
11592
  "src/targets/deepagents-cli/index.ts"() {
11407
11593
  init_command_skill();
@@ -11441,7 +11627,7 @@ var init_deepagents_cli2 = __esm({
11441
11627
  }
11442
11628
  }
11443
11629
  };
11444
- globalLayout7 = {
11630
+ globalLayout13 = {
11445
11631
  rootInstructionPath: DEEPAGENTS_CLI_GLOBAL_ROOT_FILE,
11446
11632
  skillDir: DEEPAGENTS_CLI_GLOBAL_SKILLS_DIR,
11447
11633
  managedOutputs: {
@@ -11512,7 +11698,7 @@ var init_deepagents_cli2 = __esm({
11512
11698
  globalSupport: {
11513
11699
  capabilities: globalCapabilities11,
11514
11700
  detectionPaths: [DEEPAGENTS_CLI_GLOBAL_ROOT_FILE, DEEPAGENTS_CLI_GLOBAL_MCP_FILE],
11515
- layout: globalLayout7
11701
+ layout: globalLayout13
11516
11702
  },
11517
11703
  importer: {
11518
11704
  rules: {
@@ -11734,7 +11920,7 @@ var init_lint11 = __esm({
11734
11920
  });
11735
11921
 
11736
11922
  // src/targets/factory-droid/index.ts
11737
- var target14, project14, globalLayout8, capabilities6, descriptor14;
11923
+ var target14, project14, globalLayout14, capabilities6, descriptor14;
11738
11924
  var init_factory_droid2 = __esm({
11739
11925
  "src/targets/factory-droid/index.ts"() {
11740
11926
  init_generator16();
@@ -11773,7 +11959,7 @@ var init_factory_droid2 = __esm({
11773
11959
  }
11774
11960
  }
11775
11961
  };
11776
- globalLayout8 = {
11962
+ globalLayout14 = {
11777
11963
  rootInstructionPath: FACTORY_DROID_GLOBAL_ROOT_FILE,
11778
11964
  skillDir: FACTORY_DROID_GLOBAL_SKILLS_DIR,
11779
11965
  managedOutputs: {
@@ -11840,7 +12026,7 @@ var init_factory_droid2 = __esm({
11840
12026
  FACTORY_DROID_GLOBAL_MCP_FILE,
11841
12027
  FACTORY_DROID_GLOBAL_DROIDS_DIR
11842
12028
  ],
11843
- layout: globalLayout8
12029
+ layout: globalLayout14
11844
12030
  },
11845
12031
  importer: {
11846
12032
  rules: {
@@ -12783,7 +12969,7 @@ var init_scoped_settings_emit = __esm({
12783
12969
  });
12784
12970
 
12785
12971
  // src/targets/gemini-cli/index.ts
12786
- var target15, project15, global7, globalCapabilities12, descriptor15;
12972
+ var target15, project15, globalLayout15, globalCapabilities12, descriptor15;
12787
12973
  var init_gemini_cli2 = __esm({
12788
12974
  "src/targets/gemini-cli/index.ts"() {
12789
12975
  init_generator18();
@@ -12853,7 +13039,7 @@ var init_gemini_cli2 = __esm({
12853
13039
  }
12854
13040
  }
12855
13041
  };
12856
- global7 = {
13042
+ globalLayout15 = {
12857
13043
  rootInstructionPath: GEMINI_GLOBAL_ROOT,
12858
13044
  outputFamilies: [
12859
13045
  { id: "compat-agents", kind: "additional", explicitPaths: [GEMINI_GLOBAL_COMPAT_AGENTS] }
@@ -12964,7 +13150,7 @@ var init_gemini_cli2 = __esm({
12964
13150
  GEMINI_GLOBAL_SKILLS_DIR,
12965
13151
  GEMINI_GLOBAL_AGENTS_DIR
12966
13152
  ],
12967
- layout: global7
13153
+ layout: globalLayout15
12968
13154
  },
12969
13155
  importer: {
12970
13156
  rules: {
@@ -12985,7 +13171,8 @@ var init_gemini_cli2 = __esm({
12985
13171
  }
12986
13172
  },
12987
13173
  buildImportPaths: buildGeminiCliImportPaths,
12988
- detectionPaths: ["GEMINI.md", ".gemini"]
13174
+ detectionPaths: ["GEMINI.md", ".gemini"],
13175
+ conversionDefaults: { agentsToSkills: false }
12989
13176
  };
12990
13177
  }
12991
13178
  });
@@ -13112,7 +13299,7 @@ var init_lint13 = __esm({
13112
13299
  });
13113
13300
 
13114
13301
  // src/targets/goose/index.ts
13115
- var target16, project16, globalLayout9, capabilities7, descriptor16;
13302
+ var target16, project16, globalLayout16, capabilities7, descriptor16;
13116
13303
  var init_goose2 = __esm({
13117
13304
  "src/targets/goose/index.ts"() {
13118
13305
  init_command_skill();
@@ -13153,7 +13340,7 @@ var init_goose2 = __esm({
13153
13340
  }
13154
13341
  }
13155
13342
  };
13156
- globalLayout9 = {
13343
+ globalLayout16 = {
13157
13344
  rootInstructionPath: GOOSE_GLOBAL_ROOT_FILE,
13158
13345
  skillDir: GOOSE_GLOBAL_SKILLS_DIR,
13159
13346
  managedOutputs: {
@@ -13163,9 +13350,6 @@ var init_goose2 = __esm({
13163
13350
  rewriteGeneratedPath(path) {
13164
13351
  if (path === GOOSE_ROOT_FILE) return GOOSE_GLOBAL_ROOT_FILE;
13165
13352
  if (path === GOOSE_IGNORE) return GOOSE_GLOBAL_IGNORE;
13166
- if (path.startsWith(`${GOOSE_SKILLS_DIR}/`)) {
13167
- return path;
13168
- }
13169
13353
  return path;
13170
13354
  },
13171
13355
  mirrorGlobalPath(path, activeTargets) {
@@ -13216,7 +13400,7 @@ var init_goose2 = __esm({
13216
13400
  globalSupport: {
13217
13401
  capabilities: capabilities7,
13218
13402
  detectionPaths: [GOOSE_GLOBAL_ROOT_FILE, GOOSE_GLOBAL_IGNORE, GOOSE_GLOBAL_SKILLS_DIR],
13219
- layout: globalLayout9
13403
+ layout: globalLayout16
13220
13404
  },
13221
13405
  importer: {
13222
13406
  rules: {
@@ -13245,7 +13429,8 @@ var init_goose2 = __esm({
13245
13429
  ".agents/skills/": "consumer"
13246
13430
  },
13247
13431
  buildImportPaths: buildGooseImportPaths,
13248
- detectionPaths: [GOOSE_ROOT_FILE, GOOSE_IGNORE]
13432
+ detectionPaths: [GOOSE_ROOT_FILE, GOOSE_IGNORE],
13433
+ conversionDefaults: { commandsToSkills: true, agentsToSkills: true }
13249
13434
  };
13250
13435
  }
13251
13436
  });
@@ -13641,7 +13826,7 @@ var init_lint15 = __esm({
13641
13826
  });
13642
13827
 
13643
13828
  // src/targets/junie/index.ts
13644
- var target18, project18, global8, globalCapabilities13, descriptor18;
13829
+ var target18, project18, globalLayout17, globalCapabilities13, descriptor18;
13645
13830
  var init_junie2 = __esm({
13646
13831
  "src/targets/junie/index.ts"() {
13647
13832
  init_generator21();
@@ -13681,7 +13866,7 @@ var init_junie2 = __esm({
13681
13866
  }
13682
13867
  }
13683
13868
  };
13684
- global8 = {
13869
+ globalLayout17 = {
13685
13870
  rootInstructionPath: JUNIE_GLOBAL_AGENTS_MD,
13686
13871
  renderPrimaryRootInstruction: renderJunieGlobalInstructions,
13687
13872
  skillDir: JUNIE_GLOBAL_SKILLS_DIR,
@@ -13779,7 +13964,7 @@ var init_junie2 = __esm({
13779
13964
  JUNIE_GLOBAL_COMMANDS_DIR,
13780
13965
  JUNIE_GLOBAL_MCP_FILE
13781
13966
  ],
13782
- layout: global8
13967
+ layout: globalLayout17
13783
13968
  },
13784
13969
  importer: {
13785
13970
  rules: {
@@ -14176,7 +14361,7 @@ var init_lint16 = __esm({
14176
14361
  });
14177
14362
 
14178
14363
  // src/targets/kilo-code/index.ts
14179
- var target19, project19, globalLayout10, capabilities9, descriptor19;
14364
+ var target19, project19, globalLayout18, capabilities9, descriptor19;
14180
14365
  var init_kilo_code2 = __esm({
14181
14366
  "src/targets/kilo-code/index.ts"() {
14182
14367
  init_generator22();
@@ -14217,7 +14402,7 @@ var init_kilo_code2 = __esm({
14217
14402
  }
14218
14403
  }
14219
14404
  };
14220
- globalLayout10 = {
14405
+ globalLayout18 = {
14221
14406
  rootInstructionPath: KILO_CODE_GLOBAL_AGENTS_MD,
14222
14407
  skillDir: KILO_CODE_GLOBAL_SKILLS_DIR,
14223
14408
  managedOutputs: {
@@ -14288,7 +14473,7 @@ var init_kilo_code2 = __esm({
14288
14473
  KILO_CODE_GLOBAL_MCP_FILE,
14289
14474
  KILO_CODE_GLOBAL_IGNORE
14290
14475
  ],
14291
- layout: globalLayout10
14476
+ layout: globalLayout18
14292
14477
  },
14293
14478
  importer: {
14294
14479
  rules: [
@@ -14698,7 +14883,7 @@ var init_lint17 = __esm({
14698
14883
  });
14699
14884
 
14700
14885
  // src/targets/kiro/index.ts
14701
- var target20, project20, global9, globalCapabilities14, descriptor20;
14886
+ var target20, project20, globalLayout19, globalCapabilities14, descriptor20;
14702
14887
  var init_kiro2 = __esm({
14703
14888
  "src/targets/kiro/index.ts"() {
14704
14889
  init_command_skill();
@@ -14740,7 +14925,7 @@ var init_kiro2 = __esm({
14740
14925
  }
14741
14926
  }
14742
14927
  };
14743
- global9 = {
14928
+ globalLayout19 = {
14744
14929
  rootInstructionPath: KIRO_GLOBAL_STEERING_AGENTS_MD,
14745
14930
  skillDir: KIRO_GLOBAL_SKILLS_DIR,
14746
14931
  managedOutputs: {
@@ -14839,7 +15024,7 @@ var init_kiro2 = __esm({
14839
15024
  KIRO_GLOBAL_MCP_FILE,
14840
15025
  KIRO_GLOBAL_IGNORE
14841
15026
  ],
14842
- layout: global9
15027
+ layout: globalLayout19
14843
15028
  },
14844
15029
  importer: {
14845
15030
  agents: {
@@ -14873,7 +15058,8 @@ var init_kiro2 = __esm({
14873
15058
  KIRO_HOOKS_DIR,
14874
15059
  KIRO_MCP_FILE,
14875
15060
  KIRO_IGNORE
14876
- ]
15061
+ ],
15062
+ conversionDefaults: { commandsToSkills: true }
14877
15063
  };
14878
15064
  }
14879
15065
  });
@@ -15172,7 +15358,7 @@ var init_lint18 = __esm({
15172
15358
  });
15173
15359
 
15174
15360
  // src/targets/opencode/index.ts
15175
- var target21, project21, globalLayout11, capabilities10, descriptor21;
15361
+ var target21, project21, globalLayout20, capabilities10, descriptor21;
15176
15362
  var init_opencode2 = __esm({
15177
15363
  "src/targets/opencode/index.ts"() {
15178
15364
  init_generator24();
@@ -15212,7 +15398,7 @@ var init_opencode2 = __esm({
15212
15398
  }
15213
15399
  }
15214
15400
  };
15215
- globalLayout11 = {
15401
+ globalLayout20 = {
15216
15402
  rootInstructionPath: OPENCODE_GLOBAL_AGENTS_MD,
15217
15403
  skillDir: OPENCODE_GLOBAL_SKILLS_DIR,
15218
15404
  managedOutputs: {
@@ -15284,7 +15470,7 @@ var init_opencode2 = __esm({
15284
15470
  OPENCODE_GLOBAL_SKILLS_DIR,
15285
15471
  OPENCODE_GLOBAL_CONFIG_FILE
15286
15472
  ],
15287
- layout: globalLayout11
15473
+ layout: globalLayout20
15288
15474
  },
15289
15475
  importer: {
15290
15476
  rules: [
@@ -15477,7 +15663,7 @@ var init_lint19 = __esm({
15477
15663
  });
15478
15664
 
15479
15665
  // src/targets/pi-agent/index.ts
15480
- var target22, project22, globalLayout12, capabilities11, descriptor22;
15666
+ var target22, project22, globalLayout21, capabilities11, descriptor22;
15481
15667
  var init_pi_agent2 = __esm({
15482
15668
  "src/targets/pi-agent/index.ts"() {
15483
15669
  init_command_skill();
@@ -15517,7 +15703,7 @@ var init_pi_agent2 = __esm({
15517
15703
  }
15518
15704
  }
15519
15705
  };
15520
- globalLayout12 = {
15706
+ globalLayout21 = {
15521
15707
  rootInstructionPath: PI_AGENT_GLOBAL_ROOT_FILE,
15522
15708
  skillDir: PI_AGENT_GLOBAL_SKILLS_DIR,
15523
15709
  managedOutputs: {
@@ -15580,7 +15766,7 @@ var init_pi_agent2 = __esm({
15580
15766
  globalSupport: {
15581
15767
  capabilities: capabilities11,
15582
15768
  detectionPaths: [PI_AGENT_GLOBAL_ROOT_FILE],
15583
- layout: globalLayout12
15769
+ layout: globalLayout21
15584
15770
  },
15585
15771
  importer: {
15586
15772
  rules: {
@@ -15726,7 +15912,7 @@ var init_linter23 = __esm({
15726
15912
  });
15727
15913
 
15728
15914
  // src/targets/qwen-code/index.ts
15729
- var target23, project23, globalLayout13, capabilities12, globalCapabilities15, descriptor23;
15915
+ var target23, project23, globalLayout22, capabilities12, globalCapabilities15, descriptor23;
15730
15916
  var init_qwen_code2 = __esm({
15731
15917
  "src/targets/qwen-code/index.ts"() {
15732
15918
  init_generator26();
@@ -15765,7 +15951,7 @@ var init_qwen_code2 = __esm({
15765
15951
  }
15766
15952
  }
15767
15953
  };
15768
- globalLayout13 = {
15954
+ globalLayout22 = {
15769
15955
  rootInstructionPath: QWEN_GLOBAL_ROOT,
15770
15956
  skillDir: QWEN_GLOBAL_SKILLS_DIR,
15771
15957
  managedOutputs: {
@@ -15846,7 +16032,7 @@ var init_qwen_code2 = __esm({
15846
16032
  QWEN_GLOBAL_AGENTS_DIR,
15847
16033
  QWEN_GLOBAL_SKILLS_DIR
15848
16034
  ],
15849
- layout: globalLayout13
16035
+ layout: globalLayout22
15850
16036
  },
15851
16037
  importer: {
15852
16038
  rules: [
@@ -16335,7 +16521,7 @@ function computeStatus5(existing, content) {
16335
16521
  if (existing !== content) return "updated";
16336
16522
  return "unchanged";
16337
16523
  }
16338
- var target25, project25, generateRooGlobalExtras, global10, globalCapabilities16, descriptor25;
16524
+ var target25, project25, generateRooGlobalExtras, globalLayout23, globalCapabilities16, descriptor25;
16339
16525
  var init_roo_code2 = __esm({
16340
16526
  "src/targets/roo-code/index.ts"() {
16341
16527
  init_fs();
@@ -16398,7 +16584,7 @@ var init_roo_code2 = __esm({
16398
16584
  }
16399
16585
  ];
16400
16586
  };
16401
- global10 = {
16587
+ globalLayout23 = {
16402
16588
  rootInstructionPath: ROO_CODE_GLOBAL_AGENTS_MD,
16403
16589
  skillDir: ROO_CODE_GLOBAL_SKILLS_DIR,
16404
16590
  managedOutputs: {
@@ -16499,7 +16685,7 @@ var init_roo_code2 = __esm({
16499
16685
  ROO_CODE_GLOBAL_AGENTS_MD,
16500
16686
  ROO_CODE_GLOBAL_MODES_FILE
16501
16687
  ],
16502
- layout: global10,
16688
+ layout: globalLayout23,
16503
16689
  scopeExtras: generateRooGlobalExtras
16504
16690
  },
16505
16691
  importer: {
@@ -16691,7 +16877,7 @@ var init_lint21 = __esm({
16691
16877
  });
16692
16878
 
16693
16879
  // src/targets/rovodev/index.ts
16694
- var target26, project26, globalLayout14, capabilities14, globalCapabilities17, descriptor26;
16880
+ var target26, project26, globalLayout24, capabilities14, globalCapabilities17, descriptor26;
16695
16881
  var init_rovodev2 = __esm({
16696
16882
  "src/targets/rovodev/index.ts"() {
16697
16883
  init_command_skill();
@@ -16732,7 +16918,7 @@ var init_rovodev2 = __esm({
16732
16918
  }
16733
16919
  }
16734
16920
  };
16735
- globalLayout14 = {
16921
+ globalLayout24 = {
16736
16922
  rootInstructionPath: ROVODEV_GLOBAL_ROOT_FILE,
16737
16923
  skillDir: ROVODEV_GLOBAL_SKILLS_DIR,
16738
16924
  managedOutputs: {
@@ -16806,7 +16992,7 @@ var init_rovodev2 = __esm({
16806
16992
  globalSupport: {
16807
16993
  capabilities: globalCapabilities17,
16808
16994
  detectionPaths: [ROVODEV_GLOBAL_DIR, ROVODEV_GLOBAL_ROOT_FILE, ROVODEV_GLOBAL_SKILLS_DIR],
16809
- layout: globalLayout14
16995
+ layout: globalLayout24
16810
16996
  },
16811
16997
  importer: {
16812
16998
  rules: {
@@ -16975,7 +17161,7 @@ var init_linter27 = __esm({
16975
17161
  });
16976
17162
 
16977
17163
  // src/targets/trae/index.ts
16978
- var target27, project27, global11, globalCapabilities18, descriptor27;
17164
+ var target27, project27, globalLayout25, globalCapabilities18, descriptor27;
16979
17165
  var init_trae2 = __esm({
16980
17166
  "src/targets/trae/index.ts"() {
16981
17167
  init_generator30();
@@ -17012,7 +17198,7 @@ var init_trae2 = __esm({
17012
17198
  }
17013
17199
  }
17014
17200
  };
17015
- global11 = {
17201
+ globalLayout25 = {
17016
17202
  rootInstructionPath: TRAE_GLOBAL_ROOT_RULE,
17017
17203
  skillDir: TRAE_GLOBAL_SKILLS_DIR,
17018
17204
  managedOutputs: {
@@ -17095,7 +17281,7 @@ var init_trae2 = __esm({
17095
17281
  TRAE_GLOBAL_SKILLS_DIR,
17096
17282
  TRAE_GLOBAL_MCP_FILE
17097
17283
  ],
17098
- layout: global11
17284
+ layout: globalLayout25
17099
17285
  },
17100
17286
  importer: {
17101
17287
  mcp: {
@@ -17242,7 +17428,7 @@ var init_lint22 = __esm({
17242
17428
  });
17243
17429
 
17244
17430
  // src/targets/warp/index.ts
17245
- var target28, project28, globalLayout15, capabilities15, globalCapabilities19, descriptor28;
17431
+ var target28, project28, globalLayout26, capabilities15, globalCapabilities19, descriptor28;
17246
17432
  var init_warp2 = __esm({
17247
17433
  "src/targets/warp/index.ts"() {
17248
17434
  init_command_skill();
@@ -17283,7 +17469,7 @@ var init_warp2 = __esm({
17283
17469
  }
17284
17470
  }
17285
17471
  };
17286
- globalLayout15 = {
17472
+ globalLayout26 = {
17287
17473
  rootInstructionPath: void 0,
17288
17474
  skillDir: WARP_GLOBAL_SKILLS_DIR,
17289
17475
  managedOutputs: {
@@ -17301,7 +17487,7 @@ var init_warp2 = __esm({
17301
17487
  },
17302
17488
  paths: {
17303
17489
  rulePath() {
17304
- return WARP_GLOBAL_SKILLS_DIR;
17490
+ return null;
17305
17491
  },
17306
17492
  commandPath(name) {
17307
17493
  return `${WARP_GLOBAL_SKILLS_DIR}/${commandSkillDirName(name)}/SKILL.md`;
@@ -17355,7 +17541,7 @@ var init_warp2 = __esm({
17355
17541
  globalSupport: {
17356
17542
  capabilities: globalCapabilities19,
17357
17543
  detectionPaths: [WARP_GLOBAL_SKILLS_DIR],
17358
- layout: globalLayout15
17544
+ layout: globalLayout26
17359
17545
  },
17360
17546
  importer: {
17361
17547
  rules: {
@@ -17379,7 +17565,8 @@ var init_warp2 = __esm({
17379
17565
  }
17380
17566
  },
17381
17567
  buildImportPaths: buildWarpImportPaths,
17382
- detectionPaths: [WARP_ROOT_FILE, WARP_LEGACY_ROOT_FILE, WARP_MCP_FILE]
17568
+ detectionPaths: [WARP_ROOT_FILE, WARP_LEGACY_ROOT_FILE, WARP_MCP_FILE],
17569
+ conversionDefaults: { commandsToSkills: true, agentsToSkills: true }
17383
17570
  };
17384
17571
  }
17385
17572
  });
@@ -17672,49 +17859,22 @@ var init_importer_workflows = __esm({
17672
17859
  init_constants31();
17673
17860
  }
17674
17861
  });
17862
+
17863
+ // src/targets/windsurf/skills-adapter.ts
17675
17864
  async function importSkills4(projectRoot, results, normalize, skillsRelDir = WINDSURF_SKILLS_DIR) {
17676
- const skillsDir = join(projectRoot, skillsRelDir);
17677
- const directorySkills = await findDirectorySkills(skillsDir);
17678
17865
  const options = {
17679
17866
  projectRoot,
17680
- sourceSkillsDir: skillsRelDir,
17681
17867
  destCanonicalSkillsDir: WINDSURF_CANONICAL_SKILLS_DIR,
17682
17868
  targetName: "windsurf",
17683
17869
  normalize,
17684
17870
  results
17685
17871
  };
17686
- for (const [skillName, skillDir] of directorySkills) {
17687
- const skillMdPath = join(skillDir, "SKILL.md");
17688
- const content = await readFileSafe(skillMdPath);
17689
- if (!content) continue;
17690
- const rawParsed = parseFrontmatter(content);
17691
- const projectedAgent = parseProjectedAgentSkillFrontmatter(rawParsed.frontmatter, skillName);
17692
- if (projectedAgent) {
17693
- await removePathIfExists(join(projectRoot, WINDSURF_CANONICAL_SKILLS_DIR, skillName));
17694
- const destAgentsDir = join(projectRoot, WINDSURF_CANONICAL_AGENTS_DIR);
17695
- await mkdirp(destAgentsDir);
17696
- const agentPath = join(destAgentsDir, `${projectedAgent.name}.md`);
17697
- await writeFileAtomic(
17698
- agentPath,
17699
- serializeImportedAgent(projectedAgent, normalize(rawParsed.body, skillMdPath, agentPath))
17700
- );
17701
- results.push({
17702
- fromTool: "windsurf",
17703
- fromPath: skillMdPath,
17704
- toPath: `${WINDSURF_CANONICAL_AGENTS_DIR}/${projectedAgent.name}.md`,
17705
- feature: "agents"
17706
- });
17707
- continue;
17708
- }
17709
- await importDirectorySkill(skillName, skillDir, options);
17710
- }
17872
+ await importSkillsDirectory([skillsRelDir], options, [
17873
+ projectedAgentRecognizer({ canonicalAgentsDir: WINDSURF_CANONICAL_AGENTS_DIR })
17874
+ ]);
17711
17875
  }
17712
17876
  var init_skills_adapter5 = __esm({
17713
17877
  "src/targets/windsurf/skills-adapter.ts"() {
17714
- init_fs();
17715
- init_markdown();
17716
- init_projected_agent_skill();
17717
- init_scoped_agents_import();
17718
17878
  init_skill_import_pipeline();
17719
17879
  init_constants31();
17720
17880
  }
@@ -18031,7 +18191,7 @@ function directoryScopedRuleDir2(globs) {
18031
18191
  if (dirs.length !== globs.length) return null;
18032
18192
  return dirs.every((dir) => dir === dirs[0]) ? dirs[0] : null;
18033
18193
  }
18034
- var target29, project29, global12, globalCapabilities20, descriptor29;
18194
+ var target29, project29, globalLayout27, globalCapabilities20, descriptor29;
18035
18195
  var init_windsurf2 = __esm({
18036
18196
  "src/targets/windsurf/index.ts"() {
18037
18197
  init_generator33();
@@ -18085,7 +18245,7 @@ var init_windsurf2 = __esm({
18085
18245
  }
18086
18246
  }
18087
18247
  };
18088
- global12 = {
18248
+ globalLayout27 = {
18089
18249
  rootInstructionPath: WINDSURF_GLOBAL_RULES,
18090
18250
  skillDir: WINDSURF_GLOBAL_SKILLS_DIR,
18091
18251
  managedOutputs: {
@@ -18189,10 +18349,11 @@ var init_windsurf2 = __esm({
18189
18349
  WINDSURF_GLOBAL_MCP_FILE,
18190
18350
  WINDSURF_GLOBAL_IGNORE
18191
18351
  ],
18192
- layout: global12
18352
+ layout: globalLayout27
18193
18353
  },
18194
18354
  buildImportPaths: buildWindsurfImportPaths,
18195
- detectionPaths: [".windsurfrules", ".windsurf"]
18355
+ detectionPaths: [".windsurfrules", ".windsurf"],
18356
+ conversionDefaults: { agentsToSkills: true }
18196
18357
  };
18197
18358
  }
18198
18359
  });
@@ -18353,7 +18514,7 @@ function mergeZedSettings(existing, newContent) {
18353
18514
  }
18354
18515
  return JSON.stringify(base, null, 2);
18355
18516
  }
18356
- var target30, project30, globalLayout16, capabilities16, globalCapabilities21, descriptor30;
18517
+ var target30, project30, globalLayout28, capabilities16, globalCapabilities21, descriptor30;
18357
18518
  var init_zed2 = __esm({
18358
18519
  "src/targets/zed/index.ts"() {
18359
18520
  init_generator34();
@@ -18386,7 +18547,7 @@ var init_zed2 = __esm({
18386
18547
  }
18387
18548
  }
18388
18549
  };
18389
- globalLayout16 = {
18550
+ globalLayout28 = {
18390
18551
  rootInstructionPath: void 0,
18391
18552
  managedOutputs: {
18392
18553
  dirs: [],
@@ -18451,7 +18612,7 @@ var init_zed2 = __esm({
18451
18612
  globalSupport: {
18452
18613
  capabilities: globalCapabilities21,
18453
18614
  detectionPaths: [ZED_GLOBAL_SETTINGS_FILE],
18454
- layout: globalLayout16
18615
+ layout: globalLayout28
18455
18616
  },
18456
18617
  importer: {
18457
18618
  rules: {
@@ -19057,6 +19218,72 @@ function rewriteGeneratedReferences(results, canonical, config, projectRoot, sco
19057
19218
  // src/core/reference/validate-generated-markdown-links.ts
19058
19219
  init_path_helpers();
19059
19220
  init_link_rebaser_helpers();
19221
+
19222
+ // src/utils/output/logger.ts
19223
+ var C = {
19224
+ green: "\x1B[32m",
19225
+ red: "\x1B[31m",
19226
+ yellow: "\x1B[33m",
19227
+ cyan: "\x1B[36m",
19228
+ reset: "\x1B[0m"
19229
+ };
19230
+ function out(text) {
19231
+ {
19232
+ process.stdout.write(text);
19233
+ }
19234
+ }
19235
+ function noColor() {
19236
+ return process.env.NO_COLOR !== void 0 && process.env.NO_COLOR !== "";
19237
+ }
19238
+ function c(code, text) {
19239
+ return noColor() ? text : `${code}${text}${C.reset}`;
19240
+ }
19241
+ function pad(str, width) {
19242
+ const len = [...str].length;
19243
+ return str + " ".repeat(Math.max(0, width - len));
19244
+ }
19245
+ var logger = {
19246
+ info(msg) {
19247
+ out(c(C.cyan, msg) + "\n");
19248
+ },
19249
+ warn(msg) {
19250
+ process.stderr.write(c(C.yellow, "\u26A0 ") + msg + "\n");
19251
+ },
19252
+ error(msg) {
19253
+ process.stderr.write(c(C.red, "\u2717 ") + msg + "\n");
19254
+ },
19255
+ success(msg) {
19256
+ out(c(C.green, "\u2713 ") + msg + "\n");
19257
+ },
19258
+ debug(msg) {
19259
+ if (process.env.AGENTSMESH_DEBUG === "1") {
19260
+ out(c(C.cyan, "[debug] ") + msg + "\n");
19261
+ }
19262
+ },
19263
+ table(rows) {
19264
+ if (rows.length === 0) return;
19265
+ const cols = rows[0].length;
19266
+ const widths = [];
19267
+ for (let j = 0; j < cols; j++) {
19268
+ let max = 0;
19269
+ for (let i = 0; i < rows.length; i++) {
19270
+ const len = [...rows[i][j]].length;
19271
+ if (len > max) max = len;
19272
+ }
19273
+ widths[j] = max;
19274
+ }
19275
+ const border = "+" + widths.map((w) => "-".repeat(w + 2)).join("+") + "+";
19276
+ out(border + "\n");
19277
+ for (let i = 0; i < rows.length; i++) {
19278
+ const row = rows[i];
19279
+ const line = "| " + row.map((cell, j) => pad(cell, widths[j])).join(" | ") + " |";
19280
+ out(line + "\n");
19281
+ }
19282
+ out(border + "\n");
19283
+ }
19284
+ };
19285
+
19286
+ // src/core/reference/validate-generated-markdown-links.ts
19060
19287
  var INLINE_MD_LINK = /!?\[[^\]]*\]\(([^)]+)\)/g;
19061
19288
  var REF_LINK_DEF = /^\s*\[[^\]\n]+\]:\s*(?:<([^>\n]*)>|(\S+))/gm;
19062
19289
  function isMarkdownLikeOutput(relativePath) {
@@ -19072,7 +19299,7 @@ function parseMarkdownLinkDestination(raw) {
19072
19299
  if (s.startsWith("<") && s.endsWith(">")) s = s.slice(1, -1).trim();
19073
19300
  return s;
19074
19301
  }
19075
- function shouldSkipLocalValidation(pathPart) {
19302
+ function shouldSkipLocalValidation(pathPart, projectRoot) {
19076
19303
  const t = pathPart.trim();
19077
19304
  if (!t) return true;
19078
19305
  if (t.startsWith("#")) return true;
@@ -19083,8 +19310,66 @@ function shouldSkipLocalValidation(pathPart) {
19083
19310
  if (/^ftp:/i.test(t)) return true;
19084
19311
  if (/^[a-zA-Z]:[\\/]/.test(t)) return false;
19085
19312
  if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(t)) return true;
19313
+ if (t.startsWith("/")) {
19314
+ const normalizedRoot = normalizeForProject(projectRoot, projectRoot);
19315
+ const normalizedAbs = normalizeForProject(projectRoot, t);
19316
+ if (!normalizedAbs.startsWith(`${normalizedRoot}/`) && normalizedAbs !== normalizedRoot) {
19317
+ return true;
19318
+ }
19319
+ }
19086
19320
  return false;
19087
19321
  }
19322
+ function isSkillGeneratedOutput(relativePath) {
19323
+ return /(?:^|\/)[^/]+\/skills\/[^/]+\//.test(relativePath);
19324
+ }
19325
+ var OUTPUT_DIR_TO_FEATURE = {
19326
+ rules: "rules",
19327
+ steering: "rules",
19328
+ commands: "commands",
19329
+ agents: "agents",
19330
+ skills: "skills",
19331
+ // factory-droid: native agent definitions land in `.factory/droids/<name>.md`.
19332
+ // Treat the directory as the agents feature so pack-originated key matching
19333
+ // recognizes those outputs and downgrades broken links to advisory warnings.
19334
+ droids: "agents",
19335
+ // copilot project layout: rules emit per-glob into `.github/instructions/`,
19336
+ // commands into `.github/prompts/`. Map both to their canonical features so
19337
+ // pack-originated outputs from those dirs match the same keys as their
19338
+ // canonical counterparts.
19339
+ instructions: "rules",
19340
+ prompts: "commands"
19341
+ };
19342
+ var TOP_LEVEL_DIR_TO_FEATURE = {
19343
+ ".clinerules": "rules"
19344
+ };
19345
+ var COMPOUND_MARKDOWN_SUFFIXES = [".agent.md", ".instructions.md", ".prompt.md"];
19346
+ function stripMarkdownExt(name) {
19347
+ for (const suffix of COMPOUND_MARKDOWN_SUFFIXES) {
19348
+ if (name.endsWith(suffix)) return name.slice(0, -suffix.length);
19349
+ }
19350
+ if (name.endsWith(".mdc")) return name.slice(0, -4);
19351
+ if (name.endsWith(".md")) return name.slice(0, -3);
19352
+ return name;
19353
+ }
19354
+ function canonicalKeyFromOutputPath(relativePath) {
19355
+ const m = /^[^/]+\/([^/]+)\/([^/]+)/.exec(relativePath);
19356
+ if (m) {
19357
+ const feature = OUTPUT_DIR_TO_FEATURE[m[1] ?? ""];
19358
+ if (feature) {
19359
+ let name = m[2] ?? "";
19360
+ if (feature !== "skills") name = stripMarkdownExt(name);
19361
+ return `${feature}/${name}`;
19362
+ }
19363
+ }
19364
+ const m2 = /^([^/]+)\/([^/]+)/.exec(relativePath);
19365
+ if (m2) {
19366
+ const feature = TOP_LEVEL_DIR_TO_FEATURE[m2[1] ?? ""];
19367
+ if (feature) {
19368
+ return `${feature}/${stripMarkdownExt(m2[2] ?? "")}`;
19369
+ }
19370
+ }
19371
+ return null;
19372
+ }
19088
19373
  function pathExistsForGenerate(absolutePath, planned) {
19089
19374
  if (planned.has(absolutePath)) return true;
19090
19375
  try {
@@ -19107,7 +19392,7 @@ function resolveMarkdownLinkTargets(rawDestination, projectRoot, destinationFile
19107
19392
  } catch {
19108
19393
  decoded = pathPart;
19109
19394
  }
19110
- if (shouldSkipLocalValidation(decoded)) return [];
19395
+ if (shouldSkipLocalValidation(decoded, projectRoot)) return [];
19111
19396
  let candidates = resolveProjectPath(decoded, projectRoot, destinationFileAbs);
19112
19397
  if (candidates.length === 0) {
19113
19398
  const api = pathApi(projectRoot);
@@ -19161,10 +19446,32 @@ function findBrokenMarkdownLinks(results, projectRoot) {
19161
19446
  }
19162
19447
  return broken;
19163
19448
  }
19164
- function validateGeneratedMarkdownLinks(results, projectRoot) {
19449
+ function validateGeneratedMarkdownLinks(results, projectRoot, options = {}) {
19165
19450
  const broken = findBrokenMarkdownLinks(results, projectRoot);
19166
19451
  if (broken.length === 0) return;
19167
- const lines = broken.map(
19452
+ const packKeys = options.packOriginatedKeys;
19453
+ const errors = [];
19454
+ const warnings = [];
19455
+ for (const b of broken) {
19456
+ const key = canonicalKeyFromOutputPath(b.generatePath);
19457
+ const isPackOriginated = packKeys !== void 0 && key !== null && packKeys.has(key);
19458
+ if (isSkillGeneratedOutput(b.generatePath) || isPackOriginated) {
19459
+ warnings.push(b);
19460
+ } else {
19461
+ errors.push(b);
19462
+ }
19463
+ }
19464
+ if (warnings.length > 0) {
19465
+ const lines2 = warnings.map(
19466
+ (b) => ` ${b.generatePath} (${b.target}): "${b.rawLink}" \u2192 not found`
19467
+ );
19468
+ logger.warn(
19469
+ `Third-party content contains ${warnings.length} broken local link${warnings.length === 1 ? "" : "s"} (warning only; outputs from installed packs and skill subtrees are treated as advisory):
19470
+ ${lines2.join("\n")}`
19471
+ );
19472
+ }
19473
+ if (errors.length === 0) return;
19474
+ const lines = errors.map(
19168
19475
  (b) => ` ${b.generatePath} (${b.target}): "${b.rawLink}" \u2192 not found (tried: ${b.checkedPaths.join(", ")})`
19169
19476
  );
19170
19477
  throw new Error(
@@ -19173,6 +19480,37 @@ ${lines.join("\n")}
19173
19480
  Fix canonical sources or generators so every local link targets an existing file or folder.`
19174
19481
  );
19175
19482
  }
19483
+ var PACK_MARKERS = [
19484
+ `${sep}.agentsmesh${sep}packs${sep}`,
19485
+ "/.agentsmesh/packs/"
19486
+ ];
19487
+ function isUnderPacks(sourcePath) {
19488
+ return PACK_MARKERS.some((marker) => sourcePath.includes(marker));
19489
+ }
19490
+ function buildPackOriginatedKeys(canonical) {
19491
+ const keys = /* @__PURE__ */ new Set();
19492
+ for (const rule of canonical.rules) {
19493
+ if (isUnderPacks(rule.source)) {
19494
+ const name = rule.root ? "_root" : ruleNameFromSource(rule.source);
19495
+ if (name) keys.add(`rules/${name}`);
19496
+ }
19497
+ }
19498
+ for (const agent of canonical.agents) {
19499
+ if (isUnderPacks(agent.source)) keys.add(`agents/${agent.name}`);
19500
+ }
19501
+ for (const cmd of canonical.commands) {
19502
+ if (isUnderPacks(cmd.source)) keys.add(`commands/${cmd.name}`);
19503
+ }
19504
+ for (const skill of canonical.skills) {
19505
+ if (isUnderPacks(skill.source)) keys.add(`skills/${skill.name}`);
19506
+ }
19507
+ return keys;
19508
+ }
19509
+ function ruleNameFromSource(source) {
19510
+ const slash = source.replace(/\\/g, "/");
19511
+ const base = slash.split("/").pop() ?? "";
19512
+ return base.endsWith(".md") ? base.slice(0, -3) : base;
19513
+ }
19176
19514
 
19177
19515
  // src/core/generate/collision.ts
19178
19516
  init_target_ids();
@@ -19200,6 +19538,19 @@ function mergeDuplicateMetadata(preferred, other) {
19200
19538
  function trimmedContent(content) {
19201
19539
  return content.trim();
19202
19540
  }
19541
+ var OPTIONAL_AGENTS_BLOCKS = [
19542
+ /<!-- agentsmesh:embedded-rules:start -->[\s\S]*?<!-- agentsmesh:embedded-rules:end -->\n*/g
19543
+ ];
19544
+ function normalizeAgentsContent(content) {
19545
+ let out2 = content;
19546
+ for (const block of OPTIONAL_AGENTS_BLOCKS) {
19547
+ out2 = out2.replace(block, "");
19548
+ }
19549
+ return out2.trim().replace(/\n{2,}/g, "\n\n");
19550
+ }
19551
+ function hasOptionalAgentsBlock(content) {
19552
+ return /<!-- agentsmesh:embedded-rules:start -->/.test(content);
19553
+ }
19203
19554
  function richerAgentsResult(left, right) {
19204
19555
  if (!left.path.endsWith(AGENTS_SUFFIX) || left.path !== right.path) return null;
19205
19556
  const leftTrimmed = trimmedContent(left.content);
@@ -19207,8 +19558,15 @@ function richerAgentsResult(left, right) {
19207
19558
  if (!leftTrimmed || !rightTrimmed) return null;
19208
19559
  const leftContainsRight = leftTrimmed.includes(rightTrimmed);
19209
19560
  const rightContainsLeft = rightTrimmed.includes(leftTrimmed);
19210
- if (leftContainsRight === rightContainsLeft) return null;
19211
- return leftContainsRight ? left : right;
19561
+ if (leftContainsRight !== rightContainsLeft) {
19562
+ return leftContainsRight ? left : right;
19563
+ }
19564
+ if (normalizeAgentsContent(left.content) === normalizeAgentsContent(right.content)) {
19565
+ const leftHas = hasOptionalAgentsBlock(left.content);
19566
+ const rightHas = hasOptionalAgentsBlock(right.content);
19567
+ if (leftHas !== rightHas) return leftHas ? left : right;
19568
+ }
19569
+ return null;
19212
19570
  }
19213
19571
  function richerCodexAgentsResult(left, right) {
19214
19572
  if (!left.path.endsWith(AGENTS_SUFFIX) || left.path !== right.path) return null;
@@ -19513,7 +19871,9 @@ async function generate(ctx) {
19513
19871
  targets,
19514
19872
  sharedPaths
19515
19873
  );
19516
- validateGeneratedMarkdownLinks(rewrittenResults, projectRoot);
19874
+ validateGeneratedMarkdownLinks(rewrittenResults, projectRoot, {
19875
+ packOriginatedKeys: buildPackOriginatedKeys(canonical)
19876
+ });
19517
19877
  return resolveOutputCollisions(rewrittenResults.map(refreshResultStatus));
19518
19878
  }
19519
19879
  function computeSharedRootInstructionPaths(results, scope) {
@@ -19550,72 +19910,6 @@ init_errors();
19550
19910
 
19551
19911
  // src/config/core/loader.ts
19552
19912
  init_fs();
19553
-
19554
- // src/utils/output/logger.ts
19555
- var C = {
19556
- green: "\x1B[32m",
19557
- red: "\x1B[31m",
19558
- yellow: "\x1B[33m",
19559
- cyan: "\x1B[36m",
19560
- reset: "\x1B[0m"
19561
- };
19562
- function out(text) {
19563
- {
19564
- process.stdout.write(text);
19565
- }
19566
- }
19567
- function noColor() {
19568
- return process.env.NO_COLOR !== void 0 && process.env.NO_COLOR !== "";
19569
- }
19570
- function c(code, text) {
19571
- return noColor() ? text : `${code}${text}${C.reset}`;
19572
- }
19573
- function pad(str, width) {
19574
- const len = [...str].length;
19575
- return str + " ".repeat(Math.max(0, width - len));
19576
- }
19577
- var logger = {
19578
- info(msg) {
19579
- out(c(C.cyan, msg) + "\n");
19580
- },
19581
- warn(msg) {
19582
- process.stderr.write(c(C.yellow, "\u26A0 ") + msg + "\n");
19583
- },
19584
- error(msg) {
19585
- process.stderr.write(c(C.red, "\u2717 ") + msg + "\n");
19586
- },
19587
- success(msg) {
19588
- out(c(C.green, "\u2713 ") + msg + "\n");
19589
- },
19590
- debug(msg) {
19591
- if (process.env.AGENTSMESH_DEBUG === "1") {
19592
- out(c(C.cyan, "[debug] ") + msg + "\n");
19593
- }
19594
- },
19595
- table(rows) {
19596
- if (rows.length === 0) return;
19597
- const cols = rows[0].length;
19598
- const widths = [];
19599
- for (let j = 0; j < cols; j++) {
19600
- let max = 0;
19601
- for (let i = 0; i < rows.length; i++) {
19602
- const len = [...rows[i][j]].length;
19603
- if (len > max) max = len;
19604
- }
19605
- widths[j] = max;
19606
- }
19607
- const border = "+" + widths.map((w) => "-".repeat(w + 2)).join("+") + "+";
19608
- out(border + "\n");
19609
- for (let i = 0; i < rows.length; i++) {
19610
- const row = rows[i];
19611
- const line = "| " + row.map((cell, j) => pad(cell, widths[j])).join(" | ") + " |";
19612
- out(line + "\n");
19613
- }
19614
- out(border + "\n");
19615
- }
19616
- };
19617
-
19618
- // src/config/core/loader.ts
19619
19913
  init_errors();
19620
19914
 
19621
19915
  // src/config/core/schema.ts
@@ -19632,6 +19926,7 @@ var VALID_FEATURES = [
19632
19926
  ];
19633
19927
  var targetSchema = z.enum(TARGET_IDS);
19634
19928
  var featureSchema = z.enum(VALID_FEATURES);
19929
+ var installAsSchema = z.enum(["rules", "commands", "agents", "skills"]);
19635
19930
  var extendPickSchema = z.object({
19636
19931
  skills: z.array(z.string()).optional(),
19637
19932
  commands: z.array(z.string()).optional(),
@@ -19643,6 +19938,7 @@ var extendSourceSchema = z.object({
19643
19938
  source: z.string(),
19644
19939
  version: z.string().optional(),
19645
19940
  target: targetSchema.optional(),
19941
+ as: installAsSchema.optional(),
19646
19942
  features: z.array(featureSchema),
19647
19943
  /** Repo-relative POSIX path for discovery (skill packs, nested .agentsmesh). */
19648
19944
  path: z.string().optional(),
@@ -19933,7 +20229,28 @@ async function runGit(args, cwd) {
19933
20229
 
19934
20230
  // src/config/remote/github-remote.ts
19935
20231
  init_fs();
19936
- var MAX_TARBALL_BYTES = 500 * 1024 * 1024;
20232
+ var DEFAULT_MAX_TARBALL_MB = 500;
20233
+ var MIN_MAX_TARBALL_MB = 1;
20234
+ var MAX_MAX_TARBALL_MB = 4096;
20235
+ function resolveMaxTarballBytes() {
20236
+ const raw = process.env.AGENTSMESH_MAX_TARBALL_MB;
20237
+ if (raw === void 0 || raw === "") return DEFAULT_MAX_TARBALL_MB * 1024 * 1024;
20238
+ const parsed = Number(raw);
20239
+ if (!Number.isFinite(parsed) || !Number.isInteger(parsed)) {
20240
+ console.warn(
20241
+ `[agentsmesh] AGENTSMESH_MAX_TARBALL_MB="${raw}" is not an integer; using default ${DEFAULT_MAX_TARBALL_MB} MiB.`
20242
+ );
20243
+ return DEFAULT_MAX_TARBALL_MB * 1024 * 1024;
20244
+ }
20245
+ if (parsed < MIN_MAX_TARBALL_MB || parsed > MAX_MAX_TARBALL_MB) {
20246
+ console.warn(
20247
+ `[agentsmesh] AGENTSMESH_MAX_TARBALL_MB=${parsed} is outside [${MIN_MAX_TARBALL_MB}, ${MAX_MAX_TARBALL_MB}]; using default ${DEFAULT_MAX_TARBALL_MB} MiB.`
20248
+ );
20249
+ return DEFAULT_MAX_TARBALL_MB * 1024 * 1024;
20250
+ }
20251
+ return parsed * 1024 * 1024;
20252
+ }
20253
+ var MAX_TARBALL_BYTES = resolveMaxTarballBytes();
19937
20254
  async function readBoundedResponse(res, maxBytes) {
19938
20255
  const lenHeader = typeof res.headers?.get === "function" ? res.headers.get("content-length") : null;
19939
20256
  if (lenHeader !== null) {
@@ -20283,6 +20600,7 @@ async function resolveExtendPaths(config, configDir, options = {}) {
20283
20600
  resolvedPath: fetched.resolvedPath,
20284
20601
  features: [...ext.features],
20285
20602
  target: ext.target,
20603
+ as: ext.as,
20286
20604
  version: fetched.version,
20287
20605
  path: ext.path,
20288
20606
  pick: ext.pick
@@ -20300,6 +20618,7 @@ async function resolveExtendPaths(config, configDir, options = {}) {
20300
20618
  resolvedPath,
20301
20619
  features: [...ext.features],
20302
20620
  target: ext.target,
20621
+ as: ext.as,
20303
20622
  path: ext.path,
20304
20623
  pick: ext.pick
20305
20624
  });
@@ -20400,6 +20719,28 @@ function assertNoBasenameCollisions(feature, paths, stripExt) {
20400
20719
  seen.set(slug, p);
20401
20720
  }
20402
20721
  }
20722
+ var ALTERNATE_RESOURCE_FORMATS = /* @__PURE__ */ new Set([".toml", ".yaml", ".yml", ".json"]);
20723
+ function warnIfUnrecognizedResourceFormats(featureLabel, dir, allFiles, parsedFiles, opts = {}) {
20724
+ if (allFiles.length === 0) return;
20725
+ const parsed = new Set(parsedFiles);
20726
+ const handled = opts.handledByOtherReader;
20727
+ const formats = /* @__PURE__ */ new Set();
20728
+ let droppedCount = 0;
20729
+ for (const f of allFiles) {
20730
+ if (parsed.has(f)) continue;
20731
+ if (basename(f).startsWith(".")) continue;
20732
+ const ext = extname(f).toLowerCase();
20733
+ if (!ALTERNATE_RESOURCE_FORMATS.has(ext)) continue;
20734
+ if (handled?.has(ext)) continue;
20735
+ formats.add(ext);
20736
+ droppedCount++;
20737
+ }
20738
+ if (droppedCount === 0) return;
20739
+ const formatList = [...formats].sort().join(", ");
20740
+ logger.warn(
20741
+ `Skipped ${droppedCount} ${featureLabel} file(s) in ${dir} (format${formats.size === 1 ? "" : "s"}: ${formatList}). agentsmesh ${featureLabel} are parsed from .md files only.`
20742
+ );
20743
+ }
20403
20744
 
20404
20745
  // src/canonical/features/rules.ts
20405
20746
  var VALID_TRIGGERS = ["always_on", "model_decision", "glob", "manual"];
@@ -20408,18 +20749,23 @@ function toStrArray(v) {
20408
20749
  if (typeof v === "string") return v ? [v] : [];
20409
20750
  return [];
20410
20751
  }
20411
- async function parseRules(rulesDir) {
20752
+ async function parseRules(rulesDir, opts = {}) {
20412
20753
  const files = await readDirRecursive(rulesDir);
20413
20754
  const mdFiles = files.filter((f) => {
20414
20755
  if (!f.endsWith(".md")) return false;
20415
20756
  const name = basename(f, ".md");
20416
20757
  return name === "_root" || !name.startsWith("_");
20417
20758
  });
20759
+ warnIfUnrecognizedResourceFormats("rules", rulesDir, files, mdFiles, {
20760
+ handledByOtherReader: opts.handledByOtherReader
20761
+ });
20418
20762
  const rules = [];
20419
20763
  for (const path of mdFiles) {
20420
20764
  const content = await readFileSafe(path);
20421
20765
  if (!content) continue;
20422
- const { frontmatter, body } = parseFrontmatter(content);
20766
+ const parsed = parseOrSkipFrontmatter(content, path, opts.onParseError);
20767
+ if (!parsed) continue;
20768
+ const { frontmatter, body } = parsed;
20423
20769
  const name = basename(path, ".md");
20424
20770
  assertCanonicalName("rule", name);
20425
20771
  const rootFromFilename = name === "_root";
@@ -20460,15 +20806,20 @@ function toToolsArray2(v) {
20460
20806
  }
20461
20807
  return [];
20462
20808
  }
20463
- async function parseCommands(commandsDir) {
20809
+ async function parseCommands(commandsDir, opts = {}) {
20464
20810
  const files = await readDirRecursive(commandsDir);
20465
20811
  const mdFiles = files.filter((f) => f.endsWith(".md") && !basename(f).startsWith("_"));
20812
+ warnIfUnrecognizedResourceFormats("commands", commandsDir, files, mdFiles, {
20813
+ handledByOtherReader: opts.handledByOtherReader
20814
+ });
20466
20815
  assertNoBasenameCollisions("command", mdFiles, ".md");
20467
20816
  const commands = [];
20468
20817
  for (const path of mdFiles) {
20469
20818
  const content = await readFileSafe(path);
20470
20819
  if (!content) continue;
20471
- const { frontmatter, body } = parseFrontmatter(content);
20820
+ const parsed = parseOrSkipFrontmatter(content, path, opts.onParseError);
20821
+ if (!parsed) continue;
20822
+ const { frontmatter, body } = parsed;
20472
20823
  const name = basename(path, ".md");
20473
20824
  assertCanonicalName("command", name);
20474
20825
  const fromCamel = toToolsArray2(frontmatter.allowedTools);
@@ -20515,15 +20866,20 @@ function toHooks2(v) {
20515
20866
  }
20516
20867
  return {};
20517
20868
  }
20518
- async function parseAgents(agentsDir) {
20869
+ async function parseAgents(agentsDir, opts = {}) {
20519
20870
  const files = await readDirRecursive(agentsDir);
20520
20871
  const mdFiles = files.filter((f) => f.endsWith(".md") && !basename(f).startsWith("_"));
20872
+ warnIfUnrecognizedResourceFormats("agents", agentsDir, files, mdFiles, {
20873
+ handledByOtherReader: opts.handledByOtherReader
20874
+ });
20521
20875
  assertNoBasenameCollisions("agent", mdFiles, ".md");
20522
20876
  const agents = [];
20523
20877
  for (const path of mdFiles) {
20524
20878
  const content = await readFileSafe(path);
20525
20879
  if (!content) continue;
20526
- const { frontmatter, body } = parseFrontmatter(content);
20880
+ const parsed = parseOrSkipFrontmatter(content, path, opts.onParseError);
20881
+ if (!parsed) continue;
20882
+ const { frontmatter, body } = parsed;
20527
20883
  const name = basename(path, ".md");
20528
20884
  assertCanonicalName("agent", name);
20529
20885
  const toolsCamel = toStrArray2(frontmatter.tools);
@@ -20562,11 +20918,18 @@ async function parseAgents(agentsDir) {
20562
20918
  // src/canonical/features/skills.ts
20563
20919
  init_fs();
20564
20920
  init_markdown();
20921
+ init_boilerplate_filter();
20565
20922
  async function readContent(path) {
20566
20923
  const c2 = await readFileSafe(path);
20567
20924
  return c2 ?? "";
20568
20925
  }
20569
20926
  var SKILL_FILE = "SKILL.md";
20927
+ var DOC_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".mdx", ".rst", ".txt"]);
20928
+ function isMarkdownLikeDoc(name) {
20929
+ const dot = name.lastIndexOf(".");
20930
+ if (dot < 0) return true;
20931
+ return DOC_EXTENSIONS.has(name.slice(dot).toLowerCase());
20932
+ }
20570
20933
  var EXCLUDED_DIR_PREFIXES = [".git", "node_modules"];
20571
20934
  function sanitizeSkillName(raw) {
20572
20935
  return raw.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
@@ -20581,16 +20944,20 @@ async function listSupportingFiles(skillDir) {
20581
20944
  const firstSegment = name.split("/")[0];
20582
20945
  if (EXCLUDED_DIR_PREFIXES.some((p) => firstSegment === p)) continue;
20583
20946
  if (name === ".DS_Store" || name.endsWith("/.DS_Store")) continue;
20947
+ const baseName = name.includes("/") ? name.slice(name.lastIndexOf("/") + 1) : name;
20948
+ if (isMarkdownLikeDoc(baseName) && isNoiseBoilerplate(baseName)) continue;
20584
20949
  const content = await readContent(absPath);
20585
20950
  result.push({ relativePath: name, absolutePath: absPath, content });
20586
20951
  }
20587
20952
  return result.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
20588
20953
  }
20589
- async function parseSkillDirectory(skillDir) {
20954
+ async function parseSkillDirectory(skillDir, opts = {}) {
20590
20955
  const skillPath = join(skillDir, SKILL_FILE);
20591
20956
  const content = await readFileSafe(skillPath);
20592
20957
  if (!content) return null;
20593
- const { frontmatter, body } = parseFrontmatter(content);
20958
+ const parsed = parseOrSkipFrontmatter(content, skillPath, opts.onParseError);
20959
+ if (!parsed) return null;
20960
+ const { frontmatter, body } = parsed;
20594
20961
  const supportingFiles = await listSupportingFiles(skillDir);
20595
20962
  const fmName = typeof frontmatter.name === "string" ? sanitizeSkillName(frontmatter.name) : "";
20596
20963
  const name = fmName || basename(skillDir);
@@ -20603,7 +20970,7 @@ async function parseSkillDirectory(skillDir) {
20603
20970
  supportingFiles
20604
20971
  };
20605
20972
  }
20606
- async function parseSkills(skillsDir) {
20973
+ async function parseSkills(skillsDir, opts = {}) {
20607
20974
  let entries;
20608
20975
  try {
20609
20976
  entries = await readdir(skillsDir, { withFileTypes: true });
@@ -20619,7 +20986,9 @@ async function parseSkills(skillsDir) {
20619
20986
  const skillPath = join(skillDir, SKILL_FILE);
20620
20987
  const content = await readFileSafe(skillPath);
20621
20988
  if (!content) continue;
20622
- const { frontmatter, body } = parseFrontmatter(content);
20989
+ const parsed = parseOrSkipFrontmatter(content, skillPath, opts.onParseError);
20990
+ if (!parsed) continue;
20991
+ const { frontmatter, body } = parsed;
20623
20992
  const supportingFiles = await listSupportingFiles(skillDir);
20624
20993
  skills.push({
20625
20994
  source: skillPath,
@@ -20824,14 +21193,14 @@ async function parseIgnore(ignorePath) {
20824
21193
 
20825
21194
  // src/canonical/load/loader.ts
20826
21195
  init_fs();
20827
- async function loadCanonicalFiles(canonicalDirOrProjectRoot) {
21196
+ async function loadCanonicalFiles(canonicalDirOrProjectRoot, opts = {}) {
20828
21197
  const nestedCanonicalDir = join(canonicalDirOrProjectRoot, ".agentsmesh");
20829
21198
  const canonicalDir = await exists(nestedCanonicalDir) ? nestedCanonicalDir : canonicalDirOrProjectRoot;
20830
21199
  const [rules, commands, agents, skills, mcp, permissions, hooks, ignore] = await Promise.all([
20831
- parseRules(join(canonicalDir, "rules")),
20832
- parseCommands(join(canonicalDir, "commands")),
20833
- parseAgents(join(canonicalDir, "agents")),
20834
- parseSkills(join(canonicalDir, "skills")),
21200
+ parseRules(join(canonicalDir, "rules"), opts),
21201
+ parseCommands(join(canonicalDir, "commands"), opts),
21202
+ parseAgents(join(canonicalDir, "agents"), opts),
21203
+ parseSkills(join(canonicalDir, "skills"), opts),
20835
21204
  parseMcp(join(canonicalDir, "mcp.json")),
20836
21205
  parsePermissions(join(canonicalDir, "permissions.yaml")),
20837
21206
  parseHooks(join(canonicalDir, "hooks.yaml")),
@@ -20934,132 +21303,57 @@ function mergeIgnore(base, overlay) {
20934
21303
 
20935
21304
  // src/config/resolve/native-format-detector.ts
20936
21305
  init_fs();
20937
- var TARGET_SIGNATURES = [
20938
- {
20939
- target: "claude-code",
20940
- paths: [
20941
- "CLAUDE.md",
20942
- ".claude/rules",
20943
- ".claude/commands",
20944
- ".claude/agents",
20945
- ".claude/skills",
20946
- ".claude/settings.json",
20947
- ".claudeignore"
20948
- ]
20949
- },
20950
- {
20951
- target: "cursor",
20952
- paths: [".cursorrules", ".cursor/rules", ".cursor", ".cursor/mcp.json"]
20953
- },
20954
- {
20955
- target: "copilot",
20956
- paths: [
20957
- ".github/copilot-instructions.md",
20958
- ".github/copilot",
20959
- ".github/instructions",
20960
- ".github/prompts",
20961
- ".github/skills",
20962
- ".github/agents",
20963
- ".github/hooks"
20964
- ]
20965
- },
20966
- {
20967
- target: "gemini-cli",
20968
- paths: ["GEMINI.md", ".gemini", ".gemini/settings.json"]
20969
- },
20970
- {
20971
- target: "codex-cli",
20972
- paths: [".codex", ".codex/config.toml", "AGENTS.md", "codex.md"]
20973
- },
20974
- {
20975
- target: "windsurf",
20976
- paths: [".windsurfrules", ".windsurf", ".windsurf/workflows"]
20977
- },
20978
- {
20979
- target: "cline",
20980
- paths: [".clinerules", ".cline"]
20981
- },
20982
- {
20983
- target: "continue",
20984
- paths: [".continue", ".continuerc.json"]
20985
- },
20986
- {
20987
- target: "junie",
20988
- paths: [".junie", ".junie/guidelines.md"]
20989
- },
20990
- {
20991
- target: "kiro",
20992
- paths: [".kiro", ".kiro/steering", ".kiro/settings/mcp.json"]
20993
- },
20994
- {
20995
- target: "kilo-code",
20996
- paths: [
20997
- ".kilo",
20998
- ".kilo/rules",
20999
- ".kilo/commands",
21000
- ".kilo/agents",
21001
- ".kilo/skills",
21002
- ".kilocodeignore",
21003
- ".kilocode",
21004
- ".kilocodemodes",
21005
- "kilo.jsonc",
21006
- "kilo.json"
21007
- ]
21306
+ init_builtin_targets();
21307
+ var PATH_OWNER_COUNT = (() => {
21308
+ const map = /* @__PURE__ */ new Map();
21309
+ for (const d of BUILTIN_TARGETS) {
21310
+ for (const p of d.detectionPaths) {
21311
+ map.set(p, (map.get(p) ?? 0) + 1);
21312
+ }
21008
21313
  }
21009
- ];
21314
+ return map;
21315
+ })();
21316
+ function compare(a, b) {
21317
+ if (a.uniqueHits !== b.uniqueHits) return b.uniqueHits - a.uniqueHits;
21318
+ if (a.sharedScore !== b.sharedScore) return b.sharedScore - a.sharedScore;
21319
+ return a.id.localeCompare(b.id);
21320
+ }
21010
21321
  async function detectNativeFormat(repoPath) {
21011
- let bestTarget = null;
21012
- let bestScore = 0;
21013
- for (const sig of TARGET_SIGNATURES) {
21014
- let score = 0;
21015
- for (const rel2 of sig.paths) {
21016
- if (await exists(join(repoPath, rel2))) score++;
21322
+ const scores = [];
21323
+ for (const descriptor31 of BUILTIN_TARGETS) {
21324
+ let uniqueHits = 0;
21325
+ let sharedScore = 0;
21326
+ for (const rel2 of descriptor31.detectionPaths) {
21327
+ if (!await exists(join(repoPath, rel2))) continue;
21328
+ const owners = PATH_OWNER_COUNT.get(rel2) ?? 1;
21329
+ if (owners === 1) uniqueHits += 1;
21330
+ else sharedScore += 1 / owners;
21017
21331
  }
21018
- if (score > bestScore) {
21019
- bestScore = score;
21020
- bestTarget = sig.target;
21332
+ if (uniqueHits > 0 || sharedScore > 0) {
21333
+ scores.push({ id: descriptor31.id, uniqueHits, sharedScore });
21021
21334
  }
21022
21335
  }
21023
- return bestScore > 0 ? bestTarget : null;
21336
+ if (scores.length === 0) return null;
21337
+ scores.sort(compare);
21338
+ const winner = scores[0];
21339
+ if (winner.uniqueHits === 0) return null;
21340
+ return winner.id;
21024
21341
  }
21025
- var KNOWN_NATIVE_PATHS = TARGET_SIGNATURES.map((sig) => sig.paths[0]).filter(
21026
- (p) => p !== void 0
21027
- );
21342
+ var KNOWN_NATIVE_PATHS = BUILTIN_TARGETS.map(
21343
+ (d) => d.detectionPaths[0]
21344
+ ).filter((p) => p !== void 0);
21028
21345
 
21029
21346
  // src/canonical/extends/extend-load.ts
21030
21347
  init_fs();
21031
21348
 
21032
21349
  // src/canonical/extends/native-extends-importer.ts
21033
- init_importer6();
21034
- init_importer12();
21035
- init_importer10();
21036
- init_importer15();
21037
- init_importer8();
21038
- init_importer29();
21039
- init_importer7();
21040
- init_importer9();
21041
- init_importer18();
21042
- init_importer20();
21043
- init_importer19();
21044
- var NATIVE_IMPORTERS = {
21045
- "claude-code": importFromClaudeCode,
21046
- cursor: importFromCursor,
21047
- copilot: importFromCopilot,
21048
- "gemini-cli": importFromGemini,
21049
- "codex-cli": importFromCodex,
21050
- windsurf: importFromWindsurf,
21051
- cline: importFromCline,
21052
- continue: importFromContinue,
21053
- junie: importFromJunie,
21054
- kiro: importFromKiro,
21055
- "kilo-code": importFromKiloCode
21056
- };
21350
+ init_registry();
21057
21351
  async function importNativeToCanonical(repoPath, targetName) {
21058
- const importFn = NATIVE_IMPORTERS[targetName];
21059
- if (!importFn) {
21352
+ const descriptor31 = getDescriptor(targetName);
21353
+ if (!descriptor31) {
21060
21354
  throw new Error(`No importer registered for native target: ${targetName}`);
21061
21355
  }
21062
- return importFn(repoPath);
21356
+ return descriptor31.generators.importFrom(repoPath);
21063
21357
  }
21064
21358
 
21065
21359
  // src/canonical/load/skill-pack-load.ts
@@ -21079,17 +21373,176 @@ async function isSkillPackLayout(root) {
21079
21373
  }
21080
21374
  return false;
21081
21375
  }
21082
- async function loadSkillsAtExtendPath(skillsRoot) {
21376
+ async function loadSkillsAtExtendPath(skillsRoot, opts = {}) {
21083
21377
  if (!await exists(skillsRoot)) return [];
21084
21378
  if (await exists(join(skillsRoot, SKILL))) {
21085
- const one = await parseSkillDirectory(skillsRoot);
21379
+ const one = await parseSkillDirectory(skillsRoot, opts);
21086
21380
  return one ? [one] : [];
21087
21381
  }
21088
- return parseSkills(skillsRoot);
21382
+ return parseSkills(skillsRoot, opts);
21089
21383
  }
21090
21384
 
21091
21385
  // src/canonical/load/load-canonical-slice.ts
21092
21386
  init_fs();
21387
+ init_boilerplate_filter();
21388
+ async function importAgents(agentsDir, opts = {}) {
21389
+ const agents = await parseAgents(agentsDir, opts);
21390
+ return agents.filter((entity) => !isBoilerplate(basename(entity.source)));
21391
+ }
21392
+ async function importCommands2(commandsDir, opts = {}) {
21393
+ const commands = await parseCommands(commandsDir, opts);
21394
+ return commands.filter((entity) => !isBoilerplate(basename(entity.source)));
21395
+ }
21396
+ async function importRules2(rulesDir, opts = {}) {
21397
+ const rules = await parseRules(rulesDir, opts);
21398
+ return rules.filter((entity) => !isBoilerplate(basename(entity.source)));
21399
+ }
21400
+ init_fs();
21401
+ init_registry();
21402
+ init_boilerplate_filter();
21403
+ function directorySpecsFor(importer, kind) {
21404
+ const raw = importer?.[kind];
21405
+ if (!raw) return [];
21406
+ const specs = Array.isArray(raw) ? raw : [raw];
21407
+ const out2 = [];
21408
+ for (const s of specs) {
21409
+ if (s.mode !== "directory" || !s.map || !s.extensions) continue;
21410
+ out2.push({ extensions: s.extensions, map: s.map });
21411
+ }
21412
+ return out2;
21413
+ }
21414
+ function isMarkdownExtension(ext) {
21415
+ return ext.toLowerCase().endsWith(".md");
21416
+ }
21417
+ function hasNonMdEntityMapper(targetId, kind) {
21418
+ for (const spec of directorySpecsFor(getDescriptor(targetId)?.importer, kind)) {
21419
+ if (spec.extensions.some((ext) => !isMarkdownExtension(ext))) return true;
21420
+ }
21421
+ return false;
21422
+ }
21423
+ function nonMdEntityExtensions(targetId, kind) {
21424
+ const out2 = /* @__PURE__ */ new Set();
21425
+ for (const spec of directorySpecsFor(getDescriptor(targetId)?.importer, kind)) {
21426
+ for (const ext of spec.extensions) {
21427
+ if (!isMarkdownExtension(ext)) out2.add(ext.toLowerCase());
21428
+ }
21429
+ }
21430
+ return out2;
21431
+ }
21432
+ function targetsWithNonMdEntityMapper(kind) {
21433
+ return getAllRegisteredDescriptorIds().filter((id) => hasNonMdEntityMapper(id, kind));
21434
+ }
21435
+ var CANONICAL_PARSERS = {
21436
+ rules: parseRules,
21437
+ commands: parseCommands,
21438
+ agents: parseAgents
21439
+ };
21440
+ var INSTALL_IMPORTERS = {
21441
+ rules: importRules2,
21442
+ commands: importCommands2,
21443
+ agents: importAgents
21444
+ };
21445
+ async function parseEntityDir(kind, dir, opts) {
21446
+ return CANONICAL_PARSERS[kind](dir, opts);
21447
+ }
21448
+ async function importEntities(kind, dir, opts) {
21449
+ return INSTALL_IMPORTERS[kind](dir, opts);
21450
+ }
21451
+ async function readToolNativeEntities(srcDir, targetId, kind, parseOpts = {}) {
21452
+ const specs = directorySpecsFor(getDescriptor(targetId)?.importer, kind);
21453
+ const allFiles = await readDirRecursive(srcDir);
21454
+ const nonMdExtensions = /* @__PURE__ */ new Set();
21455
+ for (const spec of specs) {
21456
+ for (const ext of spec.extensions) {
21457
+ if (!isMarkdownExtension(ext)) nonMdExtensions.add(ext.toLowerCase());
21458
+ }
21459
+ }
21460
+ const matched = allFiles.filter(
21461
+ (path) => [...nonMdExtensions].some((ext) => path.toLowerCase().endsWith(ext)) && !isBoilerplate(basename(path))
21462
+ );
21463
+ if (matched.length === 0) return { entities: [], cleanup: async () => {
21464
+ } };
21465
+ const stageDir = await mkdtemp(join(tmpdir(), `am-tool-${kind}-${targetId}-`));
21466
+ const cleanup = async () => {
21467
+ await rm(stageDir, { recursive: true, force: true });
21468
+ };
21469
+ try {
21470
+ for (const absPath of matched) {
21471
+ const content = await readFileSafe(absPath);
21472
+ if (content === null) continue;
21473
+ const relPath = relative(srcDir, absPath).replaceAll("\\", "/");
21474
+ let mapping = null;
21475
+ for (const spec of specs) {
21476
+ const claimsExt = spec.extensions.some(
21477
+ (e) => absPath.toLowerCase().endsWith(e.toLowerCase())
21478
+ );
21479
+ if (!claimsExt) continue;
21480
+ const r = await spec.map({
21481
+ absolutePath: absPath,
21482
+ relativePath: relPath,
21483
+ content,
21484
+ destDir: stageDir,
21485
+ normalizeTo: () => content
21486
+ });
21487
+ if (r) {
21488
+ mapping = r;
21489
+ break;
21490
+ }
21491
+ }
21492
+ if (!mapping) continue;
21493
+ await mkdirp(dirname(mapping.destPath));
21494
+ await writeFileAtomic(mapping.destPath, mapping.content);
21495
+ }
21496
+ const entities = await parseEntityDir(kind, stageDir, parseOpts);
21497
+ return { entities, cleanup };
21498
+ } catch (err) {
21499
+ await cleanup();
21500
+ throw err;
21501
+ }
21502
+ }
21503
+ async function readEntityDirWithMappers(srcDir, kind, opts = {}) {
21504
+ const restrict = opts.restrictToTarget;
21505
+ const targets = restrict ? hasNonMdEntityMapper(restrict, kind) ? [restrict] : [] : targetsWithNonMdEntityMapper(kind);
21506
+ const handledExts = /* @__PURE__ */ new Set();
21507
+ for (const id of targets) {
21508
+ for (const ext of nonMdEntityExtensions(id, kind)) handledExts.add(ext);
21509
+ }
21510
+ const canonical = await importEntities(kind, srcDir, {
21511
+ ...opts.parseOpts,
21512
+ handledByOtherReader: handledExts.size > 0 ? handledExts : void 0
21513
+ });
21514
+ const cleanups = [];
21515
+ const slugOf = (e) => basename(e.source).replace(/\.[^.]+$/, "");
21516
+ const byKey = /* @__PURE__ */ new Map();
21517
+ for (const e of canonical) byKey.set(slugOf(e), e);
21518
+ for (const id of targets) {
21519
+ const staged = await readToolNativeEntities(srcDir, id, kind, opts.parseOpts ?? {});
21520
+ cleanups.push(staged.cleanup);
21521
+ for (const e of staged.entities) {
21522
+ const key = slugOf(e);
21523
+ if (!byKey.has(key)) byKey.set(key, e);
21524
+ }
21525
+ }
21526
+ const entities = [...byKey.values()].sort((a, b) => slugOf(a).localeCompare(slugOf(b)));
21527
+ const cleanup = async () => {
21528
+ await Promise.allSettled(cleanups.map((fn) => fn()));
21529
+ };
21530
+ return { entities, cleanup };
21531
+ }
21532
+ async function readCommandsDirWithMappers(srcDir, opts = {}) {
21533
+ const result = await readEntityDirWithMappers(srcDir, "commands", opts);
21534
+ return { commands: [...result.entities], cleanup: result.cleanup };
21535
+ }
21536
+ async function readRulesDirWithMappers(srcDir, opts = {}) {
21537
+ const result = await readEntityDirWithMappers(srcDir, "rules", opts);
21538
+ return { rules: [...result.entities], cleanup: result.cleanup };
21539
+ }
21540
+ async function readAgentsDirWithMappers(srcDir, opts = {}) {
21541
+ const result = await readEntityDirWithMappers(srcDir, "agents", opts);
21542
+ return { agents: [...result.entities], cleanup: result.cleanup };
21543
+ }
21544
+
21545
+ // src/canonical/load/load-canonical-slice.ts
21093
21546
  function emptyCanonical() {
21094
21547
  return {
21095
21548
  rules: [],
@@ -21135,65 +21588,350 @@ async function normalizeSlicePath(absolutePath) {
21135
21588
  `Single-file install only supports .md files under rules/, commands/, or agents/. Got: ${absolutePath}`
21136
21589
  );
21137
21590
  }
21138
- async function parseRulesAt(sliceRoot) {
21139
- const base = basename(sliceRoot);
21140
- if (base === "rules") {
21141
- return parseRules(sliceRoot);
21142
- }
21143
- const nested = join(sliceRoot, "rules");
21144
- if (await exists(nested)) {
21145
- return parseRules(nested);
21146
- }
21147
- return [];
21591
+ async function resolveEntityDir(sliceRoot, kindDirName) {
21592
+ if (basename(sliceRoot) === kindDirName) return sliceRoot;
21593
+ const nested = join(sliceRoot, kindDirName);
21594
+ return await exists(nested) ? nested : null;
21148
21595
  }
21149
- async function parseCommandsAt(sliceRoot) {
21150
- const base = basename(sliceRoot);
21151
- if (base === "commands") {
21152
- return parseCommands(sliceRoot);
21153
- }
21154
- const nested = join(sliceRoot, "commands");
21155
- if (await exists(nested)) {
21156
- return parseCommands(nested);
21596
+ async function parseRulesAt(sliceRoot, opts, enableTargetMappers) {
21597
+ const noop = async () => {
21598
+ };
21599
+ const rulesDir = await resolveEntityDir(sliceRoot, "rules");
21600
+ if (!rulesDir) return { rules: [], cleanup: noop };
21601
+ if (!enableTargetMappers) {
21602
+ return { rules: await importRules2(rulesDir, opts), cleanup: noop };
21157
21603
  }
21158
- return [];
21604
+ const result = await readRulesDirWithMappers(rulesDir, { parseOpts: opts });
21605
+ return { rules: [...result.rules], cleanup: result.cleanup };
21159
21606
  }
21160
- async function parseAgentsAt(sliceRoot) {
21161
- const base = basename(sliceRoot);
21162
- if (base === "agents") {
21163
- return parseAgents(sliceRoot);
21607
+ async function parseCommandsAt(sliceRoot, opts, enableTargetMappers) {
21608
+ const noop = async () => {
21609
+ };
21610
+ const commandsDir = await resolveEntityDir(sliceRoot, "commands");
21611
+ if (!commandsDir) return { commands: [], cleanup: noop };
21612
+ if (!enableTargetMappers) {
21613
+ return { commands: await importCommands2(commandsDir, opts), cleanup: noop };
21164
21614
  }
21165
- const nested = join(sliceRoot, "agents");
21166
- if (await exists(nested)) {
21167
- return parseAgents(nested);
21615
+ const result = await readCommandsDirWithMappers(commandsDir, { parseOpts: opts });
21616
+ return { commands: [...result.commands], cleanup: result.cleanup };
21617
+ }
21618
+ async function parseAgentsAt(sliceRoot, opts, enableTargetMappers) {
21619
+ const noop = async () => {
21620
+ };
21621
+ const agentsDir = await resolveEntityDir(sliceRoot, "agents");
21622
+ if (!agentsDir) return { agents: [], cleanup: noop };
21623
+ if (!enableTargetMappers) {
21624
+ return { agents: await importAgents(agentsDir, opts), cleanup: noop };
21168
21625
  }
21169
- return [];
21626
+ const result = await readAgentsDirWithMappers(agentsDir, { parseOpts: opts });
21627
+ return { agents: [...result.agents], cleanup: result.cleanup };
21170
21628
  }
21171
- async function loadSkillsForPartialSlice(sliceRoot) {
21629
+ async function loadSkillsForPartialSlice(sliceRoot, opts) {
21172
21630
  if (await isSkillPackLayout(sliceRoot)) {
21173
- return loadSkillsAtExtendPath(sliceRoot);
21631
+ return loadSkillsAtExtendPath(sliceRoot, opts);
21174
21632
  }
21175
21633
  const nestedSkills = join(sliceRoot, "skills");
21176
21634
  if (await isSkillPackLayout(nestedSkills)) {
21177
- return loadSkillsAtExtendPath(nestedSkills);
21635
+ return loadSkillsAtExtendPath(nestedSkills, opts);
21178
21636
  }
21179
21637
  return [];
21180
21638
  }
21181
- async function loadCanonicalSliceAtPath(sliceRoot) {
21639
+ async function loadCanonicalSliceAtPath(sliceRoot, opts = {}) {
21640
+ const noop = async () => {
21641
+ };
21182
21642
  const ab = join(sliceRoot, ".agentsmesh");
21183
21643
  if (await exists(ab)) {
21184
- return loadCanonicalFiles(sliceRoot);
21644
+ return { canonical: await loadCanonicalFiles(sliceRoot, opts), cleanup: noop };
21185
21645
  }
21646
+ const enableMappers = opts.enableTargetEntityMappers ?? false;
21186
21647
  const partial = emptyCanonical();
21187
- partial.rules = await parseRulesAt(sliceRoot);
21188
- partial.commands = await parseCommandsAt(sliceRoot);
21189
- partial.agents = await parseAgentsAt(sliceRoot);
21190
- partial.skills = await loadSkillsForPartialSlice(sliceRoot);
21648
+ const rulesResult = await parseRulesAt(sliceRoot, opts, enableMappers);
21649
+ partial.rules = rulesResult.rules;
21650
+ const commandsResult = await parseCommandsAt(sliceRoot, opts, enableMappers);
21651
+ partial.commands = commandsResult.commands;
21652
+ const agentsResult = await parseAgentsAt(sliceRoot, opts, enableMappers);
21653
+ partial.agents = agentsResult.agents;
21654
+ partial.skills = await loadSkillsForPartialSlice(sliceRoot, opts);
21655
+ const mergedCleanup = async () => {
21656
+ await Promise.allSettled([
21657
+ rulesResult.cleanup(),
21658
+ commandsResult.cleanup(),
21659
+ agentsResult.cleanup()
21660
+ ]);
21661
+ };
21191
21662
  if (isCanonicalSliceEmpty(partial)) {
21663
+ await mergedCleanup();
21664
+ throw new Error(
21665
+ `No installable resources at ${sliceRoot}. Expected .agentsmesh/, or rules/, commands/, agents/, or Anthropic-style skills (SKILL.md). Hint: pass --as commands|agents|rules|skills to force a kind for flat markdown directories.`
21666
+ );
21667
+ }
21668
+ return { canonical: partial, cleanup: mergedCleanup };
21669
+ }
21670
+
21671
+ // src/install/manual/manual-install-scope.ts
21672
+ init_fs();
21673
+
21674
+ // src/install/source/skill-repo-filter.ts
21675
+ init_fs();
21676
+ init_markdown();
21677
+ init_boilerplate_filter();
21678
+ async function readSkillFrontmatterName(skillMdPath) {
21679
+ const content = await readFileSafe(skillMdPath);
21680
+ if (!content) return "";
21681
+ const parsed = tryParseFrontmatter(content, skillMdPath);
21682
+ if (!parsed.ok) return "";
21683
+ const { frontmatter } = parsed.value;
21684
+ if (typeof frontmatter.name !== "string") return "";
21685
+ return frontmatter.name.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
21686
+ }
21687
+ async function cpFilteredSkill(sourceRoot, destDir) {
21688
+ await cp(sourceRoot, destDir, {
21689
+ recursive: true,
21690
+ filter: (src) => {
21691
+ const rel2 = relative(sourceRoot, src).replace(/\\/g, "/");
21692
+ if (rel2 === "") return true;
21693
+ const first = rel2.split("/")[0];
21694
+ if (isRepoNonContentDir(first)) return false;
21695
+ if (!rel2.includes("/")) {
21696
+ if (isNoiseBoilerplate(rel2)) return false;
21697
+ if (isRepoNonContentFile(rel2)) return false;
21698
+ }
21699
+ return true;
21700
+ }
21701
+ });
21702
+ }
21703
+
21704
+ // src/install/manual/manual-install-scope.ts
21705
+ init_boilerplate_filter();
21706
+
21707
+ // src/install/manual/mdc-reader.ts
21708
+ init_markdown();
21709
+ function toStrArray3(v) {
21710
+ if (Array.isArray(v)) return v.filter((x) => typeof x === "string");
21711
+ if (typeof v === "string") return v ? [v] : [];
21712
+ return [];
21713
+ }
21714
+ function normalizeCursorKeys(fm) {
21715
+ const out2 = { ...fm };
21716
+ const isRoot = fm.alwaysApply === true;
21717
+ out2.root = isRoot;
21718
+ delete out2.alwaysApply;
21719
+ if (!isRoot) {
21720
+ const globs = toStrArray3(fm.globs);
21721
+ const description = typeof fm.description === "string" ? fm.description.trim() : "";
21722
+ if (globs.length > 0) {
21723
+ out2.trigger = "glob";
21724
+ } else if (description.length > 0) {
21725
+ out2.trigger = "model_decision";
21726
+ } else {
21727
+ out2.trigger = "manual";
21728
+ }
21729
+ }
21730
+ return out2;
21731
+ }
21732
+ function normalizeWindsurfKeys(fm) {
21733
+ const out2 = { ...fm };
21734
+ if (out2.trigger === "always") {
21735
+ out2.trigger = "always_on";
21736
+ }
21737
+ if (typeof out2.glob === "string") {
21738
+ out2.globs = toStrArray3(out2.globs).length > 0 ? toStrArray3(out2.globs) : [out2.glob];
21739
+ delete out2.glob;
21740
+ }
21741
+ return out2;
21742
+ }
21743
+ function normalizeMdcToCanonical(content) {
21744
+ const parsed = tryParseFrontmatter(content, "<mdc>");
21745
+ if (!parsed.ok) return parsed.bodyFallback;
21746
+ const { frontmatter, body } = parsed.value;
21747
+ if (Object.keys(frontmatter).length === 0 && !content.startsWith("---")) return content;
21748
+ let normalized;
21749
+ if ("alwaysApply" in frontmatter) {
21750
+ normalized = normalizeCursorKeys(frontmatter);
21751
+ } else if ("trigger" in frontmatter || "glob" in frontmatter) {
21752
+ normalized = normalizeWindsurfKeys(frontmatter);
21753
+ } else {
21754
+ normalized = frontmatter;
21755
+ }
21756
+ return serializeFrontmatter(normalized, body.trim());
21757
+ }
21758
+ function sanitizeNameSegment(segment) {
21759
+ return segment.toLowerCase().replace(/[^a-z0-9.-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
21760
+ }
21761
+ function computeDestName(file) {
21762
+ const isMdc = file.toLowerCase().endsWith(".mdc");
21763
+ return isMdc ? basename(file).replace(/\.mdc$/i, ".md") : basename(file);
21764
+ }
21765
+ function namespacedName(sourceRoot, file, bareName) {
21766
+ const rel2 = relative(sourceRoot, file).replace(/\\/g, "/");
21767
+ const segments = rel2.split("/");
21768
+ segments.pop();
21769
+ if (segments.length === 0) return bareName;
21770
+ const prefix = sanitizeNameSegment(segments[segments.length - 1]);
21771
+ if (!prefix) return bareName;
21772
+ return `${prefix}-${bareName}`;
21773
+ }
21774
+
21775
+ // src/install/manual/manual-install-scope.ts
21776
+ async function createStageRoot() {
21777
+ const stageBase = await mkdtemp(join(tmpdir(), "am-install-manual-"));
21778
+ const discoveryRoot = join(stageBase, "repo");
21779
+ await mkdirp(join(discoveryRoot, ".agentsmesh"));
21780
+ return {
21781
+ discoveryRoot,
21782
+ cleanup: async () => {
21783
+ await rm(stageBase, { recursive: true, force: true });
21784
+ }
21785
+ };
21786
+ }
21787
+ function isAcceptedFile(file, acceptMdc) {
21788
+ const lower = file.toLowerCase();
21789
+ if (lower.endsWith(".md")) return true;
21790
+ if (acceptMdc && lower.endsWith(".mdc")) return true;
21791
+ return false;
21792
+ }
21793
+ async function stageSingleFile(sourcePath, destinationDir, acceptMdc) {
21794
+ if (!isAcceptedFile(sourcePath, acceptMdc)) {
21795
+ throw new Error(`Manual install only supports .md files for this collection: ${sourcePath}`);
21796
+ }
21797
+ await mkdirp(destinationDir);
21798
+ if (sourcePath.toLowerCase().endsWith(".mdc")) {
21799
+ const content = await readFileSafe(sourcePath);
21800
+ if (!content) return;
21801
+ const destName = basename(sourcePath).replace(/\.mdc$/i, ".md");
21802
+ await writeFile(join(destinationDir, destName), normalizeMdcToCanonical(content));
21803
+ } else {
21804
+ await cp(sourcePath, join(destinationDir, basename(sourcePath)));
21805
+ }
21806
+ }
21807
+ async function stageMarkdownCollection(sourceRoot, destinationDir, acceptMdc) {
21808
+ const info = await stat(sourceRoot);
21809
+ if (info.isFile()) return stageSingleFile(sourceRoot, destinationDir, acceptMdc);
21810
+ const files = (await readDirRecursive(sourceRoot)).filter(
21811
+ (file) => isAcceptedFile(file, acceptMdc) && !isBoilerplate(basename(file))
21812
+ );
21813
+ if (files.length === 0) {
21192
21814
  throw new Error(
21193
- `No installable resources at ${sliceRoot}. Expected .agentsmesh/, or rules/, commands/, agents/, or Anthropic-style skills (SKILL.md).`
21815
+ `No installable files found under ${sourceRoot} for manual install. Try a different --path to point at the directory holding *.md (or *.mdc) files, or omit --as so agentsmesh can auto-detect the layout.`
21194
21816
  );
21195
21817
  }
21196
- return partial;
21818
+ const bareCounts = /* @__PURE__ */ new Map();
21819
+ for (const file of files) {
21820
+ const name = computeDestName(file);
21821
+ bareCounts.set(name, (bareCounts.get(name) ?? 0) + 1);
21822
+ }
21823
+ const usedNames = /* @__PURE__ */ new Map();
21824
+ await mkdirp(destinationDir);
21825
+ for (const file of files) {
21826
+ const bare = computeDestName(file);
21827
+ const hasCollision = (bareCounts.get(bare) ?? 0) > 1;
21828
+ let destName = hasCollision ? namespacedName(sourceRoot, file, bare) : bare;
21829
+ if (usedNames.has(destName) && usedNames.get(destName) !== file) {
21830
+ const rel2 = relative(sourceRoot, file).replace(/\\/g, "/").split("/").map(sanitizeNameSegment).filter(Boolean);
21831
+ const ext = bare.includes(".") ? "." + bare.split(".").pop() : "";
21832
+ const stem = rel2.join("-").replace(/\.(md|mdc)$/i, "");
21833
+ destName = stem + ext || destName;
21834
+ }
21835
+ if (usedNames.has(destName)) {
21836
+ throw new Error(
21837
+ `Manual install could not resolve duplicate name "${destName}" under ${sourceRoot} (${usedNames.get(destName)} and ${file}).`
21838
+ );
21839
+ }
21840
+ usedNames.set(destName, file);
21841
+ const isMdc = file.toLowerCase().endsWith(".mdc");
21842
+ if (isMdc) {
21843
+ const content = await readFileSafe(file);
21844
+ if (!content) continue;
21845
+ await writeFile(join(destinationDir, destName), normalizeMdcToCanonical(content));
21846
+ } else {
21847
+ await cp(file, join(destinationDir, destName));
21848
+ }
21849
+ }
21850
+ }
21851
+ async function stagePreferredSkills(sourceRoot, destinationDir, preferredSkillNames) {
21852
+ if (preferredSkillNames.length === 0) {
21853
+ return false;
21854
+ }
21855
+ const wanted = new Set(preferredSkillNames);
21856
+ const matches = /* @__PURE__ */ new Map();
21857
+ for (const file of await readDirRecursive(sourceRoot)) {
21858
+ if (!file.endsWith("/SKILL.md") && !file.endsWith("\\SKILL.md")) continue;
21859
+ const skillDir = dirname(file);
21860
+ const skillName = basename(skillDir);
21861
+ if (!wanted.has(skillName)) continue;
21862
+ const previous = matches.get(skillName);
21863
+ if (previous && previous !== skillDir) {
21864
+ throw new Error(
21865
+ `Manual skill replay found duplicate skill "${skillName}" under ${sourceRoot} (${previous} and ${skillDir}).`
21866
+ );
21867
+ }
21868
+ matches.set(skillName, skillDir);
21869
+ }
21870
+ if (matches.size !== preferredSkillNames.length) return false;
21871
+ await mkdirp(destinationDir);
21872
+ for (const skillName of preferredSkillNames) {
21873
+ await cp(matches.get(skillName), join(destinationDir, skillName), { recursive: true });
21874
+ }
21875
+ return true;
21876
+ }
21877
+ async function stageSkills(sourceRoot, destinationDir, options = {}) {
21878
+ const info = await stat(sourceRoot);
21879
+ if (info.isFile()) {
21880
+ if (basename(sourceRoot) !== "SKILL.md") {
21881
+ throw new Error(`Manual skill install expects SKILL.md or a skill directory: ${sourceRoot}`);
21882
+ }
21883
+ const skillName = basename(dirname(sourceRoot));
21884
+ const skillDir = join(destinationDir, skillName);
21885
+ await mkdirp(skillDir);
21886
+ await cp(dirname(sourceRoot), skillDir, { recursive: true });
21887
+ return;
21888
+ }
21889
+ if (await isSkillPackLayout(sourceRoot)) {
21890
+ if ((await stat(join(sourceRoot, "SKILL.md")).catch(() => null))?.isFile()) {
21891
+ if (await stagePreferredSkills(sourceRoot, destinationDir, options.preferredSkillNames ?? [])) {
21892
+ return;
21893
+ }
21894
+ const fmName = await readSkillFrontmatterName(join(sourceRoot, "SKILL.md"));
21895
+ const skillName = fmName || basename(sourceRoot);
21896
+ const skillDir = join(destinationDir, skillName);
21897
+ await mkdirp(destinationDir);
21898
+ await cpFilteredSkill(sourceRoot, skillDir);
21899
+ return;
21900
+ }
21901
+ if (await stagePreferredSkills(sourceRoot, destinationDir, options.preferredSkillNames ?? [])) {
21902
+ return;
21903
+ }
21904
+ await mkdirp(destinationDir);
21905
+ const entries = await readDirRecursive(sourceRoot);
21906
+ const roots = /* @__PURE__ */ new Set();
21907
+ for (const file of entries.filter(
21908
+ (entry) => entry.endsWith("/SKILL.md") || entry.endsWith("\\SKILL.md")
21909
+ )) {
21910
+ roots.add(relative(sourceRoot, dirname(file)).split(/[\\/]/)[0]);
21911
+ }
21912
+ for (const root of roots) {
21913
+ await cp(join(sourceRoot, root), join(destinationDir, root), { recursive: true });
21914
+ }
21915
+ return;
21916
+ }
21917
+ throw new Error(
21918
+ `Manual skill install expects a skill directory or skills collection at ${sourceRoot}.`
21919
+ );
21920
+ }
21921
+ async function stageManualInstallScope(sourceRoot, as, options = {}) {
21922
+ const staged = await createStageRoot();
21923
+ try {
21924
+ const destDir = join(staged.discoveryRoot, ".agentsmesh", as);
21925
+ if (as === "skills") {
21926
+ await stageSkills(sourceRoot, destDir, options);
21927
+ } else {
21928
+ await stageMarkdownCollection(sourceRoot, destDir, as === "rules");
21929
+ }
21930
+ return staged;
21931
+ } catch (error) {
21932
+ await staged.cleanup();
21933
+ throw error;
21934
+ }
21197
21935
  }
21198
21936
 
21199
21937
  // src/canonical/extends/extend-load.ts
@@ -21211,6 +21949,18 @@ function emptyCanonical2() {
21211
21949
  }
21212
21950
  async function loadCanonicalForExtend(ext) {
21213
21951
  const base = ext.resolvedPath;
21952
+ if (ext.as !== void 0) {
21953
+ const rawRoot2 = ext.path ? join(base, ext.path) : base;
21954
+ if (!await exists(rawRoot2)) {
21955
+ throw new Error(`Extend "${ext.name}": path does not exist: ${rawRoot2}`);
21956
+ }
21957
+ const staged = await stageManualInstallScope(rawRoot2, ext.as);
21958
+ try {
21959
+ return loadCanonicalFiles(join(staged.discoveryRoot, ".agentsmesh"));
21960
+ } finally {
21961
+ await staged.cleanup();
21962
+ }
21963
+ }
21214
21964
  if (!ext.path) {
21215
21965
  const agentsmeshDir = join(base, ".agentsmesh");
21216
21966
  if (!await exists(agentsmeshDir)) {
@@ -21248,7 +21998,8 @@ Expected one of: .agentsmesh/, ${KNOWN_NATIVE_PATHS.join(", ")}.`
21248
21998
  }
21249
21999
  const { sliceRoot } = await normalizeSlicePath(rawRoot);
21250
22000
  try {
21251
- return await loadCanonicalSliceAtPath(sliceRoot);
22001
+ const { canonical } = await loadCanonicalSliceAtPath(sliceRoot);
22002
+ return canonical;
21252
22003
  } catch (err) {
21253
22004
  const msg = err instanceof Error ? err.message : String(err);
21254
22005
  const wrapped = new Error(`Extend "${ext.name}": ${msg}`);
@@ -21334,7 +22085,15 @@ var packMetadataSchema = z.object({
21334
22085
  path: z.string().optional(),
21335
22086
  paths: z.array(z.string().min(1)).min(1).optional(),
21336
22087
  as: manualInstallAsSchema.optional(),
21337
- content_hash: z.string()
22088
+ content_hash: z.string(),
22089
+ /**
22090
+ * SPDX identifier of the LICENSE / NOTICE / COPYING file at the pack root,
22091
+ * or `null` when the file is missing or its text matches no known
22092
+ * fingerprint. Detected at materialize time from the upstream bytes — never
22093
+ * inferred from `package.json` or other secondary signals. See
22094
+ * `src/install/license/detect-license.ts`.
22095
+ */
22096
+ license: z.string().nullable().optional()
21338
22097
  });
21339
22098
 
21340
22099
  // src/install/pack/pack-reader.ts
@@ -21585,11 +22344,7 @@ var TARGET_CATALOG = Object.fromEntries(
21585
22344
  ])
21586
22345
  );
21587
22346
  function getTargetCatalogEntry(id) {
21588
- const entry = TARGET_CATALOG[id];
21589
- if (!entry) {
21590
- throw new Error(`Unknown target: ${id}`);
21591
- }
21592
- return entry;
22347
+ return TARGET_CATALOG[id];
21593
22348
  }
21594
22349
 
21595
22350
  // src/core/lint/linter.ts
@@ -21859,13 +22614,16 @@ function formatDiffSummary(summary) {
21859
22614
 
21860
22615
  // src/config/core/lock.ts
21861
22616
  init_fs();
22617
+
22618
+ // src/utils/crypto/hash.ts
22619
+ init_fs_text_encoding();
21862
22620
  function hashContent(content) {
21863
22621
  return createHash("sha256").update(content, "utf8").digest("hex");
21864
22622
  }
21865
22623
  async function hashFile(path) {
21866
22624
  try {
21867
- const content = await readFile(path, "utf8");
21868
- return hashContent(content);
22625
+ const bytes = await readFile(path);
22626
+ return createHash("sha256").update(bytes).digest("hex");
21869
22627
  } catch (err) {
21870
22628
  if (err instanceof Error && "code" in err && err.code === "ENOENT") {
21871
22629
  return null;