agentsmesh 0.22.0 → 0.23.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.
@@ -145,6 +145,14 @@ interface CanonicalFiles {
145
145
  ignore: IgnorePatterns;
146
146
  }
147
147
 
148
+ /** Cherry-pick resource names within array features (extends.install + merge). */
149
+ declare const extendPickSchema: z.ZodObject<{
150
+ skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
151
+ commands: z.ZodOptional<z.ZodArray<z.ZodString>>;
152
+ rules: z.ZodOptional<z.ZodArray<z.ZodString>>;
153
+ agents: z.ZodOptional<z.ZodArray<z.ZodString>>;
154
+ }, z.core.$strict>;
155
+ type ExtendPick = z.infer<typeof extendPickSchema>;
148
156
  /**
149
157
  * Zod schema for `agentsmesh.yaml` config validation.
150
158
  *
@@ -305,4 +313,4 @@ declare const configSchema: z.ZodObject<{
305
313
  }, z.core.$strip>;
306
314
  type ValidatedConfig = z.infer<typeof configSchema>;
307
315
 
308
- export type { CanonicalAgent as C, HookEntry as H, IgnorePatterns as I, McpConfig as M, Permissions as P, SkillSupportingFile as S, UrlMcpServer as U, ValidatedConfig as V, CanonicalCommand as a, CanonicalFiles as b, CanonicalRule as c, CanonicalSkill as d, Hooks as e, McpServer as f, StdioMcpServer as g };
316
+ export type { CanonicalAgent as C, ExtendPick as E, HookEntry as H, IgnorePatterns as I, McpConfig as M, Permissions as P, SkillSupportingFile as S, UrlMcpServer as U, ValidatedConfig as V, CanonicalCommand as a, CanonicalFiles as b, CanonicalRule as c, CanonicalSkill as d, Hooks as e, McpServer as f, StdioMcpServer as g };
@@ -1,4 +1,4 @@
1
- import { b as CanonicalFiles, c as CanonicalRule, V as ValidatedConfig } from './schema-CLmR2JOb.js';
1
+ import { b as CanonicalFiles, c as CanonicalRule, V as ValidatedConfig, E as ExtendPick } from './schema-CzaoYJlG.js';
2
2
 
3
3
  /** Result of generating files for a target */
4
4
  interface GenerateResult {
@@ -289,6 +289,54 @@ interface TargetMetadata {
289
289
  /** One-line description used in tool lists and tables. */
290
290
  readonly shortDescription: string;
291
291
  }
292
+ /**
293
+ * How a native-install pick rule derives canonical entity names from the files
294
+ * found under its directory.
295
+ * - `basename`: recursively collect files ending in `suffix`; name = basename
296
+ * minus `suffix` (e.g. `.md`, `.mdc`).
297
+ * - `skillDir`: skill tree — `{name}/SKILL.md` plus flat top-level `*.md`.
298
+ * - `firstSegment`: the single segment after the rule prefix is the name
299
+ * (e.g. `.claude/skills/{name}/...`).
300
+ */
301
+ type NativePickStrategy = {
302
+ readonly kind: 'basename';
303
+ readonly suffix: string;
304
+ } | {
305
+ readonly kind: 'skillDir';
306
+ } | {
307
+ readonly kind: 'firstSegment';
308
+ };
309
+ /** Maps a native directory prefix to a canonical feature + name strategy. */
310
+ interface NativePickRule {
311
+ /** POSIX path prefix under the repo root; matches the dir or any subpath. */
312
+ readonly prefix: string;
313
+ /** Canonical feature the matched files contribute to. */
314
+ readonly feature: 'commands' | 'rules' | 'agents' | 'skills';
315
+ /** How to derive entity names from the matched directory. */
316
+ readonly strategy: NativePickStrategy;
317
+ }
318
+ /** Frontmatter-dialect hint for `.mdc` flat-file target inference. */
319
+ interface NativeDialectHint {
320
+ /** Frontmatter key whose presence identifies this target. */
321
+ readonly frontmatterKey: string;
322
+ }
323
+ /**
324
+ * Descriptor-driven data for the install subsystem's native-path inference.
325
+ * Replaces the per-target `if (target === '…')` ladders (arch §3.1): each
326
+ * target declares its own pick paths / dialect hints instead.
327
+ */
328
+ interface NativeInstallSupport {
329
+ /** Ordered pick-path rules; the first matching prefix wins. */
330
+ readonly pickPaths?: readonly NativePickRule[];
331
+ /**
332
+ * Escape hatch for irreducibly custom inference (e.g. Gemini's `:`-namespaced
333
+ * command names, Copilot's overlapping `.github/*` dirs). When present it
334
+ * fully owns inference for this target and `pickPaths` is ignored.
335
+ */
336
+ readonly inferPick?: (repoRoot: string, posixPath: string) => Promise<ExtendPick>;
337
+ /** Frontmatter-dialect hints for `.mdc` flat-file target inference. */
338
+ readonly dialectHints?: readonly NativeDialectHint[];
339
+ }
292
340
  /**
293
341
  * Full self-describing target descriptor.
294
342
  * Bundles everything needed to generate, import, lint, and detect a target.
@@ -347,10 +395,22 @@ interface TargetDescriptor {
347
395
  readonly sharedArtifacts?: {
348
396
  readonly [pathPrefix: string]: 'owner' | 'consumer';
349
397
  };
398
+ /**
399
+ * Descriptor-driven native-install inference data (extends.pick from native
400
+ * files, `.mdc` dialect hints). Consumed by `src/install/native` and
401
+ * `src/install/manual` so those modules carry no target-id literals.
402
+ */
403
+ readonly nativeInstall?: NativeInstallSupport;
350
404
  /**
351
405
  * Optional native settings sidecar (e.g. Gemini `.gemini/settings.json` when embedded features are on).
406
+ *
407
+ * `enabledFeatures` is the active feature set for this generate run. Emitters
408
+ * MUST gate every settings key on its corresponding feature (mcpServers ->
409
+ * `mcp`, hooks -> `hooks`, agents -> `agents`, permissions -> `permissions`,
410
+ * ignore-derived keys -> `ignore`) so a disabled feature never leaks into the
411
+ * sidecar.
352
412
  */
353
- readonly emitScopedSettings?: (canonical: CanonicalFiles, scope: TargetLayoutScope) => readonly {
413
+ readonly emitScopedSettings?: (canonical: CanonicalFiles, scope: TargetLayoutScope, enabledFeatures: ReadonlySet<string>) => readonly {
354
414
  readonly path: string;
355
415
  readonly content: string;
356
416
  }[];
package/dist/targets.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { e as TargetDescriptor, h as TargetLayoutScope, C as ContentNormalizer, d as ImportResult } from './target-descriptor-CkLWz3Xk.js';
2
- export { E as ExtraRuleOutputContext, a as ExtraRuleOutputResolver, F as FeatureLinter, b as GeneratedOutputMerger, c as GlobalTargetSupport, I as ImportPathBuilder, R as RuleLinter, S as ScopeExtrasFn, T as TargetCapabilities, f as TargetGenerators, g as TargetLayout, i as TargetLintHooks, j as TargetManagedOutputs, k as TargetOutputFamily, l as TargetPathResolvers } from './target-descriptor-CkLWz3Xk.js';
3
- import './schema-CLmR2JOb.js';
1
+ import { e as TargetDescriptor, h as TargetLayoutScope, C as ContentNormalizer, d as ImportResult } from './target-descriptor-D6vLDI1w.js';
2
+ export { E as ExtraRuleOutputContext, a as ExtraRuleOutputResolver, F as FeatureLinter, b as GeneratedOutputMerger, c as GlobalTargetSupport, I as ImportPathBuilder, R as RuleLinter, S as ScopeExtrasFn, T as TargetCapabilities, f as TargetGenerators, g as TargetLayout, i as TargetLintHooks, j as TargetManagedOutputs, k as TargetOutputFamily, l as TargetPathResolvers } from './target-descriptor-D6vLDI1w.js';
3
+ import './schema-CzaoYJlG.js';
4
4
  import 'zod';
5
5
 
6
6
  /** Register a full target descriptor (for plugins). */
package/dist/targets.js CHANGED
@@ -2,6 +2,7 @@ import { z } from 'zod';
2
2
  import { stringify, parse } from 'yaml';
3
3
  import { basename, join, win32, posix, relative, dirname, extname } from 'path';
4
4
  import { readFile, readdir, stat, mkdir, lstat, unlink, writeFile, rename, chmod, rm, realpath, access } from 'fs/promises';
5
+ import 'timers/promises';
5
6
  import { existsSync, realpathSync, constants, statSync } from 'fs';
6
7
  import { parse as parse$1 } from 'smol-toml';
7
8
  import { Buffer } from 'buffer';
@@ -38,7 +39,7 @@ function validateCapabilityImplementations(descriptor31, capabilities17, ctx, pa
38
39
  function validateDescriptor(value) {
39
40
  return targetDescriptorSchema.parse(value);
40
41
  }
41
- var capabilityLevelSchema, capabilitiesSchema, generatorsSchema, pathResolversSchema, layoutSchema, globalSupportSchema, legacyGlobalKeys, generatorRequirements, settingsBackedFeatures, conversionDefaultsSchema, metadataSchema, targetDescriptorSchemaBase, targetDescriptorSchema;
42
+ var capabilityLevelSchema, capabilitiesSchema, generatorsSchema, pathResolversSchema, layoutSchema, globalSupportSchema, legacyGlobalKeys, generatorRequirements, settingsBackedFeatures, conversionDefaultsSchema, metadataSchema, nativePickStrategySchema, nativeInstallSchema, targetDescriptorSchemaBase, targetDescriptorSchema;
42
43
  var init_target_descriptor_schema = __esm({
43
44
  "src/targets/catalog/target-descriptor.schema.ts"() {
44
45
  capabilityLevelSchema = z.union([
@@ -112,6 +113,22 @@ var init_target_descriptor_schema = __esm({
112
113
  officialUrl: z.string().min(1),
113
114
  shortDescription: z.string().min(1)
114
115
  }).passthrough();
116
+ nativePickStrategySchema = z.discriminatedUnion("kind", [
117
+ z.object({ kind: z.literal("basename"), suffix: z.string().min(1) }),
118
+ z.object({ kind: z.literal("skillDir") }),
119
+ z.object({ kind: z.literal("firstSegment") })
120
+ ]);
121
+ nativeInstallSchema = z.object({
122
+ pickPaths: z.array(
123
+ z.object({
124
+ prefix: z.string().min(1),
125
+ feature: z.enum(["commands", "rules", "agents", "skills"]),
126
+ strategy: nativePickStrategySchema
127
+ })
128
+ ).optional(),
129
+ inferPick: z.function().optional(),
130
+ dialectHints: z.array(z.object({ frontmatterKey: z.string().min(1) })).optional()
131
+ }).strict();
115
132
  targetDescriptorSchemaBase = z.object({
116
133
  id: z.string().regex(/^[a-z][a-z0-9-]*$/, "Target id must be lowercase with hyphens"),
117
134
  metadata: metadataSchema,
@@ -123,6 +140,7 @@ var init_target_descriptor_schema = __esm({
123
140
  globalSupport: globalSupportSchema.optional(),
124
141
  buildImportPaths: z.function(),
125
142
  detectionPaths: z.array(z.string()),
143
+ nativeInstall: nativeInstallSchema.optional(),
126
144
  excludeFromStarterInit: z.boolean().optional(),
127
145
  conversionDefaults: conversionDefaultsSchema.optional(),
128
146
  emitScopedSettings: z.function().optional(),
@@ -675,6 +693,10 @@ var init_fs_traverse = __esm({
675
693
  MAX_SEGMENT_REPETITIONS = 3;
676
694
  }
677
695
  });
696
+ var init_rename_retry = __esm({
697
+ "src/utils/filesystem/rename-retry.ts"() {
698
+ }
699
+ });
678
700
  async function readFileSafe(path) {
679
701
  try {
680
702
  const data = await readFile(path, "utf-8");
@@ -761,6 +783,7 @@ var init_fs = __esm({
761
783
  init_fs_text_encoding();
762
784
  init_fs_traverse();
763
785
  init_fs_text_encoding();
786
+ init_rename_retry();
764
787
  }
765
788
  });
766
789
  function escapeRegExp(value) {
@@ -1845,9 +1868,8 @@ function shouldRewritePathToken(fullContent, start, end, matchText, rewriteBareP
1845
1868
  const before = fullContent[start - 1];
1846
1869
  const after = fullContent[end];
1847
1870
  if (isMarkdownReferenceDefinitionDestination(fullContent, start, candidateEnd)) return true;
1848
- if (before === "'" && after === "'" || before === '"' && after === '"' || before === "`" && after === "`") {
1849
- return true;
1850
- }
1871
+ if (before === "`" && after === "`") return true;
1872
+ if (before === "'" && after === "'" || before === '"' && after === '"') return false;
1851
1873
  if (before === "<" && after === ">") return true;
1852
1874
  if (before === "[" && after === "]") {
1853
1875
  if (!rewriteBarePathTokens && !isRootRelativePathToken(normalizedCandidate) && markdownBracketLabelDuplicatesDestination(fullContent, start, matchText)) {
@@ -3144,12 +3166,12 @@ var init_augment_code = __esm({
3144
3166
  });
3145
3167
 
3146
3168
  // src/targets/claude-code/constants.ts
3147
- var CLAUDE_CODE_TARGET, CLAUDE_ROOT, CLAUDE_LEGACY_ROOT, CLAUDE_RULES_DIR, CLAUDE_COMMANDS_DIR, CLAUDE_AGENTS_DIR, CLAUDE_SKILLS_DIR, CLAUDE_SETTINGS, CLAUDE_HOOKS_JSON, CLAUDE_OUTPUT_STYLES_DIR, CLAUDE_IGNORE, CLAUDE_MCP_JSON, CLAUDE_GLOBAL_MCP_JSON, CLAUDE_CANONICAL_RULES_DIR, CLAUDE_CANONICAL_COMMANDS_DIR, CLAUDE_CANONICAL_AGENTS_DIR, CLAUDE_CANONICAL_SKILLS_DIR, CLAUDE_CANONICAL_MCP, CLAUDE_CANONICAL_PERMISSIONS, CLAUDE_CANONICAL_HOOKS, CLAUDE_CANONICAL_IGNORE;
3169
+ var CLAUDE_CODE_TARGET, CLAUDE_ROOT, CLAUDE_NESTED_ROOT, CLAUDE_RULES_DIR, CLAUDE_COMMANDS_DIR, CLAUDE_AGENTS_DIR, CLAUDE_SKILLS_DIR, CLAUDE_SETTINGS, CLAUDE_HOOKS_JSON, CLAUDE_OUTPUT_STYLES_DIR, CLAUDE_IGNORE, CLAUDE_MCP_JSON, CLAUDE_GLOBAL_MCP_JSON, CLAUDE_CANONICAL_RULES_DIR, CLAUDE_CANONICAL_COMMANDS_DIR, CLAUDE_CANONICAL_AGENTS_DIR, CLAUDE_CANONICAL_SKILLS_DIR, CLAUDE_CANONICAL_MCP, CLAUDE_CANONICAL_PERMISSIONS, CLAUDE_CANONICAL_HOOKS, CLAUDE_CANONICAL_IGNORE;
3148
3170
  var init_constants7 = __esm({
3149
3171
  "src/targets/claude-code/constants.ts"() {
3150
3172
  CLAUDE_CODE_TARGET = "claude-code";
3151
- CLAUDE_ROOT = ".claude/CLAUDE.md";
3152
- CLAUDE_LEGACY_ROOT = "CLAUDE.md";
3173
+ CLAUDE_ROOT = "CLAUDE.md";
3174
+ CLAUDE_NESTED_ROOT = ".claude/CLAUDE.md";
3153
3175
  CLAUDE_RULES_DIR = ".claude/rules";
3154
3176
  CLAUDE_COMMANDS_DIR = ".claude/commands";
3155
3177
  CLAUDE_AGENTS_DIR = ".claude/agents";
@@ -5011,7 +5033,8 @@ var init_amp2 = __esm({
5011
5033
  markAsRoot: true
5012
5034
  }
5013
5035
  },
5014
- emitScopedSettings(canonical, _scope) {
5036
+ emitScopedSettings(canonical, _scope, enabledFeatures) {
5037
+ if (!enabledFeatures.has("mcp")) return [];
5015
5038
  if (!canonical.mcp || Object.keys(canonical.mcp.mcpServers).length === 0) return [];
5016
5039
  return [
5017
5040
  {
@@ -5763,12 +5786,12 @@ function mergeAugmentSettings(existing, newContent) {
5763
5786
  if (overlay.hooks !== void 0) base.hooks = overlay.hooks;
5764
5787
  return JSON.stringify(base, null, 2);
5765
5788
  }
5766
- function buildSettingsContent(canonical) {
5789
+ function buildSettingsContent(canonical, enabledFeatures) {
5767
5790
  const settings = {};
5768
- if (canonical.mcp && Object.keys(canonical.mcp.mcpServers).length > 0) {
5791
+ if (enabledFeatures.has("mcp") && canonical.mcp && Object.keys(canonical.mcp.mcpServers).length > 0) {
5769
5792
  settings.mcpServers = canonical.mcp.mcpServers;
5770
5793
  }
5771
- if (canonical.hooks && Object.keys(canonical.hooks).length > 0) {
5794
+ if (enabledFeatures.has("hooks") && canonical.hooks && Object.keys(canonical.hooks).length > 0) {
5772
5795
  settings.hooks = serializeHooksForSettings(canonical.hooks);
5773
5796
  }
5774
5797
  if (Object.keys(settings).length === 0) return null;
@@ -5897,8 +5920,8 @@ var init_augment_code2 = __esm({
5897
5920
  ],
5898
5921
  layout: globalLayout5
5899
5922
  },
5900
- emitScopedSettings(canonical) {
5901
- const content = buildSettingsContent(canonical);
5923
+ emitScopedSettings(canonical, _scope, enabledFeatures) {
5924
+ const content = buildSettingsContent(canonical, enabledFeatures);
5902
5925
  if (content === null) return [];
5903
5926
  return [{ path: AUGMENT_CODE_SETTINGS_FILE, content }];
5904
5927
  },
@@ -6472,7 +6495,10 @@ var init_claude_code2 = __esm({
6472
6495
  skillDir: ".claude/skills",
6473
6496
  managedOutputs: {
6474
6497
  dirs: [".claude/agents", ".claude/commands", ".claude/rules", ".claude/skills"],
6475
- files: [".claude/CLAUDE.md", ".claude/settings.json", ".claudeignore", ".mcp.json"]
6498
+ // CLAUDE_NESTED_ROOT is the pre-migration project location; listing it here lets
6499
+ // `cleanupStaleGeneratedOutputs` evict a leftover `.claude/CLAUDE.md` once generation
6500
+ // writes the root `CLAUDE.md`, so Claude Code never concatenates both into context.
6501
+ files: [CLAUDE_ROOT, CLAUDE_NESTED_ROOT, ".claude/settings.json", ".claudeignore", ".mcp.json"]
6476
6502
  },
6477
6503
  paths: {
6478
6504
  rulePath(slug, _rule) {
@@ -6487,7 +6513,7 @@ var init_claude_code2 = __esm({
6487
6513
  }
6488
6514
  };
6489
6515
  globalLayout6 = {
6490
- rootInstructionPath: CLAUDE_ROOT,
6516
+ rootInstructionPath: CLAUDE_NESTED_ROOT,
6491
6517
  skillDir: ".claude/skills",
6492
6518
  renderPrimaryRootInstruction: renderClaudeGlobalPrimaryInstructions,
6493
6519
  managedOutputs: {
@@ -6500,7 +6526,7 @@ var init_claude_code2 = __esm({
6500
6526
  ".agents/skills"
6501
6527
  ],
6502
6528
  files: [
6503
- ".claude/CLAUDE.md",
6529
+ CLAUDE_NESTED_ROOT,
6504
6530
  ".claude/settings.json",
6505
6531
  CLAUDE_GLOBAL_MCP_JSON,
6506
6532
  CLAUDE_HOOKS_JSON,
@@ -6508,6 +6534,7 @@ var init_claude_code2 = __esm({
6508
6534
  ]
6509
6535
  },
6510
6536
  rewriteGeneratedPath(path) {
6537
+ if (path === CLAUDE_ROOT) return CLAUDE_NESTED_ROOT;
6511
6538
  if (path === CLAUDE_MCP_JSON) return CLAUDE_GLOBAL_MCP_JSON;
6512
6539
  return path;
6513
6540
  },
@@ -6571,10 +6598,11 @@ var init_claude_code2 = __esm({
6571
6598
  importer: {
6572
6599
  rules: [
6573
6600
  {
6574
- // Root rule: prefer .claude/CLAUDE.md, fall back to legacy CLAUDE.md (project only).
6601
+ // Root rule: project prefers root CLAUDE.md, falls back to nested .claude/CLAUDE.md;
6602
+ // global reads the nested .claude/CLAUDE.md.
6575
6603
  feature: "rules",
6576
6604
  mode: "singleFile",
6577
- source: { project: [CLAUDE_ROOT, CLAUDE_LEGACY_ROOT], global: [CLAUDE_ROOT] },
6605
+ source: { project: [CLAUDE_ROOT, CLAUDE_NESTED_ROOT], global: [CLAUDE_NESTED_ROOT] },
6578
6606
  canonicalDir: CLAUDE_CANONICAL_RULES_DIR,
6579
6607
  canonicalRootFilename: "_root.md",
6580
6608
  markAsRoot: true
@@ -6620,7 +6648,23 @@ var init_claude_code2 = __esm({
6620
6648
  }
6621
6649
  },
6622
6650
  buildImportPaths: buildClaudeCodeImportPaths,
6623
- detectionPaths: ["CLAUDE.md", ".claude/rules", ".claude/commands"]
6651
+ detectionPaths: [CLAUDE_ROOT, CLAUDE_NESTED_ROOT, ".claude/rules", ".claude/commands"],
6652
+ nativeInstall: {
6653
+ pickPaths: [
6654
+ {
6655
+ prefix: ".claude/commands",
6656
+ feature: "commands",
6657
+ strategy: { kind: "basename", suffix: ".md" }
6658
+ },
6659
+ { prefix: ".claude/rules", feature: "rules", strategy: { kind: "basename", suffix: ".md" } },
6660
+ {
6661
+ prefix: ".claude/agents",
6662
+ feature: "agents",
6663
+ strategy: { kind: "basename", suffix: ".md" }
6664
+ },
6665
+ { prefix: ".claude/skills/", feature: "skills", strategy: { kind: "firstSegment" } }
6666
+ ]
6667
+ }
6624
6668
  };
6625
6669
  }
6626
6670
  });
@@ -7499,6 +7543,16 @@ var init_cline2 = __esm({
7499
7543
  },
7500
7544
  buildImportPaths: buildClineImportPaths,
7501
7545
  detectionPaths: [".clinerules", ".cline"],
7546
+ nativeInstall: {
7547
+ pickPaths: [
7548
+ { prefix: CLINE_SKILLS_DIR, feature: "skills", strategy: { kind: "skillDir" } },
7549
+ {
7550
+ prefix: CLINE_WORKFLOWS_DIR,
7551
+ feature: "commands",
7552
+ strategy: { kind: "basename", suffix: ".md" }
7553
+ }
7554
+ ]
7555
+ },
7502
7556
  conversionDefaults: { agentsToSkills: true }
7503
7557
  };
7504
7558
  }
@@ -8417,6 +8471,11 @@ var init_codex_cli2 = __esm({
8417
8471
  ".codex/agents",
8418
8472
  ".codex/rules"
8419
8473
  ],
8474
+ nativeInstall: {
8475
+ pickPaths: [
8476
+ { prefix: ".codex", feature: "rules", strategy: { kind: "basename", suffix: ".md" } }
8477
+ ]
8478
+ },
8420
8479
  excludeFromStarterInit: true,
8421
8480
  conversionDefaults: { commandsToSkills: true, agentsToSkills: false }
8422
8481
  };
@@ -8920,6 +8979,21 @@ var init_continue2 = __esm({
8920
8979
  },
8921
8980
  buildImportPaths: buildContinueImportPaths,
8922
8981
  detectionPaths: [".continue/rules", ".continue/skills", ".continue/mcpServers"],
8982
+ nativeInstall: {
8983
+ pickPaths: [
8984
+ {
8985
+ prefix: ".continue/rules",
8986
+ feature: "rules",
8987
+ strategy: { kind: "basename", suffix: ".md" }
8988
+ },
8989
+ {
8990
+ prefix: ".continue/prompts",
8991
+ feature: "commands",
8992
+ strategy: { kind: "basename", suffix: ".md" }
8993
+ },
8994
+ { prefix: ".continue/skills", feature: "skills", strategy: { kind: "skillDir" } }
8995
+ ]
8996
+ },
8923
8997
  conversionDefaults: { agentsToSkills: true }
8924
8998
  };
8925
8999
  }
@@ -9287,6 +9361,80 @@ var init_importer10 = __esm({
9287
9361
  init_copilot2();
9288
9362
  }
9289
9363
  });
9364
+ async function skillNamesFromNativeSkillDir(scanRoot) {
9365
+ const files = await readDirRecursive(scanRoot);
9366
+ const names = /* @__PURE__ */ new Set();
9367
+ for (const f of files) {
9368
+ if (basename(f) === "SKILL.md") {
9369
+ names.add(basename(dirname(f)));
9370
+ continue;
9371
+ }
9372
+ const rel2 = relative(scanRoot, f).replace(/\\/g, "/");
9373
+ if (!rel2.includes("/") && f.toLowerCase().endsWith(".md")) {
9374
+ names.add(basename(f, ".md"));
9375
+ }
9376
+ }
9377
+ return [...names].filter(Boolean).sort();
9378
+ }
9379
+ var init_native_skill_scan = __esm({
9380
+ "src/install/native/native-skill-scan.ts"() {
9381
+ init_fs();
9382
+ }
9383
+ });
9384
+ async function inferCopilotPickFromPath(repoRoot, posixPath) {
9385
+ const scan = join(repoRoot, ...posixPath.split("/"));
9386
+ if (posixPath.startsWith(COPILOT_PROMPTS_DIR)) {
9387
+ const files = await readDirRecursive(scan);
9388
+ const commands = [
9389
+ ...new Set(
9390
+ files.filter((f) => f.toLowerCase().endsWith(".prompt.md")).map((f) => basename(f, ".prompt.md"))
9391
+ )
9392
+ ].sort();
9393
+ return commands.length ? { commands } : {};
9394
+ }
9395
+ if (posixPath.startsWith(".github/copilot") && !posixPath.includes("copilot-instructions.md")) {
9396
+ const files = await readDirRecursive(scan);
9397
+ const rules = [
9398
+ ...new Set(
9399
+ files.filter((f) => f.includes(".instructions.md")).map((f) => basename(f).replace(/\.instructions\.md$/i, ""))
9400
+ )
9401
+ ].sort();
9402
+ return rules.length ? { rules } : {};
9403
+ }
9404
+ if (posixPath.startsWith(".github/instructions")) {
9405
+ const files = await readDirRecursive(scan);
9406
+ const names = /* @__PURE__ */ new Set();
9407
+ for (const f of files) {
9408
+ const b = basename(f);
9409
+ if (b.toLowerCase().endsWith(".instructions.md"))
9410
+ names.add(b.replace(/\.instructions\.md$/i, ""));
9411
+ else if (b.toLowerCase().endsWith(".md")) names.add(basename(f, ".md"));
9412
+ }
9413
+ const rules = [...names].sort();
9414
+ return rules.length ? { rules } : {};
9415
+ }
9416
+ if (posixPath.startsWith(".github/skills")) {
9417
+ const skills = await skillNamesFromNativeSkillDir(scan);
9418
+ return skills.length ? { skills } : {};
9419
+ }
9420
+ if (posixPath.startsWith(".github/agents")) {
9421
+ const files = await readDirRecursive(scan);
9422
+ const agents = [
9423
+ ...new Set(
9424
+ files.filter((f) => f.toLowerCase().endsWith(".agent.md")).map((f) => basename(f, ".agent.md"))
9425
+ )
9426
+ ].sort();
9427
+ return agents.length ? { agents } : {};
9428
+ }
9429
+ return {};
9430
+ }
9431
+ var init_native_path_pick_infer_copilot = __esm({
9432
+ "src/install/native/native-path-pick-infer-copilot.ts"() {
9433
+ init_fs();
9434
+ init_constants29();
9435
+ init_native_skill_scan();
9436
+ }
9437
+ });
9290
9438
  function pruneUndefined3(record) {
9291
9439
  for (const key of Object.keys(record)) {
9292
9440
  if (record[key] === void 0) delete record[key];
@@ -9576,6 +9724,7 @@ var init_copilot2 = __esm({
9576
9724
  init_generator11();
9577
9725
  init_constants29();
9578
9726
  init_importer10();
9727
+ init_native_path_pick_infer_copilot();
9579
9728
  init_import_mappers4();
9580
9729
  init_linter10();
9581
9730
  init_import_map_builders();
@@ -9790,7 +9939,8 @@ var init_copilot2 = __esm({
9790
9939
  ".github/skills",
9791
9940
  ".github/agents",
9792
9941
  ".github/hooks"
9793
- ]
9942
+ ],
9943
+ nativeInstall: { inferPick: inferCopilotPickFromPath }
9794
9944
  };
9795
9945
  }
9796
9946
  });
@@ -11290,6 +11440,23 @@ var init_cursor2 = __esm({
11290
11440
  },
11291
11441
  buildImportPaths: buildCursorImportPaths,
11292
11442
  detectionPaths: [".cursor/rules", ".cursor/mcp.json"],
11443
+ nativeInstall: {
11444
+ pickPaths: [
11445
+ { prefix: ".cursor/rules", feature: "rules", strategy: { kind: "basename", suffix: ".mdc" } },
11446
+ {
11447
+ prefix: ".cursor/commands",
11448
+ feature: "commands",
11449
+ strategy: { kind: "basename", suffix: ".md" }
11450
+ },
11451
+ {
11452
+ prefix: ".cursor/agents",
11453
+ feature: "agents",
11454
+ strategy: { kind: "basename", suffix: ".md" }
11455
+ },
11456
+ { prefix: ".cursor/skills", feature: "skills", strategy: { kind: "skillDir" } }
11457
+ ],
11458
+ dialectHints: [{ frontmatterKey: "alwaysApply" }]
11459
+ },
11293
11460
  preservesManualActivation: true
11294
11461
  };
11295
11462
  }
@@ -12051,18 +12218,18 @@ function mapHookEvent2(event) {
12051
12218
  return null;
12052
12219
  }
12053
12220
  }
12054
- function generateGeminiSettingsFiles(canonical) {
12221
+ function generateGeminiSettingsFiles(canonical, enabledFeatures) {
12055
12222
  const settings = {};
12056
12223
  let hasAnyNativeSettings = false;
12057
- if (canonical.mcp && Object.keys(canonical.mcp.mcpServers).length > 0) {
12224
+ if (enabledFeatures.has("mcp") && canonical.mcp && Object.keys(canonical.mcp.mcpServers).length > 0) {
12058
12225
  settings.mcpServers = canonical.mcp.mcpServers;
12059
12226
  hasAnyNativeSettings = true;
12060
12227
  }
12061
- if (canonical.agents.length > 0) {
12228
+ if (enabledFeatures.has("agents") && canonical.agents.length > 0) {
12062
12229
  settings.experimental = { enableAgents: true };
12063
12230
  hasAnyNativeSettings = true;
12064
12231
  }
12065
- if (canonical.hooks) {
12232
+ if (enabledFeatures.has("hooks") && canonical.hooks) {
12066
12233
  const hookEntries = Object.entries(canonical.hooks).flatMap(([event, entries]) => {
12067
12234
  const mappedEvent = mapHookEvent2(event);
12068
12235
  if (!mappedEvent || !Array.isArray(entries)) return [];
@@ -12678,6 +12845,36 @@ var init_importer15 = __esm({
12678
12845
  init_importer_skills_agents();
12679
12846
  }
12680
12847
  });
12848
+ function isUnderGeminiCommands(pathInRepoPosix) {
12849
+ const p = pathInRepoPosix.replace(/^\/+|\/+$/g, "");
12850
+ return p === ".gemini/commands" || p.startsWith(".gemini/commands/");
12851
+ }
12852
+ async function inferGeminiCommandNamesFromFiles(repoRoot, pathInRepoPosix) {
12853
+ const commandsRoot = join(repoRoot, ...GEMINI_COMMANDS_DIR.split("/"));
12854
+ const scanDir = join(repoRoot, ...pathInRepoPosix.split("/"));
12855
+ const files = await readDirRecursive(scanDir);
12856
+ const names = [];
12857
+ for (const f of files) {
12858
+ if (!/\.(toml|md)$/i.test(f)) continue;
12859
+ const rel2 = relative(commandsRoot, f).replace(/\\/g, "/");
12860
+ if (rel2.startsWith("..") || rel2 === "") continue;
12861
+ const noExt = rel2.replace(/\.(toml|md)$/i, "");
12862
+ const name = noExt.split("/").filter(Boolean).join(":");
12863
+ if (name) names.push(name);
12864
+ }
12865
+ return [...new Set(names)].sort();
12866
+ }
12867
+ async function inferGeminiPick(repoRoot, posixPath) {
12868
+ if (!isUnderGeminiCommands(posixPath)) return {};
12869
+ const commands = await inferGeminiCommandNamesFromFiles(repoRoot, posixPath);
12870
+ return commands.length ? { commands } : {};
12871
+ }
12872
+ var init_gemini_install_commands = __esm({
12873
+ "src/install/native/gemini-install-commands.ts"() {
12874
+ init_fs();
12875
+ init_constants30();
12876
+ }
12877
+ });
12681
12878
  async function mapGeminiRuleFile(relativePath, destDir, normalizeTo) {
12682
12879
  const relativeMdPath = relativePath.replace(/\\/g, "/");
12683
12880
  const destPath = join(destDir, relativeMdPath);
@@ -12789,12 +12986,12 @@ var init_lint12 = __esm({
12789
12986
  });
12790
12987
 
12791
12988
  // src/targets/gemini-cli/scoped-settings-emit.ts
12792
- function emitScopedGeminiSettings(canonical, scope) {
12989
+ function emitScopedGeminiSettings(canonical, scope, enabledFeatures) {
12793
12990
  if (scope === "project") {
12794
12991
  const caps = getTargetCapabilities("gemini-cli", scope);
12795
12992
  if (caps?.ignore.flavor !== "settings-embedded") return [];
12796
12993
  }
12797
- return generateGeminiSettingsFiles(canonical);
12994
+ return generateGeminiSettingsFiles(canonical, enabledFeatures);
12798
12995
  }
12799
12996
  var init_scoped_settings_emit = __esm({
12800
12997
  "src/targets/gemini-cli/scoped-settings-emit.ts"() {
@@ -12812,6 +13009,7 @@ var init_gemini_cli2 = __esm({
12812
13009
  init_policies_generator();
12813
13010
  init_constants30();
12814
13011
  init_importer15();
13012
+ init_gemini_install_commands();
12815
13013
  init_import_mappers6();
12816
13014
  init_linter15();
12817
13015
  init_import_map_builders();
@@ -13007,6 +13205,7 @@ var init_gemini_cli2 = __esm({
13007
13205
  },
13008
13206
  buildImportPaths: buildGeminiCliImportPaths,
13009
13207
  detectionPaths: ["GEMINI.md", ".gemini"],
13208
+ nativeInstall: { inferPick: inferGeminiPick },
13010
13209
  conversionDefaults: { agentsToSkills: false }
13011
13210
  };
13012
13211
  }
@@ -13848,7 +14047,23 @@ var init_junie2 = __esm({
13848
14047
  ".junie/skills",
13849
14048
  ".junie/mcp/mcp.json",
13850
14049
  ".aiignore"
13851
- ]
14050
+ ],
14051
+ nativeInstall: {
14052
+ pickPaths: [
14053
+ {
14054
+ prefix: ".junie/commands",
14055
+ feature: "commands",
14056
+ strategy: { kind: "basename", suffix: ".md" }
14057
+ },
14058
+ { prefix: ".junie/rules", feature: "rules", strategy: { kind: "basename", suffix: ".md" } },
14059
+ {
14060
+ prefix: ".junie/agents",
14061
+ feature: "agents",
14062
+ strategy: { kind: "basename", suffix: ".md" }
14063
+ },
14064
+ { prefix: ".junie/skills", feature: "skills", strategy: { kind: "skillDir" } }
14065
+ ]
14066
+ }
13852
14067
  };
13853
14068
  }
13854
14069
  });
@@ -18198,6 +18413,16 @@ var init_windsurf2 = __esm({
18198
18413
  },
18199
18414
  buildImportPaths: buildWindsurfImportPaths,
18200
18415
  detectionPaths: [".windsurfrules", ".windsurf"],
18416
+ nativeInstall: {
18417
+ pickPaths: [
18418
+ {
18419
+ prefix: ".windsurf/rules",
18420
+ feature: "rules",
18421
+ strategy: { kind: "basename", suffix: ".md" }
18422
+ }
18423
+ ],
18424
+ dialectHints: [{ frontmatterKey: "trigger" }]
18425
+ },
18201
18426
  conversionDefaults: { agentsToSkills: true }
18202
18427
  };
18203
18428
  }
@@ -18472,7 +18697,8 @@ var init_zed2 = __esm({
18472
18697
  markAsRoot: true
18473
18698
  }
18474
18699
  },
18475
- emitScopedSettings(canonical, _scope) {
18700
+ emitScopedSettings(canonical, _scope, enabledFeatures) {
18701
+ if (!enabledFeatures.has("mcp")) return [];
18476
18702
  if (!canonical.mcp || Object.keys(canonical.mcp.mcpServers).length === 0) return [];
18477
18703
  const contextServers = {};
18478
18704
  for (const [name, server] of Object.entries(canonical.mcp.mcpServers)) {
@@ -18527,7 +18753,10 @@ function getBuiltinTargetDefinition(target31) {
18527
18753
  function getTargetCapabilities(target31, scope = "project") {
18528
18754
  const descriptor31 = getBuiltinTargetDefinition(target31) ?? getDescriptor(target31);
18529
18755
  if (!descriptor31) return void 0;
18530
- const raw = scope === "global" ? descriptor31.globalSupport?.capabilities ?? descriptor31.capabilities : descriptor31.capabilities;
18756
+ if (scope === "global" && !descriptor31.globalSupport) {
18757
+ return normalizeTargetCapabilities(ALL_NONE_CAPABILITIES);
18758
+ }
18759
+ const raw = scope === "global" ? descriptor31.globalSupport.capabilities : descriptor31.capabilities;
18531
18760
  return normalizeTargetCapabilities(raw);
18532
18761
  }
18533
18762
  function getTargetDetectionPaths(target31, scope = "project") {
@@ -18583,6 +18812,7 @@ function isConversionUpgrading(descriptor31, feature, config, scope) {
18583
18812
  function getEffectiveTargetSupportLevel(target31, feature, config, scope = "project") {
18584
18813
  const baseLevel = getTargetCapabilities(target31, scope)?.[feature]?.level ?? "none";
18585
18814
  const descriptor31 = getBuiltinTargetDefinition(target31) ?? getDescriptor(target31);
18815
+ if (scope === "global" && descriptor31 && !descriptor31.globalSupport) return "none";
18586
18816
  if (baseLevel === "none" && isConversionUpgrading(descriptor31, feature, config, scope)) {
18587
18817
  return "embedded";
18588
18818
  }
@@ -18596,7 +18826,7 @@ function resolveTargetFeatureGenerator(target31, feature, config, scope = "proje
18596
18826
  const pick = PICK_FEATURE_GENERATOR[feature];
18597
18827
  return pick === null ? void 0 : pick(descriptor31.generators);
18598
18828
  }
18599
- var BUILTIN_TARGETS, _builtinTargetsMap, PICK_FEATURE_GENERATOR;
18829
+ var ALL_NONE_CAPABILITIES, BUILTIN_TARGETS, _builtinTargetsMap, PICK_FEATURE_GENERATOR;
18600
18830
  var init_builtin_targets = __esm({
18601
18831
  "src/targets/catalog/builtin-targets.ts"() {
18602
18832
  init_conversions();
@@ -18634,6 +18864,17 @@ var init_builtin_targets = __esm({
18634
18864
  init_warp2();
18635
18865
  init_windsurf2();
18636
18866
  init_zed2();
18867
+ ALL_NONE_CAPABILITIES = {
18868
+ rules: "none",
18869
+ additionalRules: "none",
18870
+ commands: "none",
18871
+ agents: "none",
18872
+ skills: "none",
18873
+ mcp: "none",
18874
+ hooks: "none",
18875
+ ignore: "none",
18876
+ permissions: "none"
18877
+ };
18637
18878
  BUILTIN_TARGETS = [
18638
18879
  descriptor,
18639
18880
  descriptor2,