@omnidev-ai/core 0.10.0 → 0.11.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 CHANGED
@@ -118,58 +118,10 @@ async function loadDocs(capabilityPath, capabilityId) {
118
118
  return docs;
119
119
  }
120
120
  // src/capability/loader.ts
121
- import { existsSync as existsSync9, readdirSync as readdirSync6 } from "node:fs";
122
- import { readFile as readFile7 } from "node:fs/promises";
121
+ import { existsSync as existsSync8, readdirSync as readdirSync6 } from "node:fs";
122
+ import { readFile as readFile6 } from "node:fs/promises";
123
123
  import { join as join7 } from "node:path";
124
124
 
125
- // src/config/env.ts
126
- import { existsSync as existsSync3 } from "node:fs";
127
- import { readFile as readFile3 } from "node:fs/promises";
128
- var ENV_FILE = ".omni/.env";
129
- async function loadEnvironment() {
130
- const env = {};
131
- if (existsSync3(ENV_FILE)) {
132
- const content = await readFile3(ENV_FILE, "utf-8");
133
- for (const line of content.split(`
134
- `)) {
135
- const trimmed = line.trim();
136
- if (trimmed && !trimmed.startsWith("#")) {
137
- const eqIndex = trimmed.indexOf("=");
138
- if (eqIndex > 0) {
139
- const key = trimmed.slice(0, eqIndex).trim();
140
- const value = trimmed.slice(eqIndex + 1).trim();
141
- const unquotedValue = value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'") ? value.slice(1, -1) : value;
142
- env[key] = unquotedValue;
143
- }
144
- }
145
- }
146
- }
147
- const processEnv = {};
148
- for (const [key, value] of Object.entries(process.env)) {
149
- if (value !== undefined) {
150
- processEnv[key] = value;
151
- }
152
- }
153
- return { ...env, ...processEnv };
154
- }
155
- function validateEnv(declarations, env, capabilityId) {
156
- const missing = [];
157
- for (const [key, decl] of Object.entries(declarations)) {
158
- const declaration = decl;
159
- const value = env[key] ?? declaration.default;
160
- if (declaration.required && !value) {
161
- missing.push(key);
162
- }
163
- }
164
- if (missing.length > 0) {
165
- throw new Error(`Missing required environment variable${missing.length > 1 ? "s" : ""} for capability "${capabilityId}": ${missing.join(", ")}. ` + `Set ${missing.length > 1 ? "them" : "it"} in .omni/.env or as environment variable${missing.length > 1 ? "s" : ""}.`);
166
- }
167
- }
168
- function isSecretEnvVar(key, declarations) {
169
- const decl = declarations[key];
170
- return decl?.secret === true;
171
- }
172
-
173
125
  // src/config/parser.ts
174
126
  import { parse } from "smol-toml";
175
127
  function parseOmniConfig(tomlContent) {
@@ -208,7 +160,7 @@ function parseCapabilityConfig(tomlContent) {
208
160
  }
209
161
 
210
162
  // src/hooks/loader.ts
211
- import { existsSync as existsSync5, readFileSync } from "node:fs";
163
+ import { existsSync as existsSync4, readFileSync } from "node:fs";
212
164
  import { join as join3 } from "node:path";
213
165
  import { parse as parseToml } from "smol-toml";
214
166
 
@@ -274,7 +226,7 @@ var HOOKS_CONFIG_FILENAME = "hooks.toml";
274
226
  var HOOKS_DIRECTORY = "hooks";
275
227
 
276
228
  // src/hooks/validation.ts
277
- import { existsSync as existsSync4, statSync } from "node:fs";
229
+ import { existsSync as existsSync3, statSync } from "node:fs";
278
230
  import { resolve } from "node:path";
279
231
 
280
232
  // src/hooks/types.ts
@@ -590,7 +542,7 @@ function validateScriptInCommand(command, basePath, event, matcherIndex, hookInd
590
542
  const relativePath = match[1];
591
543
  if (relativePath) {
592
544
  const fullPath = resolve(basePath, relativePath);
593
- if (!existsSync4(fullPath)) {
545
+ if (!existsSync3(fullPath)) {
594
546
  issues.push({
595
547
  severity: "error",
596
548
  code: "HOOKS_SCRIPT_NOT_FOUND",
@@ -757,7 +709,7 @@ function loadHooksFromCapability(capabilityPath, options) {
757
709
  };
758
710
  const hooksDir = join3(capabilityPath, HOOKS_DIRECTORY);
759
711
  const configPath = join3(hooksDir, HOOKS_CONFIG_FILENAME);
760
- if (!existsSync5(configPath)) {
712
+ if (!existsSync4(configPath)) {
761
713
  return {
762
714
  config: createEmptyHooksConfig(),
763
715
  validation: createEmptyValidationResult(),
@@ -844,7 +796,7 @@ function loadCapabilityHooks(capabilityName, capabilityPath, options) {
844
796
  }
845
797
  function hasHooks(capabilityPath) {
846
798
  const configPath = join3(capabilityPath, HOOKS_DIRECTORY, HOOKS_CONFIG_FILENAME);
847
- return existsSync5(configPath);
799
+ return existsSync4(configPath);
848
800
  }
849
801
  function getHooksDirectory(capabilityPath) {
850
802
  return join3(capabilityPath, HOOKS_DIRECTORY);
@@ -854,12 +806,12 @@ function getHooksConfigPath(capabilityPath) {
854
806
  }
855
807
 
856
808
  // src/capability/rules.ts
857
- import { existsSync as existsSync6, readdirSync as readdirSync3 } from "node:fs";
858
- import { readFile as readFile4 } from "node:fs/promises";
809
+ import { existsSync as existsSync5, readdirSync as readdirSync3 } from "node:fs";
810
+ import { readFile as readFile3 } from "node:fs/promises";
859
811
  import { basename as basename2, join as join4 } from "node:path";
860
812
  async function loadRules(capabilityPath, capabilityId) {
861
813
  const rulesDir = join4(capabilityPath, "rules");
862
- if (!existsSync6(rulesDir)) {
814
+ if (!existsSync5(rulesDir)) {
863
815
  return [];
864
816
  }
865
817
  const rules = [];
@@ -867,7 +819,7 @@ async function loadRules(capabilityPath, capabilityId) {
867
819
  for (const entry of entries) {
868
820
  if (entry.isFile() && entry.name.endsWith(".md")) {
869
821
  const rulePath = join4(rulesDir, entry.name);
870
- const content = await readFile4(rulePath, "utf-8");
822
+ const content = await readFile3(rulePath, "utf-8");
871
823
  rules.push({
872
824
  name: basename2(entry.name, ".md"),
873
825
  content: content.trim(),
@@ -879,12 +831,12 @@ async function loadRules(capabilityPath, capabilityId) {
879
831
  }
880
832
 
881
833
  // src/capability/skills.ts
882
- import { existsSync as existsSync7, readdirSync as readdirSync4 } from "node:fs";
883
- import { readFile as readFile5 } from "node:fs/promises";
834
+ import { existsSync as existsSync6, readdirSync as readdirSync4 } from "node:fs";
835
+ import { readFile as readFile4 } from "node:fs/promises";
884
836
  import { join as join5 } from "node:path";
885
837
  async function loadSkills(capabilityPath, capabilityId) {
886
838
  const skillsDir = join5(capabilityPath, "skills");
887
- if (!existsSync7(skillsDir)) {
839
+ if (!existsSync6(skillsDir)) {
888
840
  return [];
889
841
  }
890
842
  const skills = [];
@@ -892,7 +844,7 @@ async function loadSkills(capabilityPath, capabilityId) {
892
844
  for (const entry of entries) {
893
845
  if (entry.isDirectory()) {
894
846
  const skillPath = join5(skillsDir, entry.name, "SKILL.md");
895
- if (existsSync7(skillPath)) {
847
+ if (existsSync6(skillPath)) {
896
848
  const skill = await parseSkillFile(skillPath, capabilityId);
897
849
  skills.push(skill);
898
850
  }
@@ -901,7 +853,7 @@ async function loadSkills(capabilityPath, capabilityId) {
901
853
  return skills;
902
854
  }
903
855
  async function parseSkillFile(filePath, capabilityId) {
904
- const content = await readFile5(filePath, "utf-8");
856
+ const content = await readFile4(filePath, "utf-8");
905
857
  const parsed = parseFrontmatterWithMarkdown(content);
906
858
  if (!parsed) {
907
859
  throw new Error(`Invalid SKILL.md format at ${filePath}: missing YAML frontmatter`);
@@ -920,12 +872,12 @@ async function parseSkillFile(filePath, capabilityId) {
920
872
  }
921
873
 
922
874
  // src/capability/subagents.ts
923
- import { existsSync as existsSync8, readdirSync as readdirSync5 } from "node:fs";
924
- import { readFile as readFile6 } from "node:fs/promises";
875
+ import { existsSync as existsSync7, readdirSync as readdirSync5 } from "node:fs";
876
+ import { readFile as readFile5 } from "node:fs/promises";
925
877
  import { join as join6 } from "node:path";
926
878
  async function loadSubagents(capabilityPath, capabilityId) {
927
879
  const subagentsDir = join6(capabilityPath, "subagents");
928
- if (!existsSync8(subagentsDir)) {
880
+ if (!existsSync7(subagentsDir)) {
929
881
  return [];
930
882
  }
931
883
  const subagents = [];
@@ -933,7 +885,7 @@ async function loadSubagents(capabilityPath, capabilityId) {
933
885
  for (const entry of entries) {
934
886
  if (entry.isDirectory()) {
935
887
  const subagentPath = join6(subagentsDir, entry.name, "SUBAGENT.md");
936
- if (existsSync8(subagentPath)) {
888
+ if (existsSync7(subagentPath)) {
937
889
  const subagent = await parseSubagentFile(subagentPath, capabilityId);
938
890
  subagents.push(subagent);
939
891
  }
@@ -942,7 +894,7 @@ async function loadSubagents(capabilityPath, capabilityId) {
942
894
  return subagents;
943
895
  }
944
896
  async function parseSubagentFile(filePath, capabilityId) {
945
- const content = await readFile6(filePath, "utf-8");
897
+ const content = await readFile5(filePath, "utf-8");
946
898
  const parsed = parseFrontmatterWithMarkdown(content);
947
899
  if (!parsed) {
948
900
  throw new Error(`Invalid SUBAGENT.md format at ${filePath}: missing YAML frontmatter`);
@@ -986,13 +938,13 @@ function parseCommaSeparatedList(value) {
986
938
  var CAPABILITIES_DIR = ".omni/capabilities";
987
939
  async function discoverCapabilities() {
988
940
  const capabilities = [];
989
- if (existsSync9(CAPABILITIES_DIR)) {
941
+ if (existsSync8(CAPABILITIES_DIR)) {
990
942
  const entries = readdirSync6(CAPABILITIES_DIR, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
991
943
  for (const entry of entries) {
992
944
  if (entry.isDirectory()) {
993
945
  const entryPath = join7(CAPABILITIES_DIR, entry.name);
994
946
  const configPath = join7(entryPath, "capability.toml");
995
- if (existsSync9(configPath)) {
947
+ if (existsSync8(configPath)) {
996
948
  capabilities.push(entryPath);
997
949
  }
998
950
  }
@@ -1002,13 +954,13 @@ async function discoverCapabilities() {
1002
954
  }
1003
955
  async function loadCapabilityConfig(capabilityPath) {
1004
956
  const configPath = join7(capabilityPath, "capability.toml");
1005
- const content = await readFile7(configPath, "utf-8");
957
+ const content = await readFile6(configPath, "utf-8");
1006
958
  const config = parseCapabilityConfig(content);
1007
959
  return config;
1008
960
  }
1009
961
  async function importCapabilityExports(capabilityPath) {
1010
962
  const indexPath = join7(capabilityPath, "index.ts");
1011
- if (!existsSync9(indexPath)) {
963
+ if (!existsSync8(indexPath)) {
1012
964
  return {};
1013
965
  }
1014
966
  try {
@@ -1028,10 +980,10 @@ If this is a project-specific capability, install dependencies or remove it from
1028
980
  }
1029
981
  async function loadTypeDefinitions(capabilityPath) {
1030
982
  const typesPath = join7(capabilityPath, "types.d.ts");
1031
- if (!existsSync9(typesPath)) {
983
+ if (!existsSync8(typesPath)) {
1032
984
  return;
1033
985
  }
1034
- return readFile7(typesPath, "utf-8");
986
+ return readFile6(typesPath, "utf-8");
1035
987
  }
1036
988
  function convertSkillExports(skillExports, capabilityId) {
1037
989
  return skillExports.map((skillExport) => {
@@ -1208,12 +1160,9 @@ function convertCommandExports(commandExports, capabilityId) {
1208
1160
  return result;
1209
1161
  });
1210
1162
  }
1211
- async function loadCapability(capabilityPath, env) {
1163
+ async function loadCapability(capabilityPath) {
1212
1164
  const config = await loadCapabilityConfig(capabilityPath);
1213
1165
  const id = config.capability.id;
1214
- if (config.env) {
1215
- validateEnv(config.env, env, id);
1216
- }
1217
1166
  const exports = await importCapabilityExports(capabilityPath);
1218
1167
  const exportsAny = exports;
1219
1168
  const skills = "skills" in exports && Array.isArray(exportsAny.skills) ? convertSkillExports(exportsAny.skills, id) : await loadSkills(capabilityPath, id);
@@ -1248,13 +1197,12 @@ async function loadCapability(capabilityPath, env) {
1248
1197
  return result;
1249
1198
  }
1250
1199
  // src/config/config.ts
1251
- import { existsSync as existsSync10 } from "node:fs";
1252
- import { readFile as readFile8, writeFile } from "node:fs/promises";
1200
+ import { existsSync as existsSync9 } from "node:fs";
1201
+ import { readFile as readFile7, writeFile } from "node:fs/promises";
1253
1202
  var CONFIG_PATH = "omni.toml";
1254
1203
  var LOCAL_CONFIG = "omni.local.toml";
1255
1204
  function mergeConfigs(base, override) {
1256
1205
  const merged = { ...base, ...override };
1257
- merged.env = { ...base.env, ...override.env };
1258
1206
  merged.profiles = { ...base.profiles };
1259
1207
  for (const [name, profile] of Object.entries(override.profiles || {})) {
1260
1208
  merged.profiles[name] = {
@@ -1268,8 +1216,8 @@ function mergeConfigs(base, override) {
1268
1216
  return merged;
1269
1217
  }
1270
1218
  async function loadBaseConfig() {
1271
- if (existsSync10(CONFIG_PATH)) {
1272
- const content = await readFile8(CONFIG_PATH, "utf-8");
1219
+ if (existsSync9(CONFIG_PATH)) {
1220
+ const content = await readFile7(CONFIG_PATH, "utf-8");
1273
1221
  return parseOmniConfig(content);
1274
1222
  }
1275
1223
  return {};
@@ -1277,8 +1225,8 @@ async function loadBaseConfig() {
1277
1225
  async function loadConfig() {
1278
1226
  const baseConfig = await loadBaseConfig();
1279
1227
  let localConfig = {};
1280
- if (existsSync10(LOCAL_CONFIG)) {
1281
- const content = await readFile8(LOCAL_CONFIG, "utf-8");
1228
+ if (existsSync9(LOCAL_CONFIG)) {
1229
+ const content = await readFile7(LOCAL_CONFIG, "utf-8");
1282
1230
  localConfig = parseOmniConfig(content);
1283
1231
  }
1284
1232
  return mergeConfigs(baseConfig, localConfig);
@@ -1289,22 +1237,6 @@ async function writeConfig(config) {
1289
1237
  }
1290
1238
  function generateConfigToml(config) {
1291
1239
  const lines = [];
1292
- lines.push("# =============================================================================");
1293
- lines.push("# OmniDev Configuration");
1294
- lines.push("# =============================================================================");
1295
- lines.push("# This file defines your project's capabilities, profiles, and settings.");
1296
- lines.push("#");
1297
- lines.push("# Files:");
1298
- lines.push("# • omni.toml - Main config (commit to share with team)");
1299
- lines.push("# • omni.local.toml - Local overrides (add to .gitignore)");
1300
- lines.push("# • omni.lock.toml - Version lock file (commit for reproducibility)");
1301
- lines.push("#");
1302
- lines.push("# Quick start:");
1303
- lines.push("# 1. Add capability sources to [capabilities.sources]");
1304
- lines.push("# 2. Reference them in your profiles");
1305
- lines.push("# 3. Run: omnidev sync");
1306
- lines.push("# 4. Switch profiles: omnidev profile use <name>");
1307
- lines.push("");
1308
1240
  if (config.providers?.enabled && config.providers.enabled.length > 0) {
1309
1241
  lines.push("# AI providers to enable (claude, codex, or both)");
1310
1242
  lines.push("[providers]");
@@ -1312,23 +1244,6 @@ function generateConfigToml(config) {
1312
1244
  lines.push("");
1313
1245
  }
1314
1246
  lines.push("# =============================================================================");
1315
- lines.push("# Environment Variables");
1316
- lines.push("# =============================================================================");
1317
- lines.push("# Global environment variables available to all capabilities.");
1318
- lines.push("# Use ${VAR_NAME} syntax to reference shell environment variables.");
1319
- lines.push("#");
1320
- if (config.env && Object.keys(config.env).length > 0) {
1321
- lines.push("[env]");
1322
- for (const [key, value] of Object.entries(config.env)) {
1323
- lines.push(`${key} = "${value}"`);
1324
- }
1325
- } else {
1326
- lines.push("# [env]");
1327
- lines.push('# DATABASE_URL = "${DATABASE_URL}"');
1328
- lines.push('# API_KEY = "${MY_API_KEY}"');
1329
- }
1330
- lines.push("");
1331
- lines.push("# =============================================================================");
1332
1247
  lines.push("# Capability Sources");
1333
1248
  lines.push("# =============================================================================");
1334
1249
  lines.push("# Fetch capabilities from Git repositories. On sync, these are");
@@ -1382,6 +1297,22 @@ function generateConfigToml(config) {
1382
1297
  }
1383
1298
  lines.push("");
1384
1299
  lines.push("# =============================================================================");
1300
+ lines.push("# Always Enabled Capabilities");
1301
+ lines.push("# =============================================================================");
1302
+ lines.push("# Capabilities that load in ALL profiles, regardless of profile config.");
1303
+ lines.push("# Useful for essential tools needed everywhere.");
1304
+ lines.push("#");
1305
+ const alwaysEnabled = config.capabilities?.always_enabled;
1306
+ if (alwaysEnabled && alwaysEnabled.length > 0) {
1307
+ const caps = alwaysEnabled.map((c) => `"${c}"`).join(", ");
1308
+ lines.push(`[capabilities]`);
1309
+ lines.push(`always_enabled = [${caps}]`);
1310
+ } else {
1311
+ lines.push("# [capabilities]");
1312
+ lines.push('# always_enabled = ["git-tools", "linting"]');
1313
+ }
1314
+ lines.push("");
1315
+ lines.push("# =============================================================================");
1385
1316
  lines.push("# MCP Servers");
1386
1317
  lines.push("# =============================================================================");
1387
1318
  lines.push("# Define MCP servers that automatically become capabilities.");
@@ -1408,10 +1339,8 @@ function generateConfigToml(config) {
1408
1339
  lines.push(`url = "${mcpConfig.url}"`);
1409
1340
  }
1410
1341
  if (mcpConfig.env && Object.keys(mcpConfig.env).length > 0) {
1411
- lines.push(`[mcps.${name}.env]`);
1412
- for (const [key, value] of Object.entries(mcpConfig.env)) {
1413
- lines.push(`${key} = "${value}"`);
1414
- }
1342
+ const entries = Object.entries(mcpConfig.env).map(([key, value]) => `${key} = "${value}"`);
1343
+ lines.push(`env = { ${entries.join(", ")} }`);
1415
1344
  }
1416
1345
  if (mcpConfig.headers && Object.keys(mcpConfig.headers).length > 0) {
1417
1346
  lines.push(`[mcps.${name}.headers]`);
@@ -1431,24 +1360,10 @@ function generateConfigToml(config) {
1431
1360
  lines.push('# command = "node"');
1432
1361
  lines.push('# args = ["./servers/database.js"]');
1433
1362
  lines.push('# cwd = "./mcp-servers"');
1434
- lines.push("# [mcps.database.env]");
1435
- lines.push('# DB_URL = "${DATABASE_URL}"');
1363
+ lines.push('# env = { DB_URL = "${DATABASE_URL}" }');
1436
1364
  lines.push("");
1437
1365
  }
1438
1366
  lines.push("# =============================================================================");
1439
- lines.push("# Always Enabled Capabilities");
1440
- lines.push("# =============================================================================");
1441
- lines.push("# Capabilities that load in ALL profiles, regardless of profile config.");
1442
- lines.push("# Useful for essential tools needed everywhere.");
1443
- lines.push("#");
1444
- if (config.always_enabled_capabilities && config.always_enabled_capabilities.length > 0) {
1445
- const caps = config.always_enabled_capabilities.map((c) => `"${c}"`).join(", ");
1446
- lines.push(`always_enabled_capabilities = [${caps}]`);
1447
- } else {
1448
- lines.push('# always_enabled_capabilities = ["git-tools", "linting"]');
1449
- }
1450
- lines.push("");
1451
- lines.push("# =============================================================================");
1452
1367
  lines.push("# Profiles");
1453
1368
  lines.push("# =============================================================================");
1454
1369
  lines.push("# Define different capability sets for different workflows.");
@@ -1471,16 +1386,16 @@ function generateConfigToml(config) {
1471
1386
  }
1472
1387
 
1473
1388
  // src/state/active-profile.ts
1474
- import { existsSync as existsSync11, mkdirSync } from "node:fs";
1475
- import { readFile as readFile9, unlink, writeFile as writeFile2 } from "node:fs/promises";
1389
+ import { existsSync as existsSync10, mkdirSync } from "node:fs";
1390
+ import { readFile as readFile8, unlink, writeFile as writeFile2 } from "node:fs/promises";
1476
1391
  var STATE_DIR = ".omni/state";
1477
1392
  var ACTIVE_PROFILE_PATH = `${STATE_DIR}/active-profile`;
1478
1393
  async function readActiveProfileState() {
1479
- if (!existsSync11(ACTIVE_PROFILE_PATH)) {
1394
+ if (!existsSync10(ACTIVE_PROFILE_PATH)) {
1480
1395
  return null;
1481
1396
  }
1482
1397
  try {
1483
- const content = await readFile9(ACTIVE_PROFILE_PATH, "utf-8");
1398
+ const content = await readFile8(ACTIVE_PROFILE_PATH, "utf-8");
1484
1399
  const trimmed = content.trim();
1485
1400
  return trimmed || null;
1486
1401
  } catch {
@@ -1492,27 +1407,22 @@ async function writeActiveProfileState(profileName) {
1492
1407
  await writeFile2(ACTIVE_PROFILE_PATH, profileName, "utf-8");
1493
1408
  }
1494
1409
  async function clearActiveProfileState() {
1495
- if (existsSync11(ACTIVE_PROFILE_PATH)) {
1410
+ if (existsSync10(ACTIVE_PROFILE_PATH)) {
1496
1411
  await unlink(ACTIVE_PROFILE_PATH);
1497
1412
  }
1498
1413
  }
1499
1414
 
1500
1415
  // src/config/profiles.ts
1501
1416
  async function getActiveProfile() {
1502
- const stateProfile = await readActiveProfileState();
1503
- if (stateProfile) {
1504
- return stateProfile;
1505
- }
1506
- const config = await loadConfig();
1507
- return config.active_profile ?? null;
1417
+ return await readActiveProfileState();
1508
1418
  }
1509
1419
  async function setActiveProfile(name) {
1510
1420
  await writeActiveProfileState(name);
1511
1421
  }
1512
1422
  function resolveEnabledCapabilities(config, profileName) {
1513
- const profile = profileName ? config.profiles?.[profileName] : config.profiles?.[config.active_profile ?? "default"];
1423
+ const profile = profileName ? config.profiles?.[profileName] : config.profiles?.["default"];
1514
1424
  const profileCapabilities = profile?.capabilities ?? [];
1515
- const alwaysEnabled = config.always_enabled_capabilities ?? [];
1425
+ const alwaysEnabled = config.capabilities?.always_enabled ?? [];
1516
1426
  const groups = config.capabilities?.groups ?? {};
1517
1427
  const expandCapabilities = (caps) => {
1518
1428
  return caps.flatMap((cap) => {
@@ -1548,12 +1458,12 @@ async function setProfile(profileName, profileConfig) {
1548
1458
  // src/config/capabilities.ts
1549
1459
  async function getEnabledCapabilities() {
1550
1460
  const config = await loadConfig();
1551
- const activeProfile = await getActiveProfile() ?? config.active_profile ?? "default";
1461
+ const activeProfile = await getActiveProfile() ?? "default";
1552
1462
  return resolveEnabledCapabilities(config, activeProfile);
1553
1463
  }
1554
1464
  async function enableCapability(capabilityId) {
1555
1465
  const config = await loadBaseConfig();
1556
- const activeProfile = await getActiveProfile() ?? config.active_profile ?? "default";
1466
+ const activeProfile = await getActiveProfile() ?? "default";
1557
1467
  if (!config.profiles) {
1558
1468
  config.profiles = {};
1559
1469
  }
@@ -1567,7 +1477,7 @@ async function enableCapability(capabilityId) {
1567
1477
  }
1568
1478
  async function disableCapability(capabilityId) {
1569
1479
  const config = await loadBaseConfig();
1570
- const activeProfile = await getActiveProfile() ?? config.active_profile ?? "default";
1480
+ const activeProfile = await getActiveProfile() ?? "default";
1571
1481
  if (!config.profiles?.[activeProfile]) {
1572
1482
  return;
1573
1483
  }
@@ -1666,13 +1576,12 @@ function getEventsWithHooks(config) {
1666
1576
 
1667
1577
  // src/capability/registry.ts
1668
1578
  async function buildCapabilityRegistry() {
1669
- const env = await loadEnvironment();
1670
1579
  const enabledIds = await getEnabledCapabilities();
1671
1580
  const capabilityPaths = await discoverCapabilities();
1672
1581
  const capabilities = new Map;
1673
1582
  for (const path of capabilityPaths) {
1674
1583
  try {
1675
- const cap = await loadCapability(path, env);
1584
+ const cap = await loadCapability(path);
1676
1585
  if (enabledIds.includes(cap.id)) {
1677
1586
  capabilities.set(cap.id, cap);
1678
1587
  }
@@ -1703,9 +1612,9 @@ async function buildCapabilityRegistry() {
1703
1612
  };
1704
1613
  }
1705
1614
  // src/capability/sources.ts
1706
- import { existsSync as existsSync12 } from "node:fs";
1615
+ import { existsSync as existsSync11 } from "node:fs";
1707
1616
  import { spawn } from "node:child_process";
1708
- import { cp, mkdir, readdir, readFile as readFile10, rename, rm, stat, writeFile as writeFile3 } from "node:fs/promises";
1617
+ import { cp, mkdir, readdir, readFile as readFile9, rename, rm, stat, writeFile as writeFile3 } from "node:fs/promises";
1709
1618
  import { join as join8 } from "node:path";
1710
1619
  import { parse as parseToml2 } from "smol-toml";
1711
1620
 
@@ -1770,9 +1679,9 @@ function parseFileSourcePath(source) {
1770
1679
  }
1771
1680
  async function readCapabilityIdFromPath(capabilityPath) {
1772
1681
  const tomlPath = join8(capabilityPath, "capability.toml");
1773
- if (existsSync12(tomlPath)) {
1682
+ if (existsSync11(tomlPath)) {
1774
1683
  try {
1775
- const content = await readFile10(tomlPath, "utf-8");
1684
+ const content = await readFile9(tomlPath, "utf-8");
1776
1685
  const parsed = parseToml2(content);
1777
1686
  const capability = parsed["capability"];
1778
1687
  if (capability?.["id"] && typeof capability["id"] === "string") {
@@ -1822,11 +1731,11 @@ function getLockFilePath() {
1822
1731
  }
1823
1732
  async function loadLockFile() {
1824
1733
  const lockPath = getLockFilePath();
1825
- if (!existsSync12(lockPath)) {
1734
+ if (!existsSync11(lockPath)) {
1826
1735
  return { capabilities: {} };
1827
1736
  }
1828
1737
  try {
1829
- const content = await readFile10(lockPath, "utf-8");
1738
+ const content = await readFile9(lockPath, "utf-8");
1830
1739
  const parsed = parseToml2(content);
1831
1740
  const capabilities = parsed["capabilities"];
1832
1741
  return {
@@ -1915,16 +1824,16 @@ async function fetchRepo(repoPath, ref) {
1915
1824
  return true;
1916
1825
  }
1917
1826
  function hasCapabilityToml(dirPath) {
1918
- return existsSync12(join8(dirPath, "capability.toml"));
1827
+ return existsSync11(join8(dirPath, "capability.toml"));
1919
1828
  }
1920
1829
  async function shouldWrapDirectory(dirPath) {
1921
- if (existsSync12(join8(dirPath, ".claude-plugin", "plugin.json"))) {
1830
+ if (existsSync11(join8(dirPath, ".claude-plugin", "plugin.json"))) {
1922
1831
  return true;
1923
1832
  }
1924
1833
  const allDirs = [...SKILL_DIRS, ...AGENT_DIRS, ...COMMAND_DIRS, ...RULE_DIRS, ...DOC_DIRS];
1925
1834
  for (const dirName of allDirs) {
1926
1835
  const checkPath = join8(dirPath, dirName);
1927
- if (existsSync12(checkPath)) {
1836
+ if (existsSync11(checkPath)) {
1928
1837
  const stats = await stat(checkPath);
1929
1838
  if (stats.isDirectory()) {
1930
1839
  return true;
@@ -1936,7 +1845,7 @@ async function shouldWrapDirectory(dirPath) {
1936
1845
  async function findMatchingDirs(basePath, names) {
1937
1846
  for (const name of names) {
1938
1847
  const dirPath = join8(basePath, name);
1939
- if (existsSync12(dirPath)) {
1848
+ if (existsSync11(dirPath)) {
1940
1849
  const stats = await stat(dirPath);
1941
1850
  if (stats.isDirectory()) {
1942
1851
  return dirPath;
@@ -1947,7 +1856,7 @@ async function findMatchingDirs(basePath, names) {
1947
1856
  }
1948
1857
  async function findContentItems(dirPath, filePatterns) {
1949
1858
  const items = [];
1950
- if (!existsSync12(dirPath)) {
1859
+ if (!existsSync11(dirPath)) {
1951
1860
  return items;
1952
1861
  }
1953
1862
  const entries = (await readdir(dirPath, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name));
@@ -1955,7 +1864,7 @@ async function findContentItems(dirPath, filePatterns) {
1955
1864
  const entryPath = join8(dirPath, entry.name);
1956
1865
  if (entry.isDirectory()) {
1957
1866
  for (const pattern of filePatterns) {
1958
- if (existsSync12(join8(entryPath, pattern))) {
1867
+ if (existsSync11(join8(entryPath, pattern))) {
1959
1868
  items.push({
1960
1869
  name: entry.name,
1961
1870
  path: entryPath,
@@ -1977,11 +1886,11 @@ async function findContentItems(dirPath, filePatterns) {
1977
1886
  }
1978
1887
  async function parsePluginJson(dirPath) {
1979
1888
  const pluginJsonPath = join8(dirPath, ".claude-plugin", "plugin.json");
1980
- if (!existsSync12(pluginJsonPath)) {
1889
+ if (!existsSync11(pluginJsonPath)) {
1981
1890
  return null;
1982
1891
  }
1983
1892
  try {
1984
- const content = await readFile10(pluginJsonPath, "utf-8");
1893
+ const content = await readFile9(pluginJsonPath, "utf-8");
1985
1894
  const data = JSON.parse(content);
1986
1895
  const result = {
1987
1896
  name: data.name,
@@ -2002,11 +1911,11 @@ async function parsePluginJson(dirPath) {
2002
1911
  }
2003
1912
  async function readReadmeDescription(dirPath) {
2004
1913
  const readmePath = join8(dirPath, "README.md");
2005
- if (!existsSync12(readmePath)) {
1914
+ if (!existsSync11(readmePath)) {
2006
1915
  return null;
2007
1916
  }
2008
1917
  try {
2009
- const content = await readFile10(readmePath, "utf-8");
1918
+ const content = await readFile9(readmePath, "utf-8");
2010
1919
  const lines = content.split(`
2011
1920
  `);
2012
1921
  let description = "";
@@ -2045,7 +1954,7 @@ async function normalizeFolderNames(repoPath) {
2045
1954
  for (const { from, to } of renameMappings) {
2046
1955
  const fromPath = join8(repoPath, from);
2047
1956
  const toPath = join8(repoPath, to);
2048
- if (existsSync12(fromPath) && !existsSync12(toPath)) {
1957
+ if (existsSync11(fromPath) && !existsSync11(toPath)) {
2049
1958
  try {
2050
1959
  const stats = await stat(fromPath);
2051
1960
  if (stats.isDirectory()) {
@@ -2144,7 +2053,7 @@ async function fetchGitCapabilitySource(id, config, options) {
2144
2053
  let repoPath;
2145
2054
  if (config.path) {
2146
2055
  const tempPath = join8(OMNI_LOCAL, "_temp", `${id}-repo`);
2147
- if (existsSync12(join8(tempPath, ".git"))) {
2056
+ if (existsSync11(join8(tempPath, ".git"))) {
2148
2057
  if (!options?.silent) {
2149
2058
  console.log(` Checking ${id}...`);
2150
2059
  }
@@ -2160,17 +2069,17 @@ async function fetchGitCapabilitySource(id, config, options) {
2160
2069
  updated = true;
2161
2070
  }
2162
2071
  const sourcePath = join8(tempPath, config.path);
2163
- if (!existsSync12(sourcePath)) {
2072
+ if (!existsSync11(sourcePath)) {
2164
2073
  throw new Error(`Path not found in repository: ${config.path}`);
2165
2074
  }
2166
- if (existsSync12(targetPath)) {
2075
+ if (existsSync11(targetPath)) {
2167
2076
  await rm(targetPath, { recursive: true });
2168
2077
  }
2169
2078
  await mkdir(join8(targetPath, ".."), { recursive: true });
2170
2079
  await cp(sourcePath, targetPath, { recursive: true });
2171
2080
  repoPath = targetPath;
2172
2081
  } else {
2173
- if (existsSync12(join8(targetPath, ".git"))) {
2082
+ if (existsSync11(join8(targetPath, ".git"))) {
2174
2083
  if (!options?.silent) {
2175
2084
  console.log(` Checking ${id}...`);
2176
2085
  }
@@ -2209,9 +2118,9 @@ async function fetchGitCapabilitySource(id, config, options) {
2209
2118
  }
2210
2119
  let version = shortCommit(commit);
2211
2120
  const pkgJsonPath = join8(repoPath, "package.json");
2212
- if (existsSync12(pkgJsonPath)) {
2121
+ if (existsSync11(pkgJsonPath)) {
2213
2122
  try {
2214
- const pkgJson = JSON.parse(await readFile10(pkgJsonPath, "utf-8"));
2123
+ const pkgJson = JSON.parse(await readFile9(pkgJsonPath, "utf-8"));
2215
2124
  if (pkgJson.version) {
2216
2125
  version = pkgJson.version;
2217
2126
  }
@@ -2229,29 +2138,29 @@ async function fetchGitCapabilitySource(id, config, options) {
2229
2138
  async function fetchFileCapabilitySource(id, config, options) {
2230
2139
  const sourcePath = parseFileSourcePath(config.source);
2231
2140
  const targetPath = getSourceCapabilityPath(id);
2232
- if (!existsSync12(sourcePath)) {
2141
+ if (!existsSync11(sourcePath)) {
2233
2142
  throw new Error(`File source not found: ${sourcePath}`);
2234
2143
  }
2235
2144
  const sourceStats = await stat(sourcePath);
2236
2145
  if (!sourceStats.isDirectory()) {
2237
2146
  throw new Error(`File source must be a directory: ${sourcePath}`);
2238
2147
  }
2239
- if (!existsSync12(join8(sourcePath, "capability.toml"))) {
2148
+ if (!existsSync11(join8(sourcePath, "capability.toml"))) {
2240
2149
  throw new Error(`No capability.toml found in: ${sourcePath}`);
2241
2150
  }
2242
2151
  if (!options?.silent) {
2243
2152
  console.log(` Copying ${id} from ${sourcePath}...`);
2244
2153
  }
2245
- if (existsSync12(targetPath)) {
2154
+ if (existsSync11(targetPath)) {
2246
2155
  await rm(targetPath, { recursive: true });
2247
2156
  }
2248
2157
  await mkdir(join8(targetPath, ".."), { recursive: true });
2249
2158
  await cp(sourcePath, targetPath, { recursive: true });
2250
2159
  let version = "local";
2251
2160
  const capTomlPath = join8(targetPath, "capability.toml");
2252
- if (existsSync12(capTomlPath)) {
2161
+ if (existsSync11(capTomlPath)) {
2253
2162
  try {
2254
- const content = await readFile10(capTomlPath, "utf-8");
2163
+ const content = await readFile9(capTomlPath, "utf-8");
2255
2164
  const parsed = parseToml2(content);
2256
2165
  const capability = parsed["capability"];
2257
2166
  if (capability?.["version"] && typeof capability["version"] === "string") {
@@ -2342,12 +2251,12 @@ async function generateMcpCapabilityToml(id, mcpConfig, targetPath) {
2342
2251
  }
2343
2252
  async function isGeneratedMcpCapability(capabilityDir) {
2344
2253
  const tomlPath = join8(capabilityDir, "capability.toml");
2345
- if (!existsSync12(tomlPath)) {
2254
+ if (!existsSync11(tomlPath)) {
2346
2255
  console.warn("no capability.toml found in", capabilityDir);
2347
2256
  return false;
2348
2257
  }
2349
2258
  try {
2350
- const content = await readFile10(tomlPath, "utf-8");
2259
+ const content = await readFile9(tomlPath, "utf-8");
2351
2260
  const parsed = parseToml2(content);
2352
2261
  const capability = parsed["capability"];
2353
2262
  const metadata = capability?.["metadata"];
@@ -2358,7 +2267,7 @@ async function isGeneratedMcpCapability(capabilityDir) {
2358
2267
  }
2359
2268
  async function cleanupStaleMcpCapabilities(currentMcpIds) {
2360
2269
  const capabilitiesDir = join8(OMNI_LOCAL, "capabilities");
2361
- if (!existsSync12(capabilitiesDir)) {
2270
+ if (!existsSync11(capabilitiesDir)) {
2362
2271
  return;
2363
2272
  }
2364
2273
  const entries = await readdir(capabilitiesDir, { withFileTypes: true });
@@ -2466,7 +2375,7 @@ async function checkForUpdates(config) {
2466
2375
  continue;
2467
2376
  }
2468
2377
  const gitConfig = sourceConfig;
2469
- if (!existsSync12(join8(targetPath, ".git"))) {
2378
+ if (!existsSync11(join8(targetPath, ".git"))) {
2470
2379
  updates.push({
2471
2380
  id,
2472
2381
  source: gitConfig.source,
@@ -2502,15 +2411,15 @@ async function checkForUpdates(config) {
2502
2411
  return updates;
2503
2412
  }
2504
2413
  // src/config/provider.ts
2505
- import { existsSync as existsSync13 } from "node:fs";
2506
- import { readFile as readFile11, writeFile as writeFile4 } from "node:fs/promises";
2414
+ import { existsSync as existsSync12 } from "node:fs";
2415
+ import { readFile as readFile10, writeFile as writeFile4 } from "node:fs/promises";
2507
2416
  import { parse as parse2 } from "smol-toml";
2508
2417
  var PROVIDER_CONFIG_PATH = ".omni/provider.toml";
2509
2418
  async function loadProviderConfig() {
2510
- if (!existsSync13(PROVIDER_CONFIG_PATH)) {
2419
+ if (!existsSync12(PROVIDER_CONFIG_PATH)) {
2511
2420
  return { provider: "claude" };
2512
2421
  }
2513
- const content = await readFile11(PROVIDER_CONFIG_PATH, "utf-8");
2422
+ const content = await readFile10(PROVIDER_CONFIG_PATH, "utf-8");
2514
2423
  const parsed = parse2(content);
2515
2424
  return parsed;
2516
2425
  }
@@ -2552,14 +2461,14 @@ function parseProviderFlag(flag) {
2552
2461
  throw new Error(`Invalid provider: ${flag}. Must be 'claude', 'codex', or 'both'.`);
2553
2462
  }
2554
2463
  // src/config/toml-patcher.ts
2555
- import { existsSync as existsSync14 } from "node:fs";
2556
- import { readFile as readFile12, writeFile as writeFile5 } from "node:fs/promises";
2464
+ import { existsSync as existsSync13 } from "node:fs";
2465
+ import { readFile as readFile11, writeFile as writeFile5 } from "node:fs/promises";
2557
2466
  var CONFIG_PATH2 = "omni.toml";
2558
2467
  async function readConfigFile() {
2559
- if (!existsSync14(CONFIG_PATH2)) {
2468
+ if (!existsSync13(CONFIG_PATH2)) {
2560
2469
  return "";
2561
2470
  }
2562
- return readFile12(CONFIG_PATH2, "utf-8");
2471
+ return readFile11(CONFIG_PATH2, "utf-8");
2563
2472
  }
2564
2473
  async function writeConfigFile(content) {
2565
2474
  await writeFile5(CONFIG_PATH2, content, "utf-8");
@@ -2649,10 +2558,8 @@ function formatMcpConfig(name, config) {
2649
2558
  lines.push(`url = "${config.url}"`);
2650
2559
  }
2651
2560
  if (config.env && Object.keys(config.env).length > 0) {
2652
- lines.push(`[mcps.${name}.env]`);
2653
- for (const [key, value] of Object.entries(config.env)) {
2654
- lines.push(`${key} = "${value}"`);
2655
- }
2561
+ const entries = Object.entries(config.env).map(([key, value]) => `${key} = "${value}"`);
2562
+ lines.push(`env = { ${entries.join(", ")} }`);
2656
2563
  }
2657
2564
  if (config.headers && Object.keys(config.headers).length > 0) {
2658
2565
  lines.push(`[mcps.${name}.headers]`);
@@ -2758,15 +2665,15 @@ function escapeRegExp(str) {
2758
2665
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2759
2666
  }
2760
2667
  // src/mcp-json/manager.ts
2761
- import { existsSync as existsSync15 } from "node:fs";
2762
- import { readFile as readFile13, writeFile as writeFile6 } from "node:fs/promises";
2668
+ import { existsSync as existsSync14 } from "node:fs";
2669
+ import { readFile as readFile12, writeFile as writeFile6 } from "node:fs/promises";
2763
2670
  var MCP_JSON_PATH = ".mcp.json";
2764
2671
  async function readMcpJson() {
2765
- if (!existsSync15(MCP_JSON_PATH)) {
2672
+ if (!existsSync14(MCP_JSON_PATH)) {
2766
2673
  return { mcpServers: {} };
2767
2674
  }
2768
2675
  try {
2769
- const content = await readFile13(MCP_JSON_PATH, "utf-8");
2676
+ const content = await readFile12(MCP_JSON_PATH, "utf-8");
2770
2677
  const parsed = JSON.parse(content);
2771
2678
  return {
2772
2679
  mcpServers: parsed.mcpServers || {}
@@ -2845,19 +2752,19 @@ async function syncMcpJson(capabilities2, previousManifest, options = {}) {
2845
2752
  }
2846
2753
  }
2847
2754
  // src/state/manifest.ts
2848
- import { existsSync as existsSync16, mkdirSync as mkdirSync2, rmSync } from "node:fs";
2849
- import { readFile as readFile14, writeFile as writeFile7 } from "node:fs/promises";
2755
+ import { existsSync as existsSync15, mkdirSync as mkdirSync2, rmSync } from "node:fs";
2756
+ import { readFile as readFile13, writeFile as writeFile7 } from "node:fs/promises";
2850
2757
  var MANIFEST_PATH = ".omni/state/manifest.json";
2851
2758
  var CURRENT_VERSION = 1;
2852
2759
  async function loadManifest() {
2853
- if (!existsSync16(MANIFEST_PATH)) {
2760
+ if (!existsSync15(MANIFEST_PATH)) {
2854
2761
  return {
2855
2762
  version: CURRENT_VERSION,
2856
2763
  syncedAt: new Date().toISOString(),
2857
2764
  capabilities: {}
2858
2765
  };
2859
2766
  }
2860
- const content = await readFile14(MANIFEST_PATH, "utf-8");
2767
+ const content = await readFile13(MANIFEST_PATH, "utf-8");
2861
2768
  return JSON.parse(content);
2862
2769
  }
2863
2770
  async function saveManifest(manifest) {
@@ -2897,14 +2804,14 @@ async function cleanupStaleResources(previousManifest, currentCapabilityIds) {
2897
2804
  }
2898
2805
  for (const skillName of resources.skills) {
2899
2806
  const skillDir = `.claude/skills/${skillName}`;
2900
- if (existsSync16(skillDir)) {
2807
+ if (existsSync15(skillDir)) {
2901
2808
  rmSync(skillDir, { recursive: true });
2902
2809
  result.deletedSkills.push(skillName);
2903
2810
  }
2904
2811
  }
2905
2812
  for (const ruleName of resources.rules) {
2906
2813
  const rulePath = `.cursor/rules/omnidev-${ruleName}.mdc`;
2907
- if (existsSync16(rulePath)) {
2814
+ if (existsSync15(rulePath)) {
2908
2815
  rmSync(rulePath);
2909
2816
  result.deletedRules.push(ruleName);
2910
2817
  }
@@ -2913,17 +2820,17 @@ async function cleanupStaleResources(previousManifest, currentCapabilityIds) {
2913
2820
  return result;
2914
2821
  }
2915
2822
  // src/state/providers.ts
2916
- import { existsSync as existsSync17, mkdirSync as mkdirSync3 } from "node:fs";
2917
- import { readFile as readFile15, writeFile as writeFile8 } from "node:fs/promises";
2823
+ import { existsSync as existsSync16, mkdirSync as mkdirSync3 } from "node:fs";
2824
+ import { readFile as readFile14, writeFile as writeFile8 } from "node:fs/promises";
2918
2825
  var STATE_DIR2 = ".omni/state";
2919
2826
  var PROVIDERS_PATH = `${STATE_DIR2}/providers.json`;
2920
2827
  var DEFAULT_PROVIDERS = ["claude-code"];
2921
2828
  async function readEnabledProviders() {
2922
- if (!existsSync17(PROVIDERS_PATH)) {
2829
+ if (!existsSync16(PROVIDERS_PATH)) {
2923
2830
  return DEFAULT_PROVIDERS;
2924
2831
  }
2925
2832
  try {
2926
- const content = await readFile15(PROVIDERS_PATH, "utf-8");
2833
+ const content = await readFile14(PROVIDERS_PATH, "utf-8");
2927
2834
  const state = JSON.parse(content);
2928
2835
  return state.enabled.length > 0 ? state.enabled : DEFAULT_PROVIDERS;
2929
2836
  } catch {
@@ -2955,10 +2862,10 @@ async function isProviderEnabled(providerId) {
2955
2862
  import { spawn as spawn2 } from "node:child_process";
2956
2863
  import { mkdirSync as mkdirSync4 } from "node:fs";
2957
2864
  async function installCapabilityDependencies(silent) {
2958
- const { existsSync: existsSync18, readdirSync: readdirSync7 } = await import("node:fs");
2865
+ const { existsSync: existsSync17, readdirSync: readdirSync7 } = await import("node:fs");
2959
2866
  const { join: join9 } = await import("node:path");
2960
2867
  const capabilitiesDir = ".omni/capabilities";
2961
- if (!existsSync18(capabilitiesDir)) {
2868
+ if (!existsSync17(capabilitiesDir)) {
2962
2869
  return;
2963
2870
  }
2964
2871
  const entries = readdirSync7(capabilitiesDir, { withFileTypes: true });
@@ -2980,14 +2887,14 @@ async function installCapabilityDependencies(silent) {
2980
2887
  }
2981
2888
  const capabilityPath = join9(capabilitiesDir, entry.name);
2982
2889
  const packageJsonPath = join9(capabilityPath, "package.json");
2983
- if (!existsSync18(packageJsonPath)) {
2890
+ if (!existsSync17(packageJsonPath)) {
2984
2891
  continue;
2985
2892
  }
2986
2893
  if (!silent) {
2987
2894
  console.log(`Installing dependencies for ${capabilityPath}...`);
2988
2895
  }
2989
2896
  await new Promise((resolve2, reject) => {
2990
- const useNpmCi = hasNpm && existsSync18(join9(capabilityPath, "package-lock.json"));
2897
+ const useNpmCi = hasNpm && existsSync17(join9(capabilityPath, "package-lock.json"));
2991
2898
  const cmd = hasBun ? "bun" : "npm";
2992
2899
  const args = hasBun ? ["install"] : useNpmCi ? ["ci"] : ["install"];
2993
2900
  const proc = spawn2(cmd, args, {
@@ -3110,38 +3017,17 @@ async function syncAgentConfiguration(options) {
3110
3017
  docCount: bundle.docs.length
3111
3018
  };
3112
3019
  }
3113
- function generateInstructionsContent(rules, docs) {
3114
- if (rules.length === 0 && docs.length === 0) {
3115
- return `## Capabilities
3116
-
3117
- No capabilities enabled yet. Run \`omnidev capability enable <name>\` to enable capabilities.`;
3118
- }
3119
- let content = `## Capabilities
3120
-
3121
- `;
3122
- if (docs.length > 0) {
3123
- content += `### Documentation
3124
-
3125
- `;
3126
- for (const doc of docs) {
3127
- content += `#### ${doc.name} (from ${doc.capabilityId})
3128
-
3129
- ${doc.content}
3130
-
3131
- `;
3132
- }
3020
+ function generateInstructionsContent(rules, _docs) {
3021
+ if (rules.length === 0) {
3022
+ return "";
3133
3023
  }
3134
- if (rules.length > 0) {
3135
- content += `### Rules
3024
+ let content = `## Rules
3136
3025
 
3137
3026
  `;
3138
- for (const rule of rules) {
3139
- content += `#### ${rule.name} (from ${rule.capabilityId})
3140
-
3141
- ${rule.content}
3027
+ for (const rule of rules) {
3028
+ content += `${rule.content}
3142
3029
 
3143
3030
  `;
3144
- }
3145
3031
  }
3146
3032
  return content.trim();
3147
3033
  }
@@ -3211,33 +3097,12 @@ TODO: Add example usage
3211
3097
  `;
3212
3098
  }
3213
3099
  function generateRuleTemplate(ruleName) {
3214
- return `# ${formatDisplayName(ruleName)}
3100
+ return `### ${formatDisplayName(ruleName)}
3215
3101
 
3216
3102
  <!-- Rules are guidelines that the AI agent should follow when working in this project -->
3103
+ <!-- Each rule should start with a ### header -->
3217
3104
 
3218
- ## Overview
3219
-
3220
- TODO: Describe what this rule enforces or guides.
3221
-
3222
- ## Guidelines
3223
-
3224
- - TODO: Add specific guidelines the AI should follow
3225
- - Be specific and actionable
3226
- - Include examples where helpful
3227
-
3228
- ## Examples
3229
-
3230
- ### Good
3231
-
3232
- \`\`\`
3233
- TODO: Add example of correct behavior
3234
- \`\`\`
3235
-
3236
- ### Bad
3237
-
3238
- \`\`\`
3239
- TODO: Add example of incorrect behavior
3240
- \`\`\`
3105
+ TODO: Add specific guidelines the AI should follow. Be specific and actionable.
3241
3106
  `;
3242
3107
  }
3243
3108
  function generateHooksTemplate() {
@@ -3293,10 +3158,6 @@ function generateClaudeTemplate() {
3293
3158
  return `# Project Instructions
3294
3159
 
3295
3160
  <!-- Add your project-specific instructions here -->
3296
-
3297
- ## OmniDev
3298
-
3299
- <!-- This section is populated during sync with capability rules and docs -->
3300
3161
  `;
3301
3162
  }
3302
3163
  // src/templates/omni.ts
@@ -3349,7 +3210,6 @@ export {
3349
3210
  version,
3350
3211
  validateHooksConfig,
3351
3212
  validateHook,
3352
- validateEnv,
3353
3213
  transformToOmnidev,
3354
3214
  transformToClaude,
3355
3215
  transformHooksConfig,
@@ -3383,7 +3243,6 @@ export {
3383
3243
  loadManifest,
3384
3244
  loadLockFile,
3385
3245
  loadHooksFromCapability,
3386
- loadEnvironment,
3387
3246
  loadDocs,
3388
3247
  loadConfig,
3389
3248
  loadCommands,
@@ -3392,7 +3251,6 @@ export {
3392
3251
  loadCapability,
3393
3252
  loadBaseConfig,
3394
3253
  isValidMatcherPattern,
3395
- isSecretEnvVar,
3396
3254
  isProviderEnabled,
3397
3255
  isPromptHookEvent,
3398
3256
  isMatcherEvent,