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