@omnidev-ai/cli 0.16.0 → 0.17.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.
Files changed (2) hide show
  1. package/dist/index.js +637 -319
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1287,6 +1287,42 @@ var init_dist = __esm(() => {
1287
1287
  dist_default = { parse, stringify, TomlDate, TomlError };
1288
1288
  });
1289
1289
 
1290
+ // ../core/src/providers.ts
1291
+ function normalizeProviderId(provider) {
1292
+ if (provider in PROVIDER_ALIAS_MAP) {
1293
+ return PROVIDER_ALIAS_MAP[provider];
1294
+ }
1295
+ throw new Error(`Unknown provider: ${provider}`);
1296
+ }
1297
+ function normalizeProviderApplicability(value, fieldName) {
1298
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
1299
+ throw new Error(`${fieldName} must be a table of provider = boolean entries`);
1300
+ }
1301
+ const normalized = {};
1302
+ for (const [rawProvider, rawEnabled] of Object.entries(value)) {
1303
+ if (typeof rawEnabled !== "boolean") {
1304
+ throw new Error(`${fieldName}.${rawProvider} must be a boolean`);
1305
+ }
1306
+ const canonicalProvider = normalizeProviderId(rawProvider);
1307
+ const existing = normalized[canonicalProvider];
1308
+ if (existing !== undefined && existing !== rawEnabled) {
1309
+ throw new Error(`Conflicting provider entries in ${fieldName}: ${rawProvider} maps to ${canonicalProvider}`);
1310
+ }
1311
+ normalized[canonicalProvider] = rawEnabled;
1312
+ }
1313
+ return normalized;
1314
+ }
1315
+ var PROVIDER_ALIAS_MAP;
1316
+ var init_providers = __esm(() => {
1317
+ PROVIDER_ALIAS_MAP = {
1318
+ claude: "claude-code",
1319
+ "claude-code": "claude-code",
1320
+ codex: "codex",
1321
+ cursor: "cursor",
1322
+ opencode: "opencode"
1323
+ };
1324
+ });
1325
+
1290
1326
  // ../core/src/config/parser.ts
1291
1327
  function parseOmniConfig(tomlContent) {
1292
1328
  try {
@@ -1311,6 +1347,9 @@ function validateCapabilityConfig(parsed) {
1311
1347
  if (typeof capability["version"] !== "string") {
1312
1348
  throw new Error("capability.version is required in capability.toml");
1313
1349
  }
1350
+ if (capability["providers"] !== undefined) {
1351
+ capability["providers"] = normalizeProviderApplicability(capability["providers"], "capability.providers");
1352
+ }
1314
1353
  }
1315
1354
  function parseCapabilityConfig(tomlContent) {
1316
1355
  try {
@@ -1324,6 +1363,7 @@ function parseCapabilityConfig(tomlContent) {
1324
1363
  }
1325
1364
  var init_parser = __esm(() => {
1326
1365
  init_dist();
1366
+ init_providers();
1327
1367
  });
1328
1368
 
1329
1369
  // ../core/src/hooks/constants.ts
@@ -2411,21 +2451,122 @@ var init_loader = __esm(() => {
2411
2451
  init_constants();
2412
2452
  });
2413
2453
 
2414
- // ../core/src/capability/rules.ts
2415
- import { existsSync as existsSync6, readdirSync as readdirSync3 } from "node:fs";
2454
+ // ../core/src/capability/mcp-env.ts
2455
+ import { existsSync as existsSync6 } from "node:fs";
2416
2456
  import { readFile as readFile3 } from "node:fs/promises";
2417
- import { basename as basename3, join as join4 } from "node:path";
2457
+ import { join as join4 } from "node:path";
2458
+ import { parseEnv } from "node:util";
2459
+ function hasEnvPlaceholder(value) {
2460
+ return ENV_PLACEHOLDER_DETECTOR.test(value);
2461
+ }
2462
+ function mergeEnvSources(capabilityEnv) {
2463
+ const merged = { ...capabilityEnv };
2464
+ for (const [key, value] of Object.entries(process.env)) {
2465
+ if (typeof value === "string") {
2466
+ merged[key] = value;
2467
+ }
2468
+ }
2469
+ return merged;
2470
+ }
2471
+ async function loadCapabilityEnv(capabilityPath) {
2472
+ const envPath = join4(capabilityPath, CAPABILITY_ENV_FILE);
2473
+ if (!existsSync6(envPath)) {
2474
+ return {};
2475
+ }
2476
+ const envContent = await readFile3(envPath, "utf-8");
2477
+ return Object.fromEntries(Object.entries(parseEnv(envContent)).filter((entry) => typeof entry[1] === "string"));
2478
+ }
2479
+ function resolveString(value, variables, capabilityId, fieldPath) {
2480
+ if (!hasEnvPlaceholder(value)) {
2481
+ return value;
2482
+ }
2483
+ return value.replace(ENV_PLACEHOLDER, (_match, variableName) => {
2484
+ const resolved = variables[variableName];
2485
+ if (resolved === undefined) {
2486
+ throw new Error(`Missing environment variable "${variableName}" required by capability "${capabilityId}" in ${fieldPath}`);
2487
+ }
2488
+ return resolved;
2489
+ });
2490
+ }
2491
+ function mcpHasPlaceholders(mcp) {
2492
+ const strings = [];
2493
+ if (mcp.command) {
2494
+ strings.push(mcp.command);
2495
+ }
2496
+ if (mcp.cwd) {
2497
+ strings.push(mcp.cwd);
2498
+ }
2499
+ if (mcp.url) {
2500
+ strings.push(mcp.url);
2501
+ }
2502
+ if (mcp.args) {
2503
+ strings.push(...mcp.args);
2504
+ }
2505
+ if (mcp.env) {
2506
+ strings.push(...Object.values(mcp.env));
2507
+ }
2508
+ if (mcp.headers) {
2509
+ strings.push(...Object.values(mcp.headers));
2510
+ }
2511
+ return strings.some((value) => hasEnvPlaceholder(value));
2512
+ }
2513
+ async function resolveCapabilityMcpEnv(config, capabilityPath) {
2514
+ if (!config.mcp || !mcpHasPlaceholders(config.mcp)) {
2515
+ return config;
2516
+ }
2517
+ const variables = mergeEnvSources(await loadCapabilityEnv(capabilityPath));
2518
+ const resolvedMcp = { ...config.mcp };
2519
+ const capabilityId = config.capability.id;
2520
+ if (resolvedMcp.command) {
2521
+ resolvedMcp.command = resolveString(resolvedMcp.command, variables, capabilityId, "mcp.command");
2522
+ }
2523
+ if (resolvedMcp.cwd) {
2524
+ resolvedMcp.cwd = resolveString(resolvedMcp.cwd, variables, capabilityId, "mcp.cwd");
2525
+ }
2526
+ if (resolvedMcp.url) {
2527
+ resolvedMcp.url = resolveString(resolvedMcp.url, variables, capabilityId, "mcp.url");
2528
+ }
2529
+ if (resolvedMcp.args) {
2530
+ resolvedMcp.args = resolvedMcp.args.map((arg, index) => resolveString(arg, variables, capabilityId, `mcp.args[${index}]`));
2531
+ }
2532
+ if (resolvedMcp.env) {
2533
+ resolvedMcp.env = Object.fromEntries(Object.entries(resolvedMcp.env).map(([key, value]) => [
2534
+ key,
2535
+ resolveString(value, variables, capabilityId, `mcp.env.${key}`)
2536
+ ]));
2537
+ }
2538
+ if (resolvedMcp.headers) {
2539
+ resolvedMcp.headers = Object.fromEntries(Object.entries(resolvedMcp.headers).map(([key, value]) => [
2540
+ key,
2541
+ resolveString(value, variables, capabilityId, `mcp.headers.${key}`)
2542
+ ]));
2543
+ }
2544
+ return {
2545
+ ...config,
2546
+ mcp: resolvedMcp
2547
+ };
2548
+ }
2549
+ var CAPABILITY_ENV_FILE = ".env", ENV_PLACEHOLDER, ENV_PLACEHOLDER_DETECTOR;
2550
+ var init_mcp_env = __esm(() => {
2551
+ ENV_PLACEHOLDER = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g;
2552
+ ENV_PLACEHOLDER_DETECTOR = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/;
2553
+ });
2554
+
2555
+ // ../core/src/capability/rules.ts
2556
+ import { existsSync as existsSync7, readdirSync as readdirSync3 } from "node:fs";
2557
+ import { readFile as readFile4 } from "node:fs/promises";
2558
+ import { basename as basename3, join as join5 } from "node:path";
2418
2559
  async function loadRules(capabilityPath, capabilityId) {
2419
- const rulesDir = join4(capabilityPath, "rules");
2420
- if (!existsSync6(rulesDir)) {
2560
+ const rulesDir = join5(capabilityPath, "rules");
2561
+ if (!existsSync7(rulesDir)) {
2421
2562
  return [];
2422
2563
  }
2423
2564
  const rules = [];
2424
2565
  const entries = readdirSync3(rulesDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
2425
2566
  for (const entry of entries) {
2426
2567
  if (entry.isFile() && entry.name.endsWith(".md")) {
2427
- const rulePath = join4(rulesDir, entry.name);
2428
- const content = await readFile3(rulePath, "utf-8");
2568
+ const rulePath = join5(rulesDir, entry.name);
2569
+ const content = await readFile4(rulePath, "utf-8");
2429
2570
  rules.push({
2430
2571
  name: basename3(entry.name, ".md"),
2431
2572
  content: content.trim(),
@@ -2438,22 +2579,22 @@ async function loadRules(capabilityPath, capabilityId) {
2438
2579
  var init_rules = () => {};
2439
2580
 
2440
2581
  // ../core/src/capability/skills.ts
2441
- import { existsSync as existsSync7, readdirSync as readdirSync4 } from "node:fs";
2442
- import { readFile as readFile4 } from "node:fs/promises";
2443
- import { join as join5 } from "node:path";
2582
+ import { existsSync as existsSync8, readdirSync as readdirSync4 } from "node:fs";
2583
+ import { readFile as readFile5 } from "node:fs/promises";
2584
+ import { join as join6 } from "node:path";
2444
2585
  async function loadSkills(capabilityPath, capabilityId) {
2445
2586
  const skills = [];
2446
2587
  const possibleDirNames = ["skills", "skill"];
2447
2588
  for (const dirName of possibleDirNames) {
2448
- const dir = join5(capabilityPath, dirName);
2449
- if (!existsSync7(dir)) {
2589
+ const dir = join6(capabilityPath, dirName);
2590
+ if (!existsSync8(dir)) {
2450
2591
  continue;
2451
2592
  }
2452
2593
  const entries = readdirSync4(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
2453
2594
  for (const entry of entries) {
2454
2595
  if (entry.isDirectory()) {
2455
- const skillPath = join5(dir, entry.name, "SKILL.md");
2456
- if (existsSync7(skillPath)) {
2596
+ const skillPath = join6(dir, entry.name, "SKILL.md");
2597
+ if (existsSync8(skillPath)) {
2457
2598
  const skill = await parseSkillFile(skillPath, capabilityId);
2458
2599
  skills.push(skill);
2459
2600
  }
@@ -2463,7 +2604,7 @@ async function loadSkills(capabilityPath, capabilityId) {
2463
2604
  return skills;
2464
2605
  }
2465
2606
  async function parseSkillFile(filePath, capabilityId) {
2466
- const content = await readFile4(filePath, "utf-8");
2607
+ const content = await readFile5(filePath, "utf-8");
2467
2608
  const parsed = parseFrontmatterWithMarkdown(content);
2468
2609
  if (!parsed) {
2469
2610
  throw new Error(`Invalid SKILL.md format at ${filePath}: missing YAML frontmatter`);
@@ -2483,30 +2624,30 @@ async function parseSkillFile(filePath, capabilityId) {
2483
2624
  var init_skills = () => {};
2484
2625
 
2485
2626
  // ../core/src/capability/subagents.ts
2486
- import { existsSync as existsSync8, readdirSync as readdirSync5 } from "node:fs";
2487
- import { readFile as readFile5 } from "node:fs/promises";
2488
- import { basename as basename4, join as join6 } from "node:path";
2627
+ import { existsSync as existsSync9, readdirSync as readdirSync5 } from "node:fs";
2628
+ import { readFile as readFile6 } from "node:fs/promises";
2629
+ import { basename as basename4, join as join7 } from "node:path";
2489
2630
  async function loadSubagents(capabilityPath, capabilityId) {
2490
2631
  const subagents = [];
2491
2632
  const possibleDirNames = ["subagents", "agents", "agent", "subagent"];
2492
2633
  for (const dirName of possibleDirNames) {
2493
- const dir = join6(capabilityPath, dirName);
2494
- if (!existsSync8(dir)) {
2634
+ const dir = join7(capabilityPath, dirName);
2635
+ if (!existsSync9(dir)) {
2495
2636
  continue;
2496
2637
  }
2497
2638
  const entries = readdirSync5(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
2498
2639
  for (const entry of entries) {
2499
2640
  if (entry.isDirectory()) {
2500
- let subagentPath = join6(dir, entry.name, "SUBAGENT.md");
2501
- if (!existsSync8(subagentPath)) {
2502
- subagentPath = join6(dir, entry.name, "AGENT.md");
2641
+ let subagentPath = join7(dir, entry.name, "SUBAGENT.md");
2642
+ if (!existsSync9(subagentPath)) {
2643
+ subagentPath = join7(dir, entry.name, "AGENT.md");
2503
2644
  }
2504
- if (existsSync8(subagentPath)) {
2645
+ if (existsSync9(subagentPath)) {
2505
2646
  const subagent = await parseSubagentFile(subagentPath, capabilityId);
2506
2647
  subagents.push(subagent);
2507
2648
  }
2508
2649
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
2509
- const subagentPath = join6(dir, entry.name);
2650
+ const subagentPath = join7(dir, entry.name);
2510
2651
  const subagent = await parseSubagentFile(subagentPath, capabilityId);
2511
2652
  subagents.push(subagent);
2512
2653
  }
@@ -2515,7 +2656,7 @@ async function loadSubagents(capabilityPath, capabilityId) {
2515
2656
  return subagents;
2516
2657
  }
2517
2658
  async function parseSubagentFile(filePath, capabilityId) {
2518
- const content = await readFile5(filePath, "utf-8");
2659
+ const content = await readFile6(filePath, "utf-8");
2519
2660
  const parsed = parseFrontmatterWithMarkdown(content);
2520
2661
  if (!parsed) {
2521
2662
  throw new Error(`Invalid SUBAGENT.md format at ${filePath}: missing YAML frontmatter`);
@@ -2559,18 +2700,18 @@ function parseCommaSeparatedList(value) {
2559
2700
  var init_subagents = () => {};
2560
2701
 
2561
2702
  // ../core/src/capability/loader.ts
2562
- import { existsSync as existsSync9, readdirSync as readdirSync6 } from "node:fs";
2563
- import { readFile as readFile6 } from "node:fs/promises";
2564
- import { join as join7 } from "node:path";
2703
+ import { existsSync as existsSync10, readdirSync as readdirSync6 } from "node:fs";
2704
+ import { readFile as readFile7 } from "node:fs/promises";
2705
+ import { join as join8 } from "node:path";
2565
2706
  async function discoverCapabilities() {
2566
2707
  const capabilities = [];
2567
- if (existsSync9(CAPABILITIES_DIR)) {
2708
+ if (existsSync10(CAPABILITIES_DIR)) {
2568
2709
  const entries = readdirSync6(CAPABILITIES_DIR, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
2569
2710
  for (const entry of entries) {
2570
2711
  if (entry.isDirectory()) {
2571
- const entryPath = join7(CAPABILITIES_DIR, entry.name);
2572
- const configPath = join7(entryPath, "capability.toml");
2573
- if (existsSync9(configPath)) {
2712
+ const entryPath = join8(CAPABILITIES_DIR, entry.name);
2713
+ const configPath = join8(entryPath, "capability.toml");
2714
+ if (existsSync10(configPath)) {
2574
2715
  capabilities.push(entryPath);
2575
2716
  }
2576
2717
  }
@@ -2579,28 +2720,28 @@ async function discoverCapabilities() {
2579
2720
  return capabilities;
2580
2721
  }
2581
2722
  async function loadCapabilityConfig(capabilityPath) {
2582
- const configPath = join7(capabilityPath, "capability.toml");
2583
- const content = await readFile6(configPath, "utf-8");
2723
+ const configPath = join8(capabilityPath, "capability.toml");
2724
+ const content = await readFile7(configPath, "utf-8");
2584
2725
  const config = parseCapabilityConfig(content);
2585
2726
  return config;
2586
2727
  }
2587
2728
  async function importCapabilityExports(capabilityPath) {
2588
- const builtIndexPath = join7(capabilityPath, "dist", "index.js");
2589
- const jsIndexPath = join7(capabilityPath, "index.js");
2590
- const tsIndexPath = join7(capabilityPath, "index.ts");
2729
+ const builtIndexPath = join8(capabilityPath, "dist", "index.js");
2730
+ const jsIndexPath = join8(capabilityPath, "index.js");
2731
+ const tsIndexPath = join8(capabilityPath, "index.ts");
2591
2732
  let indexPath = null;
2592
- if (existsSync9(builtIndexPath)) {
2733
+ if (existsSync10(builtIndexPath)) {
2593
2734
  indexPath = builtIndexPath;
2594
- } else if (existsSync9(jsIndexPath)) {
2735
+ } else if (existsSync10(jsIndexPath)) {
2595
2736
  indexPath = jsIndexPath;
2596
- } else if (existsSync9(tsIndexPath)) {
2737
+ } else if (existsSync10(tsIndexPath)) {
2597
2738
  indexPath = tsIndexPath;
2598
2739
  }
2599
2740
  if (!indexPath) {
2600
2741
  return {};
2601
2742
  }
2602
2743
  try {
2603
- const absolutePath = join7(process.cwd(), indexPath);
2744
+ const absolutePath = join8(process.cwd(), indexPath);
2604
2745
  const module = await import(absolutePath);
2605
2746
  return module;
2606
2747
  } catch (error) {
@@ -2620,11 +2761,11 @@ If this is a project-specific capability, install dependencies or remove it from
2620
2761
  }
2621
2762
  }
2622
2763
  async function loadTypeDefinitions(capabilityPath) {
2623
- const typesPath = join7(capabilityPath, "types.d.ts");
2624
- if (!existsSync9(typesPath)) {
2764
+ const typesPath = join8(capabilityPath, "types.d.ts");
2765
+ if (!existsSync10(typesPath)) {
2625
2766
  return;
2626
2767
  }
2627
- return readFile6(typesPath, "utf-8");
2768
+ return readFile7(typesPath, "utf-8");
2628
2769
  }
2629
2770
  function convertSkillExports(skillExports, capabilityId) {
2630
2771
  return skillExports.map((skillExport) => {
@@ -2812,7 +2953,8 @@ function mergeByName(fileBased, programmatic) {
2812
2953
  return Array.from(byName.values());
2813
2954
  }
2814
2955
  async function loadCapability(capabilityPath) {
2815
- const config = await loadCapabilityConfig(capabilityPath);
2956
+ const rawConfig = await loadCapabilityConfig(capabilityPath);
2957
+ const config = await resolveCapabilityMcpEnv(rawConfig, capabilityPath);
2816
2958
  const id = config.capability.id;
2817
2959
  const exports = await importCapabilityExports(capabilityPath);
2818
2960
  const exportsAny = exports;
@@ -2878,6 +3020,7 @@ var CAPABILITIES_DIR = ".omni/capabilities";
2878
3020
  var init_loader2 = __esm(() => {
2879
3021
  init_parser();
2880
3022
  init_loader();
3023
+ init_mcp_env();
2881
3024
  init_commands();
2882
3025
  init_docs();
2883
3026
  init_rules();
@@ -2886,8 +3029,8 @@ var init_loader2 = __esm(() => {
2886
3029
  });
2887
3030
 
2888
3031
  // ../core/src/config/config.ts
2889
- import { existsSync as existsSync10 } from "node:fs";
2890
- import { readFile as readFile7, writeFile } from "node:fs/promises";
3032
+ import { existsSync as existsSync11 } from "node:fs";
3033
+ import { readFile as readFile8, writeFile } from "node:fs/promises";
2891
3034
  function mergeConfigs(base, override) {
2892
3035
  const merged = { ...base, ...override };
2893
3036
  merged.profiles = { ...base.profiles };
@@ -2929,8 +3072,8 @@ function mergeConfigs(base, override) {
2929
3072
  return merged;
2930
3073
  }
2931
3074
  async function loadBaseConfig() {
2932
- if (existsSync10(CONFIG_PATH)) {
2933
- const content = await readFile7(CONFIG_PATH, "utf-8");
3075
+ if (existsSync11(CONFIG_PATH)) {
3076
+ const content = await readFile8(CONFIG_PATH, "utf-8");
2934
3077
  return parseOmniConfig(content);
2935
3078
  }
2936
3079
  return {};
@@ -2938,8 +3081,8 @@ async function loadBaseConfig() {
2938
3081
  async function loadConfig() {
2939
3082
  const baseConfig = await loadBaseConfig();
2940
3083
  let localConfig = {};
2941
- if (existsSync10(LOCAL_CONFIG)) {
2942
- const content = await readFile7(LOCAL_CONFIG, "utf-8");
3084
+ if (existsSync11(LOCAL_CONFIG)) {
3085
+ const content = await readFile8(LOCAL_CONFIG, "utf-8");
2943
3086
  localConfig = parseOmniConfig(content);
2944
3087
  }
2945
3088
  return mergeConfigs(baseConfig, localConfig);
@@ -3103,14 +3246,14 @@ var init_config = __esm(() => {
3103
3246
  });
3104
3247
 
3105
3248
  // ../core/src/state/active-profile.ts
3106
- import { existsSync as existsSync11, mkdirSync } from "node:fs";
3107
- import { readFile as readFile8, unlink, writeFile as writeFile2 } from "node:fs/promises";
3249
+ import { existsSync as existsSync12, mkdirSync } from "node:fs";
3250
+ import { readFile as readFile9, unlink, writeFile as writeFile2 } from "node:fs/promises";
3108
3251
  async function readActiveProfileState() {
3109
- if (!existsSync11(ACTIVE_PROFILE_PATH)) {
3252
+ if (!existsSync12(ACTIVE_PROFILE_PATH)) {
3110
3253
  return null;
3111
3254
  }
3112
3255
  try {
3113
- const content = await readFile8(ACTIVE_PROFILE_PATH, "utf-8");
3256
+ const content = await readFile9(ACTIVE_PROFILE_PATH, "utf-8");
3114
3257
  const trimmed = content.trim();
3115
3258
  return trimmed || null;
3116
3259
  } catch {
@@ -3122,7 +3265,7 @@ async function writeActiveProfileState(profileName) {
3122
3265
  await writeFile2(ACTIVE_PROFILE_PATH, profileName, "utf-8");
3123
3266
  }
3124
3267
  async function clearActiveProfileState() {
3125
- if (existsSync11(ACTIVE_PROFILE_PATH)) {
3268
+ if (existsSync12(ACTIVE_PROFILE_PATH)) {
3126
3269
  await unlink(ACTIVE_PROFILE_PATH);
3127
3270
  }
3128
3271
  }
@@ -3366,10 +3509,10 @@ function getActiveProviders(config) {
3366
3509
  var init_types2 = () => {};
3367
3510
 
3368
3511
  // ../core/src/capability/sources.ts
3369
- import { existsSync as existsSync12 } from "node:fs";
3512
+ import { existsSync as existsSync13 } from "node:fs";
3370
3513
  import { spawn } from "node:child_process";
3371
- import { cp, mkdir, readdir, readFile as readFile9, rename, rm, stat, writeFile as writeFile3 } from "node:fs/promises";
3372
- import { join as join8 } from "node:path";
3514
+ import { cp, mkdir, readdir, readFile as readFile10, rename, rm, stat, writeFile as writeFile3 } from "node:fs/promises";
3515
+ import { join as join9 } from "node:path";
3373
3516
  import { createHash } from "node:crypto";
3374
3517
  async function spawnCapture(command, args, options) {
3375
3518
  const timeout = options?.timeout ?? 60000;
@@ -3426,10 +3569,10 @@ function parseFileSourcePath(source) {
3426
3569
  return source.slice(7);
3427
3570
  }
3428
3571
  async function readCapabilityIdFromPath(capabilityPath) {
3429
- const tomlPath = join8(capabilityPath, "capability.toml");
3430
- if (existsSync12(tomlPath)) {
3572
+ const tomlPath = join9(capabilityPath, "capability.toml");
3573
+ if (existsSync13(tomlPath)) {
3431
3574
  try {
3432
- const content = await readFile9(tomlPath, "utf-8");
3575
+ const content = await readFile10(tomlPath, "utf-8");
3433
3576
  const parsed = parse(content);
3434
3577
  const capability = parsed["capability"];
3435
3578
  if (capability?.["id"] && typeof capability["id"] === "string") {
@@ -3482,18 +3625,18 @@ function sourceToGitUrl(source) {
3482
3625
  return source;
3483
3626
  }
3484
3627
  function getSourceCapabilityPath(id) {
3485
- return join8(OMNI_LOCAL, "capabilities", id);
3628
+ return join9(OMNI_LOCAL, "capabilities", id);
3486
3629
  }
3487
3630
  function getLockFilePath() {
3488
3631
  return "omni.lock.toml";
3489
3632
  }
3490
3633
  async function loadLockFile() {
3491
3634
  const lockPath = getLockFilePath();
3492
- if (!existsSync12(lockPath)) {
3635
+ if (!existsSync13(lockPath)) {
3493
3636
  return { capabilities: {} };
3494
3637
  }
3495
3638
  try {
3496
- const content = await readFile9(lockPath, "utf-8");
3639
+ const content = await readFile10(lockPath, "utf-8");
3497
3640
  const parsed = parse(content);
3498
3641
  const rawCapabilities = parsed["capabilities"];
3499
3642
  if (!rawCapabilities) {
@@ -3551,7 +3694,7 @@ function stringifyLockFile(lockFile) {
3551
3694
  }
3552
3695
  async function saveLockFile(lockFile) {
3553
3696
  const lockPath = getLockFilePath();
3554
- await mkdir(join8(OMNI_LOCAL, "capabilities"), { recursive: true });
3697
+ await mkdir(join9(OMNI_LOCAL, "capabilities"), { recursive: true });
3555
3698
  const header = `# Auto-generated by OmniDev - DO NOT EDIT
3556
3699
  # Records installed capability versions for reproducibility
3557
3700
  # Last updated: ${new Date().toISOString()}
@@ -3585,7 +3728,7 @@ async function computeContentHash(dirPath, excludePatterns = CONTENT_HASH_EXCLUD
3585
3728
  const entries = await readdir(currentPath, { withFileTypes: true });
3586
3729
  entries.sort((a, b) => a.name.localeCompare(b.name));
3587
3730
  for (const entry of entries) {
3588
- const fullPath = join8(currentPath, entry.name);
3731
+ const fullPath = join9(currentPath, entry.name);
3589
3732
  const relativePath = fullPath.slice(relativeTo.length + 1);
3590
3733
  if (excludePatterns.some((pattern) => entry.name === pattern || relativePath.startsWith(`${pattern}/`))) {
3591
3734
  continue;
@@ -3593,7 +3736,7 @@ async function computeContentHash(dirPath, excludePatterns = CONTENT_HASH_EXCLUD
3593
3736
  if (entry.isDirectory()) {
3594
3737
  await collectFiles(fullPath, relativeTo);
3595
3738
  } else if (entry.isFile()) {
3596
- const content = await readFile9(fullPath);
3739
+ const content = await readFile10(fullPath);
3597
3740
  files.push({ relativePath, content });
3598
3741
  }
3599
3742
  }
@@ -3607,10 +3750,10 @@ async function computeContentHash(dirPath, excludePatterns = CONTENT_HASH_EXCLUD
3607
3750
  return hash.digest("hex");
3608
3751
  }
3609
3752
  async function detectDisplayVersion(dirPath, fallback, fallbackSource) {
3610
- const capTomlPath = join8(dirPath, "capability.toml");
3611
- if (existsSync12(capTomlPath)) {
3753
+ const capTomlPath = join9(dirPath, "capability.toml");
3754
+ if (existsSync13(capTomlPath)) {
3612
3755
  try {
3613
- const content = await readFile9(capTomlPath, "utf-8");
3756
+ const content = await readFile10(capTomlPath, "utf-8");
3614
3757
  const parsed = parse(content);
3615
3758
  const capability = parsed["capability"];
3616
3759
  if (capability?.["version"] && typeof capability["version"] === "string") {
@@ -3618,20 +3761,20 @@ async function detectDisplayVersion(dirPath, fallback, fallbackSource) {
3618
3761
  }
3619
3762
  } catch {}
3620
3763
  }
3621
- const pluginJsonPath = join8(dirPath, ".claude-plugin", "plugin.json");
3622
- if (existsSync12(pluginJsonPath)) {
3764
+ const pluginJsonPath = join9(dirPath, ".claude-plugin", "plugin.json");
3765
+ if (existsSync13(pluginJsonPath)) {
3623
3766
  try {
3624
- const content = await readFile9(pluginJsonPath, "utf-8");
3767
+ const content = await readFile10(pluginJsonPath, "utf-8");
3625
3768
  const parsed = JSON.parse(content);
3626
3769
  if (parsed.version && typeof parsed.version === "string") {
3627
3770
  return { version: parsed.version, source: "plugin.json" };
3628
3771
  }
3629
3772
  } catch {}
3630
3773
  }
3631
- const pkgJsonPath = join8(dirPath, "package.json");
3632
- if (existsSync12(pkgJsonPath)) {
3774
+ const pkgJsonPath = join9(dirPath, "package.json");
3775
+ if (existsSync13(pkgJsonPath)) {
3633
3776
  try {
3634
- const content = await readFile9(pkgJsonPath, "utf-8");
3777
+ const content = await readFile10(pkgJsonPath, "utf-8");
3635
3778
  const parsed = JSON.parse(content);
3636
3779
  if (parsed.version && typeof parsed.version === "string") {
3637
3780
  return { version: parsed.version, source: "package.json" };
@@ -3642,9 +3785,9 @@ async function detectDisplayVersion(dirPath, fallback, fallbackSource) {
3642
3785
  }
3643
3786
  async function validateGitCapability(sourceUrl, subPath) {
3644
3787
  const gitUrl = sourceToGitUrl(sourceUrl);
3645
- const tempPath = join8(OMNI_LOCAL, "_temp", `_validate-${Date.now()}`);
3788
+ const tempPath = join9(OMNI_LOCAL, "_temp", `_validate-${Date.now()}`);
3646
3789
  try {
3647
- await mkdir(join8(tempPath, ".."), { recursive: true });
3790
+ await mkdir(join9(tempPath, ".."), { recursive: true });
3648
3791
  const args = ["clone", "--depth", "1", gitUrl, tempPath];
3649
3792
  const { exitCode, stderr } = await spawnCapture("git", args, { timeout: 30000 });
3650
3793
  if (exitCode !== 0) {
@@ -3680,8 +3823,8 @@ async function validateGitCapability(sourceUrl, subPath) {
3680
3823
  error: `Failed to clone repository: ${stderr.trim()}`
3681
3824
  };
3682
3825
  }
3683
- const checkPath = subPath ? join8(tempPath, subPath) : tempPath;
3684
- if (subPath && !existsSync12(checkPath)) {
3826
+ const checkPath = subPath ? join9(tempPath, subPath) : tempPath;
3827
+ if (subPath && !existsSync13(checkPath)) {
3685
3828
  return {
3686
3829
  valid: false,
3687
3830
  hasCapabilityToml: false,
@@ -3692,9 +3835,9 @@ async function validateGitCapability(sourceUrl, subPath) {
3692
3835
  const hasCapToml = hasCapabilityToml(checkPath);
3693
3836
  let capabilityId;
3694
3837
  if (hasCapToml) {
3695
- const tomlPath = join8(checkPath, "capability.toml");
3838
+ const tomlPath = join9(checkPath, "capability.toml");
3696
3839
  try {
3697
- const content = await readFile9(tomlPath, "utf-8");
3840
+ const content = await readFile10(tomlPath, "utf-8");
3698
3841
  const parsed = parse(content);
3699
3842
  const capability = parsed["capability"];
3700
3843
  if (capability?.["id"] && typeof capability["id"] === "string") {
@@ -3726,27 +3869,27 @@ async function validateGitCapability(sourceUrl, subPath) {
3726
3869
  canBeWrapped: true
3727
3870
  };
3728
3871
  } finally {
3729
- if (existsSync12(tempPath)) {
3872
+ if (existsSync13(tempPath)) {
3730
3873
  await rm(tempPath, { recursive: true });
3731
3874
  }
3732
3875
  }
3733
3876
  }
3734
3877
  async function detectPinVersion(sourceUrl, subPath) {
3735
3878
  const gitUrl = sourceToGitUrl(sourceUrl);
3736
- const tempPath = join8(OMNI_LOCAL, "_temp", `_pin-detect-${Date.now()}`);
3879
+ const tempPath = join9(OMNI_LOCAL, "_temp", `_pin-detect-${Date.now()}`);
3737
3880
  try {
3738
- await mkdir(join8(tempPath, ".."), { recursive: true });
3881
+ await mkdir(join9(tempPath, ".."), { recursive: true });
3739
3882
  const args = ["clone", "--depth", "1", gitUrl, tempPath];
3740
3883
  const { exitCode, stderr } = await spawnCapture("git", args);
3741
3884
  if (exitCode !== 0) {
3742
3885
  throw new Error(`Failed to clone ${gitUrl}: ${stderr.trim()}`);
3743
3886
  }
3744
3887
  const commit = await getRepoCommit(tempPath);
3745
- const checkPath = subPath ? join8(tempPath, subPath) : tempPath;
3746
- const capTomlPath = join8(checkPath, "capability.toml");
3747
- if (existsSync12(capTomlPath)) {
3888
+ const checkPath = subPath ? join9(tempPath, subPath) : tempPath;
3889
+ const capTomlPath = join9(checkPath, "capability.toml");
3890
+ if (existsSync13(capTomlPath)) {
3748
3891
  try {
3749
- const content = await readFile9(capTomlPath, "utf-8");
3892
+ const content = await readFile10(capTomlPath, "utf-8");
3750
3893
  const parsed = parse(content);
3751
3894
  const capability = parsed["capability"];
3752
3895
  if (capability?.["version"] && typeof capability["version"] === "string") {
@@ -3754,10 +3897,10 @@ async function detectPinVersion(sourceUrl, subPath) {
3754
3897
  }
3755
3898
  } catch {}
3756
3899
  }
3757
- const pluginJsonPath = join8(checkPath, ".claude-plugin", "plugin.json");
3758
- if (existsSync12(pluginJsonPath)) {
3900
+ const pluginJsonPath = join9(checkPath, ".claude-plugin", "plugin.json");
3901
+ if (existsSync13(pluginJsonPath)) {
3759
3902
  try {
3760
- const content = await readFile9(pluginJsonPath, "utf-8");
3903
+ const content = await readFile10(pluginJsonPath, "utf-8");
3761
3904
  const parsed = JSON.parse(content);
3762
3905
  if (parsed.version && typeof parsed.version === "string") {
3763
3906
  return parsed.version;
@@ -3766,13 +3909,13 @@ async function detectPinVersion(sourceUrl, subPath) {
3766
3909
  }
3767
3910
  return commit;
3768
3911
  } finally {
3769
- if (existsSync12(tempPath)) {
3912
+ if (existsSync13(tempPath)) {
3770
3913
  await rm(tempPath, { recursive: true });
3771
3914
  }
3772
3915
  }
3773
3916
  }
3774
3917
  async function cloneRepo(gitUrl, targetPath, ref) {
3775
- await mkdir(join8(targetPath, ".."), { recursive: true });
3918
+ await mkdir(join9(targetPath, ".."), { recursive: true });
3776
3919
  const args = ["clone", "--depth", "1"];
3777
3920
  if (ref) {
3778
3921
  args.push("--branch", ref);
@@ -3830,16 +3973,16 @@ async function fetchRepo(repoPath, ref) {
3830
3973
  return true;
3831
3974
  }
3832
3975
  function hasCapabilityToml(dirPath) {
3833
- return existsSync12(join8(dirPath, "capability.toml"));
3976
+ return existsSync13(join9(dirPath, "capability.toml"));
3834
3977
  }
3835
3978
  async function shouldWrapDirectory(dirPath) {
3836
- if (existsSync12(join8(dirPath, ".claude-plugin", "plugin.json"))) {
3979
+ if (existsSync13(join9(dirPath, ".claude-plugin", "plugin.json"))) {
3837
3980
  return true;
3838
3981
  }
3839
3982
  const allDirs = [...SKILL_DIRS, ...AGENT_DIRS, ...COMMAND_DIRS, ...RULE_DIRS, ...DOC_DIRS];
3840
3983
  for (const dirName of allDirs) {
3841
- const checkPath = join8(dirPath, dirName);
3842
- if (existsSync12(checkPath)) {
3984
+ const checkPath = join9(dirPath, dirName);
3985
+ if (existsSync13(checkPath)) {
3843
3986
  const stats = await stat(checkPath);
3844
3987
  if (stats.isDirectory()) {
3845
3988
  return true;
@@ -3848,10 +3991,64 @@ async function shouldWrapDirectory(dirPath) {
3848
3991
  }
3849
3992
  return false;
3850
3993
  }
3994
+ function isRecognizedWrappedDirectory(dirName, keepGitDir = false) {
3995
+ if (keepGitDir && dirName === ".git") {
3996
+ return true;
3997
+ }
3998
+ return WRAPPED_CONTENT_DIRS.has(dirName);
3999
+ }
4000
+ function isMandatoryWrappedRootFile(fileName) {
4001
+ if (WRAPPED_ROOT_FILES_EXACT.has(fileName)) {
4002
+ return true;
4003
+ }
4004
+ return WRAPPED_ROOT_FILE_PATTERNS.some((pattern) => pattern.test(fileName));
4005
+ }
4006
+ async function copyWrappedContentOnly(sourcePath, targetPath) {
4007
+ await mkdir(targetPath, { recursive: true });
4008
+ const entries = await readdir(sourcePath, { withFileTypes: true });
4009
+ for (const entry of entries) {
4010
+ if (entry.isDirectory() && !isRecognizedWrappedDirectory(entry.name)) {
4011
+ continue;
4012
+ }
4013
+ if (entry.isFile() && !isMandatoryWrappedRootFile(entry.name)) {
4014
+ continue;
4015
+ }
4016
+ if (!entry.isDirectory() && !entry.isFile()) {
4017
+ continue;
4018
+ }
4019
+ const sourceEntryPath = join9(sourcePath, entry.name);
4020
+ const targetEntryPath = join9(targetPath, entry.name);
4021
+ if (entry.isDirectory()) {
4022
+ await cp(sourceEntryPath, targetEntryPath, { recursive: true });
4023
+ } else {
4024
+ await cp(sourceEntryPath, targetEntryPath);
4025
+ }
4026
+ }
4027
+ }
4028
+ async function pruneUnknownWrappedEntries(repoPath, keepGitDir = false) {
4029
+ const entries = await readdir(repoPath, { withFileTypes: true });
4030
+ for (const entry of entries) {
4031
+ if (entry.isDirectory()) {
4032
+ if (isRecognizedWrappedDirectory(entry.name, keepGitDir)) {
4033
+ continue;
4034
+ }
4035
+ await rm(join9(repoPath, entry.name), { recursive: true, force: true });
4036
+ continue;
4037
+ }
4038
+ if (entry.isFile()) {
4039
+ if (isMandatoryWrappedRootFile(entry.name)) {
4040
+ continue;
4041
+ }
4042
+ await rm(join9(repoPath, entry.name), { force: true });
4043
+ continue;
4044
+ }
4045
+ await rm(join9(repoPath, entry.name), { recursive: true, force: true });
4046
+ }
4047
+ }
3851
4048
  async function findMatchingDirs(basePath, names) {
3852
4049
  for (const name of names) {
3853
- const dirPath = join8(basePath, name);
3854
- if (existsSync12(dirPath)) {
4050
+ const dirPath = join9(basePath, name);
4051
+ if (existsSync13(dirPath)) {
3855
4052
  const stats = await stat(dirPath);
3856
4053
  if (stats.isDirectory()) {
3857
4054
  return dirPath;
@@ -3862,15 +4059,15 @@ async function findMatchingDirs(basePath, names) {
3862
4059
  }
3863
4060
  async function findContentItems(dirPath, filePatterns) {
3864
4061
  const items = [];
3865
- if (!existsSync12(dirPath)) {
4062
+ if (!existsSync13(dirPath)) {
3866
4063
  return items;
3867
4064
  }
3868
4065
  const entries = (await readdir(dirPath, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name));
3869
4066
  for (const entry of entries) {
3870
- const entryPath = join8(dirPath, entry.name);
4067
+ const entryPath = join9(dirPath, entry.name);
3871
4068
  if (entry.isDirectory()) {
3872
4069
  for (const pattern of filePatterns) {
3873
- if (existsSync12(join8(entryPath, pattern))) {
4070
+ if (existsSync13(join9(entryPath, pattern))) {
3874
4071
  items.push({
3875
4072
  name: entry.name,
3876
4073
  path: entryPath,
@@ -3891,12 +4088,12 @@ async function findContentItems(dirPath, filePatterns) {
3891
4088
  return items;
3892
4089
  }
3893
4090
  async function parsePluginJson(dirPath) {
3894
- const pluginJsonPath = join8(dirPath, ".claude-plugin", "plugin.json");
3895
- if (!existsSync12(pluginJsonPath)) {
4091
+ const pluginJsonPath = join9(dirPath, ".claude-plugin", "plugin.json");
4092
+ if (!existsSync13(pluginJsonPath)) {
3896
4093
  return null;
3897
4094
  }
3898
4095
  try {
3899
- const content = await readFile9(pluginJsonPath, "utf-8");
4096
+ const content = await readFile10(pluginJsonPath, "utf-8");
3900
4097
  const data = JSON.parse(content);
3901
4098
  const result = {
3902
4099
  name: data.name,
@@ -3916,12 +4113,12 @@ async function parsePluginJson(dirPath) {
3916
4113
  }
3917
4114
  }
3918
4115
  async function readReadmeDescription(dirPath) {
3919
- const readmePath = join8(dirPath, "README.md");
3920
- if (!existsSync12(readmePath)) {
4116
+ const readmePath = join9(dirPath, "README.md");
4117
+ if (!existsSync13(readmePath)) {
3921
4118
  return null;
3922
4119
  }
3923
4120
  try {
3924
- const content = await readFile9(readmePath, "utf-8");
4121
+ const content = await readFile10(readmePath, "utf-8");
3925
4122
  const lines = content.split(`
3926
4123
  `);
3927
4124
  let description = "";
@@ -3956,9 +4153,9 @@ async function normalizeFolderNames(repoPath) {
3956
4153
  { from: "rule", to: "rules" }
3957
4154
  ];
3958
4155
  for (const { from, to } of renameMappings) {
3959
- const fromPath = join8(repoPath, from);
3960
- const toPath = join8(repoPath, to);
3961
- if (existsSync12(fromPath) && !existsSync12(toPath)) {
4156
+ const fromPath = join9(repoPath, from);
4157
+ const toPath = join9(repoPath, to);
4158
+ if (existsSync13(fromPath) && !existsSync13(toPath)) {
3962
4159
  try {
3963
4160
  const stats = await stat(fromPath);
3964
4161
  if (stats.isDirectory()) {
@@ -4047,7 +4244,7 @@ repository = "${escapeTomlString(repoUrl)}"
4047
4244
  wrapped = true
4048
4245
  commit = "${commit}"
4049
4246
  `;
4050
- await writeFile3(join8(repoPath, "capability.toml"), tomlContent, "utf-8");
4247
+ await writeFile3(join9(repoPath, "capability.toml"), tomlContent, "utf-8");
4051
4248
  }
4052
4249
  async function fetchGitCapabilitySource(id, config, options) {
4053
4250
  const gitUrl = sourceToGitUrl(config.source);
@@ -4055,31 +4252,40 @@ async function fetchGitCapabilitySource(id, config, options) {
4055
4252
  let updated = false;
4056
4253
  let commit;
4057
4254
  let repoPath;
4255
+ let needsWrap = false;
4058
4256
  const gitRef = config.version && config.version !== "latest" ? config.version : undefined;
4059
4257
  if (config.path) {
4060
- const tempPath = join8(OMNI_LOCAL, "_temp", `${id}-repo`);
4061
- if (existsSync12(join8(tempPath, ".git"))) {
4258
+ const tempPath = join9(OMNI_LOCAL, "_temp", `${id}-repo`);
4259
+ if (existsSync13(join9(tempPath, ".git"))) {
4062
4260
  updated = await fetchRepo(tempPath, gitRef);
4063
4261
  commit = await getRepoCommit(tempPath);
4064
4262
  } else {
4065
- await mkdir(join8(tempPath, ".."), { recursive: true });
4263
+ await mkdir(join9(tempPath, ".."), { recursive: true });
4066
4264
  await cloneRepo(gitUrl, tempPath, gitRef);
4067
4265
  commit = await getRepoCommit(tempPath);
4068
4266
  updated = true;
4069
4267
  }
4070
- const sourcePath = join8(tempPath, config.path);
4071
- if (!existsSync12(sourcePath)) {
4268
+ const sourcePath = join9(tempPath, config.path);
4269
+ if (!existsSync13(sourcePath)) {
4072
4270
  throw new Error(`Path not found in repository: ${config.path}`);
4073
4271
  }
4074
- if (existsSync12(targetPath)) {
4272
+ const sourceHasCapabilityToml = hasCapabilityToml(sourcePath);
4273
+ if (!sourceHasCapabilityToml) {
4274
+ needsWrap = await shouldWrapDirectory(sourcePath);
4275
+ }
4276
+ if (existsSync13(targetPath)) {
4075
4277
  await rm(targetPath, { recursive: true });
4076
4278
  }
4077
- await mkdir(join8(targetPath, ".."), { recursive: true });
4078
- await cp(sourcePath, targetPath, { recursive: true });
4279
+ await mkdir(join9(targetPath, ".."), { recursive: true });
4280
+ if (needsWrap) {
4281
+ await copyWrappedContentOnly(sourcePath, targetPath);
4282
+ } else {
4283
+ await cp(sourcePath, targetPath, { recursive: true });
4284
+ }
4079
4285
  await rm(tempPath, { recursive: true });
4080
4286
  repoPath = targetPath;
4081
4287
  } else {
4082
- if (existsSync12(join8(targetPath, ".git"))) {
4288
+ if (existsSync13(join9(targetPath, ".git"))) {
4083
4289
  if (!options?.silent) {
4084
4290
  console.log(` Checking ${id}...`);
4085
4291
  }
@@ -4095,11 +4301,11 @@ async function fetchGitCapabilitySource(id, config, options) {
4095
4301
  }
4096
4302
  repoPath = targetPath;
4097
4303
  }
4098
- let needsWrap = false;
4099
- if (!hasCapabilityToml(repoPath)) {
4304
+ if (!config.path && !hasCapabilityToml(repoPath)) {
4100
4305
  needsWrap = await shouldWrapDirectory(repoPath);
4101
4306
  }
4102
4307
  if (needsWrap) {
4308
+ await pruneUnknownWrappedEntries(repoPath, true);
4103
4309
  await normalizeFolderNames(repoPath);
4104
4310
  const content = await discoverContent(repoPath);
4105
4311
  await generateCapabilityToml(id, repoPath, config.source, commit, content);
@@ -4130,7 +4336,7 @@ async function fetchGitCapabilitySource(id, config, options) {
4130
4336
  async function fetchFileCapabilitySource(id, config, options) {
4131
4337
  const sourcePath = parseFileSourcePath(config.source);
4132
4338
  const targetPath = getSourceCapabilityPath(id);
4133
- if (!existsSync12(sourcePath)) {
4339
+ if (!existsSync13(sourcePath)) {
4134
4340
  throw new Error(`File source not found: ${sourcePath}`);
4135
4341
  }
4136
4342
  const sourceStats = await stat(sourcePath);
@@ -4138,7 +4344,7 @@ async function fetchFileCapabilitySource(id, config, options) {
4138
4344
  throw new Error(`File source must be a directory: ${sourcePath}`);
4139
4345
  }
4140
4346
  const contentHash = await computeContentHash(sourcePath);
4141
- const hasCapToml = existsSync12(join8(sourcePath, "capability.toml"));
4347
+ const hasCapToml = existsSync13(join9(sourcePath, "capability.toml"));
4142
4348
  let needsWrap = false;
4143
4349
  if (!hasCapToml) {
4144
4350
  needsWrap = await shouldWrapDirectory(sourcePath);
@@ -4149,11 +4355,15 @@ async function fetchFileCapabilitySource(id, config, options) {
4149
4355
  if (!options?.silent) {
4150
4356
  console.log(` Copying ${id} from ${sourcePath}...`);
4151
4357
  }
4152
- if (existsSync12(targetPath)) {
4358
+ if (existsSync13(targetPath)) {
4153
4359
  await rm(targetPath, { recursive: true });
4154
4360
  }
4155
- await mkdir(join8(targetPath, ".."), { recursive: true });
4156
- await cp(sourcePath, targetPath, { recursive: true });
4361
+ await mkdir(join9(targetPath, ".."), { recursive: true });
4362
+ if (needsWrap) {
4363
+ await copyWrappedContentOnly(sourcePath, targetPath);
4364
+ } else {
4365
+ await cp(sourcePath, targetPath, { recursive: true });
4366
+ }
4157
4367
  if (needsWrap) {
4158
4368
  await normalizeFolderNames(targetPath);
4159
4369
  const content = await discoverContent(targetPath);
@@ -4232,7 +4442,7 @@ description = "${escapeTomlString(description)}"
4232
4442
  wrapped = true
4233
4443
  source = "${escapeTomlString(source)}"
4234
4444
  `;
4235
- await writeFile3(join8(targetPath, "capability.toml"), tomlContent, "utf-8");
4445
+ await writeFile3(join9(targetPath, "capability.toml"), tomlContent, "utf-8");
4236
4446
  }
4237
4447
  async function fetchCapabilitySource(id, sourceConfig, options) {
4238
4448
  const config = parseSourceConfig(sourceConfig);
@@ -4305,16 +4515,16 @@ generated_from_omni_toml = true
4305
4515
  }
4306
4516
  async function generateMcpCapabilityToml(id, mcpConfig, targetPath) {
4307
4517
  const tomlContent = generateMcpCapabilityTomlContent(id, mcpConfig);
4308
- await writeFile3(join8(targetPath, "capability.toml"), tomlContent, "utf-8");
4518
+ await writeFile3(join9(targetPath, "capability.toml"), tomlContent, "utf-8");
4309
4519
  }
4310
4520
  async function isGeneratedMcpCapability(capabilityDir) {
4311
- const tomlPath = join8(capabilityDir, "capability.toml");
4312
- if (!existsSync12(tomlPath)) {
4521
+ const tomlPath = join9(capabilityDir, "capability.toml");
4522
+ if (!existsSync13(tomlPath)) {
4313
4523
  console.warn("no capability.toml found in", capabilityDir);
4314
4524
  return false;
4315
4525
  }
4316
4526
  try {
4317
- const content = await readFile9(tomlPath, "utf-8");
4527
+ const content = await readFile10(tomlPath, "utf-8");
4318
4528
  const parsed = parse(content);
4319
4529
  const capability = parsed["capability"];
4320
4530
  const metadata = capability?.["metadata"];
@@ -4324,14 +4534,14 @@ async function isGeneratedMcpCapability(capabilityDir) {
4324
4534
  }
4325
4535
  }
4326
4536
  async function cleanupStaleMcpCapabilities(currentMcpIds) {
4327
- const capabilitiesDir = join8(OMNI_LOCAL, "capabilities");
4328
- if (!existsSync12(capabilitiesDir)) {
4537
+ const capabilitiesDir = join9(OMNI_LOCAL, "capabilities");
4538
+ if (!existsSync13(capabilitiesDir)) {
4329
4539
  return;
4330
4540
  }
4331
4541
  const entries = await readdir(capabilitiesDir, { withFileTypes: true });
4332
4542
  for (const entry of entries) {
4333
4543
  if (entry.isDirectory()) {
4334
- const capDir = join8(capabilitiesDir, entry.name);
4544
+ const capDir = join9(capabilitiesDir, entry.name);
4335
4545
  const isGenerated = await isGeneratedMcpCapability(capDir);
4336
4546
  if (isGenerated && !currentMcpIds.has(entry.name)) {
4337
4547
  await rm(capDir, { recursive: true });
@@ -4344,10 +4554,10 @@ async function generateMcpCapabilities(config) {
4344
4554
  await cleanupStaleMcpCapabilities(new Set);
4345
4555
  return;
4346
4556
  }
4347
- const mcpCapabilitiesDir = join8(OMNI_LOCAL, "capabilities");
4557
+ const mcpCapabilitiesDir = join9(OMNI_LOCAL, "capabilities");
4348
4558
  const currentMcpIds = new Set;
4349
4559
  for (const [id, mcpConfig] of Object.entries(config.mcps)) {
4350
- const targetPath = join8(mcpCapabilitiesDir, id);
4560
+ const targetPath = join9(mcpCapabilitiesDir, id);
4351
4561
  currentMcpIds.add(id);
4352
4562
  await mkdir(targetPath, { recursive: true });
4353
4563
  await generateMcpCapabilityToml(id, mcpConfig, targetPath);
@@ -4356,8 +4566,8 @@ async function generateMcpCapabilities(config) {
4356
4566
  }
4357
4567
  async function fetchAllCapabilitySources(config, options) {
4358
4568
  await generateMcpCapabilities(config);
4359
- const tempDir = join8(OMNI_LOCAL, "_temp");
4360
- if (existsSync12(tempDir)) {
4569
+ const tempDir = join9(OMNI_LOCAL, "_temp");
4570
+ if (existsSync13(tempDir)) {
4361
4571
  await rm(tempDir, { recursive: true });
4362
4572
  }
4363
4573
  const sources = config.capabilities?.sources;
@@ -4443,7 +4653,7 @@ async function checkForUpdates(config) {
4443
4653
  continue;
4444
4654
  }
4445
4655
  const gitConfig = sourceConfig;
4446
- if (!existsSync12(join8(targetPath, ".git"))) {
4656
+ if (!existsSync13(join9(targetPath, ".git"))) {
4447
4657
  updates.push({
4448
4658
  id,
4449
4659
  source: gitConfig.source,
@@ -4486,12 +4696,12 @@ function checkVersionMismatch(lockEntry, currentCommit, currentVersion) {
4486
4696
  }
4487
4697
  async function verifyIntegrity(id, lockEntry) {
4488
4698
  const capabilityPath = getSourceCapabilityPath(id);
4489
- if (!existsSync12(capabilityPath)) {
4699
+ if (!existsSync13(capabilityPath)) {
4490
4700
  return "capability directory missing";
4491
4701
  }
4492
4702
  if (lockEntry.commit) {
4493
- const gitDir = join8(capabilityPath, ".git");
4494
- if (existsSync12(gitDir)) {
4703
+ const gitDir = join9(capabilityPath, ".git");
4704
+ if (existsSync13(gitDir)) {
4495
4705
  try {
4496
4706
  const currentCommit = await getRepoCommit(capabilityPath);
4497
4707
  if (currentCommit !== lockEntry.commit) {
@@ -4510,7 +4720,7 @@ async function verifyIntegrity(id, lockEntry) {
4510
4720
  }
4511
4721
  return null;
4512
4722
  }
4513
- var OMNI_LOCAL = ".omni", SKILL_DIRS, AGENT_DIRS, COMMAND_DIRS, RULE_DIRS, DOC_DIRS, SKILL_FILES, AGENT_FILES, COMMAND_FILES, CONTENT_HASH_EXCLUDES;
4723
+ var OMNI_LOCAL = ".omni", SKILL_DIRS, AGENT_DIRS, COMMAND_DIRS, RULE_DIRS, DOC_DIRS, WRAPPED_CONTENT_DIRS, WRAPPED_ROOT_FILES_EXACT, WRAPPED_ROOT_FILE_PATTERNS, SKILL_FILES, AGENT_FILES, COMMAND_FILES, CONTENT_HASH_EXCLUDES;
4514
4724
  var init_sources = __esm(() => {
4515
4725
  init_dist();
4516
4726
  init_types2();
@@ -4519,6 +4729,23 @@ var init_sources = __esm(() => {
4519
4729
  COMMAND_DIRS = ["commands", "command"];
4520
4730
  RULE_DIRS = ["rules", "rule"];
4521
4731
  DOC_DIRS = ["docs", "doc", "documentation"];
4732
+ WRAPPED_CONTENT_DIRS = new Set([
4733
+ ...SKILL_DIRS,
4734
+ ...AGENT_DIRS,
4735
+ ...COMMAND_DIRS,
4736
+ ...RULE_DIRS,
4737
+ ...DOC_DIRS,
4738
+ "hooks",
4739
+ ".claude-plugin"
4740
+ ]);
4741
+ WRAPPED_ROOT_FILES_EXACT = new Set([".gitignore", "hooks.json"]);
4742
+ WRAPPED_ROOT_FILE_PATTERNS = [
4743
+ /^readme(?:\..+)?$/i,
4744
+ /^license(?:\..+)?$/i,
4745
+ /^licence(?:\..+)?$/i,
4746
+ /^notice(?:\..+)?$/i,
4747
+ /^copying(?:\..+)?$/i
4748
+ ];
4522
4749
  SKILL_FILES = ["SKILL.md", "skill.md", "Skill.md"];
4523
4750
  AGENT_FILES = ["AGENT.md", "agent.md", "Agent.md", "SUBAGENT.md", "subagent.md"];
4524
4751
  COMMAND_FILES = ["COMMAND.md", "command.md", "Command.md"];
@@ -4560,13 +4787,13 @@ var init_hooks = __esm(() => {
4560
4787
  });
4561
4788
 
4562
4789
  // ../core/src/config/provider.ts
4563
- import { existsSync as existsSync13 } from "node:fs";
4564
- import { readFile as readFile10, writeFile as writeFile4 } from "node:fs/promises";
4790
+ import { existsSync as existsSync14 } from "node:fs";
4791
+ import { readFile as readFile11, writeFile as writeFile4 } from "node:fs/promises";
4565
4792
  async function loadProviderConfig() {
4566
- if (!existsSync13(PROVIDER_CONFIG_PATH)) {
4793
+ if (!existsSync14(PROVIDER_CONFIG_PATH)) {
4567
4794
  return { provider: "claude" };
4568
4795
  }
4569
- const content = await readFile10(PROVIDER_CONFIG_PATH, "utf-8");
4796
+ const content = await readFile11(PROVIDER_CONFIG_PATH, "utf-8");
4570
4797
  const parsed = parse(content);
4571
4798
  return parsed;
4572
4799
  }
@@ -4613,13 +4840,13 @@ var init_provider = __esm(() => {
4613
4840
  });
4614
4841
 
4615
4842
  // ../core/src/config/toml-patcher.ts
4616
- import { existsSync as existsSync14 } from "node:fs";
4617
- import { readFile as readFile11, writeFile as writeFile5 } from "node:fs/promises";
4843
+ import { existsSync as existsSync15 } from "node:fs";
4844
+ import { readFile as readFile12, writeFile as writeFile5 } from "node:fs/promises";
4618
4845
  async function readConfigFile() {
4619
- if (!existsSync14(CONFIG_PATH2)) {
4846
+ if (!existsSync15(CONFIG_PATH2)) {
4620
4847
  return "";
4621
4848
  }
4622
- return readFile11(CONFIG_PATH2, "utf-8");
4849
+ return readFile12(CONFIG_PATH2, "utf-8");
4623
4850
  }
4624
4851
  async function writeConfigFile(content) {
4625
4852
  await writeFile5(CONFIG_PATH2, content, "utf-8");
@@ -4841,14 +5068,14 @@ var init_config2 = __esm(() => {
4841
5068
  });
4842
5069
 
4843
5070
  // ../core/src/mcp-json/manager.ts
4844
- import { existsSync as existsSync15 } from "node:fs";
4845
- import { readFile as readFile12, writeFile as writeFile6 } from "node:fs/promises";
5071
+ import { existsSync as existsSync16 } from "node:fs";
5072
+ import { readFile as readFile13, writeFile as writeFile6 } from "node:fs/promises";
4846
5073
  async function readMcpJson() {
4847
- if (!existsSync15(MCP_JSON_PATH)) {
5074
+ if (!existsSync16(MCP_JSON_PATH)) {
4848
5075
  return { mcpServers: {} };
4849
5076
  }
4850
5077
  try {
4851
- const content = await readFile12(MCP_JSON_PATH, "utf-8");
5078
+ const content = await readFile13(MCP_JSON_PATH, "utf-8");
4852
5079
  const parsed = JSON.parse(content);
4853
5080
  return {
4854
5081
  mcpServers: parsed.mcpServers || {}
@@ -4930,17 +5157,17 @@ var init_mcp_json = __esm(() => {
4930
5157
  });
4931
5158
 
4932
5159
  // ../core/src/state/manifest.ts
4933
- import { existsSync as existsSync16, mkdirSync as mkdirSync2, rmSync } from "node:fs";
4934
- import { readFile as readFile13, writeFile as writeFile7 } from "node:fs/promises";
5160
+ import { existsSync as existsSync17, mkdirSync as mkdirSync2, rmSync } from "node:fs";
5161
+ import { readFile as readFile14, writeFile as writeFile7 } from "node:fs/promises";
4935
5162
  async function loadManifest() {
4936
- if (!existsSync16(MANIFEST_PATH)) {
5163
+ if (!existsSync17(MANIFEST_PATH)) {
4937
5164
  return {
4938
5165
  version: CURRENT_VERSION,
4939
5166
  syncedAt: new Date().toISOString(),
4940
5167
  capabilities: {}
4941
5168
  };
4942
5169
  }
4943
- const content = await readFile13(MANIFEST_PATH, "utf-8");
5170
+ const content = await readFile14(MANIFEST_PATH, "utf-8");
4944
5171
  return JSON.parse(content);
4945
5172
  }
4946
5173
  async function saveManifest(manifest) {
@@ -4980,14 +5207,14 @@ async function cleanupStaleResources(previousManifest, currentCapabilityIds) {
4980
5207
  }
4981
5208
  for (const skillName of resources.skills) {
4982
5209
  const skillDir = `.claude/skills/${skillName}`;
4983
- if (existsSync16(skillDir)) {
5210
+ if (existsSync17(skillDir)) {
4984
5211
  rmSync(skillDir, { recursive: true });
4985
5212
  result.deletedSkills.push(skillName);
4986
5213
  }
4987
5214
  }
4988
5215
  for (const ruleName of resources.rules) {
4989
5216
  const rulePath = `.cursor/rules/omnidev-${ruleName}.mdc`;
4990
- if (existsSync16(rulePath)) {
5217
+ if (existsSync17(rulePath)) {
4991
5218
  rmSync(rulePath);
4992
5219
  result.deletedRules.push(ruleName);
4993
5220
  }
@@ -4999,14 +5226,14 @@ var MANIFEST_PATH = ".omni/state/manifest.json", CURRENT_VERSION = 1;
4999
5226
  var init_manifest = () => {};
5000
5227
 
5001
5228
  // ../core/src/state/providers.ts
5002
- import { existsSync as existsSync17, mkdirSync as mkdirSync3 } from "node:fs";
5003
- import { readFile as readFile14, writeFile as writeFile8 } from "node:fs/promises";
5229
+ import { existsSync as existsSync18, mkdirSync as mkdirSync3 } from "node:fs";
5230
+ import { readFile as readFile15, writeFile as writeFile8 } from "node:fs/promises";
5004
5231
  async function readEnabledProviders() {
5005
- if (!existsSync17(PROVIDERS_PATH)) {
5232
+ if (!existsSync18(PROVIDERS_PATH)) {
5006
5233
  return DEFAULT_PROVIDERS;
5007
5234
  }
5008
5235
  try {
5009
- const content = await readFile14(PROVIDERS_PATH, "utf-8");
5236
+ const content = await readFile15(PROVIDERS_PATH, "utf-8");
5010
5237
  const state = JSON.parse(content);
5011
5238
  return state.enabled.length > 0 ? state.enabled : DEFAULT_PROVIDERS;
5012
5239
  } catch {
@@ -5035,20 +5262,20 @@ async function isProviderEnabled(providerId) {
5035
5262
  return current.includes(providerId);
5036
5263
  }
5037
5264
  var STATE_DIR2 = ".omni/state", PROVIDERS_PATH, DEFAULT_PROVIDERS;
5038
- var init_providers = __esm(() => {
5265
+ var init_providers2 = __esm(() => {
5039
5266
  PROVIDERS_PATH = `${STATE_DIR2}/providers.json`;
5040
5267
  DEFAULT_PROVIDERS = ["claude-code"];
5041
5268
  });
5042
5269
 
5043
5270
  // ../core/src/state/security-allows.ts
5044
- import { existsSync as existsSync18, mkdirSync as mkdirSync4 } from "node:fs";
5045
- import { readFile as readFile15, writeFile as writeFile9 } from "node:fs/promises";
5271
+ import { existsSync as existsSync19, mkdirSync as mkdirSync4 } from "node:fs";
5272
+ import { readFile as readFile16, writeFile as writeFile9 } from "node:fs/promises";
5046
5273
  async function readSecurityAllows() {
5047
- if (!existsSync18(SECURITY_PATH)) {
5274
+ if (!existsSync19(SECURITY_PATH)) {
5048
5275
  return { ...DEFAULT_STATE };
5049
5276
  }
5050
5277
  try {
5051
- const content = await readFile15(SECURITY_PATH, "utf-8");
5278
+ const content = await readFile16(SECURITY_PATH, "utf-8");
5052
5279
  const state = JSON.parse(content);
5053
5280
  return state;
5054
5281
  } catch {
@@ -5137,7 +5364,7 @@ var init_security_allows = __esm(() => {
5137
5364
  var init_state = __esm(() => {
5138
5365
  init_active_profile();
5139
5366
  init_manifest();
5140
- init_providers();
5367
+ init_providers2();
5141
5368
  init_security_allows();
5142
5369
  });
5143
5370
 
@@ -5145,11 +5372,11 @@ var init_state = __esm(() => {
5145
5372
  import { spawn as spawn2 } from "node:child_process";
5146
5373
  import { mkdirSync as mkdirSync5 } from "node:fs";
5147
5374
  async function installCapabilityDependencies(silent) {
5148
- const { existsSync: existsSync19, readdirSync: readdirSync7, readFileSync: readFileSync3 } = await import("node:fs");
5149
- const { join: join9 } = await import("node:path");
5375
+ const { existsSync: existsSync20, readdirSync: readdirSync7, readFileSync: readFileSync3 } = await import("node:fs");
5376
+ const { join: join10 } = await import("node:path");
5150
5377
  const { parse: parse2 } = await Promise.resolve().then(() => (init_dist(), exports_dist));
5151
5378
  const capabilitiesDir = ".omni/capabilities";
5152
- if (!existsSync19(capabilitiesDir)) {
5379
+ if (!existsSync20(capabilitiesDir)) {
5153
5380
  return;
5154
5381
  }
5155
5382
  const entries = readdirSync7(capabilitiesDir, { withFileTypes: true });
@@ -5169,13 +5396,13 @@ async function installCapabilityDependencies(silent) {
5169
5396
  if (!entry.isDirectory()) {
5170
5397
  continue;
5171
5398
  }
5172
- const capabilityPath = join9(capabilitiesDir, entry.name);
5173
- const packageJsonPath = join9(capabilityPath, "package.json");
5174
- const capabilityTomlPath = join9(capabilityPath, "capability.toml");
5175
- if (!existsSync19(packageJsonPath)) {
5399
+ const capabilityPath = join10(capabilitiesDir, entry.name);
5400
+ const packageJsonPath = join10(capabilityPath, "package.json");
5401
+ const capabilityTomlPath = join10(capabilityPath, "capability.toml");
5402
+ if (!existsSync20(packageJsonPath)) {
5176
5403
  continue;
5177
5404
  }
5178
- if (existsSync19(capabilityTomlPath)) {
5405
+ if (existsSync20(capabilityTomlPath)) {
5179
5406
  try {
5180
5407
  const tomlContent = readFileSync3(capabilityTomlPath, "utf-8");
5181
5408
  const parsed = parse2(tomlContent);
@@ -5186,7 +5413,7 @@ async function installCapabilityDependencies(silent) {
5186
5413
  }
5187
5414
  try {
5188
5415
  await new Promise((resolve2, reject) => {
5189
- const useNpmCi = hasNpm && existsSync19(join9(capabilityPath, "package-lock.json"));
5416
+ const useNpmCi = hasNpm && existsSync20(join10(capabilityPath, "package-lock.json"));
5190
5417
  const cmd = hasBun ? "bun" : "npm";
5191
5418
  const args = hasBun ? ["install"] : useNpmCi ? ["ci"] : ["install"];
5192
5419
  const proc = spawn2(cmd, args, {
@@ -5209,7 +5436,7 @@ ${stderr}`));
5209
5436
  reject(error);
5210
5437
  });
5211
5438
  });
5212
- const hasIndexTs = existsSync19(join9(capabilityPath, "index.ts"));
5439
+ const hasIndexTs = existsSync20(join10(capabilityPath, "index.ts"));
5213
5440
  let hasBuildScript = false;
5214
5441
  try {
5215
5442
  const pkgJson = JSON.parse(readFileSync3(packageJsonPath, "utf-8"));
@@ -5240,7 +5467,7 @@ ${stderr}`));
5240
5467
  });
5241
5468
  });
5242
5469
  } else if (hasIndexTs && !silent) {
5243
- const hasBuiltIndex = existsSync19(join9(capabilityPath, "dist", "index.js"));
5470
+ const hasBuiltIndex = existsSync20(join10(capabilityPath, "dist", "index.js"));
5244
5471
  if (!hasBuiltIndex) {
5245
5472
  console.warn(`Warning: Capability at ${capabilityPath} has index.ts but no build script.
5246
5473
  Add a "build" script to package.json (e.g., "build": "tsc") to compile TypeScript.`);
@@ -5383,13 +5610,13 @@ var init_types3 = __esm(() => {
5383
5610
  });
5384
5611
 
5385
5612
  // ../core/src/security/scanner.ts
5386
- import { existsSync as existsSync19 } from "node:fs";
5387
- import { lstat, readdir as readdir2, readFile as readFile16, readlink, realpath } from "node:fs/promises";
5388
- import { join as join9, relative, resolve as resolve2 } from "node:path";
5613
+ import { existsSync as existsSync20 } from "node:fs";
5614
+ import { lstat, readdir as readdir2, readFile as readFile17, readlink, realpath } from "node:fs/promises";
5615
+ import { join as join10, relative, resolve as resolve2 } from "node:path";
5389
5616
  async function scanFileForUnicode(filePath, relativePath) {
5390
5617
  const findings = [];
5391
5618
  try {
5392
- const content = await readFile16(filePath, "utf-8");
5619
+ const content = await readFile17(filePath, "utf-8");
5393
5620
  const lines = content.split(`
5394
5621
  `);
5395
5622
  for (let lineNum = 0;lineNum < lines.length; lineNum++) {
@@ -5443,7 +5670,7 @@ async function scanFileForUnicode(filePath, relativePath) {
5443
5670
  async function scanFileForScripts(filePath, relativePath) {
5444
5671
  const findings = [];
5445
5672
  try {
5446
- const content = await readFile16(filePath, "utf-8");
5673
+ const content = await readFile17(filePath, "utf-8");
5447
5674
  const lines = content.split(`
5448
5675
  `);
5449
5676
  for (let lineNum = 0;lineNum < lines.length; lineNum++) {
@@ -5469,7 +5696,7 @@ async function scanFileForScripts(filePath, relativePath) {
5469
5696
  async function checkSymlink(symlinkPath, relativePath, capabilityRoot) {
5470
5697
  try {
5471
5698
  const linkTarget = await readlink(symlinkPath);
5472
- const resolvedTarget = resolve2(join9(symlinkPath, "..", linkTarget));
5699
+ const resolvedTarget = resolve2(join10(symlinkPath, "..", linkTarget));
5473
5700
  const normalizedRoot = await realpath(capabilityRoot);
5474
5701
  if (linkTarget.startsWith("/")) {
5475
5702
  return {
@@ -5504,7 +5731,7 @@ function isTextFile(filePath) {
5504
5731
  async function scanCapability(capabilityId, capabilityPath, settings = DEFAULT_SCAN_SETTINGS) {
5505
5732
  const startTime = Date.now();
5506
5733
  const findings = [];
5507
- if (!existsSync19(capabilityPath)) {
5734
+ if (!existsSync20(capabilityPath)) {
5508
5735
  return {
5509
5736
  capabilityId,
5510
5737
  path: capabilityPath,
@@ -5516,7 +5743,7 @@ async function scanCapability(capabilityId, capabilityPath, settings = DEFAULT_S
5516
5743
  async function scanDirectory(dirPath) {
5517
5744
  const entries = await readdir2(dirPath, { withFileTypes: true });
5518
5745
  for (const entry of entries) {
5519
- const fullPath = join9(dirPath, entry.name);
5746
+ const fullPath = join10(dirPath, entry.name);
5520
5747
  const relativePath = relative(capabilityPath, fullPath);
5521
5748
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "__pycache__") {
5522
5749
  continue;
@@ -6009,6 +6236,8 @@ __export(exports_src, {
6009
6236
  parseOmniConfig: () => parseOmniConfig,
6010
6237
  parseFileSourcePath: () => parseFileSourcePath,
6011
6238
  parseCapabilityConfig: () => parseCapabilityConfig,
6239
+ normalizeProviderId: () => normalizeProviderId,
6240
+ normalizeProviderApplicability: () => normalizeProviderApplicability,
6012
6241
  mergeHooksConfigs: () => mergeHooksConfigs,
6013
6242
  mergeAndDeduplicateHooks: () => mergeAndDeduplicateHooks,
6014
6243
  loadSubagents: () => loadSubagents,
@@ -6116,6 +6345,7 @@ var init_src = __esm(() => {
6116
6345
  init_state();
6117
6346
  init_sync();
6118
6347
  init_security();
6348
+ init_providers();
6119
6349
  init_types2();
6120
6350
  });
6121
6351
 
@@ -6123,17 +6353,17 @@ var init_src = __esm(() => {
6123
6353
  import { run } from "@stricli/core";
6124
6354
 
6125
6355
  // src/lib/dynamic-app.ts
6126
- import { existsSync as existsSync29 } from "node:fs";
6356
+ import { existsSync as existsSync30 } from "node:fs";
6127
6357
  import { createRequire as createRequire2 } from "node:module";
6128
- import { join as join26 } from "node:path";
6358
+ import { join as join27 } from "node:path";
6129
6359
  import { buildApplication, buildRouteMap as buildRouteMap7 } from "@stricli/core";
6130
6360
 
6131
6361
  // src/commands/add.ts
6132
- import { existsSync as existsSync22 } from "node:fs";
6362
+ import { existsSync as existsSync23 } from "node:fs";
6133
6363
  import { basename as basename5, resolve as resolve3 } from "node:path";
6134
6364
 
6135
6365
  // ../adapters/src/writers/generic/executor.ts
6136
- async function executeWriters(writerConfigs, bundle, projectRoot) {
6366
+ async function executeWriters(writerConfigs, bundle, projectRoot, providerId) {
6137
6367
  const seen = new Set;
6138
6368
  const uniqueConfigs = [];
6139
6369
  let deduplicatedCount = 0;
@@ -6150,7 +6380,8 @@ async function executeWriters(writerConfigs, bundle, projectRoot) {
6150
6380
  for (const config of uniqueConfigs) {
6151
6381
  const result = await config.writer.write(bundle, {
6152
6382
  outputPath: config.outputPath,
6153
- projectRoot
6383
+ projectRoot,
6384
+ ...providerId ? { providerId } : {}
6154
6385
  });
6155
6386
  allFilesWritten.push(...result.filesWritten);
6156
6387
  }
@@ -6161,23 +6392,23 @@ async function executeWriters(writerConfigs, bundle, projectRoot) {
6161
6392
  }
6162
6393
  // ../adapters/src/writers/generic/hooks.ts
6163
6394
  init_src();
6164
- import { existsSync as existsSync20 } from "node:fs";
6165
- import { mkdir as mkdir2, readFile as readFile17, writeFile as writeFile10 } from "node:fs/promises";
6166
- import { dirname, join as join10 } from "node:path";
6395
+ import { existsSync as existsSync21 } from "node:fs";
6396
+ import { mkdir as mkdir2, readFile as readFile18, writeFile as writeFile10 } from "node:fs/promises";
6397
+ import { dirname, join as join11 } from "node:path";
6167
6398
  var HooksWriter = {
6168
6399
  id: "hooks",
6169
6400
  async write(bundle, ctx) {
6170
6401
  if (!bundle.hooks) {
6171
6402
  return { filesWritten: [] };
6172
6403
  }
6173
- const settingsPath = join10(ctx.projectRoot, ctx.outputPath);
6404
+ const settingsPath = join11(ctx.projectRoot, ctx.outputPath);
6174
6405
  const parentDir = dirname(settingsPath);
6175
6406
  await mkdir2(parentDir, { recursive: true });
6176
6407
  const claudeHooks = transformHooksConfig(bundle.hooks, "toClaude");
6177
6408
  let existingSettings = {};
6178
- if (existsSync20(settingsPath)) {
6409
+ if (existsSync21(settingsPath)) {
6179
6410
  try {
6180
- const content = await readFile17(settingsPath, "utf-8");
6411
+ const content = await readFile18(settingsPath, "utf-8");
6181
6412
  existingSettings = JSON.parse(content);
6182
6413
  } catch {
6183
6414
  existingSettings = {};
@@ -6195,21 +6426,42 @@ var HooksWriter = {
6195
6426
  }
6196
6427
  };
6197
6428
  // ../adapters/src/writers/generic/instructions-md.ts
6198
- import { existsSync as existsSync21 } from "node:fs";
6199
- import { mkdir as mkdir3, readFile as readFile18, writeFile as writeFile11 } from "node:fs/promises";
6200
- import { dirname as dirname2, join as join11 } from "node:path";
6429
+ import { existsSync as existsSync22 } from "node:fs";
6430
+ import { mkdir as mkdir3, readFile as readFile19, writeFile as writeFile11 } from "node:fs/promises";
6431
+ import { dirname as dirname2, join as join12 } from "node:path";
6432
+
6433
+ // ../adapters/src/writers/generic/omni-md.ts
6434
+ init_src();
6435
+ var PROVIDER_BLOCK_REGEX = /<provider\.([a-z-]+)>([\s\S]*?)<\/provider\.\1>/g;
6436
+ var PROVIDER_TAG_REGEX = /<\/?provider\.[a-z-]+>/;
6437
+ function renderOmniMdForProvider(content, providerId) {
6438
+ if (!providerId) {
6439
+ return content;
6440
+ }
6441
+ const rendered = content.replace(PROVIDER_BLOCK_REGEX, (_match, rawProvider, providerContent) => {
6442
+ const canonicalProvider = normalizeProviderId(rawProvider);
6443
+ return canonicalProvider === providerId ? providerContent : "";
6444
+ });
6445
+ const strayTag = rendered.match(PROVIDER_TAG_REGEX);
6446
+ if (strayTag) {
6447
+ throw new Error(`Invalid provider block syntax in OMNI.md near ${strayTag[0]}`);
6448
+ }
6449
+ return rendered;
6450
+ }
6451
+
6452
+ // ../adapters/src/writers/generic/instructions-md.ts
6201
6453
  var InstructionsMdWriter = {
6202
6454
  id: "instructions-md",
6203
6455
  async write(bundle, ctx) {
6204
- const outputFullPath = join11(ctx.projectRoot, ctx.outputPath);
6456
+ const outputFullPath = join12(ctx.projectRoot, ctx.outputPath);
6205
6457
  const parentDir = dirname2(outputFullPath);
6206
6458
  if (parentDir !== ctx.projectRoot) {
6207
6459
  await mkdir3(parentDir, { recursive: true });
6208
6460
  }
6209
- const omniMdPath = join11(ctx.projectRoot, "OMNI.md");
6461
+ const omniMdPath = join12(ctx.projectRoot, "OMNI.md");
6210
6462
  let omniMdContent = "";
6211
- if (existsSync21(omniMdPath)) {
6212
- omniMdContent = await readFile18(omniMdPath, "utf-8");
6463
+ if (existsSync22(omniMdPath)) {
6464
+ omniMdContent = renderOmniMdForProvider(await readFile19(omniMdPath, "utf-8"), ctx.providerId);
6213
6465
  }
6214
6466
  let content = omniMdContent;
6215
6467
  if (bundle.instructionsContent) {
@@ -6226,17 +6478,17 @@ ${bundle.instructionsContent}
6226
6478
  };
6227
6479
  // ../adapters/src/writers/generic/skills.ts
6228
6480
  import { mkdir as mkdir4, writeFile as writeFile12 } from "node:fs/promises";
6229
- import { join as join12 } from "node:path";
6481
+ import { join as join13 } from "node:path";
6230
6482
  var SkillsWriter = {
6231
6483
  id: "skills",
6232
6484
  async write(bundle, ctx) {
6233
- const skillsDir = join12(ctx.projectRoot, ctx.outputPath);
6485
+ const skillsDir = join13(ctx.projectRoot, ctx.outputPath);
6234
6486
  await mkdir4(skillsDir, { recursive: true });
6235
6487
  const filesWritten = [];
6236
6488
  for (const skill of bundle.skills) {
6237
- const skillDir = join12(skillsDir, skill.name);
6489
+ const skillDir = join13(skillsDir, skill.name);
6238
6490
  await mkdir4(skillDir, { recursive: true });
6239
- const skillPath = join12(skillDir, "SKILL.md");
6491
+ const skillPath = join13(skillDir, "SKILL.md");
6240
6492
  const content = `---
6241
6493
  name: ${skill.name}
6242
6494
  description: "${skill.description}"
@@ -6244,7 +6496,7 @@ description: "${skill.description}"
6244
6496
 
6245
6497
  ${skill.instructions}`;
6246
6498
  await writeFile12(skillPath, content, "utf-8");
6247
- filesWritten.push(join12(ctx.outputPath, skill.name, "SKILL.md"));
6499
+ filesWritten.push(join13(ctx.outputPath, skill.name, "SKILL.md"));
6248
6500
  }
6249
6501
  return {
6250
6502
  filesWritten
@@ -6253,7 +6505,7 @@ ${skill.instructions}`;
6253
6505
  };
6254
6506
  // ../adapters/src/writers/generic/commands-as-skills.ts
6255
6507
  import { mkdir as mkdir5, writeFile as writeFile13 } from "node:fs/promises";
6256
- import { join as join13 } from "node:path";
6508
+ import { join as join14 } from "node:path";
6257
6509
  function generateSkillFrontmatter(command) {
6258
6510
  const lines = ["---"];
6259
6511
  lines.push(`name: ${command.name}`);
@@ -6268,28 +6520,75 @@ function generateSkillFrontmatter(command) {
6268
6520
  var CommandsAsSkillsWriter = {
6269
6521
  id: "commands-as-skills",
6270
6522
  async write(bundle, ctx) {
6271
- const skillsDir = join13(ctx.projectRoot, ctx.outputPath);
6523
+ const skillsDir = join14(ctx.projectRoot, ctx.outputPath);
6272
6524
  await mkdir5(skillsDir, { recursive: true });
6273
6525
  const filesWritten = [];
6274
6526
  for (const command of bundle.commands) {
6275
- const commandSkillDir = join13(skillsDir, command.name);
6527
+ const commandSkillDir = join14(skillsDir, command.name);
6276
6528
  await mkdir5(commandSkillDir, { recursive: true });
6277
6529
  const frontmatter = generateSkillFrontmatter(command);
6278
6530
  const content = `${frontmatter}
6279
6531
 
6280
6532
  ${command.prompt}`;
6281
- const skillPath = join13(commandSkillDir, "SKILL.md");
6533
+ const skillPath = join14(commandSkillDir, "SKILL.md");
6282
6534
  await writeFile13(skillPath, content, "utf-8");
6283
- filesWritten.push(join13(ctx.outputPath, command.name, "SKILL.md"));
6535
+ filesWritten.push(join14(ctx.outputPath, command.name, "SKILL.md"));
6284
6536
  }
6285
6537
  return {
6286
6538
  filesWritten
6287
6539
  };
6288
6540
  }
6289
6541
  };
6542
+ // ../adapters/src/provider-bundle.ts
6543
+ init_src();
6544
+ function capabilityAppliesToProvider(capability3, providerId) {
6545
+ const providers3 = capability3.config.capability.providers;
6546
+ if (!providers3) {
6547
+ return true;
6548
+ }
6549
+ return providers3[providerId] === true;
6550
+ }
6551
+ function generateInstructionsContent2(rules, _docs) {
6552
+ if (rules.length === 0) {
6553
+ return "";
6554
+ }
6555
+ let content = `## Rules
6556
+
6557
+ `;
6558
+ for (const rule of rules) {
6559
+ content += `${rule.content}
6560
+
6561
+ `;
6562
+ }
6563
+ return content.trimEnd();
6564
+ }
6565
+ function createProviderScopedBundle(bundle, providerId) {
6566
+ const capabilities2 = bundle.capabilities.filter((capability3) => capabilityAppliesToProvider(capability3, providerId));
6567
+ const capabilityIds = new Set(capabilities2.map((capability3) => capability3.id));
6568
+ const skills = bundle.skills.filter((skill) => capabilityIds.has(skill.capabilityId));
6569
+ const rules = bundle.rules.filter((rule) => capabilityIds.has(rule.capabilityId));
6570
+ const docs = bundle.docs.filter((doc) => capabilityIds.has(doc.capabilityId));
6571
+ const commands = bundle.commands.filter((command) => capabilityIds.has(command.capabilityId));
6572
+ const subagents = bundle.subagents.filter((subagent) => capabilityIds.has(subagent.capabilityId));
6573
+ const scopedBundle = {
6574
+ capabilities: capabilities2,
6575
+ skills,
6576
+ rules,
6577
+ docs,
6578
+ commands,
6579
+ subagents,
6580
+ instructionsContent: generateInstructionsContent2(rules, docs)
6581
+ };
6582
+ const mergedHooks = mergeHooksConfigs(capabilities2.flatMap((capability3) => capability3.hooks ? [capability3.hooks] : []));
6583
+ if (hasAnyHooks(mergedHooks)) {
6584
+ scopedBundle.hooks = mergedHooks;
6585
+ }
6586
+ return scopedBundle;
6587
+ }
6588
+
6290
6589
  // ../adapters/src/writers/claude/agents.ts
6291
6590
  import { mkdir as mkdir6, writeFile as writeFile14 } from "node:fs/promises";
6292
- import { join as join14 } from "node:path";
6591
+ import { join as join15 } from "node:path";
6293
6592
  function generateFrontmatter(agent) {
6294
6593
  const lines = ["---"];
6295
6594
  lines.push(`name: ${agent.name}`);
@@ -6316,7 +6615,7 @@ function generateFrontmatter(agent) {
6316
6615
  var ClaudeAgentsWriter = {
6317
6616
  id: "claude-agents",
6318
6617
  async write(bundle, ctx) {
6319
- const agentsDir = join14(ctx.projectRoot, ctx.outputPath);
6618
+ const agentsDir = join15(ctx.projectRoot, ctx.outputPath);
6320
6619
  await mkdir6(agentsDir, { recursive: true });
6321
6620
  const filesWritten = [];
6322
6621
  for (const agent of bundle.subagents) {
@@ -6324,9 +6623,9 @@ var ClaudeAgentsWriter = {
6324
6623
  const content = `${frontmatter}
6325
6624
 
6326
6625
  ${agent.systemPrompt}`;
6327
- const agentPath = join14(agentsDir, `${agent.name}.md`);
6626
+ const agentPath = join15(agentsDir, `${agent.name}.md`);
6328
6627
  await writeFile14(agentPath, content, "utf-8");
6329
- filesWritten.push(join14(ctx.outputPath, `${agent.name}.md`));
6628
+ filesWritten.push(join15(ctx.outputPath, `${agent.name}.md`));
6330
6629
  }
6331
6630
  return {
6332
6631
  filesWritten
@@ -6351,7 +6650,9 @@ var claudeCodeAdapter = {
6351
6650
  };
6352
6651
  },
6353
6652
  async sync(bundle, ctx) {
6354
- const result = await executeWriters(this.writers, bundle, ctx.projectRoot);
6653
+ const providerId = "claude-code";
6654
+ const providerBundle = createProviderScopedBundle(bundle, providerId);
6655
+ const result = await executeWriters(this.writers, providerBundle, ctx.projectRoot, providerId);
6355
6656
  return {
6356
6657
  filesWritten: result.filesWritten,
6357
6658
  filesDeleted: []
@@ -6360,12 +6661,12 @@ var claudeCodeAdapter = {
6360
6661
  };
6361
6662
  // ../adapters/src/codex/index.ts
6362
6663
  import { mkdirSync as mkdirSync6 } from "node:fs";
6363
- import { join as join16 } from "node:path";
6664
+ import { join as join17 } from "node:path";
6364
6665
 
6365
6666
  // ../adapters/src/writers/codex/toml.ts
6366
6667
  init_dist();
6367
6668
  import { mkdir as mkdir7, writeFile as writeFile15 } from "node:fs/promises";
6368
- import { dirname as dirname3, join as join15 } from "node:path";
6669
+ import { dirname as dirname3, join as join16 } from "node:path";
6369
6670
  var FILE_HEADER = `# Generated by OmniDev - DO NOT EDIT
6370
6671
  # Run \`omnidev sync\` to regenerate
6371
6672
 
@@ -6416,7 +6717,7 @@ var CodexTomlWriter = {
6416
6717
  if (mcps.size === 0) {
6417
6718
  return { filesWritten: [] };
6418
6719
  }
6419
- const configPath = join15(ctx.projectRoot, ctx.outputPath);
6720
+ const configPath = join16(ctx.projectRoot, ctx.outputPath);
6420
6721
  const parentDir = dirname3(configPath);
6421
6722
  await mkdir7(parentDir, { recursive: true });
6422
6723
  const mcpServers = {};
@@ -6450,7 +6751,7 @@ var codexAdapter = {
6450
6751
  { writer: CodexTomlWriter, outputPath: ".codex/config.toml" }
6451
6752
  ],
6452
6753
  async init(ctx) {
6453
- const codexDir = join16(ctx.projectRoot, ".codex");
6754
+ const codexDir = join17(ctx.projectRoot, ".codex");
6454
6755
  mkdirSync6(codexDir, { recursive: true });
6455
6756
  return {
6456
6757
  filesCreated: [".codex/"],
@@ -6458,7 +6759,9 @@ var codexAdapter = {
6458
6759
  };
6459
6760
  },
6460
6761
  async sync(bundle, ctx) {
6461
- const result = await executeWriters(this.writers, bundle, ctx.projectRoot);
6762
+ const providerId = "codex";
6763
+ const providerBundle = createProviderScopedBundle(bundle, providerId);
6764
+ const result = await executeWriters(this.writers, providerBundle, ctx.projectRoot, providerId);
6462
6765
  return {
6463
6766
  filesWritten: result.filesWritten,
6464
6767
  filesDeleted: []
@@ -6467,11 +6770,11 @@ var codexAdapter = {
6467
6770
  };
6468
6771
  // ../adapters/src/cursor/index.ts
6469
6772
  import { mkdirSync as mkdirSync7 } from "node:fs";
6470
- import { join as join21 } from "node:path";
6773
+ import { join as join22 } from "node:path";
6471
6774
 
6472
6775
  // ../adapters/src/writers/cursor/agents.ts
6473
6776
  import { mkdir as mkdir8, writeFile as writeFile16 } from "node:fs/promises";
6474
- import { join as join17 } from "node:path";
6777
+ import { join as join18 } from "node:path";
6475
6778
  function mapModelToCursor(model) {
6476
6779
  if (!model || model === "inherit")
6477
6780
  return "inherit";
@@ -6503,7 +6806,7 @@ function generateFrontmatter2(agent) {
6503
6806
  var CursorAgentsWriter = {
6504
6807
  id: "cursor-agents",
6505
6808
  async write(bundle, ctx) {
6506
- const agentsDir = join17(ctx.projectRoot, ctx.outputPath);
6809
+ const agentsDir = join18(ctx.projectRoot, ctx.outputPath);
6507
6810
  await mkdir8(agentsDir, { recursive: true });
6508
6811
  const filesWritten = [];
6509
6812
  for (const agent of bundle.subagents) {
@@ -6511,9 +6814,9 @@ var CursorAgentsWriter = {
6511
6814
  const content = `${frontmatter}
6512
6815
 
6513
6816
  ${agent.systemPrompt}`;
6514
- const agentPath = join17(agentsDir, `${agent.name}.md`);
6817
+ const agentPath = join18(agentsDir, `${agent.name}.md`);
6515
6818
  await writeFile16(agentPath, content, "utf-8");
6516
- filesWritten.push(join17(ctx.outputPath, `${agent.name}.md`));
6819
+ filesWritten.push(join18(ctx.outputPath, `${agent.name}.md`));
6517
6820
  }
6518
6821
  return {
6519
6822
  filesWritten
@@ -6522,11 +6825,11 @@ ${agent.systemPrompt}`;
6522
6825
  };
6523
6826
  // ../adapters/src/writers/cursor/commands.ts
6524
6827
  import { mkdir as mkdir9, writeFile as writeFile17 } from "node:fs/promises";
6525
- import { join as join18 } from "node:path";
6828
+ import { join as join19 } from "node:path";
6526
6829
  var CursorCommandsWriter = {
6527
6830
  id: "cursor-commands",
6528
6831
  async write(bundle, ctx) {
6529
- const commandsDir = join18(ctx.projectRoot, ctx.outputPath);
6832
+ const commandsDir = join19(ctx.projectRoot, ctx.outputPath);
6530
6833
  await mkdir9(commandsDir, { recursive: true });
6531
6834
  const filesWritten = [];
6532
6835
  for (const command of bundle.commands) {
@@ -6535,9 +6838,9 @@ var CursorCommandsWriter = {
6535
6838
  ${command.description}
6536
6839
 
6537
6840
  ${command.prompt}`;
6538
- const commandPath = join18(commandsDir, `${command.name}.md`);
6841
+ const commandPath = join19(commandsDir, `${command.name}.md`);
6539
6842
  await writeFile17(commandPath, content, "utf-8");
6540
- filesWritten.push(join18(ctx.outputPath, `${command.name}.md`));
6843
+ filesWritten.push(join19(ctx.outputPath, `${command.name}.md`));
6541
6844
  }
6542
6845
  return {
6543
6846
  filesWritten
@@ -6546,7 +6849,7 @@ ${command.prompt}`;
6546
6849
  };
6547
6850
  // ../adapters/src/writers/cursor/mcp-json.ts
6548
6851
  import { mkdir as mkdir10, writeFile as writeFile18 } from "node:fs/promises";
6549
- import { dirname as dirname4, join as join19 } from "node:path";
6852
+ import { dirname as dirname4, join as join20 } from "node:path";
6550
6853
  function buildCursorMcpConfig(mcp) {
6551
6854
  const transport = mcp.transport ?? "stdio";
6552
6855
  if (transport === "http" || transport === "sse") {
@@ -6591,7 +6894,7 @@ var CursorMcpJsonWriter = {
6591
6894
  if (mcps.size === 0) {
6592
6895
  return { filesWritten: [] };
6593
6896
  }
6594
- const configPath = join19(ctx.projectRoot, ctx.outputPath);
6897
+ const configPath = join20(ctx.projectRoot, ctx.outputPath);
6595
6898
  const parentDir = dirname4(configPath);
6596
6899
  await mkdir10(parentDir, { recursive: true });
6597
6900
  const mcpServers = {};
@@ -6616,17 +6919,17 @@ var CursorMcpJsonWriter = {
6616
6919
  };
6617
6920
  // ../adapters/src/writers/cursor/rules.ts
6618
6921
  import { mkdir as mkdir11, writeFile as writeFile19 } from "node:fs/promises";
6619
- import { join as join20 } from "node:path";
6922
+ import { join as join21 } from "node:path";
6620
6923
  var CursorRulesWriter = {
6621
6924
  id: "cursor-rules",
6622
6925
  async write(bundle, ctx) {
6623
- const rulesDir = join20(ctx.projectRoot, ctx.outputPath);
6926
+ const rulesDir = join21(ctx.projectRoot, ctx.outputPath);
6624
6927
  await mkdir11(rulesDir, { recursive: true });
6625
6928
  const filesWritten = [];
6626
6929
  for (const rule of bundle.rules) {
6627
- const rulePath = join20(rulesDir, `omnidev-${rule.name}.mdc`);
6930
+ const rulePath = join21(rulesDir, `omnidev-${rule.name}.mdc`);
6628
6931
  await writeFile19(rulePath, rule.content, "utf-8");
6629
- filesWritten.push(join20(ctx.outputPath, `omnidev-${rule.name}.mdc`));
6932
+ filesWritten.push(join21(ctx.outputPath, `omnidev-${rule.name}.mdc`));
6630
6933
  }
6631
6934
  return {
6632
6935
  filesWritten
@@ -6646,7 +6949,7 @@ var cursorAdapter = {
6646
6949
  { writer: CursorMcpJsonWriter, outputPath: ".cursor/mcp.json" }
6647
6950
  ],
6648
6951
  async init(ctx) {
6649
- const rulesDir = join21(ctx.projectRoot, ".cursor", "rules");
6952
+ const rulesDir = join22(ctx.projectRoot, ".cursor", "rules");
6650
6953
  mkdirSync7(rulesDir, { recursive: true });
6651
6954
  return {
6652
6955
  filesCreated: [".cursor/rules/"],
@@ -6654,20 +6957,29 @@ var cursorAdapter = {
6654
6957
  };
6655
6958
  },
6656
6959
  async sync(bundle, ctx) {
6657
- const result = await executeWriters(this.writers, bundle, ctx.projectRoot);
6960
+ const cursorProviderId = "cursor";
6961
+ const instructionsProviderId = "claude-code";
6962
+ const instructionsWriters = this.writers.filter((config3) => config3.writer.id === "instructions-md");
6963
+ const cursorWriters = this.writers.filter((config3) => config3.writer.id !== "instructions-md");
6964
+ const instructionsBundle = createProviderScopedBundle(bundle, instructionsProviderId);
6965
+ const cursorBundle = createProviderScopedBundle(bundle, cursorProviderId);
6966
+ const instructionsResult = await executeWriters(instructionsWriters, instructionsBundle, ctx.projectRoot, instructionsProviderId);
6967
+ const cursorResult = await executeWriters(cursorWriters, cursorBundle, ctx.projectRoot, cursorProviderId);
6658
6968
  return {
6659
- filesWritten: result.filesWritten,
6969
+ filesWritten: [
6970
+ ...new Set([...instructionsResult.filesWritten, ...cursorResult.filesWritten])
6971
+ ],
6660
6972
  filesDeleted: []
6661
6973
  };
6662
6974
  }
6663
6975
  };
6664
6976
  // ../adapters/src/opencode/index.ts
6665
6977
  import { mkdirSync as mkdirSync8 } from "node:fs";
6666
- import { join as join24 } from "node:path";
6978
+ import { join as join25 } from "node:path";
6667
6979
 
6668
6980
  // ../adapters/src/writers/opencode/agents.ts
6669
6981
  import { mkdir as mkdir12, writeFile as writeFile20 } from "node:fs/promises";
6670
- import { join as join22 } from "node:path";
6982
+ import { join as join23 } from "node:path";
6671
6983
  function mapModelToOpenCode(model) {
6672
6984
  if (!model || model === "inherit")
6673
6985
  return;
@@ -6745,7 +7057,7 @@ function generateFrontmatter3(agent) {
6745
7057
  var OpenCodeAgentsWriter = {
6746
7058
  id: "opencode-agents",
6747
7059
  async write(bundle, ctx) {
6748
- const agentsDir = join22(ctx.projectRoot, ctx.outputPath);
7060
+ const agentsDir = join23(ctx.projectRoot, ctx.outputPath);
6749
7061
  await mkdir12(agentsDir, { recursive: true });
6750
7062
  const filesWritten = [];
6751
7063
  for (const agent of bundle.subagents) {
@@ -6753,9 +7065,9 @@ var OpenCodeAgentsWriter = {
6753
7065
  const content = `${frontmatter}
6754
7066
 
6755
7067
  ${agent.systemPrompt}`;
6756
- const agentPath = join22(agentsDir, `${agent.name}.md`);
7068
+ const agentPath = join23(agentsDir, `${agent.name}.md`);
6757
7069
  await writeFile20(agentPath, content, "utf-8");
6758
- filesWritten.push(join22(ctx.outputPath, `${agent.name}.md`));
7070
+ filesWritten.push(join23(ctx.outputPath, `${agent.name}.md`));
6759
7071
  }
6760
7072
  return {
6761
7073
  filesWritten
@@ -6764,7 +7076,7 @@ ${agent.systemPrompt}`;
6764
7076
  };
6765
7077
  // ../adapters/src/writers/opencode/commands.ts
6766
7078
  import { mkdir as mkdir13, writeFile as writeFile21 } from "node:fs/promises";
6767
- import { join as join23 } from "node:path";
7079
+ import { join as join24 } from "node:path";
6768
7080
  function generateFrontmatter4(command) {
6769
7081
  const lines = ["---"];
6770
7082
  lines.push(`description: "${command.description.replace(/"/g, "\\\"")}"`);
@@ -6781,7 +7093,7 @@ function generateFrontmatter4(command) {
6781
7093
  var OpenCodeCommandsWriter = {
6782
7094
  id: "opencode-commands",
6783
7095
  async write(bundle, ctx) {
6784
- const commandsDir = join23(ctx.projectRoot, ctx.outputPath);
7096
+ const commandsDir = join24(ctx.projectRoot, ctx.outputPath);
6785
7097
  await mkdir13(commandsDir, { recursive: true });
6786
7098
  const filesWritten = [];
6787
7099
  for (const command of bundle.commands) {
@@ -6789,9 +7101,9 @@ var OpenCodeCommandsWriter = {
6789
7101
  const content = `${frontmatter}
6790
7102
 
6791
7103
  ${command.prompt}`;
6792
- const commandPath = join23(commandsDir, `${command.name}.md`);
7104
+ const commandPath = join24(commandsDir, `${command.name}.md`);
6793
7105
  await writeFile21(commandPath, content, "utf-8");
6794
- filesWritten.push(join23(ctx.outputPath, `${command.name}.md`));
7106
+ filesWritten.push(join24(ctx.outputPath, `${command.name}.md`));
6795
7107
  }
6796
7108
  return {
6797
7109
  filesWritten
@@ -6809,7 +7121,7 @@ var opencodeAdapter = {
6809
7121
  { writer: OpenCodeCommandsWriter, outputPath: ".opencode/commands/" }
6810
7122
  ],
6811
7123
  async init(ctx) {
6812
- const opencodeDir = join24(ctx.projectRoot, ".opencode");
7124
+ const opencodeDir = join25(ctx.projectRoot, ".opencode");
6813
7125
  mkdirSync8(opencodeDir, { recursive: true });
6814
7126
  return {
6815
7127
  filesCreated: [".opencode/"],
@@ -6817,7 +7129,9 @@ var opencodeAdapter = {
6817
7129
  };
6818
7130
  },
6819
7131
  async sync(bundle, ctx) {
6820
- const result = await executeWriters(this.writers, bundle, ctx.projectRoot);
7132
+ const providerId = "opencode";
7133
+ const providerBundle = createProviderScopedBundle(bundle, providerId);
7134
+ const result = await executeWriters(this.writers, providerBundle, ctx.projectRoot, providerId);
6821
7135
  return {
6822
7136
  filesWritten: result.filesWritten,
6823
7137
  filesDeleted: []
@@ -6861,7 +7175,7 @@ async function inferCapabilityId(source, sourceType) {
6861
7175
  }
6862
7176
  async function runAddCap(flags, name) {
6863
7177
  try {
6864
- if (!existsSync22("omni.toml")) {
7178
+ if (!existsSync23("omni.toml")) {
6865
7179
  console.log("✗ No config file found");
6866
7180
  console.log(" Run: omnidev init");
6867
7181
  process.exit(1);
@@ -6884,7 +7198,7 @@ async function runAddCap(flags, name) {
6884
7198
  sourceType = "local";
6885
7199
  const localPath = flags.local.startsWith("file://") ? flags.local.slice(7) : flags.local;
6886
7200
  source = `file://${localPath}`;
6887
- if (!existsSync22(localPath)) {
7201
+ if (!existsSync23(localPath)) {
6888
7202
  console.error(`✗ Local path not found: ${localPath}`);
6889
7203
  process.exit(1);
6890
7204
  }
@@ -6976,7 +7290,7 @@ async function runAddCap(flags, name) {
6976
7290
  }
6977
7291
  async function runAddMcp(flags, name) {
6978
7292
  try {
6979
- if (!existsSync22("omni.toml")) {
7293
+ if (!existsSync23("omni.toml")) {
6980
7294
  console.log("✗ No config file found");
6981
7295
  console.log(" Run: omnidev init");
6982
7296
  process.exit(1);
@@ -7263,9 +7577,9 @@ var addRoutes = buildRouteMap({
7263
7577
  });
7264
7578
 
7265
7579
  // src/commands/capability.ts
7266
- import { existsSync as existsSync23, mkdirSync as mkdirSync9 } from "node:fs";
7580
+ import { existsSync as existsSync24, mkdirSync as mkdirSync9 } from "node:fs";
7267
7581
  import { writeFile as writeFile22 } from "node:fs/promises";
7268
- import { join as join25 } from "node:path";
7582
+ import { join as join26 } from "node:path";
7269
7583
  import { input } from "@inquirer/prompts";
7270
7584
  init_src();
7271
7585
  import { buildCommand as buildCommand2, buildRouteMap as buildRouteMap2 } from "@stricli/core";
@@ -7443,14 +7757,18 @@ export default {
7443
7757
  } satisfies CapabilityExport;
7444
7758
  `;
7445
7759
  }
7446
- function generateGitignore() {
7447
- return `dist/
7448
- node_modules/
7760
+ function generateGitignore(programmatic) {
7761
+ const lines = [".env"];
7762
+ if (programmatic) {
7763
+ lines.push("dist/", "node_modules/");
7764
+ }
7765
+ return `${lines.join(`
7766
+ `)}
7449
7767
  `;
7450
7768
  }
7451
7769
  async function runCapabilityNew(flags, capabilityId) {
7452
7770
  try {
7453
- if (!existsSync23(".omni")) {
7771
+ if (!existsSync24(".omni")) {
7454
7772
  console.error("✗ OmniDev is not initialized in this directory.");
7455
7773
  console.log("");
7456
7774
  console.log(" Run: omnidev init");
@@ -7474,28 +7792,28 @@ async function runCapabilityNew(flags, capabilityId) {
7474
7792
  default: defaultPath
7475
7793
  });
7476
7794
  }
7477
- if (existsSync23(capabilityDir)) {
7795
+ if (existsSync24(capabilityDir)) {
7478
7796
  console.error(`✗ Directory already exists at ${capabilityDir}`);
7479
7797
  process.exit(1);
7480
7798
  }
7481
7799
  const name = toTitleCase(id);
7482
7800
  mkdirSync9(capabilityDir, { recursive: true });
7483
7801
  const capabilityToml = generateCapabilityToml2({ id, name });
7484
- await writeFile22(join25(capabilityDir, "capability.toml"), capabilityToml, "utf-8");
7485
- const skillDir = join25(capabilityDir, "skills", "getting-started");
7802
+ await writeFile22(join26(capabilityDir, "capability.toml"), capabilityToml, "utf-8");
7803
+ const skillDir = join26(capabilityDir, "skills", "getting-started");
7486
7804
  mkdirSync9(skillDir, { recursive: true });
7487
- await writeFile22(join25(skillDir, "SKILL.md"), generateSkillTemplate("getting-started"), "utf-8");
7488
- const rulesDir = join25(capabilityDir, "rules");
7805
+ await writeFile22(join26(skillDir, "SKILL.md"), generateSkillTemplate("getting-started"), "utf-8");
7806
+ const rulesDir = join26(capabilityDir, "rules");
7489
7807
  mkdirSync9(rulesDir, { recursive: true });
7490
- await writeFile22(join25(rulesDir, "coding-standards.md"), generateRuleTemplate("coding-standards"), "utf-8");
7491
- const hooksDir = join25(capabilityDir, "hooks");
7808
+ await writeFile22(join26(rulesDir, "coding-standards.md"), generateRuleTemplate("coding-standards"), "utf-8");
7809
+ const hooksDir = join26(capabilityDir, "hooks");
7492
7810
  mkdirSync9(hooksDir, { recursive: true });
7493
- await writeFile22(join25(hooksDir, "hooks.toml"), generateHooksTemplate(), "utf-8");
7494
- await writeFile22(join25(hooksDir, "example-hook.sh"), generateHookScript(), "utf-8");
7811
+ await writeFile22(join26(hooksDir, "hooks.toml"), generateHooksTemplate(), "utf-8");
7812
+ await writeFile22(join26(hooksDir, "example-hook.sh"), generateHookScript(), "utf-8");
7813
+ await writeFile22(join26(capabilityDir, ".gitignore"), generateGitignore(Boolean(flags.programmatic)), "utf-8");
7495
7814
  if (flags.programmatic) {
7496
- await writeFile22(join25(capabilityDir, "package.json"), generatePackageJson(id), "utf-8");
7497
- await writeFile22(join25(capabilityDir, "index.ts"), generateIndexTs(id, name), "utf-8");
7498
- await writeFile22(join25(capabilityDir, ".gitignore"), generateGitignore(), "utf-8");
7815
+ await writeFile22(join26(capabilityDir, "package.json"), generatePackageJson(id), "utf-8");
7816
+ await writeFile22(join26(capabilityDir, "index.ts"), generateIndexTs(id, name), "utf-8");
7499
7817
  }
7500
7818
  console.log(`✓ Created capability: ${name}`);
7501
7819
  console.log(` Location: ${capabilityDir}`);
@@ -7506,10 +7824,10 @@ async function runCapabilityNew(flags, capabilityId) {
7506
7824
  console.log(" - rules/coding-standards.md");
7507
7825
  console.log(" - hooks/hooks.toml");
7508
7826
  console.log(" - hooks/example-hook.sh");
7827
+ console.log(" - .gitignore");
7509
7828
  if (flags.programmatic) {
7510
7829
  console.log(" - package.json");
7511
7830
  console.log(" - index.ts");
7512
- console.log(" - .gitignore");
7513
7831
  }
7514
7832
  console.log("");
7515
7833
  if (flags.programmatic) {
@@ -7651,9 +7969,9 @@ var capabilityRoutes = buildRouteMap2({
7651
7969
  });
7652
7970
 
7653
7971
  // src/commands/doctor.ts
7654
- import { existsSync as existsSync24 } from "node:fs";
7972
+ import { existsSync as existsSync25 } from "node:fs";
7655
7973
  import { execFile } from "node:child_process";
7656
- import { readFile as readFile19 } from "node:fs/promises";
7974
+ import { readFile as readFile20 } from "node:fs/promises";
7657
7975
  import { promisify } from "node:util";
7658
7976
  import { buildCommand as buildCommand3 } from "@stricli/core";
7659
7977
  var doctorCommand = buildCommand3({
@@ -7741,7 +8059,7 @@ async function checkPackageManager() {
7741
8059
  }
7742
8060
  }
7743
8061
  async function checkOmniLocalDir() {
7744
- const exists = existsSync24(".omni");
8062
+ const exists = existsSync25(".omni");
7745
8063
  if (!exists) {
7746
8064
  return {
7747
8065
  name: ".omni/ directory",
@@ -7758,7 +8076,7 @@ async function checkOmniLocalDir() {
7758
8076
  }
7759
8077
  async function checkConfig() {
7760
8078
  const configPath = "omni.toml";
7761
- if (!existsSync24(configPath)) {
8079
+ if (!existsSync25(configPath)) {
7762
8080
  return {
7763
8081
  name: "Configuration",
7764
8082
  passed: false,
@@ -7785,7 +8103,7 @@ async function checkConfig() {
7785
8103
  }
7786
8104
  async function checkRootGitignore() {
7787
8105
  const gitignorePath = ".gitignore";
7788
- if (!existsSync24(gitignorePath)) {
8106
+ if (!existsSync25(gitignorePath)) {
7789
8107
  return {
7790
8108
  name: "Root .gitignore",
7791
8109
  passed: false,
@@ -7793,7 +8111,7 @@ async function checkRootGitignore() {
7793
8111
  fix: "Run: omnidev init"
7794
8112
  };
7795
8113
  }
7796
- const content = await readFile19(gitignorePath, "utf-8");
8114
+ const content = await readFile20(gitignorePath, "utf-8");
7797
8115
  const lines = content.split(`
7798
8116
  `).map((line) => line.trim());
7799
8117
  const hasOmniDir = lines.includes(".omni/");
@@ -7819,7 +8137,7 @@ async function checkRootGitignore() {
7819
8137
  }
7820
8138
  async function checkCapabilitiesDir() {
7821
8139
  const capabilitiesDirPath = ".omni/capabilities";
7822
- if (!existsSync24(capabilitiesDirPath)) {
8140
+ if (!existsSync25(capabilitiesDirPath)) {
7823
8141
  return {
7824
8142
  name: "Capabilities Directory",
7825
8143
  passed: true,
@@ -7835,8 +8153,8 @@ async function checkCapabilitiesDir() {
7835
8153
 
7836
8154
  // src/commands/init.ts
7837
8155
  import { exec } from "node:child_process";
7838
- import { existsSync as existsSync25, mkdirSync as mkdirSync10 } from "node:fs";
7839
- import { readFile as readFile20, writeFile as writeFile23 } from "node:fs/promises";
8156
+ import { existsSync as existsSync26, mkdirSync as mkdirSync10 } from "node:fs";
8157
+ import { readFile as readFile21, writeFile as writeFile23 } from "node:fs/promises";
7840
8158
  import { promisify as promisify2 } from "node:util";
7841
8159
  init_src();
7842
8160
  import { buildCommand as buildCommand4 } from "@stricli/core";
@@ -7849,8 +8167,8 @@ var PROVIDER_GITIGNORE_FILES = {
7849
8167
  codex: ["AGENTS.md", ".codex/"],
7850
8168
  opencode: [".opencode/"]
7851
8169
  };
7852
- function getProviderGitignoreFiles(providers2) {
7853
- return providers2.flatMap((p) => PROVIDER_GITIGNORE_FILES[p] ?? []);
8170
+ function getProviderGitignoreFiles(providers3) {
8171
+ return providers3.flatMap((p) => PROVIDER_GITIGNORE_FILES[p] ?? []);
7854
8172
  }
7855
8173
  async function promptForProviders() {
7856
8174
  const answers = await checkbox({
@@ -7905,7 +8223,7 @@ async function runInit(_flags, providerArg) {
7905
8223
  }
7906
8224
  }
7907
8225
  await writeEnabledProviders(providerIds);
7908
- if (!existsSync25("omni.toml")) {
8226
+ if (!existsSync26("omni.toml")) {
7909
8227
  await writeConfig({
7910
8228
  profiles: {
7911
8229
  default: {
@@ -7921,7 +8239,7 @@ async function runInit(_flags, providerArg) {
7921
8239
  });
7922
8240
  await setActiveProfile("default");
7923
8241
  }
7924
- if (!existsSync25("OMNI.md")) {
8242
+ if (!existsSync26("OMNI.md")) {
7925
8243
  await writeFile23("OMNI.md", generateOmniMdTemplate(), "utf-8");
7926
8244
  }
7927
8245
  const config3 = await loadConfig();
@@ -7999,8 +8317,8 @@ async function addProviderFilesToGitignore(entries) {
7999
8317
  async function addToGitignore(entriesToAdd, sectionHeader) {
8000
8318
  const gitignorePath = ".gitignore";
8001
8319
  let content = "";
8002
- if (existsSync25(gitignorePath)) {
8003
- content = await readFile20(gitignorePath, "utf-8");
8320
+ if (existsSync26(gitignorePath)) {
8321
+ content = await readFile21(gitignorePath, "utf-8");
8004
8322
  }
8005
8323
  const lines = content.split(`
8006
8324
  `);
@@ -8031,7 +8349,7 @@ async function getTrackedProviderFiles(files) {
8031
8349
  }
8032
8350
 
8033
8351
  // src/commands/profile.ts
8034
- import { existsSync as existsSync26 } from "node:fs";
8352
+ import { existsSync as existsSync27 } from "node:fs";
8035
8353
  init_src();
8036
8354
  import { buildCommand as buildCommand5, buildRouteMap as buildRouteMap3 } from "@stricli/core";
8037
8355
  var listCommand2 = buildCommand5({
@@ -8075,7 +8393,7 @@ var profileRoutes = buildRouteMap3({
8075
8393
  });
8076
8394
  async function runProfileList() {
8077
8395
  try {
8078
- if (!existsSync26("omni.toml")) {
8396
+ if (!existsSync27("omni.toml")) {
8079
8397
  console.log("✗ No config file found");
8080
8398
  console.log(" Run: omnidev init");
8081
8399
  process.exit(1);
@@ -8115,7 +8433,7 @@ async function runProfileList() {
8115
8433
  }
8116
8434
  async function runProfileSet(profileName) {
8117
8435
  try {
8118
- if (!existsSync26("omni.toml")) {
8436
+ if (!existsSync27("omni.toml")) {
8119
8437
  console.log("✗ No config file found");
8120
8438
  console.log(" Run: omnidev init");
8121
8439
  process.exit(1);
@@ -8264,7 +8582,7 @@ var providerRoutes = buildRouteMap4({
8264
8582
 
8265
8583
  // src/commands/security.ts
8266
8584
  init_src();
8267
- import { existsSync as existsSync27 } from "node:fs";
8585
+ import { existsSync as existsSync28 } from "node:fs";
8268
8586
  import { buildCommand as buildCommand7, buildRouteMap as buildRouteMap5 } from "@stricli/core";
8269
8587
  var VALID_FINDING_TYPES = [
8270
8588
  "unicode_bidi",
@@ -8381,7 +8699,7 @@ function formatFindingsWithHints(summary) {
8381
8699
  }
8382
8700
  async function runSecurityIssues(flags = {}) {
8383
8701
  try {
8384
- if (!existsSync27("omni.toml")) {
8702
+ if (!existsSync28("omni.toml")) {
8385
8703
  console.log("No config file found");
8386
8704
  console.log(" Run: omnidev init");
8387
8705
  process.exit(1);
@@ -8636,7 +8954,7 @@ var securityRoutes = buildRouteMap5({
8636
8954
  });
8637
8955
 
8638
8956
  // src/commands/sync.ts
8639
- import { existsSync as existsSync28 } from "node:fs";
8957
+ import { existsSync as existsSync29 } from "node:fs";
8640
8958
  init_src();
8641
8959
  import { buildCommand as buildCommand8 } from "@stricli/core";
8642
8960
  var PROVIDERS_STATE_PATH = ".omni/state/providers.json";
@@ -8654,7 +8972,7 @@ async function runSync() {
8654
8972
  const config3 = await loadConfig();
8655
8973
  const activeProfile = await getActiveProfile() ?? "default";
8656
8974
  let adapters = await getEnabledAdapters();
8657
- if (!existsSync28(PROVIDERS_STATE_PATH) || adapters.length === 0) {
8975
+ if (!existsSync29(PROVIDERS_STATE_PATH) || adapters.length === 0) {
8658
8976
  console.log("No providers configured yet. Select your provider(s):");
8659
8977
  const providerIds = await promptForProviders();
8660
8978
  await writeEnabledProviders(providerIds);
@@ -8864,9 +9182,9 @@ async function buildDynamicApp() {
8864
9182
  security: securityRoutes
8865
9183
  };
8866
9184
  debug("Core routes registered", Object.keys(routes));
8867
- const configPath = join26(process.cwd(), "omni.toml");
8868
- debug("Checking for config", { configPath, exists: existsSync29(configPath), cwd: process.cwd() });
8869
- if (existsSync29(configPath)) {
9185
+ const configPath = join27(process.cwd(), "omni.toml");
9186
+ debug("Checking for config", { configPath, exists: existsSync30(configPath), cwd: process.cwd() });
9187
+ if (existsSync30(configPath)) {
8870
9188
  try {
8871
9189
  debug("Loading capability commands...");
8872
9190
  const capabilityCommands = await loadCapabilityCommands();
@@ -8941,25 +9259,25 @@ async function loadCapabilityCommands() {
8941
9259
  return commands;
8942
9260
  }
8943
9261
  async function loadCapabilityExport(capability3) {
8944
- const capabilityPath = join26(process.cwd(), capability3.path);
8945
- const builtIndexPath = join26(capabilityPath, "dist", "index.js");
8946
- const jsIndexPath = join26(capabilityPath, "index.js");
8947
- const tsIndexPath = join26(capabilityPath, "index.ts");
9262
+ const capabilityPath = join27(process.cwd(), capability3.path);
9263
+ const builtIndexPath = join27(capabilityPath, "dist", "index.js");
9264
+ const jsIndexPath = join27(capabilityPath, "index.js");
9265
+ const tsIndexPath = join27(capabilityPath, "index.ts");
8948
9266
  debug(`Checking entry points for '${capability3.id}'`, {
8949
9267
  capabilityPath,
8950
9268
  builtIndexPath,
8951
- builtExists: existsSync29(builtIndexPath),
9269
+ builtExists: existsSync30(builtIndexPath),
8952
9270
  jsIndexPath,
8953
- jsExists: existsSync29(jsIndexPath),
9271
+ jsExists: existsSync30(jsIndexPath),
8954
9272
  tsIndexPath,
8955
- tsExists: existsSync29(tsIndexPath)
9273
+ tsExists: existsSync30(tsIndexPath)
8956
9274
  });
8957
9275
  let indexPath = null;
8958
- if (existsSync29(builtIndexPath)) {
9276
+ if (existsSync30(builtIndexPath)) {
8959
9277
  indexPath = builtIndexPath;
8960
- } else if (existsSync29(jsIndexPath)) {
9278
+ } else if (existsSync30(jsIndexPath)) {
8961
9279
  indexPath = jsIndexPath;
8962
- } else if (existsSync29(tsIndexPath)) {
9280
+ } else if (existsSync30(tsIndexPath)) {
8963
9281
  indexPath = tsIndexPath;
8964
9282
  }
8965
9283
  if (!indexPath) {