@omnidev-ai/cli 0.16.0 → 0.18.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 +1002 -457
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1287,45 +1287,6 @@ var init_dist = __esm(() => {
1287
1287
  dist_default = { parse, stringify, TomlDate, TomlError };
1288
1288
  });
1289
1289
 
1290
- // ../core/src/config/parser.ts
1291
- function parseOmniConfig(tomlContent) {
1292
- try {
1293
- return parse(tomlContent);
1294
- } catch (error) {
1295
- const message = error instanceof Error ? error.message : String(error);
1296
- throw new Error(`Invalid TOML in config: ${message}`);
1297
- }
1298
- }
1299
- function validateCapabilityConfig(parsed) {
1300
- const cap = parsed["capability"];
1301
- if (typeof cap !== "object" || cap === null) {
1302
- throw new Error("capability.id is required in capability.toml");
1303
- }
1304
- const capability = cap;
1305
- if (typeof capability["id"] !== "string") {
1306
- throw new Error("capability.id is required in capability.toml");
1307
- }
1308
- if (typeof capability["name"] !== "string") {
1309
- throw new Error("capability.name is required in capability.toml");
1310
- }
1311
- if (typeof capability["version"] !== "string") {
1312
- throw new Error("capability.version is required in capability.toml");
1313
- }
1314
- }
1315
- function parseCapabilityConfig(tomlContent) {
1316
- try {
1317
- const parsed = parse(tomlContent);
1318
- validateCapabilityConfig(parsed);
1319
- return parsed;
1320
- } catch (error) {
1321
- const message = error instanceof Error ? error.message : String(error);
1322
- throw new Error(`Invalid capability.toml: ${message}`);
1323
- }
1324
- }
1325
- var init_parser = __esm(() => {
1326
- init_dist();
1327
- });
1328
-
1329
1290
  // ../core/src/hooks/constants.ts
1330
1291
  var HOOK_EVENTS, MATCHER_EVENTS, PROMPT_HOOK_EVENTS, HOOK_TYPES, COMMON_TOOL_MATCHERS, NOTIFICATION_MATCHERS, SESSION_START_MATCHERS, PRE_COMPACT_MATCHERS, DEFAULT_COMMAND_TIMEOUT = 60, DEFAULT_PROMPT_TIMEOUT = 30, VARIABLE_MAPPINGS, HOOKS_CONFIG_FILENAME = "hooks.toml", CLAUDE_HOOKS_CONFIG_FILENAME = "hooks.json", HOOKS_DIRECTORY = "hooks";
1331
1292
  var init_constants = __esm(() => {
@@ -2411,21 +2372,207 @@ var init_loader = __esm(() => {
2411
2372
  init_constants();
2412
2373
  });
2413
2374
 
2414
- // ../core/src/capability/rules.ts
2415
- import { existsSync as existsSync6, readdirSync as readdirSync3 } from "node:fs";
2375
+ // ../core/src/providers.ts
2376
+ function normalizeProviderId(provider) {
2377
+ if (provider in PROVIDER_ALIAS_MAP) {
2378
+ return PROVIDER_ALIAS_MAP[provider];
2379
+ }
2380
+ throw new Error(`Unknown provider: ${provider}`);
2381
+ }
2382
+ function normalizeProviderApplicability(value, fieldName) {
2383
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
2384
+ throw new Error(`${fieldName} must be a table of provider = boolean entries`);
2385
+ }
2386
+ const normalized = {};
2387
+ for (const [rawProvider, rawEnabled] of Object.entries(value)) {
2388
+ if (typeof rawEnabled !== "boolean") {
2389
+ throw new Error(`${fieldName}.${rawProvider} must be a boolean`);
2390
+ }
2391
+ const canonicalProvider = normalizeProviderId(rawProvider);
2392
+ const existing = normalized[canonicalProvider];
2393
+ if (existing !== undefined && existing !== rawEnabled) {
2394
+ throw new Error(`Conflicting provider entries in ${fieldName}: ${rawProvider} maps to ${canonicalProvider}`);
2395
+ }
2396
+ normalized[canonicalProvider] = rawEnabled;
2397
+ }
2398
+ return normalized;
2399
+ }
2400
+ var PROVIDER_ALIAS_MAP;
2401
+ var init_providers = __esm(() => {
2402
+ PROVIDER_ALIAS_MAP = {
2403
+ claude: "claude-code",
2404
+ "claude-code": "claude-code",
2405
+ codex: "codex",
2406
+ cursor: "cursor",
2407
+ opencode: "opencode"
2408
+ };
2409
+ });
2410
+
2411
+ // ../core/src/config/parser.ts
2412
+ function parseOmniConfig(tomlContent) {
2413
+ try {
2414
+ return parse(tomlContent);
2415
+ } catch (error) {
2416
+ const message = error instanceof Error ? error.message : String(error);
2417
+ throw new Error(`Invalid TOML in config: ${message}`);
2418
+ }
2419
+ }
2420
+ function validateCapabilityConfig(parsed) {
2421
+ const cap = parsed["capability"];
2422
+ if (typeof cap !== "object" || cap === null) {
2423
+ throw new Error("capability.id is required in capability.toml");
2424
+ }
2425
+ const capability = cap;
2426
+ if (typeof capability["id"] !== "string") {
2427
+ throw new Error("capability.id is required in capability.toml");
2428
+ }
2429
+ if (typeof capability["name"] !== "string") {
2430
+ throw new Error("capability.name is required in capability.toml");
2431
+ }
2432
+ if (typeof capability["version"] !== "string") {
2433
+ throw new Error("capability.version is required in capability.toml");
2434
+ }
2435
+ if (capability["providers"] !== undefined) {
2436
+ capability["providers"] = normalizeProviderApplicability(capability["providers"], "capability.providers");
2437
+ }
2438
+ }
2439
+ function parseCapabilityConfig(tomlContent) {
2440
+ try {
2441
+ const parsed = parse(tomlContent);
2442
+ validateCapabilityConfig(parsed);
2443
+ return parsed;
2444
+ } catch (error) {
2445
+ const message = error instanceof Error ? error.message : String(error);
2446
+ throw new Error(`Invalid capability.toml: ${message}`);
2447
+ }
2448
+ }
2449
+ var init_parser = __esm(() => {
2450
+ init_dist();
2451
+ init_providers();
2452
+ });
2453
+
2454
+ // ../core/src/capability/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 mergeEnvSources(capabilityEnv) {
2460
+ const merged = { ...capabilityEnv };
2461
+ for (const [key, value] of Object.entries(process.env)) {
2462
+ if (typeof value === "string") {
2463
+ merged[key] = value;
2464
+ }
2465
+ }
2466
+ return merged;
2467
+ }
2468
+ async function loadCapabilityEnvVariables(capabilityPath) {
2469
+ const envPath = join4(capabilityPath, CAPABILITY_ENV_FILE);
2470
+ if (!existsSync6(envPath)) {
2471
+ return mergeEnvSources({});
2472
+ }
2473
+ const envContent = await readFile3(envPath, "utf-8");
2474
+ const capabilityEnv = Object.fromEntries(Object.entries(parseEnv(envContent)).filter((entry) => typeof entry[1] === "string"));
2475
+ return mergeEnvSources(capabilityEnv);
2476
+ }
2477
+ var CAPABILITY_ENV_FILE = ".env";
2478
+ var init_env = () => {};
2479
+
2480
+ // ../core/src/capability/mcp-env.ts
2481
+ function hasEnvPlaceholder(value) {
2482
+ return ENV_PLACEHOLDER_DETECTOR.test(value);
2483
+ }
2484
+ function resolveString(value, variables, capabilityId, fieldPath) {
2485
+ if (!hasEnvPlaceholder(value)) {
2486
+ return value;
2487
+ }
2488
+ return value.replace(ENV_PLACEHOLDER, (_match, variableName) => {
2489
+ const resolved = variables[variableName];
2490
+ if (resolved === undefined) {
2491
+ throw new Error(`Missing environment variable "${variableName}" required by capability "${capabilityId}" in ${fieldPath}`);
2492
+ }
2493
+ return resolved;
2494
+ });
2495
+ }
2496
+ function mcpHasPlaceholders(mcp) {
2497
+ const strings = [];
2498
+ if (mcp.command) {
2499
+ strings.push(mcp.command);
2500
+ }
2501
+ if (mcp.cwd) {
2502
+ strings.push(mcp.cwd);
2503
+ }
2504
+ if (mcp.url) {
2505
+ strings.push(mcp.url);
2506
+ }
2507
+ if (mcp.args) {
2508
+ strings.push(...mcp.args);
2509
+ }
2510
+ if (mcp.env) {
2511
+ strings.push(...Object.values(mcp.env));
2512
+ }
2513
+ if (mcp.headers) {
2514
+ strings.push(...Object.values(mcp.headers));
2515
+ }
2516
+ return strings.some((value) => hasEnvPlaceholder(value));
2517
+ }
2518
+ async function resolveCapabilityMcpEnv(config, capabilityPath, variables) {
2519
+ if (!config.mcp || !mcpHasPlaceholders(config.mcp)) {
2520
+ return config;
2521
+ }
2522
+ const resolvedVariables = variables ?? await loadCapabilityEnvVariables(capabilityPath);
2523
+ const resolvedMcp = { ...config.mcp };
2524
+ const capabilityId = config.capability.id;
2525
+ if (resolvedMcp.command) {
2526
+ resolvedMcp.command = resolveString(resolvedMcp.command, resolvedVariables, capabilityId, "mcp.command");
2527
+ }
2528
+ if (resolvedMcp.cwd) {
2529
+ resolvedMcp.cwd = resolveString(resolvedMcp.cwd, resolvedVariables, capabilityId, "mcp.cwd");
2530
+ }
2531
+ if (resolvedMcp.url) {
2532
+ resolvedMcp.url = resolveString(resolvedMcp.url, resolvedVariables, capabilityId, "mcp.url");
2533
+ }
2534
+ if (resolvedMcp.args) {
2535
+ resolvedMcp.args = resolvedMcp.args.map((arg, index) => resolveString(arg, resolvedVariables, capabilityId, `mcp.args[${index}]`));
2536
+ }
2537
+ if (resolvedMcp.env) {
2538
+ resolvedMcp.env = Object.fromEntries(Object.entries(resolvedMcp.env).map(([key, value]) => [
2539
+ key,
2540
+ resolveString(value, resolvedVariables, capabilityId, `mcp.env.${key}`)
2541
+ ]));
2542
+ }
2543
+ if (resolvedMcp.headers) {
2544
+ resolvedMcp.headers = Object.fromEntries(Object.entries(resolvedMcp.headers).map(([key, value]) => [
2545
+ key,
2546
+ resolveString(value, resolvedVariables, capabilityId, `mcp.headers.${key}`)
2547
+ ]));
2548
+ }
2549
+ return {
2550
+ ...config,
2551
+ mcp: resolvedMcp
2552
+ };
2553
+ }
2554
+ var ENV_PLACEHOLDER, ENV_PLACEHOLDER_DETECTOR;
2555
+ var init_mcp_env = __esm(() => {
2556
+ init_env();
2557
+ ENV_PLACEHOLDER = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g;
2558
+ ENV_PLACEHOLDER_DETECTOR = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/;
2559
+ });
2560
+
2561
+ // ../core/src/capability/rules.ts
2562
+ import { existsSync as existsSync7, readdirSync as readdirSync3 } from "node:fs";
2563
+ import { readFile as readFile4 } from "node:fs/promises";
2564
+ import { basename as basename3, join as join5 } from "node:path";
2418
2565
  async function loadRules(capabilityPath, capabilityId) {
2419
- const rulesDir = join4(capabilityPath, "rules");
2420
- if (!existsSync6(rulesDir)) {
2566
+ const rulesDir = join5(capabilityPath, "rules");
2567
+ if (!existsSync7(rulesDir)) {
2421
2568
  return [];
2422
2569
  }
2423
2570
  const rules = [];
2424
2571
  const entries = readdirSync3(rulesDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
2425
2572
  for (const entry of entries) {
2426
2573
  if (entry.isFile() && entry.name.endsWith(".md")) {
2427
- const rulePath = join4(rulesDir, entry.name);
2428
- const content = await readFile3(rulePath, "utf-8");
2574
+ const rulePath = join5(rulesDir, entry.name);
2575
+ const content = await readFile4(rulePath, "utf-8");
2429
2576
  rules.push({
2430
2577
  name: basename3(entry.name, ".md"),
2431
2578
  content: content.trim(),
@@ -2438,23 +2585,59 @@ async function loadRules(capabilityPath, capabilityId) {
2438
2585
  var init_rules = () => {};
2439
2586
 
2440
2587
  // ../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";
2444
- async function loadSkills(capabilityPath, capabilityId) {
2588
+ import { existsSync as existsSync8, readdirSync as readdirSync4 } from "node:fs";
2589
+ import { readFile as readFile5 } from "node:fs/promises";
2590
+ import { join as join6 } from "node:path";
2591
+ function hasSkillPlaceholder(value) {
2592
+ return SKILL_PLACEHOLDER_DETECTOR.test(value);
2593
+ }
2594
+ function resolveSkillPlaceholders(content, variables, capabilityId, sourceLabel) {
2595
+ if (!hasSkillPlaceholder(content)) {
2596
+ return content;
2597
+ }
2598
+ return content.replace(SKILL_PLACEHOLDER, (match, variableName) => {
2599
+ const resolved = variables[variableName];
2600
+ if (resolved === undefined) {
2601
+ throw new Error(`Missing environment variable "${variableName}" required by capability "${capabilityId}" in ${sourceLabel} (placeholder "${match}")`);
2602
+ }
2603
+ return resolved;
2604
+ });
2605
+ }
2606
+ function parseSkillMarkdown(content, capabilityId, options) {
2607
+ const resolvedContent = options?.variables && options.sourceLabel ? resolveSkillPlaceholders(content, options.variables, capabilityId, options.sourceLabel) : content;
2608
+ const parsed = parseFrontmatterWithMarkdown(resolvedContent);
2609
+ if (!parsed) {
2610
+ const sourceLabel = options?.sourceLabel ?? "skill content";
2611
+ throw new Error(`Invalid SKILL.md format at ${sourceLabel}: missing YAML frontmatter`);
2612
+ }
2613
+ const frontmatter = parsed.frontmatter;
2614
+ const instructions = parsed.markdown;
2615
+ if (!frontmatter.name || !frontmatter.description) {
2616
+ const sourceLabel = options?.sourceLabel ?? "skill content";
2617
+ throw new Error(`Invalid SKILL.md at ${sourceLabel}: name and description required in frontmatter`);
2618
+ }
2619
+ return {
2620
+ name: frontmatter.name,
2621
+ description: frontmatter.description,
2622
+ instructions: instructions.trim(),
2623
+ capabilityId
2624
+ };
2625
+ }
2626
+ async function loadSkills(capabilityPath, capabilityId, variables) {
2445
2627
  const skills = [];
2446
2628
  const possibleDirNames = ["skills", "skill"];
2629
+ const resolvedVariables = variables ?? await loadCapabilityEnvVariables(capabilityPath);
2447
2630
  for (const dirName of possibleDirNames) {
2448
- const dir = join5(capabilityPath, dirName);
2449
- if (!existsSync7(dir)) {
2631
+ const dir = join6(capabilityPath, dirName);
2632
+ if (!existsSync8(dir)) {
2450
2633
  continue;
2451
2634
  }
2452
2635
  const entries = readdirSync4(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
2453
2636
  for (const entry of entries) {
2454
2637
  if (entry.isDirectory()) {
2455
- const skillPath = join5(dir, entry.name, "SKILL.md");
2456
- if (existsSync7(skillPath)) {
2457
- const skill = await parseSkillFile(skillPath, capabilityId);
2638
+ const skillPath = join6(dir, entry.name, "SKILL.md");
2639
+ if (existsSync8(skillPath)) {
2640
+ const skill = await parseSkillFile(skillPath, capabilityId, resolvedVariables, `skill file ${skillPath}`);
2458
2641
  skills.push(skill);
2459
2642
  }
2460
2643
  }
@@ -2462,51 +2645,45 @@ async function loadSkills(capabilityPath, capabilityId) {
2462
2645
  }
2463
2646
  return skills;
2464
2647
  }
2465
- async function parseSkillFile(filePath, capabilityId) {
2466
- const content = await readFile4(filePath, "utf-8");
2467
- const parsed = parseFrontmatterWithMarkdown(content);
2468
- if (!parsed) {
2469
- throw new Error(`Invalid SKILL.md format at ${filePath}: missing YAML frontmatter`);
2470
- }
2471
- const frontmatter = parsed.frontmatter;
2472
- const instructions = parsed.markdown;
2473
- if (!frontmatter.name || !frontmatter.description) {
2474
- throw new Error(`Invalid SKILL.md at ${filePath}: name and description required in frontmatter`);
2475
- }
2476
- return {
2477
- name: frontmatter.name,
2478
- description: frontmatter.description,
2479
- instructions: instructions.trim(),
2480
- capabilityId
2481
- };
2648
+ async function parseSkillFile(filePath, capabilityId, variables, sourceLabel) {
2649
+ const content = await readFile5(filePath, "utf-8");
2650
+ return parseSkillMarkdown(content, capabilityId, {
2651
+ variables,
2652
+ sourceLabel
2653
+ });
2482
2654
  }
2483
- var init_skills = () => {};
2655
+ var SKILL_PLACEHOLDER, SKILL_PLACEHOLDER_DETECTOR;
2656
+ var init_skills = __esm(() => {
2657
+ init_env();
2658
+ SKILL_PLACEHOLDER = /\{OMNIDEV_([A-Za-z_][A-Za-z0-9_]*)\}/g;
2659
+ SKILL_PLACEHOLDER_DETECTOR = /\{OMNIDEV_([A-Za-z_][A-Za-z0-9_]*)\}/;
2660
+ });
2484
2661
 
2485
2662
  // ../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";
2663
+ import { existsSync as existsSync9, readdirSync as readdirSync5 } from "node:fs";
2664
+ import { readFile as readFile6 } from "node:fs/promises";
2665
+ import { basename as basename4, join as join7 } from "node:path";
2489
2666
  async function loadSubagents(capabilityPath, capabilityId) {
2490
2667
  const subagents = [];
2491
2668
  const possibleDirNames = ["subagents", "agents", "agent", "subagent"];
2492
2669
  for (const dirName of possibleDirNames) {
2493
- const dir = join6(capabilityPath, dirName);
2494
- if (!existsSync8(dir)) {
2670
+ const dir = join7(capabilityPath, dirName);
2671
+ if (!existsSync9(dir)) {
2495
2672
  continue;
2496
2673
  }
2497
2674
  const entries = readdirSync5(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
2498
2675
  for (const entry of entries) {
2499
2676
  if (entry.isDirectory()) {
2500
- let subagentPath = join6(dir, entry.name, "SUBAGENT.md");
2501
- if (!existsSync8(subagentPath)) {
2502
- subagentPath = join6(dir, entry.name, "AGENT.md");
2677
+ let subagentPath = join7(dir, entry.name, "SUBAGENT.md");
2678
+ if (!existsSync9(subagentPath)) {
2679
+ subagentPath = join7(dir, entry.name, "AGENT.md");
2503
2680
  }
2504
- if (existsSync8(subagentPath)) {
2681
+ if (existsSync9(subagentPath)) {
2505
2682
  const subagent = await parseSubagentFile(subagentPath, capabilityId);
2506
2683
  subagents.push(subagent);
2507
2684
  }
2508
2685
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
2509
- const subagentPath = join6(dir, entry.name);
2686
+ const subagentPath = join7(dir, entry.name);
2510
2687
  const subagent = await parseSubagentFile(subagentPath, capabilityId);
2511
2688
  subagents.push(subagent);
2512
2689
  }
@@ -2515,7 +2692,7 @@ async function loadSubagents(capabilityPath, capabilityId) {
2515
2692
  return subagents;
2516
2693
  }
2517
2694
  async function parseSubagentFile(filePath, capabilityId) {
2518
- const content = await readFile5(filePath, "utf-8");
2695
+ const content = await readFile6(filePath, "utf-8");
2519
2696
  const parsed = parseFrontmatterWithMarkdown(content);
2520
2697
  if (!parsed) {
2521
2698
  throw new Error(`Invalid SUBAGENT.md format at ${filePath}: missing YAML frontmatter`);
@@ -2559,18 +2736,18 @@ function parseCommaSeparatedList(value) {
2559
2736
  var init_subagents = () => {};
2560
2737
 
2561
2738
  // ../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";
2739
+ import { existsSync as existsSync10, readdirSync as readdirSync6 } from "node:fs";
2740
+ import { readFile as readFile7 } from "node:fs/promises";
2741
+ import { join as join8 } from "node:path";
2565
2742
  async function discoverCapabilities() {
2566
2743
  const capabilities = [];
2567
- if (existsSync9(CAPABILITIES_DIR)) {
2744
+ if (existsSync10(CAPABILITIES_DIR)) {
2568
2745
  const entries = readdirSync6(CAPABILITIES_DIR, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
2569
2746
  for (const entry of entries) {
2570
2747
  if (entry.isDirectory()) {
2571
- const entryPath = join7(CAPABILITIES_DIR, entry.name);
2572
- const configPath = join7(entryPath, "capability.toml");
2573
- if (existsSync9(configPath)) {
2748
+ const entryPath = join8(CAPABILITIES_DIR, entry.name);
2749
+ const configPath = join8(entryPath, "capability.toml");
2750
+ if (existsSync10(configPath)) {
2574
2751
  capabilities.push(entryPath);
2575
2752
  }
2576
2753
  }
@@ -2579,28 +2756,28 @@ async function discoverCapabilities() {
2579
2756
  return capabilities;
2580
2757
  }
2581
2758
  async function loadCapabilityConfig(capabilityPath) {
2582
- const configPath = join7(capabilityPath, "capability.toml");
2583
- const content = await readFile6(configPath, "utf-8");
2759
+ const configPath = join8(capabilityPath, "capability.toml");
2760
+ const content = await readFile7(configPath, "utf-8");
2584
2761
  const config = parseCapabilityConfig(content);
2585
2762
  return config;
2586
2763
  }
2587
2764
  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");
2765
+ const builtIndexPath = join8(capabilityPath, "dist", "index.js");
2766
+ const jsIndexPath = join8(capabilityPath, "index.js");
2767
+ const tsIndexPath = join8(capabilityPath, "index.ts");
2591
2768
  let indexPath = null;
2592
- if (existsSync9(builtIndexPath)) {
2769
+ if (existsSync10(builtIndexPath)) {
2593
2770
  indexPath = builtIndexPath;
2594
- } else if (existsSync9(jsIndexPath)) {
2771
+ } else if (existsSync10(jsIndexPath)) {
2595
2772
  indexPath = jsIndexPath;
2596
- } else if (existsSync9(tsIndexPath)) {
2773
+ } else if (existsSync10(tsIndexPath)) {
2597
2774
  indexPath = tsIndexPath;
2598
2775
  }
2599
2776
  if (!indexPath) {
2600
2777
  return {};
2601
2778
  }
2602
2779
  try {
2603
- const absolutePath = join7(process.cwd(), indexPath);
2780
+ const absolutePath = join8(process.cwd(), indexPath);
2604
2781
  const module = await import(absolutePath);
2605
2782
  return module;
2606
2783
  } catch (error) {
@@ -2620,46 +2797,19 @@ If this is a project-specific capability, install dependencies or remove it from
2620
2797
  }
2621
2798
  }
2622
2799
  async function loadTypeDefinitions(capabilityPath) {
2623
- const typesPath = join7(capabilityPath, "types.d.ts");
2624
- if (!existsSync9(typesPath)) {
2800
+ const typesPath = join8(capabilityPath, "types.d.ts");
2801
+ if (!existsSync10(typesPath)) {
2625
2802
  return;
2626
2803
  }
2627
- return readFile6(typesPath, "utf-8");
2804
+ return readFile7(typesPath, "utf-8");
2628
2805
  }
2629
- function convertSkillExports(skillExports, capabilityId) {
2630
- return skillExports.map((skillExport) => {
2806
+ function convertSkillExports(skillExports, capabilityId, variables) {
2807
+ return skillExports.map((skillExport, index) => {
2631
2808
  const exportObj = skillExport;
2632
- const lines = exportObj.skillMd.split(`
2633
- `);
2634
- let name = "unnamed";
2635
- let description = "";
2636
- let instructions = exportObj.skillMd;
2637
- if (lines[0]?.trim() === "---") {
2638
- const endIndex = lines.findIndex((line, i) => i > 0 && line.trim() === "---");
2639
- if (endIndex > 0) {
2640
- const frontmatter = lines.slice(1, endIndex);
2641
- instructions = lines.slice(endIndex + 1).join(`
2642
- `).trim();
2643
- for (const line of frontmatter) {
2644
- const match = line.match(/^(\w+):\s*(.+)$/);
2645
- if (match?.[1] && match[2]) {
2646
- const key = match[1];
2647
- const value = match[2];
2648
- if (key === "name") {
2649
- name = value.replace(/^["']|["']$/g, "");
2650
- } else if (key === "description") {
2651
- description = value.replace(/^["']|["']$/g, "");
2652
- }
2653
- }
2654
- }
2655
- }
2656
- }
2657
- return {
2658
- name,
2659
- description,
2660
- instructions,
2661
- capabilityId
2662
- };
2809
+ return parseSkillMarkdown(exportObj.skillMd, capabilityId, {
2810
+ variables,
2811
+ sourceLabel: `programmatic skill export[${index}]`
2812
+ });
2663
2813
  });
2664
2814
  }
2665
2815
  function convertRuleExports(ruleExports, capabilityId) {
@@ -2812,7 +2962,9 @@ function mergeByName(fileBased, programmatic) {
2812
2962
  return Array.from(byName.values());
2813
2963
  }
2814
2964
  async function loadCapability(capabilityPath) {
2815
- const config = await loadCapabilityConfig(capabilityPath);
2965
+ const capabilityEnvVariables = await loadCapabilityEnvVariables(capabilityPath);
2966
+ const rawConfig = await loadCapabilityConfig(capabilityPath);
2967
+ const config = await resolveCapabilityMcpEnv(rawConfig, capabilityPath, capabilityEnvVariables);
2816
2968
  const id = config.capability.id;
2817
2969
  const exports = await importCapabilityExports(capabilityPath);
2818
2970
  const exportsAny = exports;
@@ -2827,8 +2979,8 @@ async function loadCapability(capabilityPath) {
2827
2979
  return;
2828
2980
  };
2829
2981
  const skillsExport = getExportValue("skills");
2830
- const programmaticSkills = Array.isArray(skillsExport) ? convertSkillExports(skillsExport, id) : [];
2831
- const fileSkills = await loadSkills(capabilityPath, id);
2982
+ const programmaticSkills = Array.isArray(skillsExport) ? convertSkillExports(skillsExport, id, capabilityEnvVariables) : [];
2983
+ const fileSkills = await loadSkills(capabilityPath, id, capabilityEnvVariables);
2832
2984
  const skills = mergeByName(fileSkills, programmaticSkills);
2833
2985
  const rulesExport = getExportValue("rules");
2834
2986
  const programmaticRules = Array.isArray(rulesExport) ? convertRuleExports(rulesExport, id) : [];
@@ -2876,18 +3028,20 @@ async function loadCapability(capabilityPath) {
2876
3028
  }
2877
3029
  var CAPABILITIES_DIR = ".omni/capabilities";
2878
3030
  var init_loader2 = __esm(() => {
2879
- init_parser();
2880
3031
  init_loader();
3032
+ init_parser();
2881
3033
  init_commands();
2882
3034
  init_docs();
3035
+ init_env();
3036
+ init_mcp_env();
2883
3037
  init_rules();
2884
3038
  init_skills();
2885
3039
  init_subagents();
2886
3040
  });
2887
3041
 
2888
3042
  // ../core/src/config/config.ts
2889
- import { existsSync as existsSync10 } from "node:fs";
2890
- import { readFile as readFile7, writeFile } from "node:fs/promises";
3043
+ import { existsSync as existsSync11 } from "node:fs";
3044
+ import { readFile as readFile8, writeFile } from "node:fs/promises";
2891
3045
  function mergeConfigs(base, override) {
2892
3046
  const merged = { ...base, ...override };
2893
3047
  merged.profiles = { ...base.profiles };
@@ -2929,8 +3083,8 @@ function mergeConfigs(base, override) {
2929
3083
  return merged;
2930
3084
  }
2931
3085
  async function loadBaseConfig() {
2932
- if (existsSync10(CONFIG_PATH)) {
2933
- const content = await readFile7(CONFIG_PATH, "utf-8");
3086
+ if (existsSync11(CONFIG_PATH)) {
3087
+ const content = await readFile8(CONFIG_PATH, "utf-8");
2934
3088
  return parseOmniConfig(content);
2935
3089
  }
2936
3090
  return {};
@@ -2938,8 +3092,8 @@ async function loadBaseConfig() {
2938
3092
  async function loadConfig() {
2939
3093
  const baseConfig = await loadBaseConfig();
2940
3094
  let localConfig = {};
2941
- if (existsSync10(LOCAL_CONFIG)) {
2942
- const content = await readFile7(LOCAL_CONFIG, "utf-8");
3095
+ if (existsSync11(LOCAL_CONFIG)) {
3096
+ const content = await readFile8(LOCAL_CONFIG, "utf-8");
2943
3097
  localConfig = parseOmniConfig(content);
2944
3098
  }
2945
3099
  return mergeConfigs(baseConfig, localConfig);
@@ -3103,14 +3257,14 @@ var init_config = __esm(() => {
3103
3257
  });
3104
3258
 
3105
3259
  // ../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";
3260
+ import { existsSync as existsSync12, mkdirSync } from "node:fs";
3261
+ import { readFile as readFile9, unlink, writeFile as writeFile2 } from "node:fs/promises";
3108
3262
  async function readActiveProfileState() {
3109
- if (!existsSync11(ACTIVE_PROFILE_PATH)) {
3263
+ if (!existsSync12(ACTIVE_PROFILE_PATH)) {
3110
3264
  return null;
3111
3265
  }
3112
3266
  try {
3113
- const content = await readFile8(ACTIVE_PROFILE_PATH, "utf-8");
3267
+ const content = await readFile9(ACTIVE_PROFILE_PATH, "utf-8");
3114
3268
  const trimmed = content.trim();
3115
3269
  return trimmed || null;
3116
3270
  } catch {
@@ -3122,7 +3276,7 @@ async function writeActiveProfileState(profileName) {
3122
3276
  await writeFile2(ACTIVE_PROFILE_PATH, profileName, "utf-8");
3123
3277
  }
3124
3278
  async function clearActiveProfileState() {
3125
- if (existsSync11(ACTIVE_PROFILE_PATH)) {
3279
+ if (existsSync12(ACTIVE_PROFILE_PATH)) {
3126
3280
  await unlink(ACTIVE_PROFILE_PATH);
3127
3281
  }
3128
3282
  }
@@ -3366,10 +3520,10 @@ function getActiveProviders(config) {
3366
3520
  var init_types2 = () => {};
3367
3521
 
3368
3522
  // ../core/src/capability/sources.ts
3369
- import { existsSync as existsSync12 } from "node:fs";
3523
+ import { existsSync as existsSync13 } from "node:fs";
3370
3524
  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";
3525
+ import { cp, mkdir, readdir, readFile as readFile10, rename, rm, stat, writeFile as writeFile3 } from "node:fs/promises";
3526
+ import { join as join9 } from "node:path";
3373
3527
  import { createHash } from "node:crypto";
3374
3528
  async function spawnCapture(command, args, options) {
3375
3529
  const timeout = options?.timeout ?? 60000;
@@ -3426,10 +3580,10 @@ function parseFileSourcePath(source) {
3426
3580
  return source.slice(7);
3427
3581
  }
3428
3582
  async function readCapabilityIdFromPath(capabilityPath) {
3429
- const tomlPath = join8(capabilityPath, "capability.toml");
3430
- if (existsSync12(tomlPath)) {
3583
+ const tomlPath = join9(capabilityPath, "capability.toml");
3584
+ if (existsSync13(tomlPath)) {
3431
3585
  try {
3432
- const content = await readFile9(tomlPath, "utf-8");
3586
+ const content = await readFile10(tomlPath, "utf-8");
3433
3587
  const parsed = parse(content);
3434
3588
  const capability = parsed["capability"];
3435
3589
  if (capability?.["id"] && typeof capability["id"] === "string") {
@@ -3482,18 +3636,18 @@ function sourceToGitUrl(source) {
3482
3636
  return source;
3483
3637
  }
3484
3638
  function getSourceCapabilityPath(id) {
3485
- return join8(OMNI_LOCAL, "capabilities", id);
3639
+ return join9(OMNI_LOCAL, "capabilities", id);
3486
3640
  }
3487
3641
  function getLockFilePath() {
3488
3642
  return "omni.lock.toml";
3489
3643
  }
3490
3644
  async function loadLockFile() {
3491
3645
  const lockPath = getLockFilePath();
3492
- if (!existsSync12(lockPath)) {
3646
+ if (!existsSync13(lockPath)) {
3493
3647
  return { capabilities: {} };
3494
3648
  }
3495
3649
  try {
3496
- const content = await readFile9(lockPath, "utf-8");
3650
+ const content = await readFile10(lockPath, "utf-8");
3497
3651
  const parsed = parse(content);
3498
3652
  const rawCapabilities = parsed["capabilities"];
3499
3653
  if (!rawCapabilities) {
@@ -3551,7 +3705,7 @@ function stringifyLockFile(lockFile) {
3551
3705
  }
3552
3706
  async function saveLockFile(lockFile) {
3553
3707
  const lockPath = getLockFilePath();
3554
- await mkdir(join8(OMNI_LOCAL, "capabilities"), { recursive: true });
3708
+ await mkdir(join9(OMNI_LOCAL, "capabilities"), { recursive: true });
3555
3709
  const header = `# Auto-generated by OmniDev - DO NOT EDIT
3556
3710
  # Records installed capability versions for reproducibility
3557
3711
  # Last updated: ${new Date().toISOString()}
@@ -3585,7 +3739,7 @@ async function computeContentHash(dirPath, excludePatterns = CONTENT_HASH_EXCLUD
3585
3739
  const entries = await readdir(currentPath, { withFileTypes: true });
3586
3740
  entries.sort((a, b) => a.name.localeCompare(b.name));
3587
3741
  for (const entry of entries) {
3588
- const fullPath = join8(currentPath, entry.name);
3742
+ const fullPath = join9(currentPath, entry.name);
3589
3743
  const relativePath = fullPath.slice(relativeTo.length + 1);
3590
3744
  if (excludePatterns.some((pattern) => entry.name === pattern || relativePath.startsWith(`${pattern}/`))) {
3591
3745
  continue;
@@ -3593,7 +3747,7 @@ async function computeContentHash(dirPath, excludePatterns = CONTENT_HASH_EXCLUD
3593
3747
  if (entry.isDirectory()) {
3594
3748
  await collectFiles(fullPath, relativeTo);
3595
3749
  } else if (entry.isFile()) {
3596
- const content = await readFile9(fullPath);
3750
+ const content = await readFile10(fullPath);
3597
3751
  files.push({ relativePath, content });
3598
3752
  }
3599
3753
  }
@@ -3607,10 +3761,10 @@ async function computeContentHash(dirPath, excludePatterns = CONTENT_HASH_EXCLUD
3607
3761
  return hash.digest("hex");
3608
3762
  }
3609
3763
  async function detectDisplayVersion(dirPath, fallback, fallbackSource) {
3610
- const capTomlPath = join8(dirPath, "capability.toml");
3611
- if (existsSync12(capTomlPath)) {
3764
+ const capTomlPath = join9(dirPath, "capability.toml");
3765
+ if (existsSync13(capTomlPath)) {
3612
3766
  try {
3613
- const content = await readFile9(capTomlPath, "utf-8");
3767
+ const content = await readFile10(capTomlPath, "utf-8");
3614
3768
  const parsed = parse(content);
3615
3769
  const capability = parsed["capability"];
3616
3770
  if (capability?.["version"] && typeof capability["version"] === "string") {
@@ -3618,20 +3772,20 @@ async function detectDisplayVersion(dirPath, fallback, fallbackSource) {
3618
3772
  }
3619
3773
  } catch {}
3620
3774
  }
3621
- const pluginJsonPath = join8(dirPath, ".claude-plugin", "plugin.json");
3622
- if (existsSync12(pluginJsonPath)) {
3775
+ const pluginJsonPath = join9(dirPath, ".claude-plugin", "plugin.json");
3776
+ if (existsSync13(pluginJsonPath)) {
3623
3777
  try {
3624
- const content = await readFile9(pluginJsonPath, "utf-8");
3778
+ const content = await readFile10(pluginJsonPath, "utf-8");
3625
3779
  const parsed = JSON.parse(content);
3626
3780
  if (parsed.version && typeof parsed.version === "string") {
3627
3781
  return { version: parsed.version, source: "plugin.json" };
3628
3782
  }
3629
3783
  } catch {}
3630
3784
  }
3631
- const pkgJsonPath = join8(dirPath, "package.json");
3632
- if (existsSync12(pkgJsonPath)) {
3785
+ const pkgJsonPath = join9(dirPath, "package.json");
3786
+ if (existsSync13(pkgJsonPath)) {
3633
3787
  try {
3634
- const content = await readFile9(pkgJsonPath, "utf-8");
3788
+ const content = await readFile10(pkgJsonPath, "utf-8");
3635
3789
  const parsed = JSON.parse(content);
3636
3790
  if (parsed.version && typeof parsed.version === "string") {
3637
3791
  return { version: parsed.version, source: "package.json" };
@@ -3642,9 +3796,9 @@ async function detectDisplayVersion(dirPath, fallback, fallbackSource) {
3642
3796
  }
3643
3797
  async function validateGitCapability(sourceUrl, subPath) {
3644
3798
  const gitUrl = sourceToGitUrl(sourceUrl);
3645
- const tempPath = join8(OMNI_LOCAL, "_temp", `_validate-${Date.now()}`);
3799
+ const tempPath = join9(OMNI_LOCAL, "_temp", `_validate-${Date.now()}`);
3646
3800
  try {
3647
- await mkdir(join8(tempPath, ".."), { recursive: true });
3801
+ await mkdir(join9(tempPath, ".."), { recursive: true });
3648
3802
  const args = ["clone", "--depth", "1", gitUrl, tempPath];
3649
3803
  const { exitCode, stderr } = await spawnCapture("git", args, { timeout: 30000 });
3650
3804
  if (exitCode !== 0) {
@@ -3680,8 +3834,8 @@ async function validateGitCapability(sourceUrl, subPath) {
3680
3834
  error: `Failed to clone repository: ${stderr.trim()}`
3681
3835
  };
3682
3836
  }
3683
- const checkPath = subPath ? join8(tempPath, subPath) : tempPath;
3684
- if (subPath && !existsSync12(checkPath)) {
3837
+ const checkPath = subPath ? join9(tempPath, subPath) : tempPath;
3838
+ if (subPath && !existsSync13(checkPath)) {
3685
3839
  return {
3686
3840
  valid: false,
3687
3841
  hasCapabilityToml: false,
@@ -3692,9 +3846,9 @@ async function validateGitCapability(sourceUrl, subPath) {
3692
3846
  const hasCapToml = hasCapabilityToml(checkPath);
3693
3847
  let capabilityId;
3694
3848
  if (hasCapToml) {
3695
- const tomlPath = join8(checkPath, "capability.toml");
3849
+ const tomlPath = join9(checkPath, "capability.toml");
3696
3850
  try {
3697
- const content = await readFile9(tomlPath, "utf-8");
3851
+ const content = await readFile10(tomlPath, "utf-8");
3698
3852
  const parsed = parse(content);
3699
3853
  const capability = parsed["capability"];
3700
3854
  if (capability?.["id"] && typeof capability["id"] === "string") {
@@ -3726,27 +3880,27 @@ async function validateGitCapability(sourceUrl, subPath) {
3726
3880
  canBeWrapped: true
3727
3881
  };
3728
3882
  } finally {
3729
- if (existsSync12(tempPath)) {
3883
+ if (existsSync13(tempPath)) {
3730
3884
  await rm(tempPath, { recursive: true });
3731
3885
  }
3732
3886
  }
3733
3887
  }
3734
3888
  async function detectPinVersion(sourceUrl, subPath) {
3735
3889
  const gitUrl = sourceToGitUrl(sourceUrl);
3736
- const tempPath = join8(OMNI_LOCAL, "_temp", `_pin-detect-${Date.now()}`);
3890
+ const tempPath = join9(OMNI_LOCAL, "_temp", `_pin-detect-${Date.now()}`);
3737
3891
  try {
3738
- await mkdir(join8(tempPath, ".."), { recursive: true });
3892
+ await mkdir(join9(tempPath, ".."), { recursive: true });
3739
3893
  const args = ["clone", "--depth", "1", gitUrl, tempPath];
3740
3894
  const { exitCode, stderr } = await spawnCapture("git", args);
3741
3895
  if (exitCode !== 0) {
3742
3896
  throw new Error(`Failed to clone ${gitUrl}: ${stderr.trim()}`);
3743
3897
  }
3744
3898
  const commit = await getRepoCommit(tempPath);
3745
- const checkPath = subPath ? join8(tempPath, subPath) : tempPath;
3746
- const capTomlPath = join8(checkPath, "capability.toml");
3747
- if (existsSync12(capTomlPath)) {
3899
+ const checkPath = subPath ? join9(tempPath, subPath) : tempPath;
3900
+ const capTomlPath = join9(checkPath, "capability.toml");
3901
+ if (existsSync13(capTomlPath)) {
3748
3902
  try {
3749
- const content = await readFile9(capTomlPath, "utf-8");
3903
+ const content = await readFile10(capTomlPath, "utf-8");
3750
3904
  const parsed = parse(content);
3751
3905
  const capability = parsed["capability"];
3752
3906
  if (capability?.["version"] && typeof capability["version"] === "string") {
@@ -3754,10 +3908,10 @@ async function detectPinVersion(sourceUrl, subPath) {
3754
3908
  }
3755
3909
  } catch {}
3756
3910
  }
3757
- const pluginJsonPath = join8(checkPath, ".claude-plugin", "plugin.json");
3758
- if (existsSync12(pluginJsonPath)) {
3911
+ const pluginJsonPath = join9(checkPath, ".claude-plugin", "plugin.json");
3912
+ if (existsSync13(pluginJsonPath)) {
3759
3913
  try {
3760
- const content = await readFile9(pluginJsonPath, "utf-8");
3914
+ const content = await readFile10(pluginJsonPath, "utf-8");
3761
3915
  const parsed = JSON.parse(content);
3762
3916
  if (parsed.version && typeof parsed.version === "string") {
3763
3917
  return parsed.version;
@@ -3766,13 +3920,13 @@ async function detectPinVersion(sourceUrl, subPath) {
3766
3920
  }
3767
3921
  return commit;
3768
3922
  } finally {
3769
- if (existsSync12(tempPath)) {
3923
+ if (existsSync13(tempPath)) {
3770
3924
  await rm(tempPath, { recursive: true });
3771
3925
  }
3772
3926
  }
3773
3927
  }
3774
3928
  async function cloneRepo(gitUrl, targetPath, ref) {
3775
- await mkdir(join8(targetPath, ".."), { recursive: true });
3929
+ await mkdir(join9(targetPath, ".."), { recursive: true });
3776
3930
  const args = ["clone", "--depth", "1"];
3777
3931
  if (ref) {
3778
3932
  args.push("--branch", ref);
@@ -3830,16 +3984,16 @@ async function fetchRepo(repoPath, ref) {
3830
3984
  return true;
3831
3985
  }
3832
3986
  function hasCapabilityToml(dirPath) {
3833
- return existsSync12(join8(dirPath, "capability.toml"));
3987
+ return existsSync13(join9(dirPath, "capability.toml"));
3834
3988
  }
3835
3989
  async function shouldWrapDirectory(dirPath) {
3836
- if (existsSync12(join8(dirPath, ".claude-plugin", "plugin.json"))) {
3990
+ if (existsSync13(join9(dirPath, ".claude-plugin", "plugin.json"))) {
3837
3991
  return true;
3838
3992
  }
3839
3993
  const allDirs = [...SKILL_DIRS, ...AGENT_DIRS, ...COMMAND_DIRS, ...RULE_DIRS, ...DOC_DIRS];
3840
3994
  for (const dirName of allDirs) {
3841
- const checkPath = join8(dirPath, dirName);
3842
- if (existsSync12(checkPath)) {
3995
+ const checkPath = join9(dirPath, dirName);
3996
+ if (existsSync13(checkPath)) {
3843
3997
  const stats = await stat(checkPath);
3844
3998
  if (stats.isDirectory()) {
3845
3999
  return true;
@@ -3848,10 +4002,64 @@ async function shouldWrapDirectory(dirPath) {
3848
4002
  }
3849
4003
  return false;
3850
4004
  }
4005
+ function isRecognizedWrappedDirectory(dirName, keepGitDir = false) {
4006
+ if (keepGitDir && dirName === ".git") {
4007
+ return true;
4008
+ }
4009
+ return WRAPPED_CONTENT_DIRS.has(dirName);
4010
+ }
4011
+ function isMandatoryWrappedRootFile(fileName) {
4012
+ if (WRAPPED_ROOT_FILES_EXACT.has(fileName)) {
4013
+ return true;
4014
+ }
4015
+ return WRAPPED_ROOT_FILE_PATTERNS.some((pattern) => pattern.test(fileName));
4016
+ }
4017
+ async function copyWrappedContentOnly(sourcePath, targetPath) {
4018
+ await mkdir(targetPath, { recursive: true });
4019
+ const entries = await readdir(sourcePath, { withFileTypes: true });
4020
+ for (const entry of entries) {
4021
+ if (entry.isDirectory() && !isRecognizedWrappedDirectory(entry.name)) {
4022
+ continue;
4023
+ }
4024
+ if (entry.isFile() && !isMandatoryWrappedRootFile(entry.name)) {
4025
+ continue;
4026
+ }
4027
+ if (!entry.isDirectory() && !entry.isFile()) {
4028
+ continue;
4029
+ }
4030
+ const sourceEntryPath = join9(sourcePath, entry.name);
4031
+ const targetEntryPath = join9(targetPath, entry.name);
4032
+ if (entry.isDirectory()) {
4033
+ await cp(sourceEntryPath, targetEntryPath, { recursive: true });
4034
+ } else {
4035
+ await cp(sourceEntryPath, targetEntryPath);
4036
+ }
4037
+ }
4038
+ }
4039
+ async function pruneUnknownWrappedEntries(repoPath, keepGitDir = false) {
4040
+ const entries = await readdir(repoPath, { withFileTypes: true });
4041
+ for (const entry of entries) {
4042
+ if (entry.isDirectory()) {
4043
+ if (isRecognizedWrappedDirectory(entry.name, keepGitDir)) {
4044
+ continue;
4045
+ }
4046
+ await rm(join9(repoPath, entry.name), { recursive: true, force: true });
4047
+ continue;
4048
+ }
4049
+ if (entry.isFile()) {
4050
+ if (isMandatoryWrappedRootFile(entry.name)) {
4051
+ continue;
4052
+ }
4053
+ await rm(join9(repoPath, entry.name), { force: true });
4054
+ continue;
4055
+ }
4056
+ await rm(join9(repoPath, entry.name), { recursive: true, force: true });
4057
+ }
4058
+ }
3851
4059
  async function findMatchingDirs(basePath, names) {
3852
4060
  for (const name of names) {
3853
- const dirPath = join8(basePath, name);
3854
- if (existsSync12(dirPath)) {
4061
+ const dirPath = join9(basePath, name);
4062
+ if (existsSync13(dirPath)) {
3855
4063
  const stats = await stat(dirPath);
3856
4064
  if (stats.isDirectory()) {
3857
4065
  return dirPath;
@@ -3862,15 +4070,15 @@ async function findMatchingDirs(basePath, names) {
3862
4070
  }
3863
4071
  async function findContentItems(dirPath, filePatterns) {
3864
4072
  const items = [];
3865
- if (!existsSync12(dirPath)) {
4073
+ if (!existsSync13(dirPath)) {
3866
4074
  return items;
3867
4075
  }
3868
4076
  const entries = (await readdir(dirPath, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name));
3869
4077
  for (const entry of entries) {
3870
- const entryPath = join8(dirPath, entry.name);
4078
+ const entryPath = join9(dirPath, entry.name);
3871
4079
  if (entry.isDirectory()) {
3872
4080
  for (const pattern of filePatterns) {
3873
- if (existsSync12(join8(entryPath, pattern))) {
4081
+ if (existsSync13(join9(entryPath, pattern))) {
3874
4082
  items.push({
3875
4083
  name: entry.name,
3876
4084
  path: entryPath,
@@ -3891,12 +4099,12 @@ async function findContentItems(dirPath, filePatterns) {
3891
4099
  return items;
3892
4100
  }
3893
4101
  async function parsePluginJson(dirPath) {
3894
- const pluginJsonPath = join8(dirPath, ".claude-plugin", "plugin.json");
3895
- if (!existsSync12(pluginJsonPath)) {
4102
+ const pluginJsonPath = join9(dirPath, ".claude-plugin", "plugin.json");
4103
+ if (!existsSync13(pluginJsonPath)) {
3896
4104
  return null;
3897
4105
  }
3898
4106
  try {
3899
- const content = await readFile9(pluginJsonPath, "utf-8");
4107
+ const content = await readFile10(pluginJsonPath, "utf-8");
3900
4108
  const data = JSON.parse(content);
3901
4109
  const result = {
3902
4110
  name: data.name,
@@ -3916,12 +4124,12 @@ async function parsePluginJson(dirPath) {
3916
4124
  }
3917
4125
  }
3918
4126
  async function readReadmeDescription(dirPath) {
3919
- const readmePath = join8(dirPath, "README.md");
3920
- if (!existsSync12(readmePath)) {
4127
+ const readmePath = join9(dirPath, "README.md");
4128
+ if (!existsSync13(readmePath)) {
3921
4129
  return null;
3922
4130
  }
3923
4131
  try {
3924
- const content = await readFile9(readmePath, "utf-8");
4132
+ const content = await readFile10(readmePath, "utf-8");
3925
4133
  const lines = content.split(`
3926
4134
  `);
3927
4135
  let description = "";
@@ -3956,9 +4164,9 @@ async function normalizeFolderNames(repoPath) {
3956
4164
  { from: "rule", to: "rules" }
3957
4165
  ];
3958
4166
  for (const { from, to } of renameMappings) {
3959
- const fromPath = join8(repoPath, from);
3960
- const toPath = join8(repoPath, to);
3961
- if (existsSync12(fromPath) && !existsSync12(toPath)) {
4167
+ const fromPath = join9(repoPath, from);
4168
+ const toPath = join9(repoPath, to);
4169
+ if (existsSync13(fromPath) && !existsSync13(toPath)) {
3962
4170
  try {
3963
4171
  const stats = await stat(fromPath);
3964
4172
  if (stats.isDirectory()) {
@@ -4047,7 +4255,7 @@ repository = "${escapeTomlString(repoUrl)}"
4047
4255
  wrapped = true
4048
4256
  commit = "${commit}"
4049
4257
  `;
4050
- await writeFile3(join8(repoPath, "capability.toml"), tomlContent, "utf-8");
4258
+ await writeFile3(join9(repoPath, "capability.toml"), tomlContent, "utf-8");
4051
4259
  }
4052
4260
  async function fetchGitCapabilitySource(id, config, options) {
4053
4261
  const gitUrl = sourceToGitUrl(config.source);
@@ -4055,31 +4263,40 @@ async function fetchGitCapabilitySource(id, config, options) {
4055
4263
  let updated = false;
4056
4264
  let commit;
4057
4265
  let repoPath;
4266
+ let needsWrap = false;
4058
4267
  const gitRef = config.version && config.version !== "latest" ? config.version : undefined;
4059
4268
  if (config.path) {
4060
- const tempPath = join8(OMNI_LOCAL, "_temp", `${id}-repo`);
4061
- if (existsSync12(join8(tempPath, ".git"))) {
4269
+ const tempPath = join9(OMNI_LOCAL, "_temp", `${id}-repo`);
4270
+ if (existsSync13(join9(tempPath, ".git"))) {
4062
4271
  updated = await fetchRepo(tempPath, gitRef);
4063
4272
  commit = await getRepoCommit(tempPath);
4064
4273
  } else {
4065
- await mkdir(join8(tempPath, ".."), { recursive: true });
4274
+ await mkdir(join9(tempPath, ".."), { recursive: true });
4066
4275
  await cloneRepo(gitUrl, tempPath, gitRef);
4067
4276
  commit = await getRepoCommit(tempPath);
4068
4277
  updated = true;
4069
4278
  }
4070
- const sourcePath = join8(tempPath, config.path);
4071
- if (!existsSync12(sourcePath)) {
4279
+ const sourcePath = join9(tempPath, config.path);
4280
+ if (!existsSync13(sourcePath)) {
4072
4281
  throw new Error(`Path not found in repository: ${config.path}`);
4073
4282
  }
4074
- if (existsSync12(targetPath)) {
4283
+ const sourceHasCapabilityToml = hasCapabilityToml(sourcePath);
4284
+ if (!sourceHasCapabilityToml) {
4285
+ needsWrap = await shouldWrapDirectory(sourcePath);
4286
+ }
4287
+ if (existsSync13(targetPath)) {
4075
4288
  await rm(targetPath, { recursive: true });
4076
4289
  }
4077
- await mkdir(join8(targetPath, ".."), { recursive: true });
4078
- await cp(sourcePath, targetPath, { recursive: true });
4290
+ await mkdir(join9(targetPath, ".."), { recursive: true });
4291
+ if (needsWrap) {
4292
+ await copyWrappedContentOnly(sourcePath, targetPath);
4293
+ } else {
4294
+ await cp(sourcePath, targetPath, { recursive: true });
4295
+ }
4079
4296
  await rm(tempPath, { recursive: true });
4080
4297
  repoPath = targetPath;
4081
4298
  } else {
4082
- if (existsSync12(join8(targetPath, ".git"))) {
4299
+ if (existsSync13(join9(targetPath, ".git"))) {
4083
4300
  if (!options?.silent) {
4084
4301
  console.log(` Checking ${id}...`);
4085
4302
  }
@@ -4095,11 +4312,11 @@ async function fetchGitCapabilitySource(id, config, options) {
4095
4312
  }
4096
4313
  repoPath = targetPath;
4097
4314
  }
4098
- let needsWrap = false;
4099
- if (!hasCapabilityToml(repoPath)) {
4315
+ if (!config.path && !hasCapabilityToml(repoPath)) {
4100
4316
  needsWrap = await shouldWrapDirectory(repoPath);
4101
4317
  }
4102
4318
  if (needsWrap) {
4319
+ await pruneUnknownWrappedEntries(repoPath, true);
4103
4320
  await normalizeFolderNames(repoPath);
4104
4321
  const content = await discoverContent(repoPath);
4105
4322
  await generateCapabilityToml(id, repoPath, config.source, commit, content);
@@ -4130,7 +4347,7 @@ async function fetchGitCapabilitySource(id, config, options) {
4130
4347
  async function fetchFileCapabilitySource(id, config, options) {
4131
4348
  const sourcePath = parseFileSourcePath(config.source);
4132
4349
  const targetPath = getSourceCapabilityPath(id);
4133
- if (!existsSync12(sourcePath)) {
4350
+ if (!existsSync13(sourcePath)) {
4134
4351
  throw new Error(`File source not found: ${sourcePath}`);
4135
4352
  }
4136
4353
  const sourceStats = await stat(sourcePath);
@@ -4138,7 +4355,7 @@ async function fetchFileCapabilitySource(id, config, options) {
4138
4355
  throw new Error(`File source must be a directory: ${sourcePath}`);
4139
4356
  }
4140
4357
  const contentHash = await computeContentHash(sourcePath);
4141
- const hasCapToml = existsSync12(join8(sourcePath, "capability.toml"));
4358
+ const hasCapToml = existsSync13(join9(sourcePath, "capability.toml"));
4142
4359
  let needsWrap = false;
4143
4360
  if (!hasCapToml) {
4144
4361
  needsWrap = await shouldWrapDirectory(sourcePath);
@@ -4149,11 +4366,15 @@ async function fetchFileCapabilitySource(id, config, options) {
4149
4366
  if (!options?.silent) {
4150
4367
  console.log(` Copying ${id} from ${sourcePath}...`);
4151
4368
  }
4152
- if (existsSync12(targetPath)) {
4369
+ if (existsSync13(targetPath)) {
4153
4370
  await rm(targetPath, { recursive: true });
4154
4371
  }
4155
- await mkdir(join8(targetPath, ".."), { recursive: true });
4156
- await cp(sourcePath, targetPath, { recursive: true });
4372
+ await mkdir(join9(targetPath, ".."), { recursive: true });
4373
+ if (needsWrap) {
4374
+ await copyWrappedContentOnly(sourcePath, targetPath);
4375
+ } else {
4376
+ await cp(sourcePath, targetPath, { recursive: true });
4377
+ }
4157
4378
  if (needsWrap) {
4158
4379
  await normalizeFolderNames(targetPath);
4159
4380
  const content = await discoverContent(targetPath);
@@ -4232,7 +4453,7 @@ description = "${escapeTomlString(description)}"
4232
4453
  wrapped = true
4233
4454
  source = "${escapeTomlString(source)}"
4234
4455
  `;
4235
- await writeFile3(join8(targetPath, "capability.toml"), tomlContent, "utf-8");
4456
+ await writeFile3(join9(targetPath, "capability.toml"), tomlContent, "utf-8");
4236
4457
  }
4237
4458
  async function fetchCapabilitySource(id, sourceConfig, options) {
4238
4459
  const config = parseSourceConfig(sourceConfig);
@@ -4305,16 +4526,16 @@ generated_from_omni_toml = true
4305
4526
  }
4306
4527
  async function generateMcpCapabilityToml(id, mcpConfig, targetPath) {
4307
4528
  const tomlContent = generateMcpCapabilityTomlContent(id, mcpConfig);
4308
- await writeFile3(join8(targetPath, "capability.toml"), tomlContent, "utf-8");
4529
+ await writeFile3(join9(targetPath, "capability.toml"), tomlContent, "utf-8");
4309
4530
  }
4310
4531
  async function isGeneratedMcpCapability(capabilityDir) {
4311
- const tomlPath = join8(capabilityDir, "capability.toml");
4312
- if (!existsSync12(tomlPath)) {
4532
+ const tomlPath = join9(capabilityDir, "capability.toml");
4533
+ if (!existsSync13(tomlPath)) {
4313
4534
  console.warn("no capability.toml found in", capabilityDir);
4314
4535
  return false;
4315
4536
  }
4316
4537
  try {
4317
- const content = await readFile9(tomlPath, "utf-8");
4538
+ const content = await readFile10(tomlPath, "utf-8");
4318
4539
  const parsed = parse(content);
4319
4540
  const capability = parsed["capability"];
4320
4541
  const metadata = capability?.["metadata"];
@@ -4324,14 +4545,14 @@ async function isGeneratedMcpCapability(capabilityDir) {
4324
4545
  }
4325
4546
  }
4326
4547
  async function cleanupStaleMcpCapabilities(currentMcpIds) {
4327
- const capabilitiesDir = join8(OMNI_LOCAL, "capabilities");
4328
- if (!existsSync12(capabilitiesDir)) {
4548
+ const capabilitiesDir = join9(OMNI_LOCAL, "capabilities");
4549
+ if (!existsSync13(capabilitiesDir)) {
4329
4550
  return;
4330
4551
  }
4331
4552
  const entries = await readdir(capabilitiesDir, { withFileTypes: true });
4332
4553
  for (const entry of entries) {
4333
4554
  if (entry.isDirectory()) {
4334
- const capDir = join8(capabilitiesDir, entry.name);
4555
+ const capDir = join9(capabilitiesDir, entry.name);
4335
4556
  const isGenerated = await isGeneratedMcpCapability(capDir);
4336
4557
  if (isGenerated && !currentMcpIds.has(entry.name)) {
4337
4558
  await rm(capDir, { recursive: true });
@@ -4344,10 +4565,10 @@ async function generateMcpCapabilities(config) {
4344
4565
  await cleanupStaleMcpCapabilities(new Set);
4345
4566
  return;
4346
4567
  }
4347
- const mcpCapabilitiesDir = join8(OMNI_LOCAL, "capabilities");
4568
+ const mcpCapabilitiesDir = join9(OMNI_LOCAL, "capabilities");
4348
4569
  const currentMcpIds = new Set;
4349
4570
  for (const [id, mcpConfig] of Object.entries(config.mcps)) {
4350
- const targetPath = join8(mcpCapabilitiesDir, id);
4571
+ const targetPath = join9(mcpCapabilitiesDir, id);
4351
4572
  currentMcpIds.add(id);
4352
4573
  await mkdir(targetPath, { recursive: true });
4353
4574
  await generateMcpCapabilityToml(id, mcpConfig, targetPath);
@@ -4356,8 +4577,8 @@ async function generateMcpCapabilities(config) {
4356
4577
  }
4357
4578
  async function fetchAllCapabilitySources(config, options) {
4358
4579
  await generateMcpCapabilities(config);
4359
- const tempDir = join8(OMNI_LOCAL, "_temp");
4360
- if (existsSync12(tempDir)) {
4580
+ const tempDir = join9(OMNI_LOCAL, "_temp");
4581
+ if (existsSync13(tempDir)) {
4361
4582
  await rm(tempDir, { recursive: true });
4362
4583
  }
4363
4584
  const sources = config.capabilities?.sources;
@@ -4443,7 +4664,7 @@ async function checkForUpdates(config) {
4443
4664
  continue;
4444
4665
  }
4445
4666
  const gitConfig = sourceConfig;
4446
- if (!existsSync12(join8(targetPath, ".git"))) {
4667
+ if (!existsSync13(join9(targetPath, ".git"))) {
4447
4668
  updates.push({
4448
4669
  id,
4449
4670
  source: gitConfig.source,
@@ -4486,12 +4707,12 @@ function checkVersionMismatch(lockEntry, currentCommit, currentVersion) {
4486
4707
  }
4487
4708
  async function verifyIntegrity(id, lockEntry) {
4488
4709
  const capabilityPath = getSourceCapabilityPath(id);
4489
- if (!existsSync12(capabilityPath)) {
4710
+ if (!existsSync13(capabilityPath)) {
4490
4711
  return "capability directory missing";
4491
4712
  }
4492
4713
  if (lockEntry.commit) {
4493
- const gitDir = join8(capabilityPath, ".git");
4494
- if (existsSync12(gitDir)) {
4714
+ const gitDir = join9(capabilityPath, ".git");
4715
+ if (existsSync13(gitDir)) {
4495
4716
  try {
4496
4717
  const currentCommit = await getRepoCommit(capabilityPath);
4497
4718
  if (currentCommit !== lockEntry.commit) {
@@ -4510,7 +4731,7 @@ async function verifyIntegrity(id, lockEntry) {
4510
4731
  }
4511
4732
  return null;
4512
4733
  }
4513
- var OMNI_LOCAL = ".omni", SKILL_DIRS, AGENT_DIRS, COMMAND_DIRS, RULE_DIRS, DOC_DIRS, SKILL_FILES, AGENT_FILES, COMMAND_FILES, CONTENT_HASH_EXCLUDES;
4734
+ 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
4735
  var init_sources = __esm(() => {
4515
4736
  init_dist();
4516
4737
  init_types2();
@@ -4519,6 +4740,23 @@ var init_sources = __esm(() => {
4519
4740
  COMMAND_DIRS = ["commands", "command"];
4520
4741
  RULE_DIRS = ["rules", "rule"];
4521
4742
  DOC_DIRS = ["docs", "doc", "documentation"];
4743
+ WRAPPED_CONTENT_DIRS = new Set([
4744
+ ...SKILL_DIRS,
4745
+ ...AGENT_DIRS,
4746
+ ...COMMAND_DIRS,
4747
+ ...RULE_DIRS,
4748
+ ...DOC_DIRS,
4749
+ "hooks",
4750
+ ".claude-plugin"
4751
+ ]);
4752
+ WRAPPED_ROOT_FILES_EXACT = new Set([".gitignore", "hooks.json"]);
4753
+ WRAPPED_ROOT_FILE_PATTERNS = [
4754
+ /^readme(?:\..+)?$/i,
4755
+ /^license(?:\..+)?$/i,
4756
+ /^licence(?:\..+)?$/i,
4757
+ /^notice(?:\..+)?$/i,
4758
+ /^copying(?:\..+)?$/i
4759
+ ];
4522
4760
  SKILL_FILES = ["SKILL.md", "skill.md", "Skill.md"];
4523
4761
  AGENT_FILES = ["AGENT.md", "agent.md", "Agent.md", "SUBAGENT.md", "subagent.md"];
4524
4762
  COMMAND_FILES = ["COMMAND.md", "command.md", "Command.md"];
@@ -4560,13 +4798,13 @@ var init_hooks = __esm(() => {
4560
4798
  });
4561
4799
 
4562
4800
  // ../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";
4801
+ import { existsSync as existsSync14 } from "node:fs";
4802
+ import { readFile as readFile11, writeFile as writeFile4 } from "node:fs/promises";
4565
4803
  async function loadProviderConfig() {
4566
- if (!existsSync13(PROVIDER_CONFIG_PATH)) {
4804
+ if (!existsSync14(PROVIDER_CONFIG_PATH)) {
4567
4805
  return { provider: "claude" };
4568
4806
  }
4569
- const content = await readFile10(PROVIDER_CONFIG_PATH, "utf-8");
4807
+ const content = await readFile11(PROVIDER_CONFIG_PATH, "utf-8");
4570
4808
  const parsed = parse(content);
4571
4809
  return parsed;
4572
4810
  }
@@ -4613,13 +4851,13 @@ var init_provider = __esm(() => {
4613
4851
  });
4614
4852
 
4615
4853
  // ../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";
4854
+ import { existsSync as existsSync15 } from "node:fs";
4855
+ import { readFile as readFile12, writeFile as writeFile5 } from "node:fs/promises";
4618
4856
  async function readConfigFile() {
4619
- if (!existsSync14(CONFIG_PATH2)) {
4857
+ if (!existsSync15(CONFIG_PATH2)) {
4620
4858
  return "";
4621
4859
  }
4622
- return readFile11(CONFIG_PATH2, "utf-8");
4860
+ return readFile12(CONFIG_PATH2, "utf-8");
4623
4861
  }
4624
4862
  async function writeConfigFile(content) {
4625
4863
  await writeFile5(CONFIG_PATH2, content, "utf-8");
@@ -4841,14 +5079,14 @@ var init_config2 = __esm(() => {
4841
5079
  });
4842
5080
 
4843
5081
  // ../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";
5082
+ import { existsSync as existsSync16 } from "node:fs";
5083
+ import { readFile as readFile13, writeFile as writeFile6 } from "node:fs/promises";
4846
5084
  async function readMcpJson() {
4847
- if (!existsSync15(MCP_JSON_PATH)) {
5085
+ if (!existsSync16(MCP_JSON_PATH)) {
4848
5086
  return { mcpServers: {} };
4849
5087
  }
4850
5088
  try {
4851
- const content = await readFile12(MCP_JSON_PATH, "utf-8");
5089
+ const content = await readFile13(MCP_JSON_PATH, "utf-8");
4852
5090
  const parsed = JSON.parse(content);
4853
5091
  return {
4854
5092
  mcpServers: parsed.mcpServers || {}
@@ -4930,17 +5168,17 @@ var init_mcp_json = __esm(() => {
4930
5168
  });
4931
5169
 
4932
5170
  // ../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";
5171
+ import { existsSync as existsSync17, mkdirSync as mkdirSync2, rmSync } from "node:fs";
5172
+ import { readFile as readFile14, writeFile as writeFile7 } from "node:fs/promises";
4935
5173
  async function loadManifest() {
4936
- if (!existsSync16(MANIFEST_PATH)) {
5174
+ if (!existsSync17(MANIFEST_PATH)) {
4937
5175
  return {
4938
5176
  version: CURRENT_VERSION,
4939
5177
  syncedAt: new Date().toISOString(),
4940
5178
  capabilities: {}
4941
5179
  };
4942
5180
  }
4943
- const content = await readFile13(MANIFEST_PATH, "utf-8");
5181
+ const content = await readFile14(MANIFEST_PATH, "utf-8");
4944
5182
  return JSON.parse(content);
4945
5183
  }
4946
5184
  async function saveManifest(manifest) {
@@ -4980,14 +5218,14 @@ async function cleanupStaleResources(previousManifest, currentCapabilityIds) {
4980
5218
  }
4981
5219
  for (const skillName of resources.skills) {
4982
5220
  const skillDir = `.claude/skills/${skillName}`;
4983
- if (existsSync16(skillDir)) {
5221
+ if (existsSync17(skillDir)) {
4984
5222
  rmSync(skillDir, { recursive: true });
4985
5223
  result.deletedSkills.push(skillName);
4986
5224
  }
4987
5225
  }
4988
5226
  for (const ruleName of resources.rules) {
4989
5227
  const rulePath = `.cursor/rules/omnidev-${ruleName}.mdc`;
4990
- if (existsSync16(rulePath)) {
5228
+ if (existsSync17(rulePath)) {
4991
5229
  rmSync(rulePath);
4992
5230
  result.deletedRules.push(ruleName);
4993
5231
  }
@@ -4999,14 +5237,14 @@ var MANIFEST_PATH = ".omni/state/manifest.json", CURRENT_VERSION = 1;
4999
5237
  var init_manifest = () => {};
5000
5238
 
5001
5239
  // ../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";
5240
+ import { existsSync as existsSync18, mkdirSync as mkdirSync3 } from "node:fs";
5241
+ import { readFile as readFile15, writeFile as writeFile8 } from "node:fs/promises";
5004
5242
  async function readEnabledProviders() {
5005
- if (!existsSync17(PROVIDERS_PATH)) {
5243
+ if (!existsSync18(PROVIDERS_PATH)) {
5006
5244
  return DEFAULT_PROVIDERS;
5007
5245
  }
5008
5246
  try {
5009
- const content = await readFile14(PROVIDERS_PATH, "utf-8");
5247
+ const content = await readFile15(PROVIDERS_PATH, "utf-8");
5010
5248
  const state = JSON.parse(content);
5011
5249
  return state.enabled.length > 0 ? state.enabled : DEFAULT_PROVIDERS;
5012
5250
  } catch {
@@ -5035,20 +5273,20 @@ async function isProviderEnabled(providerId) {
5035
5273
  return current.includes(providerId);
5036
5274
  }
5037
5275
  var STATE_DIR2 = ".omni/state", PROVIDERS_PATH, DEFAULT_PROVIDERS;
5038
- var init_providers = __esm(() => {
5276
+ var init_providers2 = __esm(() => {
5039
5277
  PROVIDERS_PATH = `${STATE_DIR2}/providers.json`;
5040
5278
  DEFAULT_PROVIDERS = ["claude-code"];
5041
5279
  });
5042
5280
 
5043
5281
  // ../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";
5282
+ import { existsSync as existsSync19, mkdirSync as mkdirSync4 } from "node:fs";
5283
+ import { readFile as readFile16, writeFile as writeFile9 } from "node:fs/promises";
5046
5284
  async function readSecurityAllows() {
5047
- if (!existsSync18(SECURITY_PATH)) {
5285
+ if (!existsSync19(SECURITY_PATH)) {
5048
5286
  return { ...DEFAULT_STATE };
5049
5287
  }
5050
5288
  try {
5051
- const content = await readFile15(SECURITY_PATH, "utf-8");
5289
+ const content = await readFile16(SECURITY_PATH, "utf-8");
5052
5290
  const state = JSON.parse(content);
5053
5291
  return state;
5054
5292
  } catch {
@@ -5137,19 +5375,45 @@ var init_security_allows = __esm(() => {
5137
5375
  var init_state = __esm(() => {
5138
5376
  init_active_profile();
5139
5377
  init_manifest();
5140
- init_providers();
5378
+ init_providers2();
5141
5379
  init_security_allows();
5142
5380
  });
5143
5381
 
5144
5382
  // ../core/src/sync.ts
5145
5383
  import { spawn as spawn2 } from "node:child_process";
5146
- import { mkdirSync as mkdirSync5 } from "node:fs";
5384
+ import { existsSync as existsSync20, mkdirSync as mkdirSync5, readFileSync as readFileSync3 } from "node:fs";
5385
+ import { join as join10 } from "node:path";
5386
+ function getDeclaredPackageManager(packageManager) {
5387
+ if (typeof packageManager !== "string" || packageManager.trim().length === 0) {
5388
+ return;
5389
+ }
5390
+ const atIndex = packageManager.indexOf("@");
5391
+ return atIndex === -1 ? packageManager : packageManager.slice(0, atIndex);
5392
+ }
5393
+ function resolveCapabilityInstallCommand(capabilityPath, options) {
5394
+ const packageJsonPath = join10(capabilityPath, "package.json");
5395
+ const packageLockPath = join10(capabilityPath, "package-lock.json");
5396
+ let packageManager;
5397
+ try {
5398
+ const pkgJson = JSON.parse(readFileSync3(packageJsonPath, "utf-8"));
5399
+ packageManager = getDeclaredPackageManager(pkgJson.packageManager);
5400
+ } catch {}
5401
+ if (!options.hasNpm) {
5402
+ throw new Error("npm is not installed. Install npm to install capability dependencies.");
5403
+ }
5404
+ if (packageManager && packageManager !== "npm") {
5405
+ throw new Error(`Capability at ${capabilityPath} declares packageManager=${packageManager}, but OmniDev only supports npm for capability dependencies.`);
5406
+ }
5407
+ return {
5408
+ cmd: "npm",
5409
+ args: [existsSync20(packageLockPath) ? "ci" : "install"]
5410
+ };
5411
+ }
5147
5412
  async function installCapabilityDependencies(silent) {
5148
- const { existsSync: existsSync19, readdirSync: readdirSync7, readFileSync: readFileSync3 } = await import("node:fs");
5149
- const { join: join9 } = await import("node:path");
5413
+ const { readdirSync: readdirSync7 } = await import("node:fs");
5150
5414
  const { parse: parse2 } = await Promise.resolve().then(() => (init_dist(), exports_dist));
5151
5415
  const capabilitiesDir = ".omni/capabilities";
5152
- if (!existsSync19(capabilitiesDir)) {
5416
+ if (!existsSync20(capabilitiesDir)) {
5153
5417
  return;
5154
5418
  }
5155
5419
  const entries = readdirSync7(capabilitiesDir, { withFileTypes: true });
@@ -5160,22 +5424,21 @@ async function installCapabilityDependencies(silent) {
5160
5424
  proc.on("close", (code) => resolve2(code === 0));
5161
5425
  });
5162
5426
  }
5163
- const hasBun = await commandExists("bun");
5164
- const hasNpm = hasBun ? false : await commandExists("npm");
5165
- if (!hasBun && !hasNpm) {
5166
- throw new Error("Neither Bun nor npm is installed. Install one of them to install capability dependencies.");
5427
+ const hasNpm = await commandExists("npm");
5428
+ if (!hasNpm) {
5429
+ throw new Error("npm is not installed. Install npm to install capability dependencies.");
5167
5430
  }
5168
5431
  for (const entry of entries) {
5169
5432
  if (!entry.isDirectory()) {
5170
5433
  continue;
5171
5434
  }
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)) {
5435
+ const capabilityPath = join10(capabilitiesDir, entry.name);
5436
+ const packageJsonPath = join10(capabilityPath, "package.json");
5437
+ const capabilityTomlPath = join10(capabilityPath, "capability.toml");
5438
+ if (!existsSync20(packageJsonPath)) {
5176
5439
  continue;
5177
5440
  }
5178
- if (existsSync19(capabilityTomlPath)) {
5441
+ if (existsSync20(capabilityTomlPath)) {
5179
5442
  try {
5180
5443
  const tomlContent = readFileSync3(capabilityTomlPath, "utf-8");
5181
5444
  const parsed = parse2(tomlContent);
@@ -5186,9 +5449,9 @@ async function installCapabilityDependencies(silent) {
5186
5449
  }
5187
5450
  try {
5188
5451
  await new Promise((resolve2, reject) => {
5189
- const useNpmCi = hasNpm && existsSync19(join9(capabilityPath, "package-lock.json"));
5190
- const cmd = hasBun ? "bun" : "npm";
5191
- const args = hasBun ? ["install"] : useNpmCi ? ["ci"] : ["install"];
5452
+ const { cmd, args } = resolveCapabilityInstallCommand(capabilityPath, {
5453
+ hasNpm
5454
+ });
5192
5455
  const proc = spawn2(cmd, args, {
5193
5456
  cwd: capabilityPath,
5194
5457
  stdio: "pipe"
@@ -5209,7 +5472,7 @@ ${stderr}`));
5209
5472
  reject(error);
5210
5473
  });
5211
5474
  });
5212
- const hasIndexTs = existsSync19(join9(capabilityPath, "index.ts"));
5475
+ const hasIndexTs = existsSync20(join10(capabilityPath, "index.ts"));
5213
5476
  let hasBuildScript = false;
5214
5477
  try {
5215
5478
  const pkgJson = JSON.parse(readFileSync3(packageJsonPath, "utf-8"));
@@ -5217,9 +5480,7 @@ ${stderr}`));
5217
5480
  } catch {}
5218
5481
  if (hasBuildScript) {
5219
5482
  await new Promise((resolve2, reject) => {
5220
- const cmd = hasBun ? "bun" : "npm";
5221
- const args = ["run", "build"];
5222
- const proc = spawn2(cmd, args, {
5483
+ const proc = spawn2("npm", ["run", "build"], {
5223
5484
  cwd: capabilityPath,
5224
5485
  stdio: "pipe"
5225
5486
  });
@@ -5240,7 +5501,7 @@ ${stderr}`));
5240
5501
  });
5241
5502
  });
5242
5503
  } else if (hasIndexTs && !silent) {
5243
- const hasBuiltIndex = existsSync19(join9(capabilityPath, "dist", "index.js"));
5504
+ const hasBuiltIndex = existsSync20(join10(capabilityPath, "dist", "index.js"));
5244
5505
  if (!hasBuiltIndex) {
5245
5506
  console.warn(`Warning: Capability at ${capabilityPath} has index.ts but no build script.
5246
5507
  Add a "build" script to package.json (e.g., "build": "tsc") to compile TypeScript.`);
@@ -5371,25 +5632,27 @@ var init_types3 = __esm(() => {
5371
5632
  unicode: true,
5372
5633
  symlinks: true,
5373
5634
  scripts: true,
5374
- binaries: false
5635
+ binaries: false,
5636
+ hiddenCommands: true
5375
5637
  }
5376
5638
  };
5377
5639
  DEFAULT_SCAN_SETTINGS = {
5378
5640
  unicode: true,
5379
5641
  symlinks: true,
5380
5642
  scripts: true,
5381
- binaries: false
5643
+ binaries: false,
5644
+ hiddenCommands: true
5382
5645
  };
5383
5646
  });
5384
5647
 
5385
5648
  // ../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";
5649
+ import { existsSync as existsSync21 } from "node:fs";
5650
+ import { lstat, readdir as readdir2, readFile as readFile17, readlink, realpath } from "node:fs/promises";
5651
+ import { join as join11, relative, resolve as resolve2 } from "node:path";
5389
5652
  async function scanFileForUnicode(filePath, relativePath) {
5390
5653
  const findings = [];
5391
5654
  try {
5392
- const content = await readFile16(filePath, "utf-8");
5655
+ const content = await readFile17(filePath, "utf-8");
5393
5656
  const lines = content.split(`
5394
5657
  `);
5395
5658
  for (let lineNum = 0;lineNum < lines.length; lineNum++) {
@@ -5443,7 +5706,7 @@ async function scanFileForUnicode(filePath, relativePath) {
5443
5706
  async function scanFileForScripts(filePath, relativePath) {
5444
5707
  const findings = [];
5445
5708
  try {
5446
- const content = await readFile16(filePath, "utf-8");
5709
+ const content = await readFile17(filePath, "utf-8");
5447
5710
  const lines = content.split(`
5448
5711
  `);
5449
5712
  for (let lineNum = 0;lineNum < lines.length; lineNum++) {
@@ -5466,10 +5729,113 @@ async function scanFileForScripts(filePath, relativePath) {
5466
5729
  } catch {}
5467
5730
  return findings;
5468
5731
  }
5732
+ function extractHiddenRegions(fileContent) {
5733
+ const regions = [];
5734
+ HTML_COMMENT_RE.lastIndex = 0;
5735
+ for (let match = HTML_COMMENT_RE.exec(fileContent);match !== null; match = HTML_COMMENT_RE.exec(fileContent)) {
5736
+ const captured = match[1];
5737
+ if (captured === undefined)
5738
+ continue;
5739
+ const beforeMatch = fileContent.substring(0, match.index);
5740
+ const startLine = beforeMatch.split(`
5741
+ `).length;
5742
+ regions.push({ content: captured, startLine });
5743
+ }
5744
+ HIDDEN_REFERENCE_RE.lastIndex = 0;
5745
+ for (let match = HIDDEN_REFERENCE_RE.exec(fileContent);match !== null; match = HIDDEN_REFERENCE_RE.exec(fileContent)) {
5746
+ const captured = match[1];
5747
+ if (captured === undefined)
5748
+ continue;
5749
+ const beforeMatch = fileContent.substring(0, match.index);
5750
+ const startLine = beforeMatch.split(`
5751
+ `).length;
5752
+ regions.push({ content: captured, startLine });
5753
+ }
5754
+ return regions;
5755
+ }
5756
+ async function scanFileForHiddenCommands(filePath, relativePath) {
5757
+ const findings = [];
5758
+ try {
5759
+ const content = await readFile17(filePath, "utf-8");
5760
+ const hiddenRegions = extractHiddenRegions(content);
5761
+ for (const region of hiddenRegions) {
5762
+ const regionLines = region.content.split(`
5763
+ `);
5764
+ for (let i = 0;i < regionLines.length; i++) {
5765
+ const line = regionLines[i] ?? "";
5766
+ if (!line.trim())
5767
+ continue;
5768
+ for (const { pattern, message, severity } of HIDDEN_COMMAND_PATTERNS) {
5769
+ if (pattern.test(line)) {
5770
+ findings.push({
5771
+ type: "hidden_command",
5772
+ severity,
5773
+ file: relativePath,
5774
+ line: region.startLine + i,
5775
+ message: `Hidden in comment: ${message}`,
5776
+ details: line.trim().substring(0, 100)
5777
+ });
5778
+ }
5779
+ }
5780
+ for (const { pattern, message, severity } of NETWORK_REQUEST_PATTERNS) {
5781
+ if (pattern.test(line)) {
5782
+ findings.push({
5783
+ type: "network_request",
5784
+ severity: severity === "medium" ? "high" : severity,
5785
+ file: relativePath,
5786
+ line: region.startLine + i,
5787
+ message: `Hidden in comment: ${message}`,
5788
+ details: line.trim().substring(0, 100)
5789
+ });
5790
+ }
5791
+ }
5792
+ for (const { pattern, message, severity } of SUSPICIOUS_SCRIPT_PATTERNS) {
5793
+ if (pattern.test(line)) {
5794
+ findings.push({
5795
+ type: "hidden_command",
5796
+ severity: severity === "medium" ? "high" : severity,
5797
+ file: relativePath,
5798
+ line: region.startLine + i,
5799
+ message: `Hidden in comment: ${message}`,
5800
+ details: line.trim().substring(0, 100)
5801
+ });
5802
+ }
5803
+ }
5804
+ }
5805
+ }
5806
+ } catch {}
5807
+ return findings;
5808
+ }
5809
+ async function scanFileForNetworkRequests(filePath, relativePath) {
5810
+ const findings = [];
5811
+ try {
5812
+ const content = await readFile17(filePath, "utf-8");
5813
+ const lines = content.split(`
5814
+ `);
5815
+ for (let lineNum = 0;lineNum < lines.length; lineNum++) {
5816
+ const line = lines[lineNum];
5817
+ if (!line)
5818
+ continue;
5819
+ for (const { pattern, message, severity } of NETWORK_REQUEST_PATTERNS) {
5820
+ if (pattern.test(line)) {
5821
+ findings.push({
5822
+ type: "network_request",
5823
+ severity,
5824
+ file: relativePath,
5825
+ line: lineNum + 1,
5826
+ message,
5827
+ details: line.trim().substring(0, 100)
5828
+ });
5829
+ }
5830
+ }
5831
+ }
5832
+ } catch {}
5833
+ return findings;
5834
+ }
5469
5835
  async function checkSymlink(symlinkPath, relativePath, capabilityRoot) {
5470
5836
  try {
5471
5837
  const linkTarget = await readlink(symlinkPath);
5472
- const resolvedTarget = resolve2(join9(symlinkPath, "..", linkTarget));
5838
+ const resolvedTarget = resolve2(join11(symlinkPath, "..", linkTarget));
5473
5839
  const normalizedRoot = await realpath(capabilityRoot);
5474
5840
  if (linkTarget.startsWith("/")) {
5475
5841
  return {
@@ -5504,7 +5870,7 @@ function isTextFile(filePath) {
5504
5870
  async function scanCapability(capabilityId, capabilityPath, settings = DEFAULT_SCAN_SETTINGS) {
5505
5871
  const startTime = Date.now();
5506
5872
  const findings = [];
5507
- if (!existsSync19(capabilityPath)) {
5873
+ if (!existsSync21(capabilityPath)) {
5508
5874
  return {
5509
5875
  capabilityId,
5510
5876
  path: capabilityPath,
@@ -5516,7 +5882,7 @@ async function scanCapability(capabilityId, capabilityPath, settings = DEFAULT_S
5516
5882
  async function scanDirectory(dirPath) {
5517
5883
  const entries = await readdir2(dirPath, { withFileTypes: true });
5518
5884
  for (const entry of entries) {
5519
- const fullPath = join9(dirPath, entry.name);
5885
+ const fullPath = join11(dirPath, entry.name);
5520
5886
  const relativePath = relative(capabilityPath, fullPath);
5521
5887
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "__pycache__") {
5522
5888
  continue;
@@ -5543,17 +5909,27 @@ async function scanCapability(capabilityId, capabilityPath, settings = DEFAULT_S
5543
5909
  });
5544
5910
  }
5545
5911
  if (isTextFile(fullPath)) {
5912
+ const ext = fullPath.toLowerCase().substring(fullPath.lastIndexOf("."));
5546
5913
  if (settings.unicode) {
5547
5914
  const unicodeFindings = await scanFileForUnicode(fullPath, relativePath);
5548
5915
  findings.push(...unicodeFindings);
5549
5916
  }
5550
5917
  if (settings.scripts) {
5551
- const ext = fullPath.toLowerCase().substring(fullPath.lastIndexOf("."));
5552
5918
  if ([".sh", ".bash", ".zsh", ".fish", ".py", ".rb", ".js", ".ts"].includes(ext)) {
5553
5919
  const scriptFindings = await scanFileForScripts(fullPath, relativePath);
5554
5920
  findings.push(...scriptFindings);
5555
5921
  }
5556
5922
  }
5923
+ if (settings.hiddenCommands) {
5924
+ if ([".md", ".txt", ".yaml", ".yml", ".toml"].includes(ext)) {
5925
+ const hiddenFindings = await scanFileForHiddenCommands(fullPath, relativePath);
5926
+ findings.push(...hiddenFindings);
5927
+ }
5928
+ }
5929
+ if (settings.hiddenCommands) {
5930
+ const networkFindings = await scanFileForNetworkRequests(fullPath, relativePath);
5931
+ findings.push(...networkFindings);
5932
+ }
5557
5933
  }
5558
5934
  }
5559
5935
  }
@@ -5585,7 +5961,9 @@ async function scanCapabilities(capabilities2, config2 = {}) {
5585
5961
  symlink_escape: 0,
5586
5962
  symlink_absolute: 0,
5587
5963
  suspicious_script: 0,
5588
- binary_file: 0
5964
+ binary_file: 0,
5965
+ hidden_command: 0,
5966
+ network_request: 0
5589
5967
  };
5590
5968
  const findingsBySeverity = {
5591
5969
  low: 0,
@@ -5660,7 +6038,7 @@ function formatScanResults(summary, verbose = false) {
5660
6038
  return lines.join(`
5661
6039
  `);
5662
6040
  }
5663
- var UNICODE_PATTERNS, SUSPICIOUS_SCRIPT_PATTERNS, BINARY_EXTENSIONS, TEXT_EXTENSIONS;
6041
+ var UNICODE_PATTERNS, SUSPICIOUS_SCRIPT_PATTERNS, NETWORK_REQUEST_PATTERNS, HIDDEN_COMMAND_PATTERNS, BINARY_EXTENSIONS, TEXT_EXTENSIONS, HTML_COMMENT_RE, HIDDEN_REFERENCE_RE;
5664
6042
  var init_scanner = __esm(() => {
5665
6043
  init_types3();
5666
6044
  UNICODE_PATTERNS = {
@@ -5752,6 +6130,75 @@ var init_scanner = __esm(() => {
5752
6130
  severity: "high"
5753
6131
  }
5754
6132
  ];
6133
+ NETWORK_REQUEST_PATTERNS = [
6134
+ {
6135
+ pattern: /\bcurl\s+.*https?:\/\//i,
6136
+ message: "Outbound curl request detected",
6137
+ severity: "medium"
6138
+ },
6139
+ {
6140
+ pattern: /\bwget\s+.*https?:\/\//i,
6141
+ message: "Outbound wget request detected",
6142
+ severity: "medium"
6143
+ },
6144
+ {
6145
+ pattern: /\bfetch\s*\(\s*["'`]https?:\/\//i,
6146
+ message: "Outbound fetch() request detected",
6147
+ severity: "medium"
6148
+ },
6149
+ {
6150
+ pattern: /\b(?:http|https)\.(?:get|request|post|put)\s*\(/i,
6151
+ message: "Outbound HTTP request via Node.js http module",
6152
+ severity: "medium"
6153
+ },
6154
+ {
6155
+ pattern: /\brequests\.(?:get|post|put|delete|patch)\s*\(/i,
6156
+ message: "Outbound HTTP request via Python requests",
6157
+ severity: "medium"
6158
+ },
6159
+ {
6160
+ pattern: /\bnc\b.*\s\d{2,5}\b/i,
6161
+ message: "Netcat connection detected",
6162
+ severity: "high"
6163
+ },
6164
+ {
6165
+ pattern: /\b(?:Invoke-WebRequest|Invoke-RestMethod|iwr|irm)\b/i,
6166
+ message: "Outbound PowerShell web request detected",
6167
+ severity: "medium"
6168
+ }
6169
+ ];
6170
+ HIDDEN_COMMAND_PATTERNS = [
6171
+ {
6172
+ pattern: /`[^`]*(?:curl|wget|bash|sh|python|ruby|node|exec|eval|system)\s[^`]*`/i,
6173
+ message: "Executable command in backtick-wrapped code",
6174
+ severity: "critical"
6175
+ },
6176
+ {
6177
+ pattern: /\|\s*(?:ba)?sh\b/i,
6178
+ message: "Pipe to shell execution",
6179
+ severity: "critical"
6180
+ },
6181
+ {
6182
+ pattern: /(?:^|\s)(?:bash|sh|zsh)\s+-c\s+/i,
6183
+ message: "Shell invocation with -c flag",
6184
+ severity: "high"
6185
+ },
6186
+ {
6187
+ pattern: /\b(?:curl|wget)\s+.*https?:\/\//i,
6188
+ message: "Network fetch command detected",
6189
+ severity: "high"
6190
+ },
6191
+ {
6192
+ pattern: /\b(?:python|ruby|node)\s+-e\s+/i,
6193
+ message: "Inline script execution",
6194
+ severity: "high"
6195
+ },
6196
+ {
6197
+ pattern: /\beval\s*\(.*\)/i,
6198
+ message: "eval() call detected",
6199
+ severity: "high"
6200
+ }
6201
+ ];
5755
6202
  BINARY_EXTENSIONS = new Set([
5756
6203
  ".exe",
5757
6204
  ".dll",
@@ -5786,6 +6233,8 @@ var init_scanner = __esm(() => {
5786
6233
  ".py",
5787
6234
  ".rb"
5788
6235
  ]);
6236
+ HTML_COMMENT_RE = /<!--([\s\S]*?)-->/g;
6237
+ HIDDEN_REFERENCE_RE = /^\[.*?\]:\s*\S+\s+"(.+)"/gm;
5789
6238
  });
5790
6239
 
5791
6240
  // ../core/src/security/index.ts
@@ -5995,6 +6444,7 @@ __export(exports_src, {
5995
6444
  resolveEnabledCapabilities: () => resolveEnabledCapabilities,
5996
6445
  resolveCapabilityRootInConfig: () => resolveCapabilityRootInConfig,
5997
6446
  resolveCapabilityRoot: () => resolveCapabilityRoot,
6447
+ resolveCapabilityInstallCommand: () => resolveCapabilityInstallCommand,
5998
6448
  removeSecurityAllow: () => removeSecurityAllow,
5999
6449
  readSecurityAllows: () => readSecurityAllows,
6000
6450
  readMcpJson: () => readMcpJson,
@@ -6009,6 +6459,8 @@ __export(exports_src, {
6009
6459
  parseOmniConfig: () => parseOmniConfig,
6010
6460
  parseFileSourcePath: () => parseFileSourcePath,
6011
6461
  parseCapabilityConfig: () => parseCapabilityConfig,
6462
+ normalizeProviderId: () => normalizeProviderId,
6463
+ normalizeProviderApplicability: () => normalizeProviderApplicability,
6012
6464
  mergeHooksConfigs: () => mergeHooksConfigs,
6013
6465
  mergeAndDeduplicateHooks: () => mergeAndDeduplicateHooks,
6014
6466
  loadSubagents: () => loadSubagents,
@@ -6116,6 +6568,7 @@ var init_src = __esm(() => {
6116
6568
  init_state();
6117
6569
  init_sync();
6118
6570
  init_security();
6571
+ init_providers();
6119
6572
  init_types2();
6120
6573
  });
6121
6574
 
@@ -6123,17 +6576,17 @@ var init_src = __esm(() => {
6123
6576
  import { run } from "@stricli/core";
6124
6577
 
6125
6578
  // src/lib/dynamic-app.ts
6126
- import { existsSync as existsSync29 } from "node:fs";
6579
+ import { existsSync as existsSync31 } from "node:fs";
6127
6580
  import { createRequire as createRequire2 } from "node:module";
6128
- import { join as join26 } from "node:path";
6581
+ import { join as join28 } from "node:path";
6129
6582
  import { buildApplication, buildRouteMap as buildRouteMap7 } from "@stricli/core";
6130
6583
 
6131
6584
  // src/commands/add.ts
6132
- import { existsSync as existsSync22 } from "node:fs";
6585
+ import { existsSync as existsSync24 } from "node:fs";
6133
6586
  import { basename as basename5, resolve as resolve3 } from "node:path";
6134
6587
 
6135
6588
  // ../adapters/src/writers/generic/executor.ts
6136
- async function executeWriters(writerConfigs, bundle, projectRoot) {
6589
+ async function executeWriters(writerConfigs, bundle, projectRoot, providerId) {
6137
6590
  const seen = new Set;
6138
6591
  const uniqueConfigs = [];
6139
6592
  let deduplicatedCount = 0;
@@ -6150,7 +6603,8 @@ async function executeWriters(writerConfigs, bundle, projectRoot) {
6150
6603
  for (const config of uniqueConfigs) {
6151
6604
  const result = await config.writer.write(bundle, {
6152
6605
  outputPath: config.outputPath,
6153
- projectRoot
6606
+ projectRoot,
6607
+ ...providerId ? { providerId } : {}
6154
6608
  });
6155
6609
  allFilesWritten.push(...result.filesWritten);
6156
6610
  }
@@ -6161,23 +6615,23 @@ async function executeWriters(writerConfigs, bundle, projectRoot) {
6161
6615
  }
6162
6616
  // ../adapters/src/writers/generic/hooks.ts
6163
6617
  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";
6618
+ import { existsSync as existsSync22 } from "node:fs";
6619
+ import { mkdir as mkdir2, readFile as readFile18, writeFile as writeFile10 } from "node:fs/promises";
6620
+ import { dirname, join as join12 } from "node:path";
6167
6621
  var HooksWriter = {
6168
6622
  id: "hooks",
6169
6623
  async write(bundle, ctx) {
6170
6624
  if (!bundle.hooks) {
6171
6625
  return { filesWritten: [] };
6172
6626
  }
6173
- const settingsPath = join10(ctx.projectRoot, ctx.outputPath);
6627
+ const settingsPath = join12(ctx.projectRoot, ctx.outputPath);
6174
6628
  const parentDir = dirname(settingsPath);
6175
6629
  await mkdir2(parentDir, { recursive: true });
6176
6630
  const claudeHooks = transformHooksConfig(bundle.hooks, "toClaude");
6177
6631
  let existingSettings = {};
6178
- if (existsSync20(settingsPath)) {
6632
+ if (existsSync22(settingsPath)) {
6179
6633
  try {
6180
- const content = await readFile17(settingsPath, "utf-8");
6634
+ const content = await readFile18(settingsPath, "utf-8");
6181
6635
  existingSettings = JSON.parse(content);
6182
6636
  } catch {
6183
6637
  existingSettings = {};
@@ -6195,21 +6649,42 @@ var HooksWriter = {
6195
6649
  }
6196
6650
  };
6197
6651
  // ../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";
6652
+ import { existsSync as existsSync23 } from "node:fs";
6653
+ import { mkdir as mkdir3, readFile as readFile19, writeFile as writeFile11 } from "node:fs/promises";
6654
+ import { dirname as dirname2, join as join13 } from "node:path";
6655
+
6656
+ // ../adapters/src/writers/generic/omni-md.ts
6657
+ init_src();
6658
+ var PROVIDER_BLOCK_REGEX = /<provider\.([a-z-]+)>([\s\S]*?)<\/provider\.\1>/g;
6659
+ var PROVIDER_TAG_REGEX = /<\/?provider\.[a-z-]+>/;
6660
+ function renderOmniMdForProvider(content, providerId) {
6661
+ if (!providerId) {
6662
+ return content;
6663
+ }
6664
+ const rendered = content.replace(PROVIDER_BLOCK_REGEX, (_match, rawProvider, providerContent) => {
6665
+ const canonicalProvider = normalizeProviderId(rawProvider);
6666
+ return canonicalProvider === providerId ? providerContent : "";
6667
+ });
6668
+ const strayTag = rendered.match(PROVIDER_TAG_REGEX);
6669
+ if (strayTag) {
6670
+ throw new Error(`Invalid provider block syntax in OMNI.md near ${strayTag[0]}`);
6671
+ }
6672
+ return rendered;
6673
+ }
6674
+
6675
+ // ../adapters/src/writers/generic/instructions-md.ts
6201
6676
  var InstructionsMdWriter = {
6202
6677
  id: "instructions-md",
6203
6678
  async write(bundle, ctx) {
6204
- const outputFullPath = join11(ctx.projectRoot, ctx.outputPath);
6679
+ const outputFullPath = join13(ctx.projectRoot, ctx.outputPath);
6205
6680
  const parentDir = dirname2(outputFullPath);
6206
6681
  if (parentDir !== ctx.projectRoot) {
6207
6682
  await mkdir3(parentDir, { recursive: true });
6208
6683
  }
6209
- const omniMdPath = join11(ctx.projectRoot, "OMNI.md");
6684
+ const omniMdPath = join13(ctx.projectRoot, "OMNI.md");
6210
6685
  let omniMdContent = "";
6211
- if (existsSync21(omniMdPath)) {
6212
- omniMdContent = await readFile18(omniMdPath, "utf-8");
6686
+ if (existsSync23(omniMdPath)) {
6687
+ omniMdContent = renderOmniMdForProvider(await readFile19(omniMdPath, "utf-8"), ctx.providerId);
6213
6688
  }
6214
6689
  let content = omniMdContent;
6215
6690
  if (bundle.instructionsContent) {
@@ -6226,17 +6701,17 @@ ${bundle.instructionsContent}
6226
6701
  };
6227
6702
  // ../adapters/src/writers/generic/skills.ts
6228
6703
  import { mkdir as mkdir4, writeFile as writeFile12 } from "node:fs/promises";
6229
- import { join as join12 } from "node:path";
6704
+ import { join as join14 } from "node:path";
6230
6705
  var SkillsWriter = {
6231
6706
  id: "skills",
6232
6707
  async write(bundle, ctx) {
6233
- const skillsDir = join12(ctx.projectRoot, ctx.outputPath);
6708
+ const skillsDir = join14(ctx.projectRoot, ctx.outputPath);
6234
6709
  await mkdir4(skillsDir, { recursive: true });
6235
6710
  const filesWritten = [];
6236
6711
  for (const skill of bundle.skills) {
6237
- const skillDir = join12(skillsDir, skill.name);
6712
+ const skillDir = join14(skillsDir, skill.name);
6238
6713
  await mkdir4(skillDir, { recursive: true });
6239
- const skillPath = join12(skillDir, "SKILL.md");
6714
+ const skillPath = join14(skillDir, "SKILL.md");
6240
6715
  const content = `---
6241
6716
  name: ${skill.name}
6242
6717
  description: "${skill.description}"
@@ -6244,7 +6719,7 @@ description: "${skill.description}"
6244
6719
 
6245
6720
  ${skill.instructions}`;
6246
6721
  await writeFile12(skillPath, content, "utf-8");
6247
- filesWritten.push(join12(ctx.outputPath, skill.name, "SKILL.md"));
6722
+ filesWritten.push(join14(ctx.outputPath, skill.name, "SKILL.md"));
6248
6723
  }
6249
6724
  return {
6250
6725
  filesWritten
@@ -6253,7 +6728,7 @@ ${skill.instructions}`;
6253
6728
  };
6254
6729
  // ../adapters/src/writers/generic/commands-as-skills.ts
6255
6730
  import { mkdir as mkdir5, writeFile as writeFile13 } from "node:fs/promises";
6256
- import { join as join13 } from "node:path";
6731
+ import { join as join15 } from "node:path";
6257
6732
  function generateSkillFrontmatter(command) {
6258
6733
  const lines = ["---"];
6259
6734
  lines.push(`name: ${command.name}`);
@@ -6268,28 +6743,75 @@ function generateSkillFrontmatter(command) {
6268
6743
  var CommandsAsSkillsWriter = {
6269
6744
  id: "commands-as-skills",
6270
6745
  async write(bundle, ctx) {
6271
- const skillsDir = join13(ctx.projectRoot, ctx.outputPath);
6746
+ const skillsDir = join15(ctx.projectRoot, ctx.outputPath);
6272
6747
  await mkdir5(skillsDir, { recursive: true });
6273
6748
  const filesWritten = [];
6274
6749
  for (const command of bundle.commands) {
6275
- const commandSkillDir = join13(skillsDir, command.name);
6750
+ const commandSkillDir = join15(skillsDir, command.name);
6276
6751
  await mkdir5(commandSkillDir, { recursive: true });
6277
6752
  const frontmatter = generateSkillFrontmatter(command);
6278
6753
  const content = `${frontmatter}
6279
6754
 
6280
6755
  ${command.prompt}`;
6281
- const skillPath = join13(commandSkillDir, "SKILL.md");
6756
+ const skillPath = join15(commandSkillDir, "SKILL.md");
6282
6757
  await writeFile13(skillPath, content, "utf-8");
6283
- filesWritten.push(join13(ctx.outputPath, command.name, "SKILL.md"));
6758
+ filesWritten.push(join15(ctx.outputPath, command.name, "SKILL.md"));
6284
6759
  }
6285
6760
  return {
6286
6761
  filesWritten
6287
6762
  };
6288
6763
  }
6289
6764
  };
6765
+ // ../adapters/src/provider-bundle.ts
6766
+ init_src();
6767
+ function capabilityAppliesToProvider(capability3, providerId) {
6768
+ const providers3 = capability3.config.capability.providers;
6769
+ if (!providers3) {
6770
+ return true;
6771
+ }
6772
+ return providers3[providerId] === true;
6773
+ }
6774
+ function generateInstructionsContent2(rules, _docs) {
6775
+ if (rules.length === 0) {
6776
+ return "";
6777
+ }
6778
+ let content = `## Rules
6779
+
6780
+ `;
6781
+ for (const rule of rules) {
6782
+ content += `${rule.content}
6783
+
6784
+ `;
6785
+ }
6786
+ return content.trimEnd();
6787
+ }
6788
+ function createProviderScopedBundle(bundle, providerId) {
6789
+ const capabilities2 = bundle.capabilities.filter((capability3) => capabilityAppliesToProvider(capability3, providerId));
6790
+ const capabilityIds = new Set(capabilities2.map((capability3) => capability3.id));
6791
+ const skills = bundle.skills.filter((skill) => capabilityIds.has(skill.capabilityId));
6792
+ const rules = bundle.rules.filter((rule) => capabilityIds.has(rule.capabilityId));
6793
+ const docs = bundle.docs.filter((doc) => capabilityIds.has(doc.capabilityId));
6794
+ const commands = bundle.commands.filter((command) => capabilityIds.has(command.capabilityId));
6795
+ const subagents = bundle.subagents.filter((subagent) => capabilityIds.has(subagent.capabilityId));
6796
+ const scopedBundle = {
6797
+ capabilities: capabilities2,
6798
+ skills,
6799
+ rules,
6800
+ docs,
6801
+ commands,
6802
+ subagents,
6803
+ instructionsContent: generateInstructionsContent2(rules, docs)
6804
+ };
6805
+ const mergedHooks = mergeHooksConfigs(capabilities2.flatMap((capability3) => capability3.hooks ? [capability3.hooks] : []));
6806
+ if (hasAnyHooks(mergedHooks)) {
6807
+ scopedBundle.hooks = mergedHooks;
6808
+ }
6809
+ return scopedBundle;
6810
+ }
6811
+
6290
6812
  // ../adapters/src/writers/claude/agents.ts
6291
6813
  import { mkdir as mkdir6, writeFile as writeFile14 } from "node:fs/promises";
6292
- import { join as join14 } from "node:path";
6814
+ import { join as join16 } from "node:path";
6293
6815
  function generateFrontmatter(agent) {
6294
6816
  const lines = ["---"];
6295
6817
  lines.push(`name: ${agent.name}`);
@@ -6316,7 +6838,7 @@ function generateFrontmatter(agent) {
6316
6838
  var ClaudeAgentsWriter = {
6317
6839
  id: "claude-agents",
6318
6840
  async write(bundle, ctx) {
6319
- const agentsDir = join14(ctx.projectRoot, ctx.outputPath);
6841
+ const agentsDir = join16(ctx.projectRoot, ctx.outputPath);
6320
6842
  await mkdir6(agentsDir, { recursive: true });
6321
6843
  const filesWritten = [];
6322
6844
  for (const agent of bundle.subagents) {
@@ -6324,9 +6846,9 @@ var ClaudeAgentsWriter = {
6324
6846
  const content = `${frontmatter}
6325
6847
 
6326
6848
  ${agent.systemPrompt}`;
6327
- const agentPath = join14(agentsDir, `${agent.name}.md`);
6849
+ const agentPath = join16(agentsDir, `${agent.name}.md`);
6328
6850
  await writeFile14(agentPath, content, "utf-8");
6329
- filesWritten.push(join14(ctx.outputPath, `${agent.name}.md`));
6851
+ filesWritten.push(join16(ctx.outputPath, `${agent.name}.md`));
6330
6852
  }
6331
6853
  return {
6332
6854
  filesWritten
@@ -6351,7 +6873,9 @@ var claudeCodeAdapter = {
6351
6873
  };
6352
6874
  },
6353
6875
  async sync(bundle, ctx) {
6354
- const result = await executeWriters(this.writers, bundle, ctx.projectRoot);
6876
+ const providerId = "claude-code";
6877
+ const providerBundle = createProviderScopedBundle(bundle, providerId);
6878
+ const result = await executeWriters(this.writers, providerBundle, ctx.projectRoot, providerId);
6355
6879
  return {
6356
6880
  filesWritten: result.filesWritten,
6357
6881
  filesDeleted: []
@@ -6360,12 +6884,12 @@ var claudeCodeAdapter = {
6360
6884
  };
6361
6885
  // ../adapters/src/codex/index.ts
6362
6886
  import { mkdirSync as mkdirSync6 } from "node:fs";
6363
- import { join as join16 } from "node:path";
6887
+ import { join as join18 } from "node:path";
6364
6888
 
6365
6889
  // ../adapters/src/writers/codex/toml.ts
6366
6890
  init_dist();
6367
6891
  import { mkdir as mkdir7, writeFile as writeFile15 } from "node:fs/promises";
6368
- import { dirname as dirname3, join as join15 } from "node:path";
6892
+ import { dirname as dirname3, join as join17 } from "node:path";
6369
6893
  var FILE_HEADER = `# Generated by OmniDev - DO NOT EDIT
6370
6894
  # Run \`omnidev sync\` to regenerate
6371
6895
 
@@ -6416,7 +6940,7 @@ var CodexTomlWriter = {
6416
6940
  if (mcps.size === 0) {
6417
6941
  return { filesWritten: [] };
6418
6942
  }
6419
- const configPath = join15(ctx.projectRoot, ctx.outputPath);
6943
+ const configPath = join17(ctx.projectRoot, ctx.outputPath);
6420
6944
  const parentDir = dirname3(configPath);
6421
6945
  await mkdir7(parentDir, { recursive: true });
6422
6946
  const mcpServers = {};
@@ -6450,7 +6974,7 @@ var codexAdapter = {
6450
6974
  { writer: CodexTomlWriter, outputPath: ".codex/config.toml" }
6451
6975
  ],
6452
6976
  async init(ctx) {
6453
- const codexDir = join16(ctx.projectRoot, ".codex");
6977
+ const codexDir = join18(ctx.projectRoot, ".codex");
6454
6978
  mkdirSync6(codexDir, { recursive: true });
6455
6979
  return {
6456
6980
  filesCreated: [".codex/"],
@@ -6458,7 +6982,9 @@ var codexAdapter = {
6458
6982
  };
6459
6983
  },
6460
6984
  async sync(bundle, ctx) {
6461
- const result = await executeWriters(this.writers, bundle, ctx.projectRoot);
6985
+ const providerId = "codex";
6986
+ const providerBundle = createProviderScopedBundle(bundle, providerId);
6987
+ const result = await executeWriters(this.writers, providerBundle, ctx.projectRoot, providerId);
6462
6988
  return {
6463
6989
  filesWritten: result.filesWritten,
6464
6990
  filesDeleted: []
@@ -6467,11 +6993,11 @@ var codexAdapter = {
6467
6993
  };
6468
6994
  // ../adapters/src/cursor/index.ts
6469
6995
  import { mkdirSync as mkdirSync7 } from "node:fs";
6470
- import { join as join21 } from "node:path";
6996
+ import { join as join23 } from "node:path";
6471
6997
 
6472
6998
  // ../adapters/src/writers/cursor/agents.ts
6473
6999
  import { mkdir as mkdir8, writeFile as writeFile16 } from "node:fs/promises";
6474
- import { join as join17 } from "node:path";
7000
+ import { join as join19 } from "node:path";
6475
7001
  function mapModelToCursor(model) {
6476
7002
  if (!model || model === "inherit")
6477
7003
  return "inherit";
@@ -6503,7 +7029,7 @@ function generateFrontmatter2(agent) {
6503
7029
  var CursorAgentsWriter = {
6504
7030
  id: "cursor-agents",
6505
7031
  async write(bundle, ctx) {
6506
- const agentsDir = join17(ctx.projectRoot, ctx.outputPath);
7032
+ const agentsDir = join19(ctx.projectRoot, ctx.outputPath);
6507
7033
  await mkdir8(agentsDir, { recursive: true });
6508
7034
  const filesWritten = [];
6509
7035
  for (const agent of bundle.subagents) {
@@ -6511,9 +7037,9 @@ var CursorAgentsWriter = {
6511
7037
  const content = `${frontmatter}
6512
7038
 
6513
7039
  ${agent.systemPrompt}`;
6514
- const agentPath = join17(agentsDir, `${agent.name}.md`);
7040
+ const agentPath = join19(agentsDir, `${agent.name}.md`);
6515
7041
  await writeFile16(agentPath, content, "utf-8");
6516
- filesWritten.push(join17(ctx.outputPath, `${agent.name}.md`));
7042
+ filesWritten.push(join19(ctx.outputPath, `${agent.name}.md`));
6517
7043
  }
6518
7044
  return {
6519
7045
  filesWritten
@@ -6522,11 +7048,11 @@ ${agent.systemPrompt}`;
6522
7048
  };
6523
7049
  // ../adapters/src/writers/cursor/commands.ts
6524
7050
  import { mkdir as mkdir9, writeFile as writeFile17 } from "node:fs/promises";
6525
- import { join as join18 } from "node:path";
7051
+ import { join as join20 } from "node:path";
6526
7052
  var CursorCommandsWriter = {
6527
7053
  id: "cursor-commands",
6528
7054
  async write(bundle, ctx) {
6529
- const commandsDir = join18(ctx.projectRoot, ctx.outputPath);
7055
+ const commandsDir = join20(ctx.projectRoot, ctx.outputPath);
6530
7056
  await mkdir9(commandsDir, { recursive: true });
6531
7057
  const filesWritten = [];
6532
7058
  for (const command of bundle.commands) {
@@ -6535,9 +7061,9 @@ var CursorCommandsWriter = {
6535
7061
  ${command.description}
6536
7062
 
6537
7063
  ${command.prompt}`;
6538
- const commandPath = join18(commandsDir, `${command.name}.md`);
7064
+ const commandPath = join20(commandsDir, `${command.name}.md`);
6539
7065
  await writeFile17(commandPath, content, "utf-8");
6540
- filesWritten.push(join18(ctx.outputPath, `${command.name}.md`));
7066
+ filesWritten.push(join20(ctx.outputPath, `${command.name}.md`));
6541
7067
  }
6542
7068
  return {
6543
7069
  filesWritten
@@ -6546,7 +7072,7 @@ ${command.prompt}`;
6546
7072
  };
6547
7073
  // ../adapters/src/writers/cursor/mcp-json.ts
6548
7074
  import { mkdir as mkdir10, writeFile as writeFile18 } from "node:fs/promises";
6549
- import { dirname as dirname4, join as join19 } from "node:path";
7075
+ import { dirname as dirname4, join as join21 } from "node:path";
6550
7076
  function buildCursorMcpConfig(mcp) {
6551
7077
  const transport = mcp.transport ?? "stdio";
6552
7078
  if (transport === "http" || transport === "sse") {
@@ -6591,7 +7117,7 @@ var CursorMcpJsonWriter = {
6591
7117
  if (mcps.size === 0) {
6592
7118
  return { filesWritten: [] };
6593
7119
  }
6594
- const configPath = join19(ctx.projectRoot, ctx.outputPath);
7120
+ const configPath = join21(ctx.projectRoot, ctx.outputPath);
6595
7121
  const parentDir = dirname4(configPath);
6596
7122
  await mkdir10(parentDir, { recursive: true });
6597
7123
  const mcpServers = {};
@@ -6616,17 +7142,17 @@ var CursorMcpJsonWriter = {
6616
7142
  };
6617
7143
  // ../adapters/src/writers/cursor/rules.ts
6618
7144
  import { mkdir as mkdir11, writeFile as writeFile19 } from "node:fs/promises";
6619
- import { join as join20 } from "node:path";
7145
+ import { join as join22 } from "node:path";
6620
7146
  var CursorRulesWriter = {
6621
7147
  id: "cursor-rules",
6622
7148
  async write(bundle, ctx) {
6623
- const rulesDir = join20(ctx.projectRoot, ctx.outputPath);
7149
+ const rulesDir = join22(ctx.projectRoot, ctx.outputPath);
6624
7150
  await mkdir11(rulesDir, { recursive: true });
6625
7151
  const filesWritten = [];
6626
7152
  for (const rule of bundle.rules) {
6627
- const rulePath = join20(rulesDir, `omnidev-${rule.name}.mdc`);
7153
+ const rulePath = join22(rulesDir, `omnidev-${rule.name}.mdc`);
6628
7154
  await writeFile19(rulePath, rule.content, "utf-8");
6629
- filesWritten.push(join20(ctx.outputPath, `omnidev-${rule.name}.mdc`));
7155
+ filesWritten.push(join22(ctx.outputPath, `omnidev-${rule.name}.mdc`));
6630
7156
  }
6631
7157
  return {
6632
7158
  filesWritten
@@ -6646,7 +7172,7 @@ var cursorAdapter = {
6646
7172
  { writer: CursorMcpJsonWriter, outputPath: ".cursor/mcp.json" }
6647
7173
  ],
6648
7174
  async init(ctx) {
6649
- const rulesDir = join21(ctx.projectRoot, ".cursor", "rules");
7175
+ const rulesDir = join23(ctx.projectRoot, ".cursor", "rules");
6650
7176
  mkdirSync7(rulesDir, { recursive: true });
6651
7177
  return {
6652
7178
  filesCreated: [".cursor/rules/"],
@@ -6654,20 +7180,29 @@ var cursorAdapter = {
6654
7180
  };
6655
7181
  },
6656
7182
  async sync(bundle, ctx) {
6657
- const result = await executeWriters(this.writers, bundle, ctx.projectRoot);
7183
+ const cursorProviderId = "cursor";
7184
+ const instructionsProviderId = "claude-code";
7185
+ const instructionsWriters = this.writers.filter((config3) => config3.writer.id === "instructions-md");
7186
+ const cursorWriters = this.writers.filter((config3) => config3.writer.id !== "instructions-md");
7187
+ const instructionsBundle = createProviderScopedBundle(bundle, instructionsProviderId);
7188
+ const cursorBundle = createProviderScopedBundle(bundle, cursorProviderId);
7189
+ const instructionsResult = await executeWriters(instructionsWriters, instructionsBundle, ctx.projectRoot, instructionsProviderId);
7190
+ const cursorResult = await executeWriters(cursorWriters, cursorBundle, ctx.projectRoot, cursorProviderId);
6658
7191
  return {
6659
- filesWritten: result.filesWritten,
7192
+ filesWritten: [
7193
+ ...new Set([...instructionsResult.filesWritten, ...cursorResult.filesWritten])
7194
+ ],
6660
7195
  filesDeleted: []
6661
7196
  };
6662
7197
  }
6663
7198
  };
6664
7199
  // ../adapters/src/opencode/index.ts
6665
7200
  import { mkdirSync as mkdirSync8 } from "node:fs";
6666
- import { join as join24 } from "node:path";
7201
+ import { join as join26 } from "node:path";
6667
7202
 
6668
7203
  // ../adapters/src/writers/opencode/agents.ts
6669
7204
  import { mkdir as mkdir12, writeFile as writeFile20 } from "node:fs/promises";
6670
- import { join as join22 } from "node:path";
7205
+ import { join as join24 } from "node:path";
6671
7206
  function mapModelToOpenCode(model) {
6672
7207
  if (!model || model === "inherit")
6673
7208
  return;
@@ -6745,7 +7280,7 @@ function generateFrontmatter3(agent) {
6745
7280
  var OpenCodeAgentsWriter = {
6746
7281
  id: "opencode-agents",
6747
7282
  async write(bundle, ctx) {
6748
- const agentsDir = join22(ctx.projectRoot, ctx.outputPath);
7283
+ const agentsDir = join24(ctx.projectRoot, ctx.outputPath);
6749
7284
  await mkdir12(agentsDir, { recursive: true });
6750
7285
  const filesWritten = [];
6751
7286
  for (const agent of bundle.subagents) {
@@ -6753,9 +7288,9 @@ var OpenCodeAgentsWriter = {
6753
7288
  const content = `${frontmatter}
6754
7289
 
6755
7290
  ${agent.systemPrompt}`;
6756
- const agentPath = join22(agentsDir, `${agent.name}.md`);
7291
+ const agentPath = join24(agentsDir, `${agent.name}.md`);
6757
7292
  await writeFile20(agentPath, content, "utf-8");
6758
- filesWritten.push(join22(ctx.outputPath, `${agent.name}.md`));
7293
+ filesWritten.push(join24(ctx.outputPath, `${agent.name}.md`));
6759
7294
  }
6760
7295
  return {
6761
7296
  filesWritten
@@ -6764,7 +7299,7 @@ ${agent.systemPrompt}`;
6764
7299
  };
6765
7300
  // ../adapters/src/writers/opencode/commands.ts
6766
7301
  import { mkdir as mkdir13, writeFile as writeFile21 } from "node:fs/promises";
6767
- import { join as join23 } from "node:path";
7302
+ import { join as join25 } from "node:path";
6768
7303
  function generateFrontmatter4(command) {
6769
7304
  const lines = ["---"];
6770
7305
  lines.push(`description: "${command.description.replace(/"/g, "\\\"")}"`);
@@ -6781,7 +7316,7 @@ function generateFrontmatter4(command) {
6781
7316
  var OpenCodeCommandsWriter = {
6782
7317
  id: "opencode-commands",
6783
7318
  async write(bundle, ctx) {
6784
- const commandsDir = join23(ctx.projectRoot, ctx.outputPath);
7319
+ const commandsDir = join25(ctx.projectRoot, ctx.outputPath);
6785
7320
  await mkdir13(commandsDir, { recursive: true });
6786
7321
  const filesWritten = [];
6787
7322
  for (const command of bundle.commands) {
@@ -6789,9 +7324,9 @@ var OpenCodeCommandsWriter = {
6789
7324
  const content = `${frontmatter}
6790
7325
 
6791
7326
  ${command.prompt}`;
6792
- const commandPath = join23(commandsDir, `${command.name}.md`);
7327
+ const commandPath = join25(commandsDir, `${command.name}.md`);
6793
7328
  await writeFile21(commandPath, content, "utf-8");
6794
- filesWritten.push(join23(ctx.outputPath, `${command.name}.md`));
7329
+ filesWritten.push(join25(ctx.outputPath, `${command.name}.md`));
6795
7330
  }
6796
7331
  return {
6797
7332
  filesWritten
@@ -6809,7 +7344,7 @@ var opencodeAdapter = {
6809
7344
  { writer: OpenCodeCommandsWriter, outputPath: ".opencode/commands/" }
6810
7345
  ],
6811
7346
  async init(ctx) {
6812
- const opencodeDir = join24(ctx.projectRoot, ".opencode");
7347
+ const opencodeDir = join26(ctx.projectRoot, ".opencode");
6813
7348
  mkdirSync8(opencodeDir, { recursive: true });
6814
7349
  return {
6815
7350
  filesCreated: [".opencode/"],
@@ -6817,7 +7352,9 @@ var opencodeAdapter = {
6817
7352
  };
6818
7353
  },
6819
7354
  async sync(bundle, ctx) {
6820
- const result = await executeWriters(this.writers, bundle, ctx.projectRoot);
7355
+ const providerId = "opencode";
7356
+ const providerBundle = createProviderScopedBundle(bundle, providerId);
7357
+ const result = await executeWriters(this.writers, providerBundle, ctx.projectRoot, providerId);
6821
7358
  return {
6822
7359
  filesWritten: result.filesWritten,
6823
7360
  filesDeleted: []
@@ -6861,7 +7398,7 @@ async function inferCapabilityId(source, sourceType) {
6861
7398
  }
6862
7399
  async function runAddCap(flags, name) {
6863
7400
  try {
6864
- if (!existsSync22("omni.toml")) {
7401
+ if (!existsSync24("omni.toml")) {
6865
7402
  console.log("✗ No config file found");
6866
7403
  console.log(" Run: omnidev init");
6867
7404
  process.exit(1);
@@ -6884,7 +7421,7 @@ async function runAddCap(flags, name) {
6884
7421
  sourceType = "local";
6885
7422
  const localPath = flags.local.startsWith("file://") ? flags.local.slice(7) : flags.local;
6886
7423
  source = `file://${localPath}`;
6887
- if (!existsSync22(localPath)) {
7424
+ if (!existsSync24(localPath)) {
6888
7425
  console.error(`✗ Local path not found: ${localPath}`);
6889
7426
  process.exit(1);
6890
7427
  }
@@ -6976,7 +7513,7 @@ async function runAddCap(flags, name) {
6976
7513
  }
6977
7514
  async function runAddMcp(flags, name) {
6978
7515
  try {
6979
- if (!existsSync22("omni.toml")) {
7516
+ if (!existsSync24("omni.toml")) {
6980
7517
  console.log("✗ No config file found");
6981
7518
  console.log(" Run: omnidev init");
6982
7519
  process.exit(1);
@@ -7263,9 +7800,9 @@ var addRoutes = buildRouteMap({
7263
7800
  });
7264
7801
 
7265
7802
  // src/commands/capability.ts
7266
- import { existsSync as existsSync23, mkdirSync as mkdirSync9 } from "node:fs";
7803
+ import { existsSync as existsSync25, mkdirSync as mkdirSync9 } from "node:fs";
7267
7804
  import { writeFile as writeFile22 } from "node:fs/promises";
7268
- import { join as join25 } from "node:path";
7805
+ import { join as join27 } from "node:path";
7269
7806
  import { input } from "@inquirer/prompts";
7270
7807
  init_src();
7271
7808
  import { buildCommand as buildCommand2, buildRouteMap as buildRouteMap2 } from "@stricli/core";
@@ -7443,14 +7980,18 @@ export default {
7443
7980
  } satisfies CapabilityExport;
7444
7981
  `;
7445
7982
  }
7446
- function generateGitignore() {
7447
- return `dist/
7448
- node_modules/
7983
+ function generateGitignore(programmatic) {
7984
+ const lines = [".env"];
7985
+ if (programmatic) {
7986
+ lines.push("dist/", "node_modules/");
7987
+ }
7988
+ return `${lines.join(`
7989
+ `)}
7449
7990
  `;
7450
7991
  }
7451
7992
  async function runCapabilityNew(flags, capabilityId) {
7452
7993
  try {
7453
- if (!existsSync23(".omni")) {
7994
+ if (!existsSync25(".omni")) {
7454
7995
  console.error("✗ OmniDev is not initialized in this directory.");
7455
7996
  console.log("");
7456
7997
  console.log(" Run: omnidev init");
@@ -7474,28 +8015,28 @@ async function runCapabilityNew(flags, capabilityId) {
7474
8015
  default: defaultPath
7475
8016
  });
7476
8017
  }
7477
- if (existsSync23(capabilityDir)) {
8018
+ if (existsSync25(capabilityDir)) {
7478
8019
  console.error(`✗ Directory already exists at ${capabilityDir}`);
7479
8020
  process.exit(1);
7480
8021
  }
7481
8022
  const name = toTitleCase(id);
7482
8023
  mkdirSync9(capabilityDir, { recursive: true });
7483
8024
  const capabilityToml = generateCapabilityToml2({ id, name });
7484
- await writeFile22(join25(capabilityDir, "capability.toml"), capabilityToml, "utf-8");
7485
- const skillDir = join25(capabilityDir, "skills", "getting-started");
8025
+ await writeFile22(join27(capabilityDir, "capability.toml"), capabilityToml, "utf-8");
8026
+ const skillDir = join27(capabilityDir, "skills", "getting-started");
7486
8027
  mkdirSync9(skillDir, { recursive: true });
7487
- await writeFile22(join25(skillDir, "SKILL.md"), generateSkillTemplate("getting-started"), "utf-8");
7488
- const rulesDir = join25(capabilityDir, "rules");
8028
+ await writeFile22(join27(skillDir, "SKILL.md"), generateSkillTemplate("getting-started"), "utf-8");
8029
+ const rulesDir = join27(capabilityDir, "rules");
7489
8030
  mkdirSync9(rulesDir, { recursive: true });
7490
- await writeFile22(join25(rulesDir, "coding-standards.md"), generateRuleTemplate("coding-standards"), "utf-8");
7491
- const hooksDir = join25(capabilityDir, "hooks");
8031
+ await writeFile22(join27(rulesDir, "coding-standards.md"), generateRuleTemplate("coding-standards"), "utf-8");
8032
+ const hooksDir = join27(capabilityDir, "hooks");
7492
8033
  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");
8034
+ await writeFile22(join27(hooksDir, "hooks.toml"), generateHooksTemplate(), "utf-8");
8035
+ await writeFile22(join27(hooksDir, "example-hook.sh"), generateHookScript(), "utf-8");
8036
+ await writeFile22(join27(capabilityDir, ".gitignore"), generateGitignore(Boolean(flags.programmatic)), "utf-8");
7495
8037
  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");
8038
+ await writeFile22(join27(capabilityDir, "package.json"), generatePackageJson(id), "utf-8");
8039
+ await writeFile22(join27(capabilityDir, "index.ts"), generateIndexTs(id, name), "utf-8");
7499
8040
  }
7500
8041
  console.log(`✓ Created capability: ${name}`);
7501
8042
  console.log(` Location: ${capabilityDir}`);
@@ -7506,10 +8047,10 @@ async function runCapabilityNew(flags, capabilityId) {
7506
8047
  console.log(" - rules/coding-standards.md");
7507
8048
  console.log(" - hooks/hooks.toml");
7508
8049
  console.log(" - hooks/example-hook.sh");
8050
+ console.log(" - .gitignore");
7509
8051
  if (flags.programmatic) {
7510
8052
  console.log(" - package.json");
7511
8053
  console.log(" - index.ts");
7512
- console.log(" - .gitignore");
7513
8054
  }
7514
8055
  console.log("");
7515
8056
  if (flags.programmatic) {
@@ -7651,9 +8192,9 @@ var capabilityRoutes = buildRouteMap2({
7651
8192
  });
7652
8193
 
7653
8194
  // src/commands/doctor.ts
7654
- import { existsSync as existsSync24 } from "node:fs";
8195
+ import { existsSync as existsSync26 } from "node:fs";
7655
8196
  import { execFile } from "node:child_process";
7656
- import { readFile as readFile19 } from "node:fs/promises";
8197
+ import { readFile as readFile20 } from "node:fs/promises";
7657
8198
  import { promisify } from "node:util";
7658
8199
  import { buildCommand as buildCommand3 } from "@stricli/core";
7659
8200
  var doctorCommand = buildCommand3({
@@ -7698,50 +8239,52 @@ async function runDoctor() {
7698
8239
  async function checkPackageManager() {
7699
8240
  const execFileAsync = promisify(execFile);
7700
8241
  try {
7701
- const { stdout } = await execFileAsync("bun", ["--version"]);
7702
- const version2 = stdout.trim();
7703
- const firstPart = version2.split(".")[0];
7704
- if (!firstPart) {
8242
+ const { stdout: npmStdout } = await execFileAsync("npm", ["--version"]);
8243
+ const npmVersion = npmStdout.trim();
8244
+ try {
8245
+ const { stdout: bunStdout } = await execFileAsync("bun", ["--version"]);
8246
+ const bunVersion = bunStdout.trim();
8247
+ const firstPart = bunVersion.split(".")[0];
8248
+ if (!firstPart) {
8249
+ return {
8250
+ name: "Package Manager",
8251
+ passed: false,
8252
+ message: `Invalid Bun version format: ${bunVersion}`,
8253
+ fix: "Reinstall Bun: curl -fsSL https://bun.sh/install | bash"
8254
+ };
8255
+ }
8256
+ const major = Number.parseInt(firstPart, 10);
8257
+ if (major < 1) {
8258
+ return {
8259
+ name: "Package Manager",
8260
+ passed: false,
8261
+ message: `npm v${npmVersion}; bun v${bunVersion}`,
8262
+ fix: "Upgrade Bun: curl -fsSL https://bun.sh/install | bash"
8263
+ };
8264
+ }
7705
8265
  return {
7706
8266
  name: "Package Manager",
7707
- passed: false,
7708
- message: `Invalid Bun version format: ${version2}`,
7709
- fix: "Reinstall Bun: curl -fsSL https://bun.sh/install | bash"
8267
+ passed: true,
8268
+ message: `npm v${npmVersion}; bun v${bunVersion}`
7710
8269
  };
7711
- }
7712
- const major = Number.parseInt(firstPart, 10);
7713
- if (major < 1) {
8270
+ } catch {
7714
8271
  return {
7715
8272
  name: "Package Manager",
7716
- passed: false,
7717
- message: `bun v${version2}`,
7718
- fix: "Upgrade Bun: curl -fsSL https://bun.sh/install | bash"
8273
+ passed: true,
8274
+ message: `npm v${npmVersion}`
7719
8275
  };
7720
8276
  }
7721
- return {
7722
- name: "Package Manager",
7723
- passed: true,
7724
- message: `bun v${version2}`
7725
- };
7726
- } catch {}
7727
- try {
7728
- const { stdout } = await execFileAsync("npm", ["--version"]);
7729
- return {
7730
- name: "Package Manager",
7731
- passed: true,
7732
- message: `npm v${stdout.trim()}`
7733
- };
7734
8277
  } catch {
7735
8278
  return {
7736
8279
  name: "Package Manager",
7737
8280
  passed: false,
7738
- message: "Neither Bun nor npm is installed",
7739
- fix: "Install Bun (recommended): curl -fsSL https://bun.sh/install | bash"
8281
+ message: "npm is not installed",
8282
+ fix: "Install Node.js and npm: https://nodejs.org/"
7740
8283
  };
7741
8284
  }
7742
8285
  }
7743
8286
  async function checkOmniLocalDir() {
7744
- const exists = existsSync24(".omni");
8287
+ const exists = existsSync26(".omni");
7745
8288
  if (!exists) {
7746
8289
  return {
7747
8290
  name: ".omni/ directory",
@@ -7758,7 +8301,7 @@ async function checkOmniLocalDir() {
7758
8301
  }
7759
8302
  async function checkConfig() {
7760
8303
  const configPath = "omni.toml";
7761
- if (!existsSync24(configPath)) {
8304
+ if (!existsSync26(configPath)) {
7762
8305
  return {
7763
8306
  name: "Configuration",
7764
8307
  passed: false,
@@ -7785,7 +8328,7 @@ async function checkConfig() {
7785
8328
  }
7786
8329
  async function checkRootGitignore() {
7787
8330
  const gitignorePath = ".gitignore";
7788
- if (!existsSync24(gitignorePath)) {
8331
+ if (!existsSync26(gitignorePath)) {
7789
8332
  return {
7790
8333
  name: "Root .gitignore",
7791
8334
  passed: false,
@@ -7793,7 +8336,7 @@ async function checkRootGitignore() {
7793
8336
  fix: "Run: omnidev init"
7794
8337
  };
7795
8338
  }
7796
- const content = await readFile19(gitignorePath, "utf-8");
8339
+ const content = await readFile20(gitignorePath, "utf-8");
7797
8340
  const lines = content.split(`
7798
8341
  `).map((line) => line.trim());
7799
8342
  const hasOmniDir = lines.includes(".omni/");
@@ -7819,7 +8362,7 @@ async function checkRootGitignore() {
7819
8362
  }
7820
8363
  async function checkCapabilitiesDir() {
7821
8364
  const capabilitiesDirPath = ".omni/capabilities";
7822
- if (!existsSync24(capabilitiesDirPath)) {
8365
+ if (!existsSync26(capabilitiesDirPath)) {
7823
8366
  return {
7824
8367
  name: "Capabilities Directory",
7825
8368
  passed: true,
@@ -7835,8 +8378,8 @@ async function checkCapabilitiesDir() {
7835
8378
 
7836
8379
  // src/commands/init.ts
7837
8380
  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";
8381
+ import { existsSync as existsSync27, mkdirSync as mkdirSync10 } from "node:fs";
8382
+ import { readFile as readFile21, writeFile as writeFile23 } from "node:fs/promises";
7840
8383
  import { promisify as promisify2 } from "node:util";
7841
8384
  init_src();
7842
8385
  import { buildCommand as buildCommand4 } from "@stricli/core";
@@ -7849,8 +8392,8 @@ var PROVIDER_GITIGNORE_FILES = {
7849
8392
  codex: ["AGENTS.md", ".codex/"],
7850
8393
  opencode: [".opencode/"]
7851
8394
  };
7852
- function getProviderGitignoreFiles(providers2) {
7853
- return providers2.flatMap((p) => PROVIDER_GITIGNORE_FILES[p] ?? []);
8395
+ function getProviderGitignoreFiles(providers3) {
8396
+ return providers3.flatMap((p) => PROVIDER_GITIGNORE_FILES[p] ?? []);
7854
8397
  }
7855
8398
  async function promptForProviders() {
7856
8399
  const answers = await checkbox({
@@ -7905,7 +8448,7 @@ async function runInit(_flags, providerArg) {
7905
8448
  }
7906
8449
  }
7907
8450
  await writeEnabledProviders(providerIds);
7908
- if (!existsSync25("omni.toml")) {
8451
+ if (!existsSync27("omni.toml")) {
7909
8452
  await writeConfig({
7910
8453
  profiles: {
7911
8454
  default: {
@@ -7921,7 +8464,7 @@ async function runInit(_flags, providerArg) {
7921
8464
  });
7922
8465
  await setActiveProfile("default");
7923
8466
  }
7924
- if (!existsSync25("OMNI.md")) {
8467
+ if (!existsSync27("OMNI.md")) {
7925
8468
  await writeFile23("OMNI.md", generateOmniMdTemplate(), "utf-8");
7926
8469
  }
7927
8470
  const config3 = await loadConfig();
@@ -7999,8 +8542,8 @@ async function addProviderFilesToGitignore(entries) {
7999
8542
  async function addToGitignore(entriesToAdd, sectionHeader) {
8000
8543
  const gitignorePath = ".gitignore";
8001
8544
  let content = "";
8002
- if (existsSync25(gitignorePath)) {
8003
- content = await readFile20(gitignorePath, "utf-8");
8545
+ if (existsSync27(gitignorePath)) {
8546
+ content = await readFile21(gitignorePath, "utf-8");
8004
8547
  }
8005
8548
  const lines = content.split(`
8006
8549
  `);
@@ -8031,7 +8574,7 @@ async function getTrackedProviderFiles(files) {
8031
8574
  }
8032
8575
 
8033
8576
  // src/commands/profile.ts
8034
- import { existsSync as existsSync26 } from "node:fs";
8577
+ import { existsSync as existsSync28 } from "node:fs";
8035
8578
  init_src();
8036
8579
  import { buildCommand as buildCommand5, buildRouteMap as buildRouteMap3 } from "@stricli/core";
8037
8580
  var listCommand2 = buildCommand5({
@@ -8075,7 +8618,7 @@ var profileRoutes = buildRouteMap3({
8075
8618
  });
8076
8619
  async function runProfileList() {
8077
8620
  try {
8078
- if (!existsSync26("omni.toml")) {
8621
+ if (!existsSync28("omni.toml")) {
8079
8622
  console.log("✗ No config file found");
8080
8623
  console.log(" Run: omnidev init");
8081
8624
  process.exit(1);
@@ -8115,7 +8658,7 @@ async function runProfileList() {
8115
8658
  }
8116
8659
  async function runProfileSet(profileName) {
8117
8660
  try {
8118
- if (!existsSync26("omni.toml")) {
8661
+ if (!existsSync28("omni.toml")) {
8119
8662
  console.log("✗ No config file found");
8120
8663
  console.log(" Run: omnidev init");
8121
8664
  process.exit(1);
@@ -8264,7 +8807,7 @@ var providerRoutes = buildRouteMap4({
8264
8807
 
8265
8808
  // src/commands/security.ts
8266
8809
  init_src();
8267
- import { existsSync as existsSync27 } from "node:fs";
8810
+ import { existsSync as existsSync29 } from "node:fs";
8268
8811
  import { buildCommand as buildCommand7, buildRouteMap as buildRouteMap5 } from "@stricli/core";
8269
8812
  var VALID_FINDING_TYPES = [
8270
8813
  "unicode_bidi",
@@ -8303,7 +8846,9 @@ async function filterAllowedFindings(summary, options = {}) {
8303
8846
  symlink_escape: 0,
8304
8847
  symlink_absolute: 0,
8305
8848
  suspicious_script: 0,
8306
- binary_file: 0
8849
+ binary_file: 0,
8850
+ hidden_command: 0,
8851
+ network_request: 0
8307
8852
  };
8308
8853
  const findingsBySeverity = {
8309
8854
  low: 0,
@@ -8381,7 +8926,7 @@ function formatFindingsWithHints(summary) {
8381
8926
  }
8382
8927
  async function runSecurityIssues(flags = {}) {
8383
8928
  try {
8384
- if (!existsSync27("omni.toml")) {
8929
+ if (!existsSync29("omni.toml")) {
8385
8930
  console.log("No config file found");
8386
8931
  console.log(" Run: omnidev init");
8387
8932
  process.exit(1);
@@ -8636,7 +9181,7 @@ var securityRoutes = buildRouteMap5({
8636
9181
  });
8637
9182
 
8638
9183
  // src/commands/sync.ts
8639
- import { existsSync as existsSync28 } from "node:fs";
9184
+ import { existsSync as existsSync30 } from "node:fs";
8640
9185
  init_src();
8641
9186
  import { buildCommand as buildCommand8 } from "@stricli/core";
8642
9187
  var PROVIDERS_STATE_PATH = ".omni/state/providers.json";
@@ -8654,7 +9199,7 @@ async function runSync() {
8654
9199
  const config3 = await loadConfig();
8655
9200
  const activeProfile = await getActiveProfile() ?? "default";
8656
9201
  let adapters = await getEnabledAdapters();
8657
- if (!existsSync28(PROVIDERS_STATE_PATH) || adapters.length === 0) {
9202
+ if (!existsSync30(PROVIDERS_STATE_PATH) || adapters.length === 0) {
8658
9203
  console.log("No providers configured yet. Select your provider(s):");
8659
9204
  const providerIds = await promptForProviders();
8660
9205
  await writeEnabledProviders(providerIds);
@@ -8864,9 +9409,9 @@ async function buildDynamicApp() {
8864
9409
  security: securityRoutes
8865
9410
  };
8866
9411
  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)) {
9412
+ const configPath = join28(process.cwd(), "omni.toml");
9413
+ debug("Checking for config", { configPath, exists: existsSync31(configPath), cwd: process.cwd() });
9414
+ if (existsSync31(configPath)) {
8870
9415
  try {
8871
9416
  debug("Loading capability commands...");
8872
9417
  const capabilityCommands = await loadCapabilityCommands();
@@ -8941,25 +9486,25 @@ async function loadCapabilityCommands() {
8941
9486
  return commands;
8942
9487
  }
8943
9488
  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");
9489
+ const capabilityPath = join28(process.cwd(), capability3.path);
9490
+ const builtIndexPath = join28(capabilityPath, "dist", "index.js");
9491
+ const jsIndexPath = join28(capabilityPath, "index.js");
9492
+ const tsIndexPath = join28(capabilityPath, "index.ts");
8948
9493
  debug(`Checking entry points for '${capability3.id}'`, {
8949
9494
  capabilityPath,
8950
9495
  builtIndexPath,
8951
- builtExists: existsSync29(builtIndexPath),
9496
+ builtExists: existsSync31(builtIndexPath),
8952
9497
  jsIndexPath,
8953
- jsExists: existsSync29(jsIndexPath),
9498
+ jsExists: existsSync31(jsIndexPath),
8954
9499
  tsIndexPath,
8955
- tsExists: existsSync29(tsIndexPath)
9500
+ tsExists: existsSync31(tsIndexPath)
8956
9501
  });
8957
9502
  let indexPath = null;
8958
- if (existsSync29(builtIndexPath)) {
9503
+ if (existsSync31(builtIndexPath)) {
8959
9504
  indexPath = builtIndexPath;
8960
- } else if (existsSync29(jsIndexPath)) {
9505
+ } else if (existsSync31(jsIndexPath)) {
8961
9506
  indexPath = jsIndexPath;
8962
- } else if (existsSync29(tsIndexPath)) {
9507
+ } else if (existsSync31(tsIndexPath)) {
8963
9508
  indexPath = tsIndexPath;
8964
9509
  }
8965
9510
  if (!indexPath) {